Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cabability to retrieve raw frame hardware STC timestamp #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions src/private/private_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ namespace raspicam {

// Default everything to zero
memset ( &State, 0, sizeof ( RASPIVID_STATE ) );
State.framerate = 30;
State.width = 1280; // use a multiple of 320 (640, 1280)
State.height = 960; // use a multiple of 240 (480, 960)
State.framerate = 30;
State.width = 1280; // use a multiple of 320 (640, 1280)
State.height = 960; // use a multiple of 240 (480, 960)
State.sharpness = 0;
State.contrast = 0;
State.brightness = 50;
Expand All @@ -93,6 +93,7 @@ namespace raspicam {
State.shutterSpeed=0;//auto
State.awbg_red=1.0;
State.awbg_blue=1.0;
State.ptc_tsMode = RASPICAM_TIMESTAMP_MODE_RAW_STC;

}
bool Private_Impl::open ( bool StartCapture ) {
Expand Down Expand Up @@ -173,7 +174,12 @@ namespace raspicam {
/**
*
*/
void Private_Impl::retrieve ( unsigned char *data,RASPICAM_FORMAT type ) {
void Private_Impl::retrieve ( unsigned char *data, RASPICAM_FORMAT type ) {
int64_t ts;
retrieve(&ts, data, type);
}
void Private_Impl::retrieve ( int64_t *timestamp, unsigned char *data, RASPICAM_FORMAT type ) {
(*timestamp) = 0;
if ( callback_data._buffData.size==0 ) return;
if ( type!=RASPICAM_FORMAT_IGNORE ) {
cerr<<__FILE__<<":"<<__LINE__<<" :Private_Impl::retrieve type is not RASPICAM_FORMAT_IGNORE as it should be"<<endl;
Expand Down Expand Up @@ -202,13 +208,19 @@ namespace raspicam {
imagePtr+=format->es->video.width*3;//line stride
}
}

(*timestamp) = callback_data.timestamp;
}


unsigned char *Private_Impl::getImageBufferData() const{
return callback_data._buffData.data;
}
/**
* Returns the timestamp of the image that is in the current internal buffer
*/
int64_t Private_Impl::getTimeStamp() const {
return callback_data.timestamp;
}

size_t Private_Impl::getImageBufferSize() const{
return getImageTypeSize ( getFormat() );
Expand Down Expand Up @@ -288,7 +300,7 @@ namespace raspicam {
cam_config.num_preview_video_frames = 3;
cam_config.stills_capture_circular_buffer_height = 0;
cam_config.fast_preview_resume = 0;
cam_config.use_stc_timestamp = MMAL_PARAM_TIMESTAMP_MODE_RESET_STC;
cam_config.use_stc_timestamp = convertTimestampMode(state->ptc_tsMode);
mmal_port_parameter_set ( camera->control, &cam_config.hdr );

// Set the encode format on the video port
Expand Down Expand Up @@ -500,6 +512,7 @@ namespace raspicam {
memcpy ( pData->_buffData.data,buffer->data,buffer->length );
pData->wantToGrab =false;
hasGrabbed=true;
pData->timestamp = buffer->pts;
mmal_buffer_header_mem_unlock ( buffer );
}
}
Expand Down Expand Up @@ -720,6 +733,19 @@ namespace raspicam {
return MMAL_PARAM_AWBMODE_AUTO;
}
}
MMAL_PARAMETER_CAMERA_CONFIG_TIMESTAMP_MODE_T Private_Impl::convertTimestampMode ( RASPICAM_TIMESTAMP_MODE tsMode )
{
switch(tsMode) {
case RASPICAM_TIMESTAMP_MODE_ZERO:
return MMAL_PARAM_TIMESTAMP_MODE_ZERO;
case RASPICAM_TIMESTAMP_MODE_RAW_STC:
return MMAL_PARAM_TIMESTAMP_MODE_RAW_STC;
case RASPICAM_TIMESTAMP_MODE_RESET_STC:
return MMAL_PARAM_TIMESTAMP_MODE_RESET_STC;
default:
return MMAL_PARAM_TIMESTAMP_MODE_RAW_STC;
}
}

MMAL_PARAM_IMAGEFX_T Private_Impl::convertImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect ) {
switch ( imageEffect ) {
Expand Down Expand Up @@ -771,6 +797,11 @@ namespace raspicam {
void Private_Impl::setFrameRate ( unsigned int frame_rate ) {
State.framerate = frame_rate;
}

void Private_Impl::setTimestampMode(RASPICAM_TIMESTAMP_MODE tsMode)
{
State.ptc_tsMode = tsMode;
}

int Private_Impl::convertFormat ( RASPICAM_FORMAT fmt ) {
switch ( fmt ) {
Expand Down
19 changes: 15 additions & 4 deletions src/private/private_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ namespace raspicam {
ThreadCondition Thcond;
bool wantToGrab;
membuf<unsigned char> _buffData;

int64_t timestamp;
};

public:
Expand Down Expand Up @@ -112,6 +112,7 @@ namespace raspicam {
* You can use getFormat to know the current format
*/
void retrieve ( unsigned char *data,RASPICAM_FORMAT type=RASPICAM_FORMAT_IGNORE );
void retrieve ( int64_t *timestamp, unsigned char *data,RASPICAM_FORMAT type=RASPICAM_FORMAT_IGNORE );
/**Alternative to retrieve. Returns a pointer to the original image data buffer.
* Be careful, if you call grab(), this will be rewritten with the new data
*/
Expand All @@ -120,7 +121,11 @@ namespace raspicam {
* Returns the size of the buffer returned in getImagePtr. If is like calling getImageTypeSize(getFormat()). Just for dummies :P
*/
size_t getImageBufferSize() const;

/**
* Returns the timestamp of the image that is in the current internal buffer
*/
int64_t getTimeStamp() const;

/** Stops camera and free resources
*/
void release();
Expand All @@ -141,7 +146,8 @@ namespace raspicam {
void setExposureCompensation ( int val ); //-10,10
void setAWB ( RASPICAM_AWB awb );
void setAWB_RB ( float red,float blue );//ranges [0,1]
void setFrameRate ( unsigned int frame_rate ) ;
void setFrameRate ( unsigned int frame_rate );
void setTimestampMode(RASPICAM_TIMESTAMP_MODE tsMode);

void setImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect );
void setMetering ( RASPICAM_METERING metering );
Expand Down Expand Up @@ -203,6 +209,10 @@ namespace raspicam {
{
return State.rpc_awbMode;
}
RASPICAM_TIMESTAMP_MODE getTimestampMode() const
{
return State.ptc_tsMode;
}

float getAWBG_red(){return State.awbg_red;}

Expand Down Expand Up @@ -263,11 +273,12 @@ namespace raspicam {
MMAL_PARAM_AWBMODE_T convertAWB ( RASPICAM_AWB awb ) ;
MMAL_PARAM_IMAGEFX_T convertImageEffect ( RASPICAM_IMAGE_EFFECT imageEffect ) ;
MMAL_PARAM_EXPOSUREMETERINGMODE_T convertMetering ( RASPICAM_METERING metering ) ;
MMAL_PARAMETER_CAMERA_CONFIG_TIMESTAMP_MODE_T convertTimestampMode ( RASPICAM_TIMESTAMP_MODE tsMode );
int convertFormat ( RASPICAM_FORMAT fmt ) ;


//Color conversion
void convertBGR2RGB(unsigned char * in_bgr,unsigned char * out_rgb,int size);
void convertBGR2RGB(unsigned char * in_bgr,unsigned char * out_rgb,int size);
float VIDEO_FRAME_RATE_NUM;
RASPIVID_STATE State;
MMAL_STATUS_T status;
Expand Down
3 changes: 2 additions & 1 deletion src/private/private_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,12 @@ namespace raspicam {
bool videoStabilisation; /// 0 or 1 (false or true)
int exposureCompensation; /// -10 to +10 ?
int shutterSpeed;
RASPICAM_FORMAT captureFtm;
RASPICAM_FORMAT captureFtm;
RASPICAM_EXPOSURE rpc_exposureMode;
RASPICAM_METERING rpc_exposureMeterMode;
RASPICAM_AWB rpc_awbMode;
RASPICAM_IMAGE_EFFECT rpc_imageEffect;
RASPICAM_TIMESTAMP_MODE ptc_tsMode;
MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imageEffectsParameters;
MMAL_PARAM_COLOURFX_T colourEffects;
int rotation; /// 0-359
Expand Down
15 changes: 14 additions & 1 deletion src/raspicam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,12 @@ namespace raspicam {
void RaspiCam::retrieve ( unsigned char *data,RASPICAM_FORMAT type ) {
_impl->retrieve ( data,type );
}
void RaspiCam::retrieve ( int64_t *timestamp, unsigned char *data,RASPICAM_FORMAT type ) {
_impl->retrieve ( timestamp,data,type );
}
unsigned char *RaspiCam::getImageBufferData() const{return _impl->getImageBufferData();}
size_t RaspiCam::getImageBufferSize() const{return _impl->getImageBufferSize();}
int64_t RaspiCam::getTimeStamp() const { return _impl->getTimeStamp();}

size_t RaspiCam::getImageTypeSize ( RASPICAM_FORMAT type ) const{return _impl->getImageTypeSize ( type );}

Expand Down Expand Up @@ -134,7 +138,12 @@ namespace raspicam {
void RaspiCam::setVerticalFlip ( bool vFlip ) {
_impl->setVerticalFlip ( vFlip );
}
void RaspiCam::setFrameRate( unsigned int fr) { _impl->setFrameRate(fr);}
void RaspiCam::setFrameRate( unsigned int fr) {
_impl->setFrameRate(fr);
}
void RaspiCam::setTimestampMode(RASPICAM_TIMESTAMP_MODE tsMode) {
_impl->setTimestampMode(tsMode);
};


RASPICAM_FORMAT RaspiCam::getFormat()const{return _impl->getFormat( ); }
Expand All @@ -145,6 +154,10 @@ namespace raspicam {
int RaspiCam::getISO() const{return _impl->getISO() ;}
unsigned int RaspiCam::getShutterSpeed() const{return _impl->getShutterSpeed();}//return _impl->getShutterSpeed();}
unsigned int RaspiCam::getFrameRate()const{return _impl->getFrameRate();}
RASPICAM_TIMESTAMP_MODE RaspiCam::getTimestampMode() const {
return _impl->getTimestampMode();
}


int RaspiCam::getSharpness() const{return _impl->getSharpness() ;}
int RaspiCam::getContrast() const{return _impl->getContrast() ;}
Expand Down
10 changes: 9 additions & 1 deletion src/raspicam.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ namespace raspicam {
* You can use getFormat() to know the current format
*/
void retrieve ( unsigned char *data,RASPICAM_FORMAT type=RASPICAM_FORMAT_IGNORE );
void retrieve ( int64_t *timestamp, unsigned char *data,RASPICAM_FORMAT type=RASPICAM_FORMAT_IGNORE );
/**Alternative to retrieve. Returns a pointer to the original image data buffer (which is in getFormat() format).
*
* Be careful, if you call grab(), this will be rewritten with the new data
Expand All @@ -86,6 +87,10 @@ namespace raspicam {
* Returns the size of the images captured.
*/
size_t getImageBufferSize() const;
/**
* Returns the timestamp of the image that is in the current internal buffer
*/
int64_t getTimeStamp() const;


/** Stops camera and free resources
Expand Down Expand Up @@ -139,6 +144,8 @@ namespace raspicam {
void setHorizontalFlip ( bool hFlip );
void setVerticalFlip ( bool vFlip );
void setFrameRate(unsigned int fr);
void setTimestampMode(RASPICAM_TIMESTAMP_MODE tsMode);

//Accessors
RASPICAM_FORMAT getFormat() const;
unsigned int getWidth() const;
Expand All @@ -158,7 +165,8 @@ namespace raspicam {
RASPICAM_METERING getMetering() const;
bool isHorizontallyFlipped() const ;
bool isVerticallyFlipped() const ;
unsigned int getFrameRate()const;
unsigned int getFrameRate() const;
RASPICAM_TIMESTAMP_MODE getTimestampMode() const;

/** Returns an id of the camera. We assume the camera id is the one of the raspberry
*the id is obtained using raspberry serial number obtained in /proc/cpuinfo
Expand Down
7 changes: 7 additions & 0 deletions src/raspicamtypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ namespace raspicam {
RASPICAM_ENCODING_RGB
} RASPICAM_ENCODING;

typedef enum RASPICAM_TIMESTAMP_MODE {
RASPICAM_TIMESTAMP_MODE_ZERO, /* Always timestamp frames as 0 */
RASPICAM_TIMESTAMP_MODE_RAW_STC, /* Use the raw STC value for the frame timestamp */
RASPICAM_TIMESTAMP_MODE_RESET_STC, /* Use the STC timestamp but subtract the timestamp
* of the first frame sent to give a zero based timestamp. */
} RASPICAM_TIMESTAMP_MODE;

};
#endif

8 changes: 6 additions & 2 deletions utils/raspicam_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ int main ( int argc,char **argv ) {
}
cout<<"Connected to camera ="<<Camera.getId() <<" bufs="<<Camera.getImageBufferSize( )<<endl;
unsigned char *data=new unsigned char[ Camera.getImageBufferSize( )];
int64_t timestamp=0;
Timer timer;


Expand All @@ -209,9 +210,12 @@ int main ( int argc,char **argv ) {
timer.start();
do{
Camera.grab();
Camera.retrieve ( data );
Camera.retrieve ( &timestamp, data );
if ( !doTestSpeedOnly ) {
if ( i%5==0 ) cout<<"\r capturing ..."<<i<<"/"<<nFramesCaptured<<std::flush;
if ( i%5==0 ) {
cout<<"\r capturing ..."<<i<<"/"<<nFramesCaptured
<< " at pts(us): " << timestamp << " " << std::flush;
}
if ( i%30==0 && i!=0 && nFramesCaptured>0 ) { //save image if not in inifite loop
std::stringstream fn;
fn<<"image";
Expand Down