Fix invalid format usage - Phase#2
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_videorec.c
index 04c2a21..1acd72f 100644 (file)
@@ -41,6 +41,7 @@
 #define _MMCAMCORDER_FRAME_WAIT_TIME   200000  /* ms */
 #define _OFFSET_COMPOSITION_MATRIX             40L
 #define _GOP_GEN_INTERVAL                              1000000000      /*nano seconds*/
+#define _MMCAMCORDER_VIDEO_MINIMUM_SPACE       (_MMCAMCORDER_MINIMUM_SPACE << 1)      /* byte */
 
 /*---------------------------------------------------------------------------------------
 |    LOCAL FUNCTION PROTOTYPES:                                                                                                                        |
@@ -54,7 +55,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 +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) {
@@ -130,7 +131,6 @@ int _mmcamcorder_create_recorder_pipeline(MMHandleType handle)
 {
        int i = 0;
        int err = MM_ERROR_NONE;
-       int audio_disable = FALSE;
        const char* gst_element_rsink_name = NULL;
 
        GstBus *bus = NULL;
@@ -165,16 +165,13 @@ int _mmcamcorder_create_recorder_pipeline(MMHandleType handle)
 
        /* get audio disable */
        mm_camcorder_get_attributes(handle, NULL,
-               MMCAM_AUDIO_DISABLE, &audio_disable,
+               MMCAM_AUDIO_DISABLE, &sc->audio_disable,
                NULL);
 
-       if (sc->is_modified_rate || audio_disable)
-               sc->audio_disable = TRUE;
-       else
-               sc->audio_disable = FALSE;
+       _mmcam_dbg_log("MMCAM_AUDIO_DISABLE %d, is_modified_rate %d",
+               sc->audio_disable, sc->is_modified_rate);
 
-       _mmcam_dbg_log("AUDIO DISABLE : %d (is_modified_rate %d, audio_disable %d)",
-               sc->audio_disable, sc->is_modified_rate, audio_disable);
+       sc->audio_disable |= sc->is_modified_rate;
 
        if (sc->audio_disable == FALSE) {
                /* create audiosrc bin */
@@ -220,12 +217,17 @@ int _mmcamcorder_create_recorder_pipeline(MMHandleType handle)
                &RecordsinkElement);
        _mmcamcorder_conf_get_value_element_name(RecordsinkElement, &gst_element_rsink_name);
 
+       if (!gst_element_rsink_name) {
+               _mmcam_dbg_err("failed to get recordsink name");
+               err = MM_ERROR_CAMCORDER_INTERNAL;
+               goto pipeline_creation_error;
+       }
+
        /* set data probe function */
 
        /* 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 +281,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 */
@@ -347,6 +357,9 @@ int _mmcamcorder_remove_encode_pipeline(MMHandleType handle)
        GstPad *reqpad = NULL;
        mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
        _MMCamcorderSubContext *sc = NULL;
+#ifdef _MMCAMCORDER_MM_RM_SUPPORT
+       int ret = MM_ERROR_NONE;
+#endif /* _MMCAMCORDER_MM_RM_SUPPORT */
 
        mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
 
@@ -386,7 +399,31 @@ int _mmcamcorder_remove_encode_pipeline(MMHandleType handle)
                /* _mmcamcorder_remove_element_handle(handle, (void *)sc->encode_element,
                        _MMCAMCORDER_ENCODE_MAIN_PIPE, _MMCAMCORDER_ENCSINK_SINK); */
 
-               _mmcam_dbg_log("Encoder pipeline removed");
+               _mmcam_dbg_warn("Encoder pipeline removed");
+
+#ifdef _MMCAMCORDER_MM_RM_SUPPORT
+               _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
+
+               _mmcam_dbg_warn("lock resource - cb calling %d", hcamcorder->is_release_cb_calling);
+
+               if (hcamcorder->is_release_cb_calling == FALSE) {
+                       /* release resource */
+                       ret = mm_resource_manager_mark_for_release(hcamcorder->resource_manager,
+                                       hcamcorder->video_encoder_resource);
+                       if (ret == MM_RESOURCE_MANAGER_ERROR_NONE)
+                               hcamcorder->video_encoder_resource = NULL;
+
+                       _mmcam_dbg_warn("mark resource for release 0x%x", ret);
+
+                       ret = mm_resource_manager_commit(hcamcorder->resource_manager);
+
+                       _mmcam_dbg_warn("commit resource release 0x%x", ret);
+               }
+
+               _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+
+               _mmcam_dbg_warn("unlock resource");
+#endif /* _MMCAMCORDER_MM_RM_SUPPORT */
        }
 
        return MM_ERROR_NONE;
@@ -511,6 +548,37 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                        /* Recording */
                        _mmcam_dbg_log("Record Start - dual stream %d", info->support_dual_stream);
 
+#ifdef _MMCAMCORDER_MM_RM_SUPPORT
+                       _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
+
+                       /* prepare resource manager for H/W encoder */
+                       if (hcamcorder->video_encoder_resource == NULL) {
+                               ret = mm_resource_manager_mark_for_acquire(hcamcorder->resource_manager,
+                                               MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER,
+                                               MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
+                                               &hcamcorder->video_encoder_resource);
+                               if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+                                       _mmcam_dbg_err("could not prepare for encoder resource");
+                                       ret = MM_ERROR_RESOURCE_INTERNAL;
+                                       _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+                                       goto _ERR_CAMCORDER_VIDEO_COMMAND;
+                               }
+                       } else {
+                               _mmcam_dbg_log("encoder already acquired");
+                       }
+
+                       /* acquire resources */
+                       ret = mm_resource_manager_commit(hcamcorder->resource_manager);
+                       if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+                               _mmcam_dbg_err("could not acquire resources");
+                               ret = MM_ERROR_RESOURCE_INTERNAL;
+                               _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+                               goto _ERR_CAMCORDER_VIDEO_COMMAND;
+                       }
+
+                       _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+#endif /* _MMCAMCORDER_MM_RM_SUPPORT */
+
                        /* init record_dual_stream */
                        info->record_dual_stream = FALSE;
 
@@ -534,8 +602,8 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                goto _ERR_CAMCORDER_VIDEO_COMMAND;
                        }
 
-                       if (temp_filename == NULL) {
-                               _mmcam_dbg_err("filename is not set");
+                       if (!temp_filename && !hcamcorder->mstream_cb) {
+                               _mmcam_dbg_err("filename is not set and muxed stream cb is NULL");
                                ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
                                goto _ERR_CAMCORDER_VIDEO_COMMAND;
                        }
@@ -550,13 +618,15 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                        if (imax_time <= 0)
                                info->max_time = 0; /* do not check */
                        else
-                               info->max_time = ((guint64)imax_time) * 1000; /* to millisecond */
+                               info->max_time = (guint64)((double)imax_time * (double)1000 * motion_rate); /* to millisecond */
 
                        dir_name = g_path_get_dirname(temp_filename);
                        if (dir_name) {
                                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;
                                }
 
@@ -568,7 +638,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                        /* MSDOS_SUPER_MAGIC : 0x4d44 */
                                        if (file_system_type == MSDOS_SUPER_MAGIC &&
                                            (info->max_size == 0 || info->max_size > FAT32_FILE_SYSTEM_MAX_SIZE)) {
-                                               _mmcam_dbg_warn("FAT32 and too large max[%"G_GUINT64_FORMAT"], set max as %"G_GUINT64_FORMAT,
+                                               _mmcam_dbg_warn("FAT32 and too large max[%"G_GUINT64_FORMAT"], set max as %lu",
                                                        info->max_size, FAT32_FILE_SYSTEM_MAX_SIZE);
                                                info->max_size = FAT32_FILE_SYSTEM_MAX_SIZE;
                                        } else {
@@ -586,9 +656,10 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                ret_free_space = -1;
                        }
 
-                       if ((ret_free_space == -1) || free_space <= (_MMCAMCORDER_MINIMUM_SPACE<<1)) {
+                       if (temp_filename &&
+                               (ret_free_space == -1 || free_space <= _MMCAMCORDER_VIDEO_MINIMUM_SPACE)) {
                                _mmcam_dbg_err("OUT of STORAGE [ret_free_space:%d or free space [%" G_GUINT64_FORMAT "] is smaller than [%d]",
-                                       ret_free_space, free_space, (_MMCAMCORDER_MINIMUM_SPACE<<1));
+                                       ret_free_space, free_space, _MMCAMCORDER_VIDEO_MINIMUM_SPACE);
                                return MM_ERROR_OUT_OF_STORAGE;
                        }
 
@@ -640,6 +711,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 +724,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 +831,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) {
@@ -849,10 +923,10 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                if (info->video_frame_count >= _MMCAMCORDER_MINIMUM_FRAME) {
                                        break;
                                } else if (count == _MMCAMCORDER_RETRIAL_COUNT) {
-                                       _mmcam_dbg_err("Pause fail, frame count %llu", info->video_frame_count);
+                                       _mmcam_dbg_err("Pause fail, frame count %"G_GUINT64_FORMAT, info->video_frame_count);
                                        return MM_ERROR_CAMCORDER_INVALID_CONDITION;
                                } else {
-                                       _mmcam_dbg_warn("Waiting for enough video frame, retrial[%d], frame %llu", count, info->video_frame_count);
+                                       _mmcam_dbg_warn("Waiting for enough video frame, retrial[%d], frame %"G_GUINT64_FORMAT, count, info->video_frame_count);
                                }
 
                                usleep(_MMCAMCORDER_FRAME_WAIT_TIME);
@@ -861,11 +935,11 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                if (info->video_frame_count >= _MMCAMCORDER_MINIMUM_FRAME && info->audio_frame_count) {
                                        break;
                                } else if (count == _MMCAMCORDER_RETRIAL_COUNT) {
-                                       _mmcam_dbg_err("Pause fail, frame count VIDEO[%llu], AUDIO [%llu]",
+                                       _mmcam_dbg_err("Pause fail, frame count VIDEO[%"G_GUINT64_FORMAT"], AUDIO [%"G_GUINT64_FORMAT"]",
                                                info->video_frame_count, info->audio_frame_count);
                                        return MM_ERROR_CAMCORDER_INVALID_CONDITION;
                                } else {
-                                       _mmcam_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%llu], AUDIO [%llu]",
+                                       _mmcam_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%"G_GUINT64_FORMAT"], AUDIO [%"G_GUINT64_FORMAT"]",
                                                count, info->video_frame_count, info->audio_frame_count);
                                }
 
@@ -928,6 +1002,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 +1014,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;
@@ -975,6 +1051,8 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
        }
        case _MMCamcorder_CMD_COMMIT:
        {
+               guint64 free_space;
+
                if (info->b_commiting) {
                        _mmcam_dbg_err("now on commiting previous file!!(command : %d)", command);
                        return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
@@ -991,7 +1069,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                    hcamcorder->capture_in_recording == FALSE) {
                                        break;
                                } else if (count == _MMCAMCORDER_RETRIAL_COUNT) {
-                                       _mmcam_dbg_err("Commit fail, frame count is %llu, capturing %d",
+                                       _mmcam_dbg_err("Commit fail, frame count is %"G_GUINT64_FORMAT", capturing %d",
                                                info->video_frame_count, hcamcorder->capture_in_recording);
 
                                        if (info->video_frame_count >= _MMCAMCORDER_MINIMUM_FRAME) {
@@ -1001,7 +1079,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                                return MM_ERROR_CAMCORDER_INVALID_CONDITION;
                                        }
                                } else {
-                                       _mmcam_dbg_warn("Waiting for enough video frame, retrial [%d], frame %llu, capturing %d",
+                                       _mmcam_dbg_warn("Waiting for enough video frame, retrial [%d], frame %"G_GUINT64_FORMAT", capturing %d",
                                                count, info->video_frame_count, hcamcorder->capture_in_recording);
                                }
                        } else {
@@ -1011,7 +1089,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                    hcamcorder->capture_in_recording == FALSE) {
                                        break;
                                } else if (count == _MMCAMCORDER_RETRIAL_COUNT) {
-                                       _mmcam_dbg_err("Commit fail, VIDEO[%llu], AUDIO [%llu], capturing %d",
+                                       _mmcam_dbg_err("Commit fail, VIDEO[%"G_GUINT64_FORMAT"], AUDIO [%"G_GUINT64_FORMAT"], capturing %d",
                                                info->video_frame_count, info->audio_frame_count, hcamcorder->capture_in_recording);
 
                                        if (info->video_frame_count >= _MMCAMCORDER_MINIMUM_FRAME && info->audio_frame_count) {
@@ -1023,18 +1101,15 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
 
                                        return MM_ERROR_CAMCORDER_INVALID_CONDITION;
                                } else {
-                                       _mmcam_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%llu], AUDIO [%llu], capturing %d",
+                                       _mmcam_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%"G_GUINT64_FORMAT"], AUDIO [%"G_GUINT64_FORMAT"], capturing %d",
                                                count, info->video_frame_count, info->audio_frame_count, hcamcorder->capture_in_recording);
                                }
                        }
 
                        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 {
+                               if (!_MMCAMCORDER_CMD_WAIT_UNTIL(handle, end_time))
                                        _mmcam_dbg_warn("timeout");
-                               }
                        } else {
                                usleep(_MMCAMCORDER_FRAME_WAIT_TIME);
                        }
@@ -1044,6 +1119,13 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                info->push_encoding_buffer = PUSH_ENCODING_BUFFER_STOP;
                _mmcam_dbg_log("block push buffer to appsrc");
 
+               _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
+               if (free_space < _MMCAMCORDER_MINIMUM_SPACE) {
+                       _mmcam_dbg_warn("_MMCamcorder_CMD_COMMIT out of storage [%" G_GUINT64_FORMAT "]", free_space);
+                       ret = MM_ERROR_OUT_OF_STORAGE;
+                       goto _ERR_CAMCORDER_VIDEO_COMMAND;
+               }
+
                if (sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst != NULL) {
                        if (gst_element_send_event(sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst, gst_event_new_eos())) {
                                _mmcam_dbg_warn("VIDEO: send eos to appsrc done");
@@ -1126,18 +1208,8 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
 
        _mmcam_dbg_err("");
 
-       if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_FOCUS) {
-               /* Play record stop sound */
-               _mmcamcorder_sound_solo_play(handle, _MMCAMCORDER_SAMPLE_SOUND_NAME_REC_STOP, FALSE);
-       } else {
-               _mmcam_dbg_warn("Play stop sound through pulseaudio");
-
-               _mmcamcorder_sound_init(handle);
-
-               _mmcamcorder_sound_play((MMHandleType)hcamcorder, _MMCAMCORDER_SAMPLE_SOUND_NAME_REC_STOP, TRUE);
-
-               _mmcamcorder_sound_finalize(handle);
-       }
+       /* Play record stop sound */
+       _mmcamcorder_sound_solo_play(handle, _MMCAMCORDER_SAMPLE_SOUND_NAME_REC_STOP, FALSE);
 
        /* remove blocking part */
        MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
@@ -1170,17 +1242,13 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
 
        if (enabletag && !(sc->ferror_send)) {
                ret = __mmcamcorder_add_metadata((MMHandleType)hcamcorder, info->fileformat);
-               if (ret) {
-                       _mmcam_dbg_log("Writing location information SUCCEEDED !!");
-               } else {
-                       _mmcam_dbg_err("Writing location information FAILED !!");
-               }
+               _mmcam_dbg_log("Writing location information [%s] !!", ret ? "SUCCEEDED" : "FAILED");
        }
 
        /* Check file size */
        if (info->max_size > 0) {
                _mmcamcorder_get_file_size(info->filename, &file_size);
-               _mmcam_dbg_log("MAX size %lld byte - created filesize %lld byte",
+               _mmcam_dbg_log("MAX size %"G_GUINT64_FORMAT" byte - created filesize %"G_GUINT64_FORMAT" byte",
                                           info->max_size, file_size);
 
                if (file_size > info->max_size) {
@@ -1196,6 +1264,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 +1278,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;
@@ -1220,7 +1291,13 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
                info->restart_preview = FALSE;
 
                /* recover preview size */
-               _mmcamcorder_set_camera_resolution(handle, info->preview_width, info->preview_height);
+               if (!_mmcamcorder_set_camera_resolution(handle, info->preview_width, info->preview_height)) {
+                       msg.id = MM_MESSAGE_CAMCORDER_ERROR;
+                       msg.param.code = MM_ERROR_CAMCORDER_INTERNAL;
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
+                       _mmcam_dbg_err("Failed to set camera resolution %dx%d",
+                               info->preview_width, info->preview_height);
+               }
 
                ret = _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_MAIN_PIPE].gst, GST_STATE_PLAYING);
                /* Do not return when error is occurred.
@@ -1259,10 +1336,8 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
        info->filesize = 0;
        info->b_commiting = FALSE;
 
-       if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_FOCUS) {
-               /* check recording stop sound */
-               _mmcamcorder_sound_solo_play_wait(handle);
-       }
+       /* check recording stop sound */
+       _mmcamcorder_sound_solo_play_wait(handle);
 
        _mmcam_dbg_err("_MMCamcorder_CMD_COMMIT : end");
 
@@ -1270,51 +1345,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);
@@ -1361,11 +1391,10 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_check(GstPad *pad, GstPad
        }
 
        /* get trailer size */
-       if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4) {
+       if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4)
                MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
-       } else {
+       else
                trailer_size = 0;
-       }
 
        /* check max size of recorded file */
        max_size = videoinfo->filesize + buffer_size + trailer_size + _MMCAMCORDER_MMS_MARGIN_SPACE;
@@ -1448,11 +1477,10 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
        }
 
        /* get trailer size */
-       if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4) {
+       if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4)
                MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
-       } else {
+       else
                trailer_size = 0;
-       }
 
        /* check free space */
        ret = _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
@@ -1505,13 +1533,11 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
        }
 
        /* get queued buffer size */
-       if (sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst) {
+       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) {
+       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;
 
@@ -1599,16 +1625,15 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_audio_disable(GstPad *pad
 
        rec_pipe_time = GST_TIME_AS_MSECONDS(b_time);
 
-       if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4) {
+       if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4)
                MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
-       } else {
+       else
                trailer_size = 0;
-       }
 
        /* check max time */
        if (videoinfo->max_time > 0 && rec_pipe_time > videoinfo->max_time) {
-               _mmcam_dbg_warn("Current time : [%" G_GUINT64_FORMAT "], Maximum time : [%" G_GUINT64_FORMAT "]", \
-                       rec_pipe_time, videoinfo->max_time);
+               _mmcam_dbg_warn("Time current [%" G_GUINT64_FORMAT "], Max [%" G_GUINT64_FORMAT "], motion rate [%lf]", \
+                       rec_pipe_time, videoinfo->max_time, videoinfo->record_motion_rate);
 
                if (!sc->isMaxtimePausing) {
                        MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
@@ -1673,6 +1698,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;
@@ -1707,11 +1733,10 @@ static GstPadProbeReturn __mmcamcorder_audioque_dataprobe(GstPad *pad, GstPadPro
 
        rec_pipe_time = GST_TIME_AS_MSECONDS(GST_BUFFER_PTS(buffer));
 
-       if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4) {
+       if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4)
                MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
-       } else {
+       else
                trailer_size = 0;
-       }
 
        /* calculate remained time can be recorded */
        if (videoinfo->max_time > 0 && videoinfo->max_time < (remained_time + rec_pipe_time)) {
@@ -1724,8 +1749,8 @@ static GstPadProbeReturn __mmcamcorder_audioque_dataprobe(GstPad *pad, GstPadPro
        }
 
        if (videoinfo->max_time > 0 && rec_pipe_time > videoinfo->max_time) {
-               _mmcam_dbg_warn("Current time : [%" G_GUINT64_FORMAT "], Maximum time : [%" G_GUINT64_FORMAT "]", \
-                       rec_pipe_time, videoinfo->max_time);
+               _mmcam_dbg_warn("Time current [%" G_GUINT64_FORMAT "], Max [%" G_GUINT64_FORMAT "], motion rate [%lf]", \
+                       rec_pipe_time, videoinfo->max_time, videoinfo->record_motion_rate);
 
                if (!sc->isMaxtimePausing) {
                        MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
@@ -1920,7 +1945,7 @@ static gboolean __mmcamcorder_add_metadata_mp4(MMHandleType handle)
 
                nread = fread(&buf, sizeof(char), sizeof(buf), f);
 
-               _mmcam_dbg_log("recorded file fread %d", nread);
+               _mmcam_dbg_log("recorded file fread %zu", nread);
 
                udta_size = _mmcamcorder_get_container_size(buf);
 
@@ -1978,7 +2003,7 @@ static gboolean __mmcamcorder_add_metadata_mp4(MMHandleType handle)
 
                /* add orientation info */
                if (fseeko(f, internal_pos, SEEK_SET) < 0) {
-                       _mmcam_dbg_err("fseek failed : errno %d", errno);
+                       _mmcam_dbg_err("fseeko failed : errno %d", errno);
                        goto fail;
                }
 
@@ -1995,10 +2020,13 @@ static gboolean __mmcamcorder_add_metadata_mp4(MMHandleType handle)
                _mmcam_dbg_log("found [tkhd] tag");
 
                /* seek to start position of composition matrix */
-               fseek(f, _OFFSET_COMPOSITION_MATRIX, SEEK_CUR);
-
-               /* update composition matrix for orientation */
-               _mmcamcorder_update_composition_matrix(f, orientation);
+               if (fseek(f, _OFFSET_COMPOSITION_MATRIX, SEEK_CUR) == 0) {
+                       /* update composition matrix for orientation */
+                       _mmcamcorder_update_composition_matrix(f, orientation);
+               } else {
+                       _mmcam_dbg_err("fseek failed : errno %d", errno);
+                       goto fail;
+               }
        } else {
                _mmcam_dbg_err("No 'moov' container");
                goto fail;
@@ -2046,6 +2074,8 @@ int _mmcamcorder_connect_video_stream_cb_signal(MMHandleType handle)
 int _mmcamcorder_video_prepare_record(MMHandleType handle)
 {
        int ret = MM_ERROR_NONE;
+       int size = 0;
+       char *temp_filename = NULL;
 
        _MMCamcorderVideoInfo *info = NULL;
        _MMCamcorderSubContext *sc = NULL;
@@ -2066,25 +2096,25 @@ int _mmcamcorder_video_prepare_record(MMHandleType handle)
        if (ret != MM_ERROR_NONE)
                goto _ERR_PREPARE_RECORD;
 
-       if (info->filename == NULL) {
-               char *temp_filename = NULL;
-               int size = 0;
-
-               mm_camcorder_get_attributes(handle, NULL,
-                       MMCAM_TARGET_FILENAME, &temp_filename, &size,
-                       NULL);
-               if (temp_filename)
-                       info->filename = g_strdup(temp_filename);
+       SAFE_G_FREE(info->filename);
 
+       mm_camcorder_get_attributes(handle, NULL,
+               MMCAM_TARGET_FILENAME, &temp_filename, &size,
+               NULL);
+       if (temp_filename) {
+               info->filename = g_strdup(temp_filename);
                if (!info->filename) {
                        _mmcam_dbg_err("strdup[src:%p] was failed", temp_filename);
                        goto _ERR_PREPARE_RECORD;
                }
-       }
 
-       _mmcam_dbg_log("Record file name [%s]", info->filename);
+               _mmcam_dbg_log("Record file name [%s]", info->filename);
+               MMCAMCORDER_G_OBJECT_SET_POINTER(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, "location", info->filename);
+       } else {
+               _mmcam_dbg_log("Recorded data will be written in [%s]", _MMCamcorder_FILENAME_NULL);
+               MMCAMCORDER_G_OBJECT_SET_POINTER(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, "location", _MMCamcorder_FILENAME_NULL);
+       }
 
-       MMCAMCORDER_G_OBJECT_SET_POINTER(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, "location", info->filename);
        MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", 0);
 
        /* Adjust display FPS */