Bug fix - fast/slow motion recording failure
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_videorec.c
index 136aa45..83f85da 100644 (file)
@@ -105,6 +105,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) {
@@ -554,7 +555,15 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
 
                        dir_name = g_path_get_dirname(temp_filename);
                        if (dir_name) {
-                               ret_free_space = _mmcamcorder_get_freespace(dir_name, hcamcorder->root_directory, &free_space);
+                               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;
+                               }
+
+                               ret_free_space = _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
 
                                _mmcam_dbg_warn("current space - %s [%" G_GUINT64_FORMAT "]", dir_name, free_space);
 
@@ -634,6 +643,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);
 
@@ -646,6 +656,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;
@@ -922,6 +933,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);
 
@@ -933,6 +945,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;
@@ -1190,6 +1203,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);
@@ -1203,6 +1217,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;
@@ -1405,9 +1421,9 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
        guint64 trailer_size = 0;
        guint64 queued_buffer = 0;
        guint64 max_size = 0;
-       char *dir_name = NULL;
        GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
        GstMapInfo mapinfo;
+       storage_state_e storage_state = STORAGE_STATE_UNMOUNTABLE;
 
        mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
        _MMCamcorderMsgItem msg;
@@ -1448,29 +1464,15 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
                trailer_size = 0;
        }
 
-       dir_name = g_path_get_dirname(videoinfo->filename);
-       if (dir_name) {
-               ret = _mmcamcorder_get_freespace(dir_name, hcamcorder->root_directory, &free_space);
-               g_free(dir_name);
-               dir_name = NULL;
-       } else {
-               _mmcam_dbg_err("failed to get dir name from [%s]", videoinfo->filename);
-               ret = -1;
-       }
-
-       /*_mmcam_dbg_log("check free space for recording");*/
-
-       switch (ret) {
-       case -2: /* file not exist */
-       case -1: /* failed to get free space */
+       /* check free space */
+       ret = _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
+       if (ret != 0) {
                _mmcam_dbg_err("Error occured. [%d]", ret);
                if (sc->ferror_count == 2 && sc->ferror_send == FALSE) {
                        sc->ferror_send = TRUE;
+
                        msg.id = MM_MESSAGE_CAMCORDER_ERROR;
-                       if (ret == -2)
-                               msg.param.code = MM_ERROR_FILE_NOT_FOUND;
-                       else
-                               msg.param.code = MM_ERROR_FILE_READ;
+                       msg.param.code = MM_ERROR_FILE_READ;
 
                        _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
                } else {
@@ -1478,38 +1480,66 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
                }
 
                return GST_PAD_PROBE_DROP; /* skip this buffer */
-               break;
-       default: /* succeeded to get free space */
-               /* check free space for recording */
-               /* get queued buffer size */
-               if (sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst) {
-                       MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst, "current-level-bytes", &aq_size);
-               }
+       }
 
-               if (sc->encode_element[_MMCAMCORDER_ENCSINK_VENC_QUE].gst) {
-                       MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_VENC_QUE].gst, "current-level-bytes", &vq_size);
-               }
+       if (free_space == 0) {
+               /* check storage state */
+               storage_get_state(hcamcorder->storage_info.id, &storage_state);
 
-               queued_buffer = aq_size + vq_size;
+               _mmcam_dbg_warn("storage state %d", storage_state);
 
-               /* check free space */
-               if (free_space < (_MMCAMCORDER_MINIMUM_SPACE + buffer_size + trailer_size + queued_buffer)) {
-                       _mmcam_dbg_warn("No more space for recording!!! Recording is paused.");
-                       _mmcam_dbg_warn("Free Space : [%" G_GUINT64_FORMAT "], trailer size : [%" G_GUINT64_FORMAT "]," \
-                               " buffer size : [%" G_GUINT64_FORMAT "], queued buffer size : [%" G_GUINT64_FORMAT "]", \
-                               free_space, trailer_size, buffer_size, queued_buffer);
+               if (storage_state == STORAGE_STATE_REMOVED ||
+                       storage_state == STORAGE_STATE_UNMOUNTABLE) {
+                       _mmcam_dbg_err("storage was removed!");
 
-                       if (!sc->isMaxsizePausing) {
-                               MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
-                               sc->isMaxsizePausing = TRUE;
+                       _MMCAMCORDER_LOCK(hcamcorder);
+
+                       if (sc->ferror_send == FALSE) {
+                               _mmcam_dbg_err("OUT_OF_STORAGE error");
+
+                               sc->ferror_send = TRUE;
+
+                               _MMCAMCORDER_UNLOCK(hcamcorder);
+
+                               msg.id = MM_MESSAGE_CAMCORDER_ERROR;
+                               msg.param.code = MM_ERROR_OUT_OF_STORAGE;
 
-                               msg.id = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE;
                                _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
+                       } else {
+                               _MMCAMCORDER_UNLOCK(hcamcorder);
+                               _mmcam_dbg_warn("error was already sent");
                        }
 
                        return GST_PAD_PROBE_DROP;
                }
-               break;
+       }
+
+       /* get queued buffer size */
+       if (sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst) {
+               MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst, "current-level-bytes", &aq_size);
+       }
+
+       if (sc->encode_element[_MMCAMCORDER_ENCSINK_VENC_QUE].gst) {
+               MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_VENC_QUE].gst, "current-level-bytes", &vq_size);
+       }
+
+       queued_buffer = aq_size + vq_size;
+
+       if (free_space < (_MMCAMCORDER_MINIMUM_SPACE + buffer_size + trailer_size + queued_buffer)) {
+               _mmcam_dbg_warn("No more space for recording!!! Recording is paused.");
+               _mmcam_dbg_warn("Free Space : [%" G_GUINT64_FORMAT "], trailer size : [%" G_GUINT64_FORMAT "]," \
+                       " buffer size : [%" G_GUINT64_FORMAT "], queued buffer size : [%" G_GUINT64_FORMAT "]", \
+                       free_space, trailer_size, buffer_size, queued_buffer);
+
+               if (!sc->isMaxsizePausing) {
+                       MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
+                       sc->isMaxsizePausing = TRUE;
+
+                       msg.id = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE;
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
+               }
+
+               return GST_PAD_PROBE_DROP;
        }
 
        g_mutex_lock(&videoinfo->size_check_lock);
@@ -1653,6 +1683,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;