[Release 0.10.61] TSAM-6195 : Fix crash when stop camera
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_videorec.c
index df85937..47fcb39 100644 (file)
@@ -46,7 +46,7 @@
 |    LOCAL FUNCTION PROTOTYPES:                                                                |
 ---------------------------------------------------------------------------------------*/
 /* STATIC INTERNAL FUNCTION */
-static void __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sample, gpointer u_data);
+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_audioque_dataprobe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
@@ -62,18 +62,18 @@ static GstPadProbeReturn __mmcamcorder_eventprobe_monitor(GstPad *pad, GstPadPro
 /*---------------------------------------------------------------------------------------
 |    GLOBAL FUNCTION DEFINITIONS:                                                      |
 ---------------------------------------------------------------------------------------*/
-static void __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sample, gpointer u_data)
+static gboolean __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sample, gpointer u_data)
 {
        mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
        _MMCamcorderSubContext *sc = NULL;
 
        GstBuffer *buffer = gst_sample_get_buffer(sample);
-       mmf_return_if_fail(buffer);
-       mmf_return_if_fail(gst_buffer_n_memory(buffer));
-       mmf_return_if_fail(hcamcorder);
+       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_if_fail(sc);
+       mmf_return_val_if_fail(sc, FALSE);
 
        /*
        _mmcam_dbg_log("ENTER - push_encoding_buffer %d, buffer %p, MALLOCDATA %p, size %d",
@@ -123,7 +123,7 @@ static void __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sample
                buffer = NULL;
        }
 
-       return;
+       return TRUE;
 }
 
 
@@ -288,6 +288,9 @@ int _mmcamcorder_create_recorder_pipeline(MMHandleType handle)
        /* register pipeline message callback */
        hcamcorder->encode_pipeline_cb_event_id = gst_bus_add_watch(bus, (GstBusFunc)_mmcamcorder_pipeline_cb_message, hcamcorder);
 
+       /* set sync handler */
+       gst_bus_set_sync_handler(bus, _mmcamcorder_encode_pipeline_bus_sync_callback, (gpointer)hcamcorder, NULL);
+
        gst_object_unref(bus);
        bus = NULL;
 
@@ -639,6 +642,13 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
 
                                ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
 
+                               /* check decoder recreation */
+                               if (!_mmcamcorder_recreate_decoder_for_encoded_preview(handle)) {
+                                       _mmcam_dbg_err("_mmcamcorder_recreate_decoder_for_encoded_preview failed");
+                                       ret = MM_ERROR_CAMCORDER_INTERNAL;
+                                       goto _ERR_CAMCORDER_VIDEO_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);
 
@@ -927,8 +937,15 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
 
                        ret =_mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
 
+                       /* check decoder recreation */
+                       if (!_mmcamcorder_recreate_decoder_for_encoded_preview(handle)) {
+                               _mmcam_dbg_err("_mmcamcorder_recreate_decoder_for_encoded_preview failed");
+                               ret = MM_ERROR_CAMCORDER_INTERNAL;
+                       }
+
                        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);
+
                        if (ret != MM_ERROR_NONE) {
                                goto _ERR_CAMCORDER_VIDEO_COMMAND;
                        }
@@ -1019,7 +1036,16 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                }
                        }
 
-                       usleep(_MMCAMCORDER_FRAME_WAIT_TIME);
+                       if (hcamcorder->capture_in_recording) {
+                               gint64 end_time = g_get_monotonic_time() + (200 * G_TIME_SPAN_MILLISECOND);
+                               if (_MMCAMCORDER_CMD_WAIT_UNTIL(handle, end_time)) {
+                                       _mmcam_dbg_warn("signal received");
+                               } else {
+                                       _mmcam_dbg_warn("timeout");
+                               }
+                       } else {
+                               usleep(_MMCAMCORDER_FRAME_WAIT_TIME);
+                       }
                }
 
                /* block push buffer */
@@ -1184,6 +1210,12 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
                _mmcam_dbg_log("Set state of pipeline as READY");
                ret = _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_MAIN_PIPE].gst, GST_STATE_READY);
 
+               /* check decoder recreation */
+               if (!_mmcamcorder_recreate_decoder_for_encoded_preview(handle)) {
+                       _mmcam_dbg_err("_mmcamcorder_recreate_decoder_for_encoded_preview failed");
+                       ret = MM_ERROR_CAMCORDER_INTERNAL;
+               }
+
                /* 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);