|
From: Tapio V. <aa...@us...> - 2010-08-21 14:02:13
|
Module: performous
Branch: joinmenu
Commit: 1b0da1dc3e26db845c41583c51e50e2a6eabeb46
Author: Tapio Vierros <tap...@gm...>
Date: Mon Aug 16 23:08:35 2010 +0300
Use OpenCV C++ API for Webcam, also use and catch exceptions.
---
game/screen_sing.cc | 8 ++++--
game/webcam.cc | 57 ++++++++++++++++++++++++++++----------------------
game/webcam.hh | 11 ++++++---
3 files changed, 44 insertions(+), 32 deletions(-)
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index a32966d..3543c3e 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -58,7 +58,9 @@ void ScreenSing::enter() {
}
// Initialize webcam
if (config["graphic/webcam"].b() && Webcam::enabled()) {
- m_cam.reset(new Webcam(config["graphic/webcamid"].i()));
+ try {
+ m_cam.reset(new Webcam(config["graphic/webcamid"].i()));
+ } catch (std::exception& e) { std::cout << e.what() << std::endl; };
}
// Load video
if (!m_song->video.empty() && config["graphic/video"].b()) {
@@ -76,7 +78,6 @@ void ScreenSing::enter() {
}
}
}
- //FIXME: this line crashes under windows. Have to fix. At moment, just don't use it on Windows
m_pause_icon.reset(new Surface(getThemePath("sing_pause.svg")));
m_help.reset(new Surface(getThemePath("instrumenthelp.svg")));
m_progress.reset(new ProgressBar(getThemePath("sing_progressbg.svg"), getThemePath("sing_progressfg.svg"), ProgressBar::HORIZONTAL, 0.01f, 0.01f, true));
@@ -252,7 +253,8 @@ void ScreenSing::manageEvent(SDL_Event event) {
if (key == SDLK_w) dispInFlash(++config["game/pitch"]); // Toggle pitch wave
// Toggle webcam
if (key == SDLK_a && Webcam::enabled()) {
- if (!m_cam) m_cam.reset(new Webcam(config["graphic/webcamid"].i())); // Initialize if we haven't done that already
+ // Initialize if we haven't done that already
+ if (!m_cam) { try { m_cam.reset(new Webcam(config["graphic/webcamid"].i())); } catch (...) { }; }
if (m_cam) { dispInFlash(++config["graphic/webcam"]); m_cam->pause(!config["graphic/webcam"].b()); }
}
// Latency settings
diff --git a/game/webcam.cc b/game/webcam.cc
index aff3c8a..1e5baa3 100644
--- a/game/webcam.cc
+++ b/game/webcam.cc
@@ -1,4 +1,5 @@
#include <iostream>
+#include <stdexcept>
#include "webcam.hh"
#include "xtime.hh"
@@ -9,38 +10,46 @@
#include <highgui.h>
#define SAVE_WEBCAM_VIDEO
+
+#else
+// Dummy classes
+namespace cv {
+ class VideoCapture {};
+ class VideoWriter {};
+}
#endif
Webcam::Webcam(int cam_id):
- m_thread(), m_capture(NULL), m_writer(NULL), m_frameAvailable(false), m_running(false), m_quit(false)
+ m_thread(), m_capture(), m_writer(), m_frameAvailable(false), m_running(false), m_quit(false)
{
#ifdef USE_OPENCV
// Initialize the capture device
- m_capture = cvCaptureFromCAM(cam_id);
- if (!m_capture) {
+ m_capture.reset(new cv::VideoCapture(cam_id));
+ if (!m_capture->isOpened()) {
if (cam_id != -1) {
- std::cout << "Webcam id " << cam_id << " failed, trying autodetecting...";
- m_capture = cvCaptureFromCAM(-1);
- }
- if (!m_capture) {
- std::cout << "Could not initialize webcam capturing!" << std::endl;
- return;
+ std::clog << "Webcam id " << cam_id << " failed, trying autodetecting...";
+ m_capture.reset(new cv::VideoCapture(-1));
}
+ if (!m_capture->isOpened())
+ throw std::runtime_error("Could not initialize webcam capturing!");
}
// Initialize the video writer
#ifdef SAVE_WEBCAM_VIDEO
- float fps = cvGetCaptureProperty(m_capture, CV_CAP_PROP_FPS);
- int framew = cvGetCaptureProperty(m_capture, CV_CAP_PROP_FRAME_WIDTH);
- int frameh = cvGetCaptureProperty(m_capture, CV_CAP_PROP_FRAME_HEIGHT);
+ float fps = m_capture->get(CV_CAP_PROP_FPS);
+ int framew = m_capture->get(CV_CAP_PROP_FRAME_WIDTH);
+ int frameh = m_capture->get(CV_CAP_PROP_FRAME_HEIGHT);
int codec = CV_FOURCC('P','I','M','1'); // MPEG-1
std::string out_file((getHomeDir() / std::string("performous-webcam_out.mpg")).string());
- m_writer = cvCreateVideoWriter(out_file.c_str(), codec, fps > 0 ? fps : 30.0f, cvSize(framew,frameh));
- if (!m_writer) std::cout << "Could not initialize webcam video saving!" << std::endl;
+ m_writer.reset(new cv::VideoWriter(out_file.c_str(), codec, fps > 0 ? fps : 30.0f, cvSize(framew,frameh)));
+ if (!m_writer->isOpened()) {
+ std::cout << "Could not initialize webcam video saving!" << std::endl;
+ m_writer.reset();
+ }
#endif
// Start thread
m_thread.reset(new boost::thread(boost::ref(*this)));
#else
- ++cam_id; // dummy
+ (void)cam_id; // Avoid unused warning
#endif
}
@@ -48,8 +57,6 @@ Webcam::~Webcam() {
m_quit = true;
#ifdef USE_OPENCV
if (m_thread) m_thread->join();
- cvReleaseCapture(&m_capture);
- cvReleaseVideoWriter(&m_writer);
#endif
}
@@ -57,16 +64,16 @@ void Webcam::operator()() {
#ifdef USE_OPENCV
m_running = true;
while (!m_quit) {
- IplImage* frame = 0;
- // Try to get a new frame
- if (m_running) frame = cvQueryFrame(m_capture);
- if (frame) {
- if (m_writer) cvWriteFrame(m_writer, frame);
+ if (m_running) {
+ // Get a new frame
+ cv::Mat frame;
+ *m_capture >> frame;
+ if (m_writer) *m_writer << frame;
boost::mutex::scoped_lock l(m_mutex);
// Copy the frame to storage
- m_frame.width = frame->width;
- m_frame.height = frame->height;
- m_frame.data.assign(frame->imageData, frame->imageData + (m_frame.width * m_frame.height * 3));
+ m_frame.width = frame.cols;
+ m_frame.height = frame.rows;
+ m_frame.data.assign(frame.data, frame.data + (m_frame.width * m_frame.height * 3));
// Notify renderer
m_frameAvailable = true;
}
diff --git a/game/webcam.hh b/game/webcam.hh
index f63087d..9566f2e 100644
--- a/game/webcam.hh
+++ b/game/webcam.hh
@@ -7,8 +7,11 @@
#include "surface.hh"
-struct CvCapture;
-struct CvVideoWriter;
+namespace cv {
+ // Forward declarations
+ class VideoCapture;
+ class VideoWriter;
+}
struct CamFrame {
int width;
@@ -39,8 +42,8 @@ class Webcam {
private:
boost::scoped_ptr<boost::thread> m_thread;
mutable boost::mutex m_mutex;
- CvCapture* m_capture;
- CvVideoWriter* m_writer;
+ boost::scoped_ptr<cv::VideoCapture> m_capture;
+ boost::scoped_ptr<cv::VideoWriter> m_writer;
CamFrame m_frame;
Surface m_surface;
bool m_frameAvailable;
|