From fb889179964c5d7e31f68ea163a992acb9445adc Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Mon, 27 Jul 2020 14:39:24 +0900 Subject: [PATCH] Add sub function to remove duplicated code [Version] 0.10.207 [Profile] Common [Issue Type] Optimization Change-Id: I91b4bf5b7d53157b3826f3211ae6dbf2775d0a88 Signed-off-by: Jeongmo Yang --- packaging/libmm-camcorder.spec | 2 +- src/include/mm_camcorder_videorec.h | 13 ++- src/mm_camcorder_gstcommon.c | 162 +++++---------------------- src/mm_camcorder_stillshot.c | 2 +- src/mm_camcorder_videorec.c | 167 ++++++++++++++++++---------- 5 files changed, 148 insertions(+), 198 deletions(-) diff --git a/packaging/libmm-camcorder.spec b/packaging/libmm-camcorder.spec index 3fd96f7..7219da9 100644 --- a/packaging/libmm-camcorder.spec +++ b/packaging/libmm-camcorder.spec @@ -1,6 +1,6 @@ Name: libmm-camcorder Summary: Camera and recorder library -Version: 0.10.206 +Version: 0.10.207 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_camcorder_videorec.h b/src/include/mm_camcorder_videorec.h index f592e93..630fa16 100644 --- a/src/include/mm_camcorder_videorec.h +++ b/src/include/mm_camcorder_videorec.h @@ -74,8 +74,7 @@ typedef struct { int video_width; /**< video width */ int video_height; /**< video height */ int fps; /**< fps in videosrc caps */ - gboolean is_firstframe; - gboolean get_first_I_frame; /**< start flag for H.264 preview recording */ + gboolean is_first_frame; /**< flag for first frame */ gboolean support_dual_stream; /**< support dual stream flag */ gboolean record_dual_stream; /**< record with dual stream flag */ gboolean restart_preview; /**< flag for whether restart preview or not when start recording */ @@ -158,6 +157,16 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle); */ int _mmcamcorder_video_prepare_record(MMHandleType handle); +/** + * This function pushes video buffer to encoding pipeline + * + * @param[in] handle Handle of camcorder context. + * @param[in] buffer Buffer to push. + * @return This function returns TRUE on success, or FALSE on failure. + * @remarks + */ +gboolean _mmcamcorder_video_push_buffer(void *handle, GstBuffer *buffer); + #ifdef __cplusplus } diff --git a/src/mm_camcorder_gstcommon.c b/src/mm_camcorder_gstcommon.c index 19dbcc8..f324b2b 100644 --- a/src/mm_camcorder_gstcommon.c +++ b/src/mm_camcorder_gstcommon.c @@ -128,8 +128,6 @@ gboolean videocodec_fileformat_compatibility_table[MM_VIDEO_CODEC_NUM][MM_FILE_F #define USE_AUDIO_CLOCK_TUNE #define _MMCAMCORDER_WAIT_EOS_TIME 60.0 /* sec */ #define _MMCAMCORDER_CONVERT_OUTPUT_BUFFER_NUM 6 -#define _MMCAMCORDER_MIN_TIME_TO_PASS_FRAME 30000000 /* ns */ -#define _MMCAMCORDER_FRAME_PASS_MIN_FPS 30 #define _MMCAMCORDER_NANOSEC_PER_1SEC 1000000000 #define _MMCAMCORDER_NANOSEC_PER_1MILISEC 1000 @@ -139,19 +137,20 @@ gboolean videocodec_fileformat_compatibility_table[MM_VIDEO_CODEC_NUM][MM_FILE_F -----------------------------------------------------------------------*/ /* STATIC INTERNAL FUNCTION */ /** - * These functions are preview video data probing function. - * If this function is linked with certain pad by gst_pad_add_buffer_probe(), - * this function will be called when data stream pass through the pad. + * These are video data probing functions. + * If there are pads which set probe callback by gst_pad_add_probe(), + * the functions will be called when data stream pass through the pad. * - * @param[in] pad probing pad which calls this function. - * @param[in] buffer buffer which contains stream data. - * @param[in] u_data user data. - * @return This function returns true on success, or false value with error + * @param[in] pad probing pad which calls this function. + * @param[in] buffer buffer which contains stream data. + * @param[in] u_data user data. + * @return Refer #GstPadProbeReturn in gstpad.h * @remarks - * @see __mmcamcorder_create_preview_pipeline() + * @see __mmcamcorder_create_preview_pipeline() */ static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); -static GstPadProbeReturn __mmcamcorder_video_dataprobe_push_buffer_to_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); +static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); + static int __mmcamcorder_get_amrnb_bitrate_mode(int bitrate); static guint32 _mmcamcorder_convert_fourcc_string_to_value(const gchar* format_name); #ifdef _MMCAMCORDER_PRODUCT_TV @@ -1347,16 +1346,18 @@ int _mmcamcorder_create_preview_pipeline(MMHandleType handle) goto pipeline_creation_error; } - /* set dataprobe for video recording */ - if (_mmcamcorder_is_encoded_preview_pixel_format(sc->info_image->preview_format)) - srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "src"); - else - srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "src"); + /* set dataprobe for video recording if it does not support dual stream. */ + if (sc->info_video->record_dual_stream == FALSE) { + if (_mmcamcorder_is_encoded_preview_pixel_format(sc->info_image->preview_format)) + srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "src"); + else + srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "src"); - MMCAMCORDER_ADD_BUFFER_PROBE(srcpad, _MMCAMCORDER_HANDLER_PREVIEW, - __mmcamcorder_video_dataprobe_push_buffer_to_record, hcamcorder); - gst_object_unref(srcpad); - srcpad = NULL; + MMCAMCORDER_ADD_BUFFER_PROBE(srcpad, _MMCAMCORDER_HANDLER_PREVIEW, + __mmcamcorder_video_dataprobe_record, hcamcorder); + gst_object_unref(srcpad); + srcpad = NULL; + } bus = gst_pipeline_get_bus(GST_PIPELINE(sc->element[_MMCAMCORDER_MAIN_PIPE].gst)); @@ -1390,7 +1391,6 @@ void _mmcamcorder_ready_to_encode_callback(GstElement *element, guint size, gpoi /* set flag */ if (sc->info_video->push_encoding_buffer == PUSH_ENCODING_BUFFER_INIT) { - sc->info_video->get_first_I_frame = FALSE; sc->info_video->push_encoding_buffer = PUSH_ENCODING_BUFFER_RUN; _mmcam_dbg_warn("set push_encoding_buffer RUN"); } @@ -2023,123 +2023,13 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstP return GST_PAD_PROBE_OK; } -static GstPadProbeReturn __mmcamcorder_video_dataprobe_push_buffer_to_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data) -{ - mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data); - _MMCamcorderSubContext *sc = NULL; - GstClockTime diff = 0; /* nsec */ - GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info); - - mmf_return_val_if_fail(buffer, GST_PAD_PROBE_DROP); - mmf_return_val_if_fail(gst_buffer_n_memory(buffer), GST_PAD_PROBE_DROP); - mmf_return_val_if_fail(hcamcorder, GST_PAD_PROBE_DROP); - - sc = MMF_CAMCORDER_SUBCONTEXT(u_data); - mmf_return_val_if_fail(sc, GST_PAD_PROBE_DROP); - - /* push buffer in appsrc to encode */ - if (!sc->info_video) { - _mmcam_dbg_warn("sc->info_video is NULL!!"); - return GST_PAD_PROBE_DROP; - } - - if (sc->info_video->push_encoding_buffer == PUSH_ENCODING_BUFFER_RUN && - sc->info_video->record_dual_stream == FALSE && - sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst) { - int ret = 0; - GstClock *clock = NULL; - - /* - _mmcam_dbg_log("GST_BUFFER_FLAG_DELTA_UNIT is set : %d", - GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)); - */ - - /* check first I frame */ - if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264 && - sc->info_video->get_first_I_frame == FALSE) { - if (!GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) { - _mmcam_dbg_warn("first I frame is come"); - sc->info_video->get_first_I_frame = TRUE; - } else { - _mmcam_dbg_warn("NOT I frame.. skip this buffer"); - return GST_PAD_PROBE_OK; - } - } - - if (sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst) { - if (sc->info_video->is_firstframe) { - clock = GST_ELEMENT_CLOCK(sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst); - if (clock) { - gst_object_ref(clock); - sc->info_video->base_video_ts = GST_BUFFER_PTS(buffer) - (gst_clock_get_time(clock) - GST_ELEMENT(sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst)->base_time); - gst_object_unref(clock); - } - } - } else { - if (sc->info_video->is_firstframe) { - /* for image capture with encodebin(ex:emulator) */ - if (sc->bencbin_capture && sc->info_image->capturing) { - g_mutex_lock(&hcamcorder->task_thread_lock); - _mmcam_dbg_log("send signal for sound play"); - hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_SOUND_SOLO_PLAY_START; - g_cond_signal(&hcamcorder->task_thread_cond); - g_mutex_unlock(&hcamcorder->task_thread_lock); - } - sc->info_video->base_video_ts = GST_BUFFER_PTS(buffer); - } - } - GST_BUFFER_PTS(buffer) = GST_BUFFER_PTS(buffer) - sc->info_video->base_video_ts; - GST_BUFFER_DTS(buffer) = GST_BUFFER_PTS(buffer); - - /*_mmcam_dbg_log("buffer %p, timestamp %"GST_TIME_FORMAT, buffer, GST_TIME_ARGS(GST_BUFFER_PTS(buffer)));*/ - - if (0) { - GstCaps *caps = gst_pad_get_current_caps(pad); - if (caps) { - char *caps_string = gst_caps_to_string(caps); - if (caps_string) { - _mmcam_dbg_log("%s", caps_string); - g_free(caps_string); - caps_string = NULL; - } - gst_caps_unref(caps); - caps = NULL; - } else { - _mmcam_dbg_warn("failed to get caps from pad"); - } - } - g_signal_emit_by_name(sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst, "push-buffer", buffer, &ret); - - /*_mmcam_dbg_log("push buffer result : 0x%x", ret);*/ - - if (sc->info_video->is_firstframe) { - sc->info_video->is_firstframe = FALSE; - - /* drop buffer if it's from tizen allocator */ - if (gst_is_tizen_memory(gst_buffer_peek_memory(buffer, 0))) { - _mmcam_dbg_warn("drop first buffer from tizen allocator to avoid copy in basesrc"); - return GST_PAD_PROBE_DROP; - } - } - } - - /* skip display if too fast FPS */ - if (sc->info_video && sc->info_video->fps > _MMCAMCORDER_FRAME_PASS_MIN_FPS) { - if (sc->info_video->prev_preview_ts != 0) { - diff = GST_BUFFER_PTS(buffer) - sc->info_video->prev_preview_ts; - if (diff < _MMCAMCORDER_MIN_TIME_TO_PASS_FRAME) { - _mmcam_dbg_log("it's too fast. drop frame..."); - return GST_PAD_PROBE_DROP; - } - } - - /*_mmcam_dbg_log("diff %llu", diff);*/ - - sc->info_video->prev_preview_ts = GST_BUFFER_PTS(buffer); - } +static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data) +{ + if (_mmcamcorder_video_push_buffer(u_data, GST_PAD_PROBE_INFO_BUFFER(info))) + return GST_PAD_PROBE_OK; - return GST_PAD_PROBE_OK; + return GST_PAD_PROBE_DROP; } diff --git a/src/mm_camcorder_stillshot.c b/src/mm_camcorder_stillshot.c index 554273d..723cf73 100644 --- a/src/mm_camcorder_stillshot.c +++ b/src/mm_camcorder_stillshot.c @@ -563,7 +563,7 @@ int _mmcamcorder_image_cmd_capture(MMHandleType handle) MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE); /* Prepare for the shutter sound when it's the bencbin mode capture */ - sc->info_video->is_firstframe = TRUE; + sc->info_video->is_first_frame = TRUE; /* set push encoding buffer as TRUE */ sc->info_video->push_encoding_buffer = PUSH_ENCODING_BUFFER_INIT; diff --git a/src/mm_camcorder_videorec.c b/src/mm_camcorder_videorec.c index 1413b08..8ea4758 100644 --- a/src/mm_camcorder_videorec.c +++ b/src/mm_camcorder_videorec.c @@ -22,26 +22,23 @@ /*======================================================================================= | INCLUDE FILES | =======================================================================================*/ +#include #include #include #include "mm_camcorder_internal.h" #include "mm_camcorder_videorec.h" -/*--------------------------------------------------------------------------------------- -| GLOBAL VARIABLE DEFINITIONS for internal | ----------------------------------------------------------------------------------------*/ -#define _MMCAMCORDER_LOCATION_INFO /* for add gps information */ -#define MAX_ERROR_MESSAGE_LEN 128 - /*--------------------------------------------------------------------------------------- | LOCAL VARIABLE DEFINITIONS for internal | ---------------------------------------------------------------------------------------*/ -#define _MMCAMCORDER_MINIMUM_FRAME 5 -#define _MMCAMCORDER_RETRIAL_COUNT 15 -#define _MMCAMCORDER_FRAME_WAIT_TIME 200000 /* us */ -#define _OFFSET_COMPOSITION_MATRIX 40L -#define _GOP_GEN_INTERVAL 1000000000 /* ns */ -#define _MMCAMCORDER_VIDEO_MINIMUM_SPACE (_MMCAMCORDER_MINIMUM_SPACE << 1) /* byte */ +#define _MMCAMCORDER_MINIMUM_FRAME 5 +#define _MMCAMCORDER_RETRIAL_COUNT 15 +#define _MMCAMCORDER_FRAME_WAIT_TIME 200000 /* us */ +#define _MMCAMCORDER_FRAME_PASS_MIN_FPS 30 +#define _MMCAMCORDER_MIN_TIME_TO_PASS_FRAME 30000000 /* ns */ +#define _MMCAMCORDER_VIDEO_MINIMUM_SPACE (_MMCAMCORDER_MINIMUM_SPACE << 1) /* byte */ +#define OFFSET_COMPOSITION_MATRIX 40L +#define MAX_ERROR_MESSAGE_LEN 128 /*--------------------------------------------------------------------------------------- | LOCAL FUNCTION PROTOTYPES: | @@ -49,7 +46,7 @@ /* STATIC INTERNAL FUNCTION */ static gboolean __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sample, gpointer u_data); static GstPadProbeReturn __mmcamcorder_audio_dataprobe_check(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); -static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); +static GstPadProbeReturn __mmcamcorder_video_dataprobe_encoded(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); static GstPadProbeReturn __mmcamcorder_audioque_dataprobe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); static GstPadProbeReturn __mmcamcorder_video_dataprobe_audio_disable(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); static GstPadProbeReturn __mmcamcorder_audio_dataprobe_audio_mute(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); @@ -62,71 +59,126 @@ static gboolean __mmcamcorder_add_metadata_mp4(MMHandleType handle); /*--------------------------------------------------------------------------------------- | GLOBAL FUNCTION DEFINITIONS: | ---------------------------------------------------------------------------------------*/ -static gboolean __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sample, gpointer u_data) +gboolean _mmcamcorder_video_push_buffer(void *handle, GstBuffer *buffer) { - mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data); + mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle); _MMCamcorderSubContext *sc = NULL; + _MMCamcorderImageInfo *info_image = NULL; + _MMCamcorderVideoInfo *info_video = NULL; + _MMCamcorderGstElement *element = NULL; + GstClockTime diff = 0; /* nsec */ + + mmf_return_val_if_fail(hcamcorder, FALSE); + mmf_return_val_if_fail(MMF_CAMCORDER_SUBCONTEXT(hcamcorder), FALSE); - GstBuffer *buffer = gst_sample_get_buffer(sample); mmf_return_val_if_fail(buffer, FALSE); mmf_return_val_if_fail(gst_buffer_n_memory(buffer), FALSE); - mmf_return_val_if_fail(hcamcorder, FALSE); sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder); - mmf_return_val_if_fail(sc, FALSE); - /* - _mmcam_dbg_log("ENTER - push_encoding_buffer %d, buffer %p, MALLOCDATA %p, size %d", - sc->info_video->push_encoding_buffer, buffer, GST_BUFFER_MALLOCDATA(buffer), GST_BUFFER_SIZE(buffer)); - */ + mmf_return_val_if_fail(sc->info_image, FALSE); + mmf_return_val_if_fail(sc->info_video, FALSE); + mmf_return_val_if_fail(sc->encode_element, FALSE); + + info_image = sc->info_image; + info_video = sc->info_video; + element = sc->encode_element; + + if (info_video->push_encoding_buffer == PUSH_ENCODING_BUFFER_RUN && + element[_MMCAMCORDER_ENCSINK_SRC].gst) { + int ret = 0; + GstClock *clock = NULL; + + /* + _mmcam_dbg_log("GST_BUFFER_FLAG_DELTA_UNIT is set : %d", + GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)); + */ - /* push buffer in appsrc to encode */ - if (sc->info_video->push_encoding_buffer == PUSH_ENCODING_BUFFER_RUN && - sc->info_video->record_dual_stream && - sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst) { - GstFlowReturn ret = 0; - GstClock *pipe_clock = NULL; - - if (sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst) { - if (sc->info_video->is_firstframe) { - sc->info_video->is_firstframe = FALSE; - pipe_clock = GST_ELEMENT_CLOCK(sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst); - if (pipe_clock) { - gst_object_ref(pipe_clock); - sc->info_video->base_video_ts = GST_BUFFER_PTS(buffer) - (gst_clock_get_time(pipe_clock) - GST_ELEMENT(sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst)->base_time); - gst_object_unref(pipe_clock); + if (info_video->is_first_frame) { + /* check first I frame for H.264 stream */ + if (info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264) { + if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) { + _mmcam_dbg_warn("NOT I frame.. skip this buffer"); + return TRUE; + } else { + _mmcam_dbg_warn("[H.264] first I frame"); } } - } else { - if (sc->info_video->is_firstframe) { - sc->info_video->is_firstframe = FALSE; - sc->info_video->base_video_ts = GST_BUFFER_PTS(buffer); + + /* set base timestamp */ + if (element[_MMCAMCORDER_AUDIOSRC_SRC].gst) { + clock = GST_ELEMENT_CLOCK(element[_MMCAMCORDER_AUDIOSRC_SRC].gst); + if (clock) { + gst_object_ref(clock); + info_video->base_video_ts = GST_BUFFER_PTS(buffer) - (gst_clock_get_time(clock) - \ + GST_ELEMENT(element[_MMCAMCORDER_ENCSINK_SRC].gst)->base_time); + gst_object_unref(clock); + } + } else { + /* for image capture with encodebin and v4l2src */ + if (sc->bencbin_capture && info_image->capturing) { + g_mutex_lock(&hcamcorder->task_thread_lock); + _mmcam_dbg_log("send signal for sound play"); + hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_SOUND_SOLO_PLAY_START; + g_cond_signal(&hcamcorder->task_thread_cond); + g_mutex_unlock(&hcamcorder->task_thread_lock); + } + info_video->base_video_ts = GST_BUFFER_PTS(buffer); } } - GST_BUFFER_PTS(buffer) = GST_BUFFER_PTS(buffer) - sc->info_video->base_video_ts; + GST_BUFFER_PTS(buffer) = GST_BUFFER_PTS(buffer) - info_video->base_video_ts; GST_BUFFER_DTS(buffer) = GST_BUFFER_PTS(buffer); - ret = gst_app_src_push_buffer((GstAppSrc *)sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst, buffer); - if (ret != GST_FLOW_OK && ret != GST_FLOW_FLUSHING) { - _mmcam_dbg_err("gst_app_src_push_buffer failed [0x%x]", ret); - gst_buffer_unref(buffer); - buffer = NULL; + /*_mmcam_dbg_log("buffer %p, timestamp %"GST_TIME_FORMAT, buffer, GST_TIME_ARGS(GST_BUFFER_PTS(buffer)));*/ + + if (info_video->record_dual_stream) { + /* It will NOT INCREASE reference count of buffer */ + ret = gst_app_src_push_buffer((GstAppSrc *)element[_MMCAMCORDER_ENCSINK_SRC].gst, buffer); + } else { + /* It will INCREASE reference count of buffer */ + g_signal_emit_by_name(element[_MMCAMCORDER_ENCSINK_SRC].gst, "push-buffer", buffer, &ret); } /*_mmcam_dbg_log("push buffer result : 0x%x", ret);*/ - } else { - _mmcam_dbg_warn("unref video buffer immediately - push encoding buffer %d", - sc->info_video->push_encoding_buffer); - gst_buffer_unref(buffer); - buffer = NULL; + if (info_video->is_first_frame) { + info_video->is_first_frame = FALSE; + + /* drop buffer if it's from tizen allocator */ + if (gst_is_tizen_memory(gst_buffer_peek_memory(buffer, 0))) { + _mmcam_dbg_warn("drop first buffer from tizen allocator to avoid copy in basesrc"); + return FALSE; + } + } + } + + /* skip display if too fast FPS */ + if (info_video->record_dual_stream == FALSE && + info_video->fps > _MMCAMCORDER_FRAME_PASS_MIN_FPS) { + if (info_video->prev_preview_ts != 0) { + diff = GST_BUFFER_PTS(buffer) - info_video->prev_preview_ts; + if (diff < _MMCAMCORDER_MIN_TIME_TO_PASS_FRAME) { + _mmcam_dbg_log("it's too fast. drop frame..."); + return FALSE; + } + } + + /*_mmcam_dbg_log("diff %llu", diff);*/ + + info_video->prev_preview_ts = GST_BUFFER_PTS(buffer); } return TRUE; } +static gboolean __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sample, gpointer u_data) +{ + return _mmcamcorder_video_push_buffer(u_data, gst_sample_get_buffer(sample)); +} + + int _mmcamcorder_create_recorder_pipeline(MMHandleType handle) { int i = 0; @@ -270,7 +322,7 @@ int _mmcamcorder_create_recorder_pipeline(MMHandleType handle) if (!strcmp(gst_element_rsink_name, "filesink")) { srcpad = gst_element_get_static_pad(sc->encode_element[_MMCAMCORDER_ENCSINK_VENC].gst, "src"); MMCAMCORDER_ADD_BUFFER_PROBE(srcpad, _MMCAMCORDER_HANDLER_VIDEOREC, - __mmcamcorder_video_dataprobe_record, hcamcorder); + __mmcamcorder_video_dataprobe_encoded, hcamcorder); gst_object_unref(srcpad); srcpad = NULL; @@ -735,8 +787,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command) info->push_encoding_buffer = PUSH_ENCODING_BUFFER_INIT; info->base_video_ts = 0; - /* connect video stream cb signal */ - /*130826 Connect video stream cb for handling fast record frame cb*/ + /* connect video stream cb signal if it supports dual stream. */ if (info->record_dual_stream) { if (_mmcamcorder_connect_video_stream_cb_signal((MMHandleType)hcamcorder) != MM_ERROR_NONE) goto _ERR_CAMCORDER_VIDEO_COMMAND; @@ -785,7 +836,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command) */ info->video_frame_count = 0; - info->is_firstframe = TRUE; + info->is_first_frame = TRUE; info->audio_frame_count = 0; info->filesize = 0; sc->ferror_send = FALSE; @@ -1364,7 +1415,7 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_check(GstPad *pad, GstPad } -static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data) +static GstPadProbeReturn __mmcamcorder_video_dataprobe_encoded(GstPad *pad, GstPadProbeInfo *info, gpointer u_data) { gint ret = 0; guint vq_size = 0; @@ -1954,7 +2005,7 @@ static gboolean __mmcamcorder_add_metadata_mp4(MMHandleType handle) _mmcam_dbg_log("found [tkhd] tag"); /* seek to start position of composition matrix */ - if (fseek(f, _OFFSET_COMPOSITION_MATRIX, SEEK_CUR) == 0) { + if (fseek(f, OFFSET_COMPOSITION_MATRIX, SEEK_CUR) == 0) { /* update composition matrix for orientation */ _mmcamcorder_update_composition_matrix(f, orientation); } else { -- 2.34.1