Add new callback for muxed stream
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_videorec.c
index 04c2a21..644a610 100644 (file)
@@ -54,7 +54,6 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_audio_disable(GstPad *pad
 static GstPadProbeReturn __mmcamcorder_audio_dataprobe_audio_mute(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
 static gboolean __mmcamcorder_add_metadata(MMHandleType handle, int fileformat);
 static gboolean __mmcamcorder_add_metadata_mp4(MMHandleType handle);
-static GstPadProbeReturn __mmcamcorder_eventprobe_monitor(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
 
 /*=======================================================================================
 |  FUNCTION DEFINITIONS                                                                        |
@@ -105,6 +104,7 @@ static gboolean __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sa
                }
 
                GST_BUFFER_PTS(buffer) = GST_BUFFER_PTS(buffer) - sc->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) {
@@ -224,8 +224,7 @@ int _mmcamcorder_create_recorder_pipeline(MMHandleType handle)
 
        /* register message cb */
 
-       /* set data probe function for audio */
-
+       /* set data probe functions */
        if (sc->audio_disable == FALSE) {
                sinkpad = gst_element_get_static_pad(sc->encode_element[_MMCAMCORDER_ENCSINK_AENC].gst, "sink");
                MMCAMCORDER_ADD_BUFFER_PROBE(sinkpad, _MMCAMCORDER_HANDLER_VIDEOREC,
@@ -279,6 +278,14 @@ int _mmcamcorder_create_recorder_pipeline(MMHandleType handle)
                srcpad = NULL;
        }
 
+       sinkpad = gst_element_get_static_pad(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, "sink");
+       MMCAMCORDER_ADD_BUFFER_PROBE(sinkpad, _MMCAMCORDER_HANDLER_VIDEOREC,
+               __mmcamcorder_muxed_dataprobe, hcamcorder);
+       MMCAMCORDER_ADD_EVENT_PROBE(sinkpad, _MMCAMCORDER_HANDLER_VIDEOREC,
+               __mmcamcorder_eventprobe_monitor, hcamcorder);
+       gst_object_unref(sinkpad);
+       sinkpad = NULL;
+
        bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst));
 
        /* register pipeline message callback */
@@ -557,6 +564,8 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                ret = _mmcamcorder_get_storage_info(dir_name, hcamcorder->root_directory, &hcamcorder->storage_info);
                                if (ret != 0) {
                                        _mmcam_dbg_err("get storage info failed");
+                                       g_free(dir_name);
+                                       dir_name = NULL;
                                        return MM_ERROR_OUT_OF_STORAGE;
                                }
 
@@ -640,6 +649,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
 
                                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", TRUE);
                                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
+                               MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "keep-camera-preview", TRUE);
 
                                ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
 
@@ -652,6 +662,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
 
                                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", FALSE);
                                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
+                               MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "keep-camera-preview", FALSE);
 
                                if (ret != MM_ERROR_NONE)
                                        goto _ERR_CAMCORDER_VIDEO_COMMAND;
@@ -758,6 +769,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                        sc->ferror_count = 0;
                        hcamcorder->error_occurs = FALSE;
                        sc->bget_eos = FALSE;
+                       sc->muxed_stream_offset = 0;
 
                        ret = _mmcamcorder_gst_set_state(handle, sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_PLAYING);
                        if (ret != MM_ERROR_NONE) {
@@ -928,6 +940,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                        /* restart preview */
                        MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", TRUE);
                        MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
+                       MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "keep-camera-preview", TRUE);
 
                        ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
 
@@ -939,6 +952,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
 
                        MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
                        MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", FALSE);
+                       MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "keep-camera-preview", FALSE);
 
                        if (ret != MM_ERROR_NONE)
                                goto _ERR_CAMCORDER_VIDEO_COMMAND;
@@ -1196,6 +1210,7 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
                /* block queue */
                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", TRUE);
+               MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "keep-camera-preview", TRUE);
 
                _mmcam_dbg_log("Set state of pipeline as READY");
                ret = _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_MAIN_PIPE].gst, GST_STATE_READY);
@@ -1209,6 +1224,8 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
                /* unblock queue */
                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", FALSE);
+               MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "keep-camera-preview", FALSE);
+
                if (ret != MM_ERROR_NONE) {
                        msg.id = MM_MESSAGE_CAMCORDER_ERROR;
                        msg.param.code = ret;
@@ -1270,51 +1287,6 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
 }
 
 
-/**
- * This function is record 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.
- *
- * @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
- * @remarks
- * @see
- */
-static GstPadProbeReturn __mmcamcorder_eventprobe_monitor(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
-{
-       GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info);
-       switch (GST_EVENT_TYPE(event)) {
-       case GST_EVENT_UNKNOWN:
-       /* upstream events */
-       case GST_EVENT_QOS:
-       case GST_EVENT_SEEK:
-       case GST_EVENT_NAVIGATION:
-       case GST_EVENT_LATENCY:
-       /* downstream serialized events */
-       case GST_EVENT_SEGMENT:
-       case GST_EVENT_TAG:
-       case GST_EVENT_BUFFERSIZE:
-               _mmcam_dbg_log("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
-               break;
-       case GST_EVENT_EOS:
-               _mmcam_dbg_warn("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
-               break;
-       /* bidirectional events */
-       case GST_EVENT_FLUSH_START:
-       case GST_EVENT_FLUSH_STOP:
-               _mmcam_dbg_err("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
-               break;
-       default:
-               _mmcam_dbg_log("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
-               break;
-       }
-
-       return GST_PAD_PROBE_OK;
-}
-
-
 static GstPadProbeReturn __mmcamcorder_audio_dataprobe_check(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
 {
        mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
@@ -1673,6 +1645,7 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_audio_disable(GstPad *pad
                }
 
                GST_BUFFER_PTS(buffer) = b_time * (videoinfo->record_timestamp_ratio);
+               GST_BUFFER_DTS(buffer) = GST_BUFFER_PTS(buffer);
        }
 
        return GST_PAD_PROBE_OK;