Add sub function to remove duplicated code 85/239485/2
authorJeongmo Yang <jm80.yang@samsung.com>
Mon, 27 Jul 2020 05:39:24 +0000 (14:39 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Mon, 27 Jul 2020 09:41:33 +0000 (18:41 +0900)
[Version] 0.10.207
[Profile] Common
[Issue Type] Optimization

Change-Id: I91b4bf5b7d53157b3826f3211ae6dbf2775d0a88
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
packaging/libmm-camcorder.spec
src/include/mm_camcorder_videorec.h
src/mm_camcorder_gstcommon.c
src/mm_camcorder_stillshot.c
src/mm_camcorder_videorec.c

index 3fd96f7..7219da9 100644 (file)
@@ -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
index f592e93..630fa16 100644 (file)
@@ -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
 }
index 19dbcc8..f324b2b 100644 (file)
@@ -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;
 }
 
 
index 554273d..723cf73 100644 (file)
@@ -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;
index 1413b08..8ea4758 100644 (file)
 /*=======================================================================================
 |  INCLUDE FILES                                                                                                                                               |
 =======================================================================================*/
+#include <gst/allocators/gsttizenmemory.h>
 #include <gst/video/cameracontrol.h>
 #include <gst/app/gstappsrc.h>
 #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 {