CM H264 Encode Pre-Record
CM H264 Encode Pre-Record
The cmPrerecH264 is an h264 encoder with a cache that is used to encode the video/x-raw(YUV) data to video/h264(H264) data by the gstvideo4linux2 library. It supports set cache duration in second for the codec data, mainly used for MP4 records. This is designed for pre-recording.
API Instructions
create/destroy
gpointer cm_prerec_h264_create();
void cm_prerec_h264_destroy(gpointer hd);
start/stop
void cm_prerec_h264_start(gpointer hd);
void cm_prerec_h264_stop(gpointer hd);
parameters
/* @duration Cache time in seconds*/
void cm_prerec_h264_set_duration(gpointer hd, guint64 duration );
/* @return Encode output format, "video/h264,..." */
const char* cm_prerec_h264_get_caps_str(gpointer hd);
data
The encoder needs to know the actual format of the input before encoding, so must ensure the source is ready to be linked(the media info is ready).
/* @src An video/x-raw source(cmV4l2Src, ...) */
void cm_prerec_h264_link_to_source(gpointer hd, gpointer src);
void cm_prerec_h264_unlink(gpointer hd);
/* @cb data callback to get data */
void cm_prerec_h264_set_data_callback(gpointer hd, cm_data_cb_ptr cb, gpointer user_data);
void cm_prerec_h264_remove_data_callback(gpointer hd, cm_data_cb_ptr cb, gpointer user_data);
/* The h264 media is ready */
gboolean cm_prerec_h264_is_ready(gpointer hd);
Demo
Mp4 PreRecord Demo
Structure
Get raw data and use prerecord to encode, then start the mp4 record 3s later.
Main codes
static GstClockTime clock0 = -1;
static gboolean _main_loop(gpointer arg) {
if(!vsrc) {
//Create source
vsrc = cm_video_v4l2_source_create("/dev/video0");
//Choose video format
cm_video_v4l2_source_set_caps_str0(vsrc,
"video/x-raw,format=UYVY,width=1280,height=720,colorimetry=(string)1:4:7:1");
cm_video_v4l2_source_start(vsrc);
}
if(!asrc) {
//Create audio source
asrc = cm_audio_alsa_source_create("hw:1,0");
cm_audio_alsa_source_start(asrc);
}
//Wait the video source ready
if(cm_video_v4l2_source_is_ready(vsrc)){
if(!pre_h264){
//Create prerecord h264
pre_h264 = cm_prerec_h264_create();
//Set prerecord duration
cm_prerec_h264_set_duration(pre_h264, 5);
//Link to source
cm_prerec_h264_link_to_source(pre_h264, vsrc);
//Start
cm_prerec_h264_start(pre_h264);
}
}
//Wait the audio source ready
if(cm_audio_alsa_source_is_ready(asrc)){
if(!pre_aac){
//Create prerecord aac
pre_aac = cm_prerec_aac_create();
//Set prerecord duration
cm_prerec_aac_set_duration(pre_aac, 5);
//Link to source
cm_prerec_aac_link_to_source(pre_aac, asrc);
//Start
cm_prerec_aac_start(pre_aac);
}
}
if(clock0 == -1) clock0 = gst_util_get_timestamp();
//Wait prerecord h264 and prerecord aac are ready
if((pre_h264 && cm_prerec_h264_is_ready(pre_h264))
&& (pre_aac && cm_prerec_aac_is_ready(pre_aac))){
GstClockTime clock1 = gst_util_get_timestamp();
//Start mp4 record 3s later
int delay = GST_TIME_AS_SECONDS(GST_CLOCK_DIFF (clock0, clock1));
if( delay > 3){
if(!mp4){
gst_print("start Mp4 record after %d seconds \n", delay);
//Create record
mp4 = cm_mp4_record_create(TRUE);
//Set duration to 15s
cm_mp4_record_set_duration(mp4, 15);
time_t cur_time;
time(&cur_time);
struct tm *local = localtime(&cur_time);
char filename[64] = {0};
sprintf(filename, "REC_%04d%02d%02d%02d%02d%02d.mp4",
local->tm_year + 1900, local->tm_mon + 1, local->tm_mday,
local->tm_hour, local->tm_min, local->tm_sec);
//Set filename
cm_mp4_record_set_filename(mp4, filename);
//Set queue size to avoid lost frame
cm_mp4_record_set_queue_size(mp4, 512);
//Link to prerecord
cm_mp4_record_link_to_source(mp4, pre_h264, pre_aac);
//Set watch hadle
cm_mp4_record_set_bus_handler(mp4, _record_bus_handler, NULL);
//Start record
cm_mp4_record_start(mp4);
gst_print("%s\n", filename);
}
else{
guint64 duration_ms;
//Get current duration
cm_mp4_record_get_control_info(mp4, "current-duration", (void**)&duration_ms);
gst_print("Mp4 recording......%d%%\r", duration_ms / duration / 10);
if(duration_ms/1000 >= duration){
is_exit = TRUE;
}
}
}
}
......
}
For more details please refer to the demo file.
Test result
The mp4 file can be displayed on the PC, it contains pre-recorded data for about 4s.
, multiple selections available,