41#include "mmal/util/mmal_util.h"
42#include "mmal/util/mmal_util_params.h"
43#include "mmal/util/mmal_default_components.h"
47#define MMAL_CAMERA_VIDEO_PORT 1
48#define MMAL_CAMERA_CAPTURE_PORT 2
49#define VIDEO_FRAME_RATE_DEN 1
50#define VIDEO_OUTPUT_BUFFERS_NUM 3
54 camera_video_port = NULL;
59 setDefaultStateParams();
67 void Private_Impl::setDefaultStateParams() {
99 if ( _isOpened )
return false;
101 if ( ! create_camera_component ( &State ) ) {
102 cerr<<__func__<<
" Failed to create camera component"<<__FILE__<<
" "<<__LINE__<<endl;
107 callback_data.pstate = &State;
109 camera_video_port->userdata = (
struct MMAL_PORT_USERDATA_T * ) &callback_data;
119 cerr<<__FILE__<<
":"<<__LINE__<<
":"<<__func__<<
" not opened."<<endl;
124 if ( mmal_port_parameter_set_boolean ( camera_video_port, MMAL_PARAMETER_CAPTURE, 1 ) != MMAL_SUCCESS ) {
130 int num = mmal_queue_length ( State.
video_pool->queue );
132 for ( q=0; q<num; q++ ) {
133 MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get ( State.
video_pool->queue );
136 cerr<<
"Unable to get a required buffer"<<q<<
" from pool queue"<<endl;
138 if ( mmal_port_send_buffer ( camera_video_port, buffer ) != MMAL_SUCCESS )
139 cerr<<
"Unable to send a buffer to encoder output port "<< q<<endl;
146 if ( !_isOpened )
return;
149 if ( camera_video_port && camera_video_port->is_enabled ) {
150 mmal_port_disable ( camera_video_port );
151 camera_video_port = NULL;
159 destroy_camera_component ( &State );
170 callback_data.waitForFrame();
177 if ( callback_data._buffData.size==0 )
return;
179 cerr<<__FILE__<<
":"<<__LINE__<<
" :Private_Impl::retrieve type is not RASPICAM_FORMAT_IGNORE as it should be"<<endl;
182 auto imagePtr=callback_data._buffData.data;
184 memcpy ( data,imagePtr,State.
width);
186 imagePtr+=format->es->video.width;
190 auto imagePtr=callback_data._buffData.data;
191 for(
int i=0;i<State.
height;i++) {
192 memcpy ( data,imagePtr,State.
width);
194 imagePtr+=format->es->video.width;
198 auto imagePtr=callback_data._buffData.data;
199 for(
int i=0;i<State.
height;i++) {
200 memcpy ( data,imagePtr,State.
width*3);
202 imagePtr+=format->es->video.width*3;
210 return callback_data._buffData.data;
248 void Private_Impl::destroy_camera_component (
RASPIVID_STATE *state ) {
256 MMAL_COMPONENT_T *Private_Impl::create_camera_component ( RASPIVID_STATE *state ) {
257 MMAL_COMPONENT_T *camera = 0;
258 MMAL_PORT_T *video_port = NULL;
260 MMAL_STATUS_T status;
262 status = mmal_component_create ( MMAL_COMPONENT_DEFAULT_CAMERA, &camera );
264 if ( status != MMAL_SUCCESS ) {
265 cerr<< (
"Failed to create camera component" );
269 if ( !camera->output_num ) {
270 cerr<< (
"Camera doesn't have output ports" );
271 mmal_component_destroy ( camera );
279 MMAL_PARAMETER_CAMERA_CONFIG_T cam_config;
280 cam_config.hdr.id=MMAL_PARAMETER_CAMERA_CONFIG;
281 cam_config.hdr.size=
sizeof ( cam_config );
282 cam_config.max_stills_w = state->width;
283 cam_config.max_stills_h = state->height;
284 cam_config.stills_yuv422 = 0;
285 cam_config.one_shot_stills = 0;
286 cam_config.max_preview_video_w = state->width;
287 cam_config.max_preview_video_h = state->height;
288 cam_config.num_preview_video_frames = 3;
289 cam_config.stills_capture_circular_buffer_height = 0;
290 cam_config.fast_preview_resume = 0;
291 cam_config.use_stc_timestamp = MMAL_PARAM_TIMESTAMP_MODE_RESET_STC;
292 mmal_port_parameter_set ( camera->control, &cam_config.hdr );
296 format = video_port->format;
297 format->encoding_variant = convertFormat ( State.
captureFtm );
298 format->encoding = convertFormat ( State.
captureFtm );
299 format->es->video.width = VCOS_ALIGN_UP(state->width, 32);
300 format->es->video.height = VCOS_ALIGN_UP(state->height, 16);
301 format->es->video.crop.x = 0;
302 format->es->video.crop.y = 0;
303 format->es->video.crop.width = state->width;
304 format->es->video.crop.height = state->height;
305 format->es->video.frame_rate.num = state->framerate;
308 status = mmal_port_format_commit ( video_port );
310 cerr<< (
"camera video format couldn't be set" );
311 mmal_component_destroy ( camera );
316 status = mmal_port_enable ( video_port,video_buffer_callback );
318 cerr<< (
"camera video callback2 error" );
319 mmal_component_destroy ( camera );
331 video_port->buffer_size = video_port->buffer_size_recommended;
332 video_port->buffer_num = video_port->buffer_num_recommended;
333 pool = mmal_port_pool_create ( video_port, video_port->buffer_num, video_port->buffer_size );
335 cerr<< (
"Failed to create buffer header pool for video output port" );
337 state->video_pool = pool;
341 status = mmal_component_enable ( camera );
344 cerr<< (
"camera component couldn't be enabled" );
345 mmal_component_destroy ( camera );
349 state->camera_component = camera;
355 void Private_Impl::commitBrightness() {
356 mmal_port_parameter_set_rational ( State.
camera_component->control, MMAL_PARAMETER_BRIGHTNESS, ( MMAL_RATIONAL_T ) {
357 State.brightness, 100
362 void Private_Impl::commitRotation() {
363 int rotation = int ( State.
rotation / 90 ) * 90;
364 mmal_port_parameter_set_int32 ( State.
camera_component->output[0], MMAL_PARAMETER_ROTATION,rotation );
365 mmal_port_parameter_set_int32 ( State.
camera_component->output[1], MMAL_PARAMETER_ROTATION,rotation );
366 mmal_port_parameter_set_int32 ( State.
camera_component->output[2], MMAL_PARAMETER_ROTATION, rotation );
369 void Private_Impl::commitISO() {
370 if ( mmal_port_parameter_set_uint32 ( State.
camera_component->control, MMAL_PARAMETER_ISO, State.
ISO ) != MMAL_SUCCESS )
371 cout << __func__ <<
": Failed to set ISO parameter.\n";
374 void Private_Impl::commitSharpness() {
375 if ( mmal_port_parameter_set_rational ( State.
camera_component->control, MMAL_PARAMETER_SHARPNESS, ( MMAL_RATIONAL_T ) {
377 } ) != MMAL_SUCCESS )
378 cout << __func__ <<
": Failed to set sharpness parameter.\n";
381 void Private_Impl::commitShutterSpeed() {
382 if ( mmal_port_parameter_set_uint32 ( State.
camera_component->control, MMAL_PARAMETER_SHUTTER_SPEED, State.
shutterSpeed ) != MMAL_SUCCESS )
383 cout << __func__ <<
": Failed to set shutter parameter.\n";
388 void Private_Impl::commitContrast() {
389 if ( mmal_port_parameter_set_rational ( State.
camera_component->control, MMAL_PARAMETER_CONTRAST, ( MMAL_RATIONAL_T ) {
391 } ) != MMAL_SUCCESS )
392 cout << __func__ <<
": Failed to set contrast parameter.\n";
395 void Private_Impl::commitSaturation() {
396 if ( mmal_port_parameter_set_rational ( State.
camera_component->control, MMAL_PARAMETER_SATURATION, ( MMAL_RATIONAL_T ) {
397 State.saturation, 100
398 } ) != MMAL_SUCCESS )
399 cout << __func__ <<
": Failed to set saturation parameter.\n";
402 void Private_Impl::commitExposure() {
403 MMAL_PARAMETER_EXPOSUREMODE_T exp_mode = {{MMAL_PARAMETER_EXPOSURE_MODE,
sizeof ( exp_mode ) }, convertExposure ( State.
rpc_exposureMode ) };
404 if ( mmal_port_parameter_set ( State.
camera_component->control, &exp_mode.hdr ) != MMAL_SUCCESS )
405 cout << __func__ <<
": Failed to set exposure parameter.\n";
413 void Private_Impl::commitExposureCompensation() {
415 cout << __func__ <<
": Failed to set Exposure Compensation parameter.\n";
420 void Private_Impl::commitAWB() {
421 MMAL_PARAMETER_AWBMODE_T param = {{MMAL_PARAMETER_AWB_MODE,
sizeof ( param ) }, convertAWB ( State.
rpc_awbMode ) };
422 if ( mmal_port_parameter_set ( State.
camera_component->control, ¶m.hdr ) != MMAL_SUCCESS )
423 cout << __func__ <<
": Failed to set AWB parameter.\n";
426 void Private_Impl::commitImageEffect() {
427 MMAL_PARAMETER_IMAGEFX_T imgFX = {{MMAL_PARAMETER_IMAGE_EFFECT,
sizeof ( imgFX ) }, convertImageEffect ( State.
rpc_imageEffect ) };
428 if ( mmal_port_parameter_set ( State.
camera_component->control, &imgFX.hdr ) != MMAL_SUCCESS )
429 cout << __func__ <<
": Failed to set image effect parameter.\n";
432 void Private_Impl::commitMetering() {
433 MMAL_PARAMETER_EXPOSUREMETERINGMODE_T meter_mode = {{MMAL_PARAMETER_EXP_METERING_MODE,
sizeof ( meter_mode ) }, convertMetering ( State.
rpc_exposureMeterMode ) };
434 if ( mmal_port_parameter_set ( State.
camera_component->control, &meter_mode.hdr ) != MMAL_SUCCESS )
435 cout << __func__ <<
": Failed to set metering parameter.\n";
438 void Private_Impl::commitFlips() {
439 MMAL_PARAMETER_MIRROR_T mirror = {{MMAL_PARAMETER_MIRROR,
sizeof ( MMAL_PARAMETER_MIRROR_T ) }, MMAL_PARAM_MIRROR_NONE};
441 mirror.value = MMAL_PARAM_MIRROR_BOTH;
442 else if ( State.
hflip )
443 mirror.value = MMAL_PARAM_MIRROR_HORIZONTAL;
444 else if ( State.
vflip )
445 mirror.value = MMAL_PARAM_MIRROR_VERTICAL;
446 if ( mmal_port_parameter_set ( State.
camera_component->output[0], &mirror.hdr ) != MMAL_SUCCESS ||
447 mmal_port_parameter_set ( State.
camera_component->output[1], &mirror.hdr ) != MMAL_SUCCESS ||
448 mmal_port_parameter_set ( State.
camera_component->output[2], &mirror.hdr ) )
449 cout << __func__ <<
": Failed to set horizontal/vertical flip parameter.\n";
459 void Private_Impl::commitParameters ( ) {
467 commitShutterSpeed();
472 commitExposureCompensation();
477 commitVideoStabilization();
482 void Private_Impl::commitVideoStabilization() {
485 cout << __func__ <<
": Failed to set video stabilization parameter.\n";
490 void Private_Impl::video_buffer_callback ( MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer ) {
491 MMAL_BUFFER_HEADER_T *new_buffer;
492 PORT_USERDATA *pData = ( PORT_USERDATA * ) port->userdata;
494 bool hasGrabbed=
false;
496 std::unique_lock<std::mutex> lck ( pData->_mutex );
498 if ( pData->wantToGrab && buffer->length ) {
499 mmal_buffer_header_mem_lock ( buffer );
500 pData->_buffData.resize ( buffer->length );
501 memcpy ( pData->_buffData.data,buffer->data,buffer->length );
502 pData->wantToGrab =
false;
504 mmal_buffer_header_mem_unlock ( buffer );
510 mmal_buffer_header_release ( buffer );
512 if ( port->is_enabled ) {
513 MMAL_STATUS_T status;
515 new_buffer = mmal_queue_get ( pData->pstate->video_pool->queue );
518 status = mmal_port_send_buffer ( port, new_buffer );
520 if ( !new_buffer || status != MMAL_SUCCESS )
521 printf (
"Unable to return a buffer to the encoder port" );
524 if ( pData->pstate->shutterSpeed!=0 )
525 mmal_port_parameter_set_uint32 ( pData->pstate->camera_component->control, MMAL_PARAMETER_SHUTTER_SPEED, pData->pstate->shutterSpeed ) ;
526 if ( hasGrabbed ) pData->Thcond.BroadCast();
533 State.
width = width - (width % 320);
537 State.
height = height - (height % 240);
541 cerr<<__FILE__<<
":"<<__LINE__<<
":"<<__func__<<
": can not change format with camera already opened"<<endl;
554 if (
isOpened() ) commitVideoStabilization();
558 if ( brightness > 100 ) brightness = 100 ;
560 if (
isOpened() ) commitBrightness();
563 if ( shutter > 330000 )
566 if (
isOpened() ) commitShutterSpeed();
573 while ( rotation < 0 )
575 if ( rotation >= 360 )
576 rotation = rotation % 360;
587 if ( sharpness < -100 ) sharpness = -100;
588 if ( sharpness > 100 ) sharpness = 100;
590 if (
isOpened() ) commitSharpness();
594 if ( contrast < -100 ) contrast = -100;
595 if ( contrast > 100 ) contrast = 100;
601 if ( saturation < -100 ) saturation = -100;
602 if ( saturation > 100 ) saturation = 100;
604 if (
isOpened() ) commitSaturation();
625 if (
isOpened() ) commitImageEffect();
633 if ( val < -10 ) val= -10;
634 if ( val > 10 ) val = 10;
636 if (
isOpened() ) commitExposureCompensation();
650 MMAL_PARAM_EXPOSUREMETERINGMODE_T Private_Impl::convertMetering (
RASPICAM_METERING metering ) {
651 switch ( metering ) {
653 return MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
655 return MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT;
657 return MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT;
659 return MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX;
661 return MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
664 MMAL_PARAM_EXPOSUREMODE_T Private_Impl::convertExposure (
RASPICAM_EXPOSURE exposure ) {
666 switch ( exposure ) {
668 return MMAL_PARAM_EXPOSUREMODE_OFF;
670 return MMAL_PARAM_EXPOSUREMODE_AUTO;
672 return MMAL_PARAM_EXPOSUREMODE_NIGHT;
674 return MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW;
676 return MMAL_PARAM_EXPOSUREMODE_BACKLIGHT;
678 return MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT;
680 return MMAL_PARAM_EXPOSUREMODE_SPORTS;
682 return MMAL_PARAM_EXPOSUREMODE_SNOW;
684 return MMAL_PARAM_EXPOSUREMODE_BEACH;
686 return MMAL_PARAM_EXPOSUREMODE_VERYLONG;
688 return MMAL_PARAM_EXPOSUREMODE_FIXEDFPS;
690 return MMAL_PARAM_EXPOSUREMODE_ANTISHAKE;
692 return MMAL_PARAM_EXPOSUREMODE_FIREWORKS;
694 return MMAL_PARAM_EXPOSUREMODE_AUTO;
698 MMAL_PARAM_AWBMODE_T Private_Impl::convertAWB (
RASPICAM_AWB awb ) {
701 return MMAL_PARAM_AWBMODE_OFF;
703 return MMAL_PARAM_AWBMODE_AUTO;
705 return MMAL_PARAM_AWBMODE_SUNLIGHT;
707 return MMAL_PARAM_AWBMODE_CLOUDY;
709 return MMAL_PARAM_AWBMODE_SHADE;
711 return MMAL_PARAM_AWBMODE_TUNGSTEN;
713 return MMAL_PARAM_AWBMODE_FLUORESCENT;
715 return MMAL_PARAM_AWBMODE_INCANDESCENT;
717 return MMAL_PARAM_AWBMODE_FLASH;
719 return MMAL_PARAM_AWBMODE_HORIZON;
721 return MMAL_PARAM_AWBMODE_AUTO;
726 switch ( imageEffect ) {
728 return MMAL_PARAM_IMAGEFX_NONE;
730 return MMAL_PARAM_IMAGEFX_NEGATIVE;
732 return MMAL_PARAM_IMAGEFX_SOLARIZE;
734 return MMAL_PARAM_IMAGEFX_SKETCH;
736 return MMAL_PARAM_IMAGEFX_DENOISE;
738 return MMAL_PARAM_IMAGEFX_EMBOSS;
740 return MMAL_PARAM_IMAGEFX_OILPAINT;
742 return MMAL_PARAM_IMAGEFX_HATCH;
744 return MMAL_PARAM_IMAGEFX_GPEN;
746 return MMAL_PARAM_IMAGEFX_PASTEL;
748 return MMAL_PARAM_IMAGEFX_WATERCOLOUR;
750 return MMAL_PARAM_IMAGEFX_FILM;
752 return MMAL_PARAM_IMAGEFX_BLUR;
754 return MMAL_PARAM_IMAGEFX_SATURATION;
756 return MMAL_PARAM_IMAGEFX_COLOURSWAP;
758 return MMAL_PARAM_IMAGEFX_WASHEDOUT;
760 return MMAL_PARAM_IMAGEFX_POSTERISE;
762 return MMAL_PARAM_IMAGEFX_COLOURPOINT;
764 return MMAL_PARAM_IMAGEFX_COLOURBALANCE;
766 return MMAL_PARAM_IMAGEFX_CARTOON;
768 return MMAL_PARAM_IMAGEFX_NONE;
779 return MMAL_ENCODING_RGB24;
781 return MMAL_ENCODING_BGR24;
783 return MMAL_ENCODING_I420;
785 return MMAL_ENCODING_I420;
787 return MMAL_ENCODING_I420;
797 ifstream file (
"/proc/cpuinfo" );
799 cerr<<__FILE__<<
" "<<__LINE__<<
":"<<__func__<<
"Could not read /proc/cpuinfo"<<endl;
804 while ( !file.eof() && !found ) {
806 file.getline ( line,1024 );
810 if ( str.find (
"Serial" ) !=string::npos ) {
811 if ( sscanf ( line,
"%s : %s",aux,serial ) !=2 ) {
812 cerr<<__FILE__<<
" "<<__LINE__<<
":"<<__func__<<
"Error parsing /proc/cpuinfo"<<endl;
819 void Private_Impl::convertBGR2RGB (
unsigned char * in_bgr,
unsigned char * out_rgb,
int size ) {
820 unsigned char *end=in_bgr+size;
821 unsigned char *in_ptr=in_bgr;
822 while ( in_ptr<end ) {
823 swap ( in_ptr[2],in_ptr[0] );
826 mempcpy ( out_rgb,in_bgr,size );
830 void Private_Impl::commitAWB_RB() {
831 MMAL_PARAMETER_AWB_GAINS_T param = {{MMAL_PARAMETER_CUSTOM_AWB_GAINS,
sizeof(param)}, {0,0}, {0,0}};
832 param.r_gain.num = (
unsigned int)(State.
awbg_red * 65536);
833 param.b_gain.num = (
unsigned int)(State.
awbg_blue * 65536);
834 param.r_gain.den = param.b_gain.den = 65536;
835 if ( mmal_port_parameter_set(State.
camera_component->control, ¶m.hdr) != MMAL_SUCCESS )
836 cout << __func__ <<
": Failed to set AWBG gains parameter.\n";
unsigned int getWidth() const
void setHeight(unsigned int height)
void setFormat(RASPICAM_FORMAT fmt)
void setExposureCompensation(int val)
void setHorizontalFlip(bool hFlip)
void setContrast(int contrast)
void setWidth(unsigned int width)
void setRotation(int rotation)
void setVideoStabilization(bool v)
size_t getImageTypeSize(RASPICAM_FORMAT type) const
unsigned int getHeight() const
void setImageEffect(RASPICAM_IMAGE_EFFECT imageEffect)
void setBrightness(unsigned int brightness)
void setAWB_RB(float red, float blue)
RASPICAM_FORMAT getFormat() const
std::string getId() const
void setExposure(RASPICAM_EXPOSURE exposure)
void setSharpness(int sharpness)
void setShutterSpeed(unsigned int shutter)
bool open(bool StartCapture=true)
void setAWB(RASPICAM_AWB awb)
void setFrameRate(unsigned int frame_rate)
unsigned char * getImageBufferData() const
size_t getImageBufferSize() const
void setSaturation(int saturation)
void setMetering(RASPICAM_METERING metering)
void setCaptureSize(unsigned int width, unsigned int height)
void retrieve(unsigned char *data, RASPICAM_FORMAT type=RASPICAM_FORMAT_IGNORE)
void setVerticalFlip(bool vFlip)
@ RASPICAM_AWB_INCANDESCENT
@ RASPICAM_AWB_FLUORESCENT
@ RASPICAM_METERING_AVERAGE
@ RASPICAM_METERING_MATRIX
@ RASPICAM_METERING_BACKLIT
@ RASPICAM_EXPOSURE_SPOTLIGHT
@ RASPICAM_EXPOSURE_BEACH
@ RASPICAM_EXPOSURE_NIGHTPREVIEW
@ RASPICAM_EXPOSURE_BACKLIGHT
@ RASPICAM_EXPOSURE_ANTISHAKE
@ RASPICAM_EXPOSURE_FIREWORKS
@ RASPICAM_EXPOSURE_NIGHT
@ RASPICAM_EXPOSURE_SPORTS
@ RASPICAM_EXPOSURE_FIXEDFPS
@ RASPICAM_EXPOSURE_VERYLONG
@ RASPICAM_IMAGE_EFFECT_WATERCOLOR
@ RASPICAM_IMAGE_EFFECT_DENOISE
@ RASPICAM_IMAGE_EFFECT_GPEN
@ RASPICAM_IMAGE_EFFECT_CARTOON
@ RASPICAM_IMAGE_EFFECT_COLORSWAP
@ RASPICAM_IMAGE_EFFECT_COLORPOINT
@ RASPICAM_IMAGE_EFFECT_WASHEDOUT
@ RASPICAM_IMAGE_EFFECT_SKETCH
@ RASPICAM_IMAGE_EFFECT_EMBOSS
@ RASPICAM_IMAGE_EFFECT_HATCH
@ RASPICAM_IMAGE_EFFECT_OILPAINT
@ RASPICAM_IMAGE_EFFECT_SOLARIZE
@ RASPICAM_IMAGE_EFFECT_POSTERISE
@ RASPICAM_IMAGE_EFFECT_FILM
@ RASPICAM_IMAGE_EFFECT_NEGATIVE
@ RASPICAM_IMAGE_EFFECT_NONE
@ RASPICAM_IMAGE_EFFECT_BLUR
@ RASPICAM_IMAGE_EFFECT_SATURATION
@ RASPICAM_IMAGE_EFFECT_PASTEL
@ RASPICAM_IMAGE_EFFECT_COLORBALANCE
#define VIDEO_FRAME_RATE_DEN
#define VIDEO_OUTPUT_BUFFERS_NUM
#define MMAL_CAMERA_VIDEO_PORT
int height
Requested width of image.
float awbg_red
region of interest to use on the sensor. Normalised [0,1] values in the rect
RASPICAM_EXPOSURE rpc_exposureMode
RASPICAM_METERING rpc_exposureMeterMode
MMAL_POOL_T * video_pool
Pointer to the camera component.
PARAM_FLOAT_RECT_T roi
0 or 1
RASPICAM_IMAGE_EFFECT rpc_imageEffect
MMAL_PARAM_COLOURFX_T colourEffects
RASPICAM_FORMAT captureFtm
int exposureCompensation
0 or 1 (false or true)
int framerate
requested height of image
bool videoStabilisation
TODO : what range?
MMAL_COMPONENT_T * camera_component
the camera output or the encoder output (with compression artifacts)
int brightness
-100 to 100
int sharpness
Pointer to the pool of buffers used by encoder output port.
int shutterSpeed
-10 to +10 ?