Skip to content
Permalink
6d5f52307c
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
486 lines (398 sloc) 13.3 KB
/** \file dab_tracker_camera.cpp
*/
#include "dab_tracker_camera.h"
#include "ofxCvGrayscaleImage.h"
#include "ofxCvColorImage.h"
#include "ofxJSON.h"
#include "dab_tracker_serialize_helper.h"
#include "dab_tracker_image_save_queue.h"
using namespace dab;
using namespace dab::tracker;
float Camera::sFrameRate = 30.0;
Camera::Camera()
: mFrameSize( {640, 470} )
, mChannelCount(3)
, mFrameRate(30.0)
, mSettingsFileName("Camera_Settings.json")
, mFrame(nullptr)
, mColorConversionFrame(nullptr)
, mMoviePlayer(nullptr)
, mMovieRecorder(nullptr)
, mMovieRecordFileName("capture")
, mMovieRecordFileSuffix("mp4")
, mBlocked(false)
, mCapturing(false)
, mLoadSettings(false)
, mSaveSettings(false)
, mMovieRecording(false)
, mMoviePlaying(false)
{
mSelf = std::shared_ptr<Camera>(this);
createBaseParameters();
}
Camera::Camera(std::array<unsigned int, 2> pFrameSize, unsigned int pChannelCount) throw (dab::Exception)
: mFrameSize(pFrameSize)
, mChannelCount(pChannelCount)
, mFrameRate(sFrameRate)
, mSettingsFileName("Camera_Settings.json")
, mFrame(nullptr)
, mColorConversionFrame(nullptr)
, mMoviePlayer(nullptr)
, mMovieRecorder(nullptr)
, mMovieRecordFileName("capture")
, mMovieRecordFileSuffix("mp4")
, mBlocked(false)
, mCapturing(false)
, mLoadSettings(false)
, mSaveSettings(false)
, mMovieRecording(false)
, mMoviePlaying(false)
{
mSelf = std::shared_ptr<Camera>(this);
createBaseParameters();
}
Camera::Camera(const std::string& pMoviePlayFileName, unsigned int pChannelCount, unsigned int pFrameRate) throw (dab::Exception)
: mMoviePlayFileName(pMoviePlayFileName)
, mChannelCount(pChannelCount)
, mFrameRate(pFrameRate)
, mSettingsFileName("Camera_Settings.json")
, mFrame(nullptr)
, mColorConversionFrame(nullptr)
, mMoviePlayer(nullptr)
, mMovieRecorder(nullptr)
, mBlocked(false)
, mCapturing(false)
, mLoadSettings(false)
, mSaveSettings(false)
, mMovieRecording(false)
, mMoviePlaying(true)
{
mSelf = std::shared_ptr<Camera>(this);
bool success;
mMoviePlayer = new ofVideoPlayer();
success = mMoviePlayer->load(mMoviePlayFileName);
if(success == false) throw dab::Exception("TRACKER ERROR: failed to load move file " + mMoviePlayFileName, __FILE__, __FUNCTION__, __LINE__);
if(mChannelCount == 1)
{
mChannelCount = 1;
mFrame = new ofxCvGrayscaleImage();
}
else if(mChannelCount == 3)
{
mChannelCount = 3;
mFrame = new ofxCvColorImage();
}
else throw dab::Exception("TRACKER ERROR: movie file " + mMoviePlayFileName + " has an unsupported color format", __FILE__, __FUNCTION__, __LINE__);
mFrameSize[0] = mMoviePlayer->getWidth();
mFrameSize[1] = mMoviePlayer->getHeight();
std::cout << "framerate " << mFrameRate << "\n";
mMoviePlayer->setLoopState(OF_LOOP_NORMAL);
createBaseParameters();
}
Camera::~Camera() throw (dab::Exception)
{
if(mFrame != nullptr) delete mFrame;
for(auto controlIter = mControls.begin(); controlIter != mControls.end(); ++controlIter)
{
delete controlIter->second;
}
mControls.clear();
}
void
Camera::createBaseParameters()
{
Parameter<bool>* recordingControl = new Parameter<bool>( "record", mMovieRecording);
recordingControl->registerParameterListener(mSelf);
mControls["record"] = recordingControl;
mDontSaveControlNames.push_back("record");
Parameter<bool>* saveSettingsControl = new Parameter<bool>("savesettings", mSaveSettings);
saveSettingsControl->registerParameterListener(mSelf);
mControls["savesettings"] = saveSettingsControl;
mDontSaveControlNames.push_back("savesettings");
Parameter<bool>* loadSettingsControl = new Parameter<bool>("loadsettings", mLoadSettings);
loadSettingsControl->registerParameterListener(mSelf);
mControls["loadsettings"] = loadSettingsControl;
mDontSaveControlNames.push_back("loadsettings");
}
const array<unsigned int, 2>&
Camera::frameSize() const
{
return mFrameSize;
}
void
Camera::setSettingsFileName(const std::string& pSettingsFileName)
{
mSettingsFileName = pSettingsFileName;
}
void
Camera::setMovieRecordFileName( const std::string& pMovieRecordFileName )
{
mMovieRecordFileName = pMovieRecordFileName;
}
unsigned int
Camera::channelCount() const
{
return mChannelCount;
}
float
Camera::frameRate() const
{
return mFrameRate;
}
ofxCvImage*
Camera::frame()
{
return mFrame;
}
bool
Camera::checkControl(const std::string& pControlName) const
{
return mControls.find(pControlName) != mControls.end();
}
bool
Camera::checkControlValue(const std::string& pControlName) const
{
auto controlIter = mControls.find(pControlName);
if( controlIter == mControls.end() ) return false;
return controlIter->second->hasValue();
}
std::map<std::string,AbstractParameter*>&
Camera::controls()
{
return mControls;
}
const std::map<std::string, AbstractParameter*>&
Camera::controls() const
{
return mControls;
}
AbstractParameter&
Camera::getControl(const std::string& pControlName ) throw (dab::Exception)
{
auto controlIter = mControls.find(pControlName);
if( controlIter == mControls.end() ) throw dab::Exception("TRACKER ERROR: Camera has no control named " + pControlName, __FILE__, __FUNCTION__, __LINE__);
return *(controlIter->second);
}
const AbstractParameter&
Camera::getControl(const std::string& pControlName ) const throw (dab::Exception)
{
auto controlIter = mControls.find(pControlName);
if( controlIter == mControls.end() ) throw dab::Exception("TRACKER ERROR: Camera has no control named " + pControlName, __FILE__, __FUNCTION__, __LINE__);
return *(controlIter->second);
}
const AbstractValue&
Camera::getControlValue(const std::string& pControlName) const throw (dab::Exception)
{
auto controlIter = mControls.find(pControlName);
if( controlIter == mControls.end() ) throw dab::Exception("TRACKER ERROR: Camera has no control named " + pControlName, __FILE__, __FUNCTION__, __LINE__);
AbstractParameter* cameraControl = controlIter->second;
if(cameraControl->hasValue() == false) throw dab::Exception("TRACKER ERROR: Camera control " + pControlName + " has no value", __FILE__, __FUNCTION__, __LINE__);
return cameraControl->value();
}
void
Camera::setControlValue(const std::string& pControlName) throw (dab::Exception)
{}
void
Camera::setControlValue(const std::string& pControlName, const AbstractValue& pValue ) throw (dab::Exception)
{
auto controlIter = mControls.find(pControlName);
if( controlIter == mControls.end() ) throw dab::Exception("TRACKER ERROR: Camera has no control named " + pControlName, __FILE__, __FUNCTION__, __LINE__);
try
{
if( pControlName == "record" )
{
bool controlValue = pValue.get<bool>();
if( controlValue == true ) startRecording();
else if( controlValue == false ) stopRecording();
}
else if( pControlName == "savesettings" )
{
bool controlValue = pValue.get<bool>();
mSaveSettings = true;
}
else if( pControlName == "loadsettings" )
{
bool controlValue = pValue.get<bool>();
mLoadSettings = true;
}
}
catch(dab::Exception& e)
{
throw;
}
}
void
Camera::notifyParameterChange( const AbstractParameter& pParameter )
{
//std::cout << "notifyParameterChange " << pParameter.name() << "\n";
try
{
if( pParameter.hasValue() == true ) setControlValue(pParameter.name(), pParameter.value());
else setControlValue(pParameter.name());
}
catch (dab::Exception& e)
{
e += dab::Exception("TRACKER ERROR: notifyParameterChange failed for parameter " + pParameter.name() + "\n", __FILE__, __FUNCTION__, __LINE__);
std::cout << e << "\n";
}
}
void
Camera::start() throw (dab::Exception)
{
if(mMoviePlaying == true && mMoviePlayer != nullptr)
{
mMoviePlayer->play();
}
}
void
Camera::stop() throw (dab::Exception)
{
if( mMoviePlaying == true && mMoviePlayer != nullptr)
{
mMoviePlayer->stop();
}
}
void
Camera::capture() throw (dab::Exception)
{
bool isFrameNew;
bool success;
if(mLoadSettings == true)
{
restoreSettings();
mLoadSettings = false;
}
if(mSaveSettings == true)
{
saveSettings();
mSaveSettings = false;
}
if( mMoviePlaying == true && mMoviePlayer != nullptr)
{
mMoviePlayer->update();
isFrameNew = mMoviePlayer->isFrameNew();
if(isFrameNew == true)
{
if(mChannelCount == 1) // color to grayscale conversion necessary
{
if(mColorConversionFrame == nullptr)
{
mColorConversionFrame = new ofxCvColorImage();
mColorConversionFrame->allocate( mFrameSize[0], mFrameSize[1] );
}
mColorConversionFrame->setFromPixels( mMoviePlayer->getPixels().getData(), mFrameSize[0], mFrameSize[1] );
*mFrame = *mColorConversionFrame;
}
else mFrame->setFromPixels( mMoviePlayer->getPixels().getData(), mFrameSize[0], mFrameSize[1] );
}
}
if( mMovieRecording == true && isFrameNew == true)
{
if(mChannelCount == 1) // color to grayscale conversion necessary
{
if(mColorConversionFrame == nullptr)
{
mColorConversionFrame = new ofxCvColorImage();
mColorConversionFrame->allocate( mFrameSize[0], mFrameSize[1] );
}
*mColorConversionFrame = *static_cast<ofxCvGrayscaleImage*>(mFrame);
success = mMovieRecorder->addFrame( mColorConversionFrame->getPixels() );
}
else
{
success = mMovieRecorder->addFrame( mFrame->getPixels() );
}
if( success == false ) throw dab::Exception("TRACKER ERROR: failed to record camera frame", __FUNCTION__, __FUNCTION__, __LINE__);
//if( mMovieRecorder->hasVideoError() ) throw dab::Exception("TRACKER ERROR: failed to record camera frame", __FUNCTION__, __FUNCTION__, __LINE__);
}
if (mCaptureStill == true)
{
saveStill(mFrame, "color_" + mCaptureStillFileName + ".bmp");
mCaptureStill = false;
}
}
void
Camera::startRecording() throw (dab::Exception)
{
if(mMovieRecording == true) return;
bool success;
if( mMovieRecorder == nullptr )
{
mMovieRecorder = new ofxVideoRecorder();
mMovieRecorder->setFfmpegLocation("C:\\ffmpeg\\bin\\ffmpeg.exe");
mMovieRecorder->setVideoCodec("mpeg4"); // mjpeg / h264
//mMovieRecorder->setVideoBitrate("10000k");
}
std::string fileName = mMovieRecordFileName + "_" + ofGetTimestampString() + "." + mMovieRecordFileSuffix;
success = mMovieRecorder->setup(fileName, mFrameSize[0], mFrameSize[1], mFrameRate);
if(success == false) throw dab::Exception("TRACKER ERROR: failed to start recording to file " + mMovieRecordFileName, __FILE__, __FUNCTION__, __LINE__);
mMovieRecorder->start();
mMovieRecording = true;
}
void
Camera::stopRecording() throw (dab::Exception)
{
if(mMovieRecording == false ) return;
mMovieRecorder->close();
mMovieRecording = false;
}
void
Camera::recordStill(const std::string& pFileName) throw (dab::Exception)
{
mCaptureStillFileName = pFileName;
mCaptureStill = true;
}
void
Camera::saveStill(ofxCvImage* pImage, const std::string& pFileName) throw (dab::Exception)
{
ImageSaveQueue::get().addImage(pImage, pFileName);
}
void
Camera::saveSettings() throw (dab::Exception)
{
std::cout << "save settings\n";
SerializeHelper& serializeHelper = SerializeHelper::get();
Json::Value jsonData;
try
{
for( auto controlIter = mControls.begin(); controlIter != mControls.end(); controlIter++)
{
AbstractParameter* cameraParameter = controlIter->second;
if( std::find(mDontSaveControlNames.begin(), mDontSaveControlNames.end(), cameraParameter->name() ) == mDontSaveControlNames.end() )
{
serializeHelper.addValue(jsonData, *cameraParameter);
}
}
serializeHelper.save(jsonData, mSettingsFileName);
}
catch (Exception& e)
{
e += Exception("TRACKER ERROR: failed to save camera settings", __FILE__, __FUNCTION__, __LINE__);
throw e;
}
}
void
Camera::restoreSettings() throw (dab::Exception)
{
std::cout << "load settings\n";
SerializeHelper& serializeHelper = SerializeHelper::get();
Json::Value jsonData;
try
{
serializeHelper.restore(jsonData, mSettingsFileName);
for( auto controlIter = mControls.begin(); controlIter != mControls.end(); controlIter++)
{
AbstractParameter* cameraParameter = controlIter->second;
const std::string& parameterName = cameraParameter->name();
if(serializeHelper.hasValue(jsonData, *cameraParameter) == true)
{
serializeHelper.getValue(jsonData, *cameraParameter);
}
}
}
catch (Exception& e)
{
e += Exception("TRACKER ERROR: failed to restore camera settings", __FILE__, __FUNCTION__, __LINE__);
throw e;
}
}