[Release 0.10.61] TSAM-6195 : Fix crash when stop camera
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_videorec.c
index cc0c3ff..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;
 
@@ -463,6 +466,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
 {
        int size = 0;
        int fileformat = 0;
+       int count = 0;
        int ret = MM_ERROR_NONE;
        double motion_rate = _MMCAMCORDER_DEFAULT_RECORDING_MOTION_RATE;
        char *err_name = NULL;
@@ -504,8 +508,8 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                        int ret_free_space = 0;
                        char *dir_name = NULL;
                        guint64 free_space = 0;
-                       guint64 free_space_exceptsystem = 0;
                        int file_system_type = 0;
+                       int root_directory_length = 0;
 
                        /* Recording */
                        _mmcam_dbg_log("Record Start - dual stream %d", info->support_dual_stream);
@@ -525,6 +529,7 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                                          MMCAM_TARGET_TIME_LIMIT, &imax_time,
                                                          MMCAM_FILE_FORMAT, &(info->fileformat),
                                                          MMCAM_CAMERA_RECORDING_MOTION_RATE, &motion_rate,
+                                                         MMCAM_ROOT_DIRECTORY, &hcamcorder->root_directory, &root_directory_length,
                                                          NULL);
                        if (ret != MM_ERROR_NONE) {
                                _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
@@ -554,18 +559,9 @@ 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, &free_space);
-                               if(_mmcamcorder_check_file_path(dir_name)) {
-                                       if (_mmcamcorder_get_freespace_except_system(&free_space_exceptsystem) == MM_ERROR_NONE) {
-                                               hcamcorder->system_memory = free_space - free_space_exceptsystem;
-                                               free_space = free_space - hcamcorder->system_memory;
-                                       } else {
-                                               hcamcorder->system_memory = 0;
-                                       }
-                               }
+                               ret_free_space = _mmcamcorder_get_freespace(dir_name, hcamcorder->root_directory, &free_space);
 
-                               _mmcam_dbg_warn("current space - %s [%" G_GUINT64_FORMAT "], system [%" G_GUINT64_FORMAT "]",
-                                               dir_name, free_space, hcamcorder->system_memory);
+                               _mmcam_dbg_warn("current space - %s [%" G_GUINT64_FORMAT "]", dir_name, free_space);
 
                                if (_mmcamcorder_get_file_system_type(dir_name, &file_system_type) == 0) {
                                        /* MSDOS_SUPER_MAGIC : 0x4d44 */
@@ -595,13 +591,13 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                return MM_ERROR_OUT_OF_STORAGE;
                        }
 
-                       pthread_mutex_lock(&(hcamcorder->task_thread_lock));
+                       g_mutex_lock(&hcamcorder->task_thread_lock);
                        if (sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst == NULL &&
                            hcamcorder->task_thread_state == _MMCAMCORDER_TASK_THREAD_STATE_NONE) {
                                /* Play record start sound */
-                               _mmcamcorder_sound_solo_play(handle, _MMCAMCORDER_FILEPATH_REC_START_SND, FALSE);
+                               _mmcamcorder_sound_solo_play(handle, _MMCAMCORDER_SAMPLE_SOUND_NAME_REC_START, FALSE);
                        }
-                       pthread_mutex_unlock(&(hcamcorder->task_thread_lock));
+                       g_mutex_unlock(&hcamcorder->task_thread_lock);
 
                        _mmcam_dbg_warn("video size [%dx%d]", info->video_width, info->video_height);
 
@@ -634,6 +630,9 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                info->restart_preview = TRUE;
                        }
 
+                       /* set recording hint */
+                       MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "recording-hint", TRUE);
+
                        if (info->restart_preview) {
                                /* stop preview and set new size */
                                _mmcam_dbg_log("restart preview");
@@ -643,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);
 
@@ -710,10 +716,10 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                CameraControl =  GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
                                if (CameraControl) {
                                        MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "stop-video", TRUE);
-#ifdef LATEST_CAMERA_CONTROL
+
                                        _mmcam_dbg_log("GST_CAMERA_CONTROL_RECORD_COMMAND_START");
                                        gst_camera_control_set_record_command(CameraControl, GST_CAMERA_CONTROL_RECORD_COMMAND_START);
-#endif /* LATEST_CAMERA_CONTROL */
+
                                        MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "stop-video", FALSE);
                                } else {
                                        _mmcam_dbg_err("could not get camera control");
@@ -721,17 +727,17 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                        }
 
                        /* check pre-created encode pipeline */
-                       pthread_mutex_lock(&(hcamcorder->task_thread_lock));
+                       g_mutex_lock(&hcamcorder->task_thread_lock);
                        if (sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst == NULL &&
                            hcamcorder->task_thread_state == _MMCAMCORDER_TASK_THREAD_STATE_NONE) {
                                /* create encoding pipeline */
                                ret =_mmcamcorder_video_prepare_record((MMHandleType)hcamcorder);
                                if (ret != MM_ERROR_NONE) {
-                                       pthread_mutex_unlock(&(hcamcorder->task_thread_lock));
+                                       g_mutex_unlock(&hcamcorder->task_thread_lock);
                                        goto _ERR_CAMCORDER_VIDEO_COMMAND;
                                }
                        }
-                       pthread_mutex_unlock(&(hcamcorder->task_thread_lock));
+                       g_mutex_unlock(&hcamcorder->task_thread_lock);
 
                        /* check recording start sound */
                        _mmcamcorder_sound_solo_play_wait(handle);
@@ -761,10 +767,10 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                                        CameraControl = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
                                        if (CameraControl) {
                                                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "stop-video", TRUE);
-#ifdef LATEST_CAMERA_CONTROL
+
                                                _mmcam_dbg_log("GST_CAMERA_CONTROL_RECORD_COMMAND_STOP");
                                                gst_camera_control_set_record_command(CameraControl, GST_CAMERA_CONTROL_RECORD_COMMAND_STOP);
-#endif /* LATEST_CAMERA_CONTROL */
+
                                                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "stop-video", FALSE);
                                        } else {
                                                _mmcam_dbg_err("failed to get camera control");
@@ -835,8 +841,6 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                break;
        case _MMCamcorder_CMD_PAUSE:
        {
-               int count = 0;
-
                if (info->b_commiting) {
                        _mmcam_dbg_warn("now on commiting previous file!!(command : %d)", command);
                        return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
@@ -848,11 +852,11 @@ 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 %" G_GUINT64_FORMAT "",
+                                       _mmcam_dbg_err("Pause fail, frame count %llu",
                                                       info->video_frame_count);
                                        return MM_ERROR_CAMCORDER_INVALID_CONDITION;
                                } else {
-                                       _mmcam_dbg_warn("Waiting for enough video frame, retrial[%d], frame %" G_GUINT64_FORMAT "",
+                                       _mmcam_dbg_warn("Waiting for enough video frame, retrial[%d], frame %llu",
                                                        count, info->video_frame_count);
                                }
 
@@ -862,11 +866,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[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]",
+                                       _mmcam_dbg_err("Pause fail, frame count VIDEO[%llu], AUDIO [%llu]",
                                                       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[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]",
+                                       _mmcam_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%llu], AUDIO [%llu]",
                                                        count, info->video_frame_count, info->audio_frame_count);
                                }
 
@@ -885,6 +889,21 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                        return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
                }
 
+               for (count = 0 ; count <= _MMCAMCORDER_RETRIAL_COUNT ; count++) {
+                       /* capturing */
+                       if (hcamcorder->capture_in_recording == FALSE) {
+                               break;
+                       } else if (count == _MMCAMCORDER_RETRIAL_COUNT) {
+                               _mmcam_dbg_err("Failed to Wait capture data");
+                               hcamcorder->capture_in_recording = FALSE;
+                               break;
+                       } else {
+                               _mmcam_dbg_warn("Waiting for capture data - retrial [%d]", count);
+                       }
+
+                       usleep(_MMCAMCORDER_FRAME_WAIT_TIME);
+               }
+
                /* block push buffer */
                info->push_encoding_buffer = PUSH_ENCODING_BUFFER_STOP;
 
@@ -893,15 +912,18 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                        goto _ERR_CAMCORDER_VIDEO_COMMAND;
                }
 
+               /* set recording hint */
+               MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "recording-hint", FALSE);
+
                /* stop video stream */
                if (info->record_dual_stream) {
                        CameraControl = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
                        if (CameraControl) {
                                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "stop-video", TRUE);
-#ifdef LATEST_CAMERA_CONTROL
+
                                _mmcam_dbg_log("GST_CAMERA_CONTROL_RECORD_COMMAND_STOP");
                                gst_camera_control_set_record_command(CameraControl, GST_CAMERA_CONTROL_RECORD_COMMAND_STOP);
-#endif /* LATEST_CAMERA_CONTROL */
+
                                MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "stop-video", FALSE);
                        } else {
                                _mmcam_dbg_err("failed to get camera control");
@@ -915,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;
                        }
@@ -949,12 +978,11 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                info->video_frame_count = 0;
                info->audio_frame_count = 0;
                info->filesize = 0;
+               hcamcorder->capture_in_recording = FALSE;
                break;
        }
        case _MMCamcorder_CMD_COMMIT:
        {
-               int count = 0;
-
                if (info->b_commiting) {
                        _mmcam_dbg_err("now on commiting previous file!!(command : %d)", command);
                        return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
@@ -967,34 +995,55 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                for (count = 0 ; count <= _MMCAMCORDER_RETRIAL_COUNT ; count++) {
                        if (sc->audio_disable) {
                                /* check only video frame */
-                               if (info->video_frame_count >= _MMCAMCORDER_MINIMUM_FRAME) {
+                               if (info->video_frame_count >= _MMCAMCORDER_MINIMUM_FRAME &&
+                                   hcamcorder->capture_in_recording == FALSE) {
                                        break;
                                } else if (count == _MMCAMCORDER_RETRIAL_COUNT) {
-                                       _mmcam_dbg_err("Commit fail, frame count is %" G_GUINT64_FORMAT "",
-                                                      info->video_frame_count);
-                                       info->b_commiting = FALSE;
-                                       return MM_ERROR_CAMCORDER_INVALID_CONDITION;
+                                       _mmcam_dbg_err("Commit fail, frame count is %llu, capturing %d",
+                                                      info->video_frame_count, hcamcorder->capture_in_recording);
+
+                                       if (info->video_frame_count >= _MMCAMCORDER_MINIMUM_FRAME) {
+                                               _mmcam_dbg_warn("video frames are enough. keep going...");
+                                       } else {
+                                               info->b_commiting = FALSE;
+                                               return MM_ERROR_CAMCORDER_INVALID_CONDITION;
+                                       }
                                } else {
-                                       _mmcam_dbg_warn("Waiting for enough video frame, retrial [%d], frame %" G_GUINT64_FORMAT "",
-                                                       count, info->video_frame_count);
+                                       _mmcam_dbg_warn("Waiting for enough video frame, retrial [%d], frame %llu, capturing %d",
+                                                       count, info->video_frame_count, hcamcorder->capture_in_recording);
                                }
-
-                               usleep(_MMCAMCORDER_FRAME_WAIT_TIME);
                        } else {
                                /* check both of video and audio frame */
-                               if (info->video_frame_count >= _MMCAMCORDER_MINIMUM_FRAME && info->audio_frame_count) {
+                               if (info->video_frame_count >= _MMCAMCORDER_MINIMUM_FRAME &&
+                                   info->audio_frame_count &&
+                                   hcamcorder->capture_in_recording == FALSE) {
                                        break;
                                } else if (count == _MMCAMCORDER_RETRIAL_COUNT) {
-                                       _mmcam_dbg_err("Commit fail, VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]",
-                                                      info->video_frame_count, info->audio_frame_count);
+                                       _mmcam_dbg_err("Commit fail, VIDEO[%llu], AUDIO [%llu], 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) {
+                                               _mmcam_dbg_warn("video/audio frames are enough. keep going...");
+                                       } else {
+                                               info->b_commiting = FALSE;
+                                               return MM_ERROR_CAMCORDER_INVALID_CONDITION;
+                                       }
 
-                                       info->b_commiting = FALSE;
                                        return MM_ERROR_CAMCORDER_INVALID_CONDITION;
                                } else {
-                                       _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);
+                                       _mmcam_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%llu], AUDIO [%llu], 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 {
+                                       _mmcam_dbg_warn("timeout");
+                               }
+                       } else {
                                usleep(_MMCAMCORDER_FRAME_WAIT_TIME);
                        }
                }
@@ -1004,22 +1053,38 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                _mmcam_dbg_log("block push buffer to appsrc");
 
                if (sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst != NULL) {
-                       ret = gst_element_send_event(sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst, gst_event_new_eos());
-                       _mmcam_dbg_warn("send eos to appsrc result : %d", ret);
+                       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");
+                       } else {
+                               _mmcam_dbg_err("VIDEO: send EOS failed");
+                               info->b_commiting = FALSE;
+                               ret = MM_ERROR_CAMCORDER_INTERNAL;
+                               goto _ERR_CAMCORDER_VIDEO_COMMAND;
+                       }
+               } else {
+                       _mmcam_dbg_err("No video stream source");
+                       info->b_commiting = FALSE;
+                       ret = MM_ERROR_CAMCORDER_INTERNAL;
+                       goto _ERR_CAMCORDER_VIDEO_COMMAND;
                }
 
                if (sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst != NULL) {
-                       ret = gst_element_send_event(sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst, gst_event_new_eos());
-                       _mmcam_dbg_warn("send eos to audiosrc result : %d", ret);
+                       if (gst_element_send_event(sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst, gst_event_new_eos())) {
+                               _mmcam_dbg_warn("AUDIO: send eos to audiosrc done");
+                       } else {
+                               _mmcam_dbg_err("AUDIO: send EOS failed");
+                               info->b_commiting = FALSE;
+                               ret = MM_ERROR_CAMCORDER_INTERNAL;
+                               goto _ERR_CAMCORDER_VIDEO_COMMAND;
+                       }
+               } else {
+                       _mmcam_dbg_log("No audio stream");
                }
 
                /* sc */
                sc->display_interval = 0;
                sc->previous_slot_time = 0;
 
-               /* init system memory size */
-               hcamcorder->system_memory = 0;
-
                /* Wait EOS */
                _mmcam_dbg_log("Start to wait EOS");
                ret =_mmcamcorder_get_eos_message(handle);
@@ -1027,6 +1092,9 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                        info->b_commiting = FALSE;
                        goto _ERR_CAMCORDER_VIDEO_COMMAND;
                }
+
+               /* reset flag */
+               hcamcorder->capture_in_recording = FALSE;
        }
                break;
        default:
@@ -1069,15 +1137,11 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
 
        if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_ASM) {
                /* Play record stop sound */
-               _mmcamcorder_sound_solo_play(handle, _MMCAMCORDER_FILEPATH_REC_STOP_SND, FALSE);
+               _mmcamcorder_sound_solo_play(handle, _MMCAMCORDER_SAMPLE_SOUND_NAME_REC_STOP, FALSE);
        } else {
                _mmcam_dbg_warn("Play stop sound through pulseaudio");
 
-#ifdef _MMCAMCORDER_UPLOAD_SAMPLE
-               _mmcamcorder_sound_init(handle, _MMCAMCORDER_FILEPATH_REC_STOP_SND);
-#else /* _MMCAMCORDER_UPLOAD_SAMPLE */
                _mmcamcorder_sound_init(handle);
-#endif /* _MMCAMCORDER_UPLOAD_SAMPLE */
 
                _mmcamcorder_sound_play((MMHandleType)hcamcorder, _MMCAMCORDER_SAMPLE_SOUND_NAME_REC_STOP, TRUE);
 
@@ -1096,15 +1160,18 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
                _mmcam_dbg_warn("_MMCamcorder_CMD_COMMIT:__mmcamcorder_remove_recorder_pipeline failed. error[%x]", ret);
        }
 
+       /* set recording hint */
+       MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "recording-hint", FALSE);
+
        /* stop video stream */
        if (info->record_dual_stream) {
                GstCameraControl *control = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
                if (control) {
                        MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "stop-video", TRUE);
-#ifdef LATEST_CAMERA_CONTROL
+
                        _mmcam_dbg_log("GST_CAMERA_CONTROL_RECORD_COMMAND_STOP");
                        gst_camera_control_set_record_command(control, GST_CAMERA_CONTROL_RECORD_COMMAND_STOP);
-#endif /* LATEST_CAMERA_CONTROL */
+
                        MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "stop-video", FALSE);
                } else {
                        _mmcam_dbg_err("failed to get camera control");
@@ -1131,7 +1198,7 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
                        _mmcam_dbg_err("File size is greater than max size !!");
                        message.id = MM_MESSAGE_CAMCORDER_ERROR;
                        message.param.code = MM_ERROR_CAMCORDER_FILE_SIZE_OVER;
-                       _mmcamcroder_send_message((MMHandleType)hcamcorder, &message);
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &message);
                }
        }
 
@@ -1143,13 +1210,19 @@ 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);
                if (ret != MM_ERROR_NONE) {
                        msg.id = MM_MESSAGE_CAMCORDER_ERROR;
                        msg.param.code = ret;
-                       _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
                        _mmcam_dbg_err("Failed to set state READY[%x]", ret);
                }
 
@@ -1165,7 +1238,7 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
                if (ret != MM_ERROR_NONE) {
                        msg.id = MM_MESSAGE_CAMCORDER_ERROR;
                        msg.param.code = ret;
-                       _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
                        _mmcam_dbg_err("Failed to set state PLAYING[%x]", ret);
                }
        } else {
@@ -1174,14 +1247,14 @@ int _mmcamcorder_video_handle_eos(MMHandleType handle)
 
        /* Send recording report to application */
        msg.id = MM_MESSAGE_CAMCORDER_VIDEO_CAPTURED;
-       report = (MMCamRecordingReport *)malloc(sizeof(MMCamRecordingReport));
+       report = (MMCamRecordingReport *)g_malloc(sizeof(MMCamRecordingReport));
        if (!report) {
                _mmcam_dbg_err("Recording report fail(%s). Out of memory.", info->filename);
        } else {
-               report->recording_filename = strdup(info->filename);
+               report->recording_filename = g_strdup(info->filename);
                msg.param.data= report;
                msg.param.code = 1;
-               _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+               _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
        }
 
        /* Finishing */
@@ -1280,18 +1353,18 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_check(GstPad *pad, GstPad
 
        /*_mmcam_dbg_err("[%" GST_TIME_FORMAT "]", GST_TIME_ARGS(GST_BUFFER_PTS(buffer)));*/
 
-       pthread_mutex_lock(&(videoinfo->size_check_lock));
+       g_mutex_lock(&videoinfo->size_check_lock);
 
        if (videoinfo->audio_frame_count == 0) {
                videoinfo->filesize += buffer_size;
                videoinfo->audio_frame_count++;
-               pthread_mutex_unlock(&(videoinfo->size_check_lock));
+               g_mutex_unlock(&videoinfo->size_check_lock);
                return GST_PAD_PROBE_OK;
        }
 
        if (sc->ferror_send || sc->isMaxsizePausing) {
                _mmcam_dbg_warn("Recording is paused, drop frames");
-               pthread_mutex_unlock(&(videoinfo->size_check_lock));
+               g_mutex_unlock(&videoinfo->size_check_lock);
                return GST_PAD_PROBE_DROP;
        }
 
@@ -1320,10 +1393,10 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_check(GstPad *pad, GstPad
                        }
 
                        msg.id = MM_MESSAGE_CAMCORDER_MAX_SIZE;
-                       _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
                }
 
-               pthread_mutex_unlock(&(videoinfo->size_check_lock));
+               g_mutex_unlock(&videoinfo->size_check_lock);
 
                return FALSE;
        }
@@ -1331,7 +1404,7 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_check(GstPad *pad, GstPad
        videoinfo->filesize += buffer_size;
        videoinfo->audio_frame_count++;
 
-       pthread_mutex_unlock(&(videoinfo->size_check_lock));
+       g_mutex_unlock(&videoinfo->size_check_lock);
 
        return GST_PAD_PROBE_OK;
 }
@@ -1346,7 +1419,7 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
        guint64 buffer_size = 0;
        guint64 trailer_size = 0;
        guint64 queued_buffer = 0;
-       char *filename = NULL;
+       char *dir_name = NULL;
        GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
        GstMapInfo mapinfo;
 
@@ -1376,9 +1449,9 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
        if (videoinfo->video_frame_count <= (guint64)_MMCAMCORDER_MINIMUM_FRAME) {
                /* _mmcam_dbg_log("Pass minimum frame: info->video_frame_count: %" G_GUINT64_FORMAT " ",
                                info->video_frame_count); */
-               pthread_mutex_lock(&(videoinfo->size_check_lock));
+               g_mutex_lock(&videoinfo->size_check_lock);
                videoinfo->filesize += buffer_size;
-               pthread_mutex_unlock(&(videoinfo->size_check_lock));
+               g_mutex_unlock(&videoinfo->size_check_lock);
                return GST_PAD_PROBE_OK;
        }
 
@@ -1389,11 +1462,14 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
                trailer_size = 0;
        }
 
-       filename = videoinfo->filename;
-       ret = _mmcamcorder_get_freespace(filename, &free_space);
-
-       if(_mmcamcorder_check_file_path(filename) && hcamcorder->system_memory) {
-               free_space = free_space - hcamcorder->system_memory;
+       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");*/
@@ -1410,7 +1486,7 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
                        } else {
                                msg.param.code = MM_ERROR_FILE_READ;
                        }
-                       _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
                } else {
                        sc->ferror_count++;
                }
@@ -1441,7 +1517,7 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
                                sc->isMaxsizePausing = TRUE;
 
                                msg.id = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE;
-                               _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+                               _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
                        }
 
                        return GST_PAD_PROBE_DROP;
@@ -1449,7 +1525,7 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
                break;
        }
 
-       pthread_mutex_lock(&(videoinfo->size_check_lock));
+       g_mutex_lock(&videoinfo->size_check_lock);
 
        /* check max size of recorded file */
        if (videoinfo->max_size > 0 &&
@@ -1469,10 +1545,10 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
                        }
 
                        msg.id = MM_MESSAGE_CAMCORDER_MAX_SIZE;
-                       _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
                }
 
-               pthread_mutex_unlock(&(videoinfo->size_check_lock));
+               g_mutex_unlock(&videoinfo->size_check_lock);
 
                return GST_PAD_PROBE_DROP;
        }
@@ -1483,7 +1559,7 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPa
        _mmcam_dbg_log("filesize %lld Byte, ", videoinfo->filesize);
        */
 
-       pthread_mutex_unlock(&(videoinfo->size_check_lock));
+       g_mutex_unlock(&videoinfo->size_check_lock);
 
        return GST_PAD_PROBE_OK;
 }
@@ -1537,10 +1613,10 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_audio_disable(GstPad *pad
                        msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
                        msg.param.recording_status.filesize = (unsigned long long)((videoinfo->filesize + trailer_size) >> 10);
                        msg.param.recording_status.remained_time = 0;
-                       _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
 
                        msg.id = MM_MESSAGE_CAMCORDER_TIME_LIMIT;
-                       _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
                }
 
                return GST_PAD_PROBE_DROP;
@@ -1560,7 +1636,7 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_audio_disable(GstPad *pad
        msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
        msg.param.recording_status.filesize = (unsigned long long)((videoinfo->filesize + trailer_size) >> 10);
        msg.param.recording_status.remained_time = remained_time;
-       _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
 
        /*
        _mmcam_dbg_log("time [%" GST_TIME_FORMAT "], size [%d]",
@@ -1654,10 +1730,10 @@ static GstPadProbeReturn __mmcamcorder_audioque_dataprobe(GstPad *pad, GstPadPro
                        msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
                        msg.param.recording_status.filesize = (unsigned long long)((videoinfo->filesize + trailer_size) >> 10);
                        msg.param.recording_status.remained_time = 0;
-                       _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
 
                        msg.id = MM_MESSAGE_CAMCORDER_TIME_LIMIT;
-                       _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
                }
 
                return GST_PAD_PROBE_DROP;
@@ -1667,7 +1743,7 @@ static GstPadProbeReturn __mmcamcorder_audioque_dataprobe(GstPad *pad, GstPadPro
        msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
        msg.param.recording_status.filesize = (unsigned long long)((videoinfo->filesize + trailer_size) >> 10);
        msg.param.recording_status.remained_time = remained_time;
-       _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
 
        /*
        _mmcam_dbg_log("audio data probe :: time [%" GST_TIME_FORMAT "], size [%lld KB]",
@@ -1797,7 +1873,7 @@ static gboolean __mmcamcorder_add_metadata_mp4(MMHandleType handle)
 
        info = sc->info_video;
 
-       f = fopen(info->filename, "rb+");
+       f = fopen64(info->filename, "rb+");
        if (f == NULL) {
                strerror_r(errno, err_msg, MAX_ERROR_MESSAGE_LEN);
                _mmcam_dbg_err("file open failed [%s]", err_msg);
@@ -1835,7 +1911,7 @@ static gboolean __mmcamcorder_add_metadata_mp4(MMHandleType handle)
                        goto fail;
                }
 
-               udta_pos = ftell(f);
+               udta_pos = ftello(f);
                if (udta_pos < 0) {
                        goto ftell_fail;
                }
@@ -1863,7 +1939,7 @@ static gboolean __mmcamcorder_add_metadata_mp4(MMHandleType handle)
                        }
                }
 
-               current_pos = ftell(f);
+               current_pos = ftello(f);
                if (current_pos < 0) {
                        goto ftell_fail;
                }
@@ -1885,18 +1961,18 @@ static gboolean __mmcamcorder_add_metadata_mp4(MMHandleType handle)
 
        /* find moov container.
           update moov container size. */
-       if((current_pos = ftell(f))<0)
+       if((current_pos = ftello(f))<0)
                goto ftell_fail;
 
        if (_mmcamcorder_find_tag(f, MMCAM_FOURCC('m','o','o','v'), TRUE)) {
-               gint64 internal_pos = ftell(f);
+               gint64 internal_pos = ftello(f);
 
                _mmcam_dbg_log("found moov container");
                if (fseek(f, -8L, SEEK_CUR) !=0) {
                        goto fail;
                }
 
-               moov_pos = ftell(f);
+               moov_pos = ftello(f);
                if (moov_pos < 0) {
                        goto ftell_fail;
                }
@@ -1906,7 +1982,7 @@ static gboolean __mmcamcorder_add_metadata_mp4(MMHandleType handle)
                }
 
                /* add orientation info */
-               if (fseek(f, internal_pos, SEEK_SET) < 0) {
+               if (fseeko(f, internal_pos, SEEK_SET) < 0) {
                        _mmcam_dbg_err("fseek failed : errno %d", errno);
                        goto fail;
                }
@@ -2004,7 +2080,7 @@ int _mmcamcorder_video_prepare_record(MMHandleType handle)
                                            MMCAM_TARGET_FILENAME, &temp_filename, &size,
                                            NULL);
                if (temp_filename) {
-                       info->filename = strdup(temp_filename);
+                       info->filename = g_strdup(temp_filename);
                }
 
                if (!info->filename) {
@@ -2015,7 +2091,7 @@ int _mmcamcorder_video_prepare_record(MMHandleType handle)
 
        _mmcam_dbg_log("Record file name [%s]", info->filename);
 
-       MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, "location", info->filename);
+       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 */