/
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.

image-20240520-072300.png

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

image-20240520-072332.png

The mp4 file can be displayed on the PC, it contains pre-recorded data for about 4s.

 

Related content