Created
July 15, 2021 18:50
-
-
Save natxopedreira/5b2aa56b69489f24468dd6b69a0db05a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef VIDEOMMALOBJECT_H | |
#define VIDEOMMALOBJECT_H | |
#include <mutex> | |
#include <iostream> | |
#include <fstream> | |
#include <functional> | |
#include "mmal/mmal.h" | |
#include "mmal/util/mmal_util.h" | |
#include "mmal/util/mmal_util_params.h" | |
#include "mmal/util/mmal_default_components.h" | |
#include "mmal/util/mmal_connection.h" | |
#include "mmal/mmal_buffer.h" | |
#include <condition_variable> | |
#include "interface/vcos/vcos.h" | |
using namespace std; | |
#define MMAL_CAMERA_PREVIEW_PORT 0 | |
#define MMAL_CAMERA_VIDEO_PORT 1 | |
#define MMAL_CAMERA_STILL_PORT 2 | |
#define VIDEO_FRAME_RATE_DEN 1 | |
#define VIDEO_OUTPUT_BUFFERS_NUM 3 | |
#define MAX_VIDEO_WIDTH 1920 | |
#define MAX_VIDEO_HEIGHT 1080 | |
#define MAX_STILL_WIDTH 4056 | |
#define MAX_STILL_HEIGHT 3040 | |
/* Structures from | |
* https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/raspicam/RaspiCamControl.h | |
*/ | |
// There isn't actually a MMAL structure for the following, so make one | |
struct MMAL_PARAM_COLOURFX_T | |
{ | |
int enable; /// Turn colourFX on or off | |
int u,v; /// U and V to use | |
}; | |
struct MMAL_PARAM_THUMBNAIL_CONFIG_T | |
{ | |
int enable; | |
int width,height; | |
int quality; | |
}; | |
struct PARAM_FLOAT_RECT_T | |
{ | |
double x; | |
double y; | |
double w; | |
double h; | |
}; | |
struct CAMERA_PARAMETERS | |
{ | |
int framerate; | |
int sharpness; /// -100 to 100 | |
int contrast; /// -100 to 100 | |
int brightness; /// 0 to 100 | |
int saturation; /// -100 to 100 | |
int ISO; /// TODO : what range? 100 to 6400? | |
bool videoStabilisation; /// 0 or 1 (false or true) | |
int exposureCompensation; /// -10 to +10 ? | |
int shutterSpeed; | |
MMAL_PARAM_EXPOSUREMODE_T exposureMode; | |
MMAL_PARAM_EXPOSUREMETERINGMODE_T exposureMeterMode; | |
MMAL_PARAM_AWBMODE_T awbMode; | |
MMAL_PARAM_IMAGEFX_T imageEffect; | |
MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imageEffectsParameters; | |
MMAL_PARAM_COLOURFX_T colourEffects; | |
MMAL_PARAM_FLICKERAVOID_T flickerAvoidMode; | |
int rotation; /// 0-359 | |
int hflip; /// 0 or 1 | |
int vflip; /// 0 or 1 | |
PARAM_FLOAT_RECT_T roi; /// region of interest to use on the sensor. Normalised [0,1] values in the rect | |
float awbg_red;//white balance red and blue | |
float awbg_blue; | |
}; | |
/** Struct used to pass information in encoder port userdata to callback | |
*/ | |
struct PORT_PREVIEW_USERDATA | |
{ | |
PORT_PREVIEW_USERDATA() { | |
wantToGrab=false; | |
} | |
void waitForFrame() { | |
//_mutex.lock(); | |
std::unique_lock<std::mutex> lck ( _mutex ); | |
wantToGrab=true; | |
ready = false; | |
while ( !ready ) cv.wait ( lck ); //this will unlock the mutex and wait atomically | |
}; | |
void Broadcast() { | |
ready = true; | |
cv.notify_all(); | |
}; | |
MMAL_POOL_T *pool; | |
std::mutex _mutex; | |
bool ready; | |
condition_variable cv; | |
bool wantToGrab; | |
unsigned int buffer_length; | |
unsigned char * buffer_data; | |
}; | |
struct PORT_ENCODER_USERDATA | |
{ | |
std::ofstream * file; | |
MMAL_POOL_T * encoder_pool; | |
bool encode_completed;/// Pointer to the pool of buffers used by encoder output port | |
}; | |
class VideoMMALObject | |
{ | |
public: | |
void setStillPreviewSize(unsigned int preview_width, unsigned int preview_height); | |
void setStillPreviewImageFormat(int mmal_image_format); | |
int getStillPreviewImageFormat() { return m_still_preview_format;}; | |
void startStillPreview(); | |
void stopStillPreview(); | |
unsigned int getStillPreviewWidth(){ return m_still_preview_width;}; | |
unsigned int getStillPreviewHeight(){ return m_still_preview_height;}; | |
bool isStillPreviewOpened(){ return m_is_still_preview_opened;} | |
void setVideoPreviewSize(unsigned int preview_width, unsigned int preview_height); | |
void setVideoPreviewImageFormat(int mmal_image_format); | |
int getVideoPreviewImageFormat() { return m_video_preview_format;}; | |
void startVideoPreview(); | |
void stopVideoPreview(); | |
unsigned int getVideoPreviewWidth(){ return m_video_preview_width;}; | |
unsigned int getVideoPreviewHeight(){ return m_video_preview_height;}; | |
bool isVideoPreviewOpened(){ return m_is_video_preview_opened;} | |
bool grab(); | |
void retrieve(unsigned char *data); | |
void setVideoRecordSize(unsigned int record_width, unsigned int record_height); | |
unsigned int getVideoRecordWidth(){ return m_video_record_width;}; | |
unsigned int getVideoRecordHeight(){ return m_video_record_height;}; | |
void startVideoRecord(std::string filename); | |
void stopVideoRecord(); | |
void setStillRecordSize(unsigned int record_width, unsigned int record_height); | |
unsigned int getStillRecordWidth(){ return m_still_record_width;}; | |
unsigned int getStillRecordHeight(){ return m_still_record_height;}; | |
void startStillRecord(std::string filename); | |
//void stopStillRecord(); | |
VideoMMALObject(const VideoMMALObject&) = delete; | |
VideoMMALObject& operator=(const VideoMMALObject&) = delete; | |
bool isStillRecording(){ return m_is_still_recording;} | |
bool isVideoRecording(){ return m_is_video_recording;} | |
bool areVideoComponentsReady(){ return m_are_video_components_ready;} | |
bool isOpened(){ return m_is_opened;} | |
void setCamId(int n); | |
bool open(); | |
void release(); | |
void setVideoStabilization(bool v); | |
void setBrightness(unsigned int brightness); | |
void setShutterSpeed(unsigned int shutter); | |
void setRotation(int rotation); | |
void setISO(int iso); | |
void setSharpness(int sharpness) ; | |
void setContrast(int contrast); | |
void setSaturation(int saturation); | |
void setAWB_RB(float red_g, float blue_g); | |
void setExposure(MMAL_PARAM_EXPOSUREMODE_T exposure); | |
void setAWB(MMAL_PARAM_AWBMODE_T awb); | |
void setImageEffect(MMAL_PARAM_IMAGEFX_T imageEffect); | |
void setMetering(MMAL_PARAM_EXPOSUREMETERINGMODE_T metering); | |
void setExposureCompensation(int val); | |
void setHorizontalFlip(bool hFlip); | |
void setVerticalFlip(bool vFlip); | |
void setFrameRate(unsigned int framerate); | |
VideoMMALObject(); | |
~VideoMMALObject(); | |
private: | |
int m_still_preview_format; | |
unsigned int m_still_preview_width; | |
unsigned int m_still_preview_height; | |
bool m_is_still_preview_opened; | |
int camera_num; | |
int m_video_preview_format; | |
unsigned int m_video_preview_width; | |
unsigned int m_video_preview_height; | |
bool m_is_video_preview_opened; | |
unsigned int m_video_record_width; | |
unsigned int m_video_record_height; | |
bool m_is_video_recording; | |
unsigned int m_still_record_width; | |
unsigned int m_still_record_height; | |
bool m_is_still_recording; | |
bool m_is_opened; | |
bool m_are_video_components_ready; | |
CAMERA_PARAMETERS m_cam_params; | |
void setDefaultsCamParams(); | |
void commitParameters(); | |
void destroyCameraComponent(); | |
void createCameraComponent(); | |
void destroyVideoComponents(); | |
void createVideoComponents(); | |
void createStillEncoderComponent(); | |
void destroyStillEncoderComponent(); | |
void createVideoEncoderComponent(); | |
void destroyVideoEncoderComponent(); | |
void destroyVideoPreviewComponent(); | |
void createVideoPreviewComponent(); | |
void destroyStillPreviewComponent(); | |
void createStillPreviewComponent(); | |
MMAL_STATUS_T connectPorts ( MMAL_PORT_T *output_port, MMAL_PORT_T *input_port, MMAL_CONNECTION_T **connection ); | |
void destroyConnection(MMAL_CONNECTION_T *connection); | |
static void encoder_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); | |
static void preview_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); | |
void add_preview_buffer_callback(void * data); | |
//void preview_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); | |
MMAL_COMPONENT_T *camera_component; | |
MMAL_PORT_T *camera_video_output_port; | |
MMAL_PORT_T *camera_preview_output_port; | |
MMAL_PORT_T *camera_still_output_port; | |
/* Used in Video components */ | |
MMAL_PORT_T *splitter_output_record_port; | |
MMAL_PORT_T *splitter_output_video_port; | |
MMAL_PORT_T *splitter_input_port; | |
MMAL_COMPONENT_T *splitter_component; | |
MMAL_CONNECTION_T *splitter_connection; // Connection from the camera to the splitter | |
/* Used in Video record */ | |
MMAL_COMPONENT_T *video_encoder_component; /// Pointer to the video_encoder component | |
MMAL_CONNECTION_T *video_encoder_connection; // Connection from the splitter to the video_encoder | |
MMAL_PORT_T *video_encoder_input_port; | |
MMAL_PORT_T *video_encoder_output_port; | |
MMAL_POOL_T *video_encoder_pool; | |
/* Used in Still record */ | |
MMAL_COMPONENT_T *still_encoder_component; /// Pointer to the video_encoder component | |
MMAL_CONNECTION_T *still_encoder_connection; // Connection from the splitter to the video_encoder | |
MMAL_PORT_T *still_encoder_input_port; | |
MMAL_PORT_T *still_encoder_output_port; | |
MMAL_POOL_T *still_encoder_pool; | |
/* Used in records */ | |
PORT_ENCODER_USERDATA encoder_callback_data; | |
/* Used in preview video*/ | |
MMAL_PORT_T *resizer_output_port; | |
MMAL_PORT_T *resizer_input_port; | |
MMAL_COMPONENT_T *resizer_component; | |
MMAL_CONNECTION_T *resizer_connection; // Connection from the splitter to the resizer | |
MMAL_POOL_T *resize_pool; | |
/* Used in preview Still*/ | |
MMAL_POOL_T *still_preview_pool; | |
// used in both preview | |
PORT_PREVIEW_USERDATA preview_callback_data; | |
void commitSaturation(); | |
void commitSharpness(); | |
void commitContrast(); | |
void commitBrightness(); | |
void commitISO(); | |
void commitShutterSpeed(); | |
void commitExposure(); | |
void commitExposureCompensation(); | |
void commitMetering(); | |
void commitImageEffect(); | |
void commitRotation(); | |
void commitFlips(); | |
void commitVideoStabilization(); | |
void commitAWB(); | |
void commitAWB_RB(); | |
}; | |
#endif // VIDEOMMALOBJECT_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment