Moved the space checking code at proper place.
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_audiorec.c
index a9789f1..f0df3e4 100644 (file)
 /*---------------------------------------------------------------------------------------
 |    GLOBAL VARIABLE DEFINITIONS for internal                                          |
 ---------------------------------------------------------------------------------------*/
-#define MM_CAMCORDER_START_CHANGE_STATE _MMCamcorderStartHelperFunc((void *)hcamcorder)
-#define MM_CAMCORDER_STOP_CHANGE_STATE _MMCamcorderStopHelperFunc((void *)hcamcorder)
+
 /*---------------------------------------------------------------------------------------
 |    LOCAL VARIABLE DEFINITIONS for internal                                           |
 ---------------------------------------------------------------------------------------*/
 #define RESET_PAUSE_TIME                        0
-#define _MMCAMCORDER_AUDIO_MINIMUM_SPACE        (100*1024)
-#define _MMCAMCORDER_AUDIO_MARGIN_SPACE         (1*1024)
+#define _MMCAMCORDER_AUDIO_MINIMUM_SPACE        ((100*1024) + (5*1024))
 #define _MMCAMCORDER_RETRIAL_COUNT              10
 #define _MMCAMCORDER_FRAME_WAIT_TIME            200000 /* micro second */
 #define _MMCAMCORDER_FREE_SPACE_CHECK_INTERVAL  10
@@ -62,10 +60,12 @@ static gboolean __mmcamcorder_audio_add_metadata_info_m4a(MMHandleType handle);
 static int __mmcamcorder_create_audiop_with_encodebin(MMHandleType handle)
 {
        int err = MM_ERROR_NONE;
-       int ret = MM_ERROR_NONE;
+       int file_name_len = 0;
 
+       char *file_name = NULL;
        const char *aenc_name = NULL;
        const char *mux_name = NULL;
+       const char *sink_name = NULL;
 
        GstBus *bus = NULL;
        GstPad *srcpad = NULL;
@@ -77,6 +77,7 @@ static int __mmcamcorder_create_audiop_with_encodebin(MMHandleType handle)
        _MMCamcorderSubContext *sc = NULL;
        type_element *aenc_elem = NULL;
        type_element *mux_elem = NULL;
+       type_element *sink_elem = NULL;
 
        mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
        sc = MMF_CAMCORDER_SUBCONTEXT(handle);
@@ -113,7 +114,26 @@ static int __mmcamcorder_create_audiop_with_encodebin(MMHandleType handle)
                err = _mmcamcorder_create_encodesink_bin((MMHandleType)hcamcorder, MM_CAMCORDER_ENCBIN_PROFILE_AUDIO);
                if (err != MM_ERROR_NONE)
                        return err;
+
+               /* Add and link elements */
+               gst_bin_add_many(GST_BIN(sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst),
+                       sc->encode_element[_MMCAMCORDER_AUDIOSRC_BIN].gst,
+                       sc->encode_element[_MMCAMCORDER_ENCSINK_BIN].gst,
+                       NULL);
+
+               srcpad = gst_element_get_static_pad(sc->encode_element[_MMCAMCORDER_AUDIOSRC_BIN].gst, "src");
+               sinkpad = gst_element_get_static_pad(sc->encode_element[_MMCAMCORDER_ENCSINK_BIN].gst, "audio_sink0");
+               _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
        } else {
+               err = mm_camcorder_get_attributes(handle, NULL,
+                       MMCAM_TARGET_FILENAME, &file_name, &file_name_len,
+                       NULL);
+               if (err != MM_ERROR_NONE) {
+                       _mmcam_dbg_err("failed to get filename [0x%x]", err);
+                       err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
+                       goto pipeline_creation_error;
+               }
+
                /* without muxing. can't use encodebin. */
                aenc_elem = _mmcamcorder_get_type_element(handle, MM_CAM_AUDIO_ENCODER);
                if (!aenc_elem) {
@@ -129,6 +149,8 @@ static int __mmcamcorder_create_audiop_with_encodebin(MMHandleType handle)
                        goto pipeline_creation_error;
                }
 
+               element_list = g_list_append(element_list, &sc->encode_element[_MMCAMCORDER_AUDIOSRC_BIN]);
+
                _MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_ENCSINK_AQUE, "queue",  NULL, element_list, err);
 
                if (strcmp(aenc_name, "wavenc") != 0)
@@ -136,58 +158,30 @@ static int __mmcamcorder_create_audiop_with_encodebin(MMHandleType handle)
 
                _MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_ENCSINK_AENC, aenc_name, NULL, element_list, err);
 
-               _MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_ENCSINK_SINK, "filesink", NULL, element_list, err);
-       }
+               _mmcamcorder_conf_get_element(handle, hcamcorder->conf_main,
+                       CONFIGURE_CATEGORY_MAIN_RECORD,
+                       "RecordsinkElement",
+                       &sink_elem);
+               _mmcamcorder_conf_get_value_element_name(sink_elem, &sink_name);
 
-       /* Add and link elements */
-       if (info->bMuxing) {
-               /* IF MUX is indicated create MUX */
-               gst_bin_add_many(GST_BIN(sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst),
-                       sc->encode_element[_MMCAMCORDER_AUDIOSRC_BIN].gst,
-                       sc->encode_element[_MMCAMCORDER_ENCSINK_BIN].gst,
-                       NULL);
+               _mmcam_dbg_log("encode sink : %s", sink_name);
 
-               srcpad = gst_element_get_static_pad(sc->encode_element[_MMCAMCORDER_AUDIOSRC_BIN].gst, "src");
-               sinkpad = gst_element_get_static_pad(sc->encode_element[_MMCAMCORDER_ENCSINK_BIN].gst, "audio_sink0");
-               _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error);
-       } else {
-               /* IF MUX in not chosen then record in raw amr file */
-               if (!strcmp(aenc_name, "wavenc")) {
-                       gst_bin_add_many(GST_BIN(sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst),
-                               sc->encode_element[_MMCAMCORDER_AUDIOSRC_BIN].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_AQUE].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_AENC].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst,
-                               NULL);
+               _MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_ENCSINK_SINK, sink_name, NULL, element_list, err);
 
-                       ret = _MM_GST_ELEMENT_LINK_MANY(sc->encode_element[_MMCAMCORDER_AUDIOSRC_BIN].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_AQUE].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_AENC].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst,
-                               NULL);
-                       if (!ret) {
-                               err = MM_ERROR_CAMCORDER_GST_LINK;
-                               goto pipeline_creation_error;
-                       }
-               } else {
-                       gst_bin_add_many(GST_BIN(sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst),
-                               sc->encode_element[_MMCAMCORDER_AUDIOSRC_BIN].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_AQUE].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_CONV].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_AENC].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst,
-                               NULL);
+               _mmcamcorder_conf_set_value_element_property(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, sink_elem);
 
-                       ret = _MM_GST_ELEMENT_LINK_MANY(sc->encode_element[_MMCAMCORDER_AUDIOSRC_BIN].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_AQUE].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_CONV].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_AENC].gst,
-                               sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst,
-                               NULL);
-                       if (!ret) {
-                               err = MM_ERROR_CAMCORDER_GST_LINK;
-                               goto pipeline_creation_error;
-                       }
+               /* add elements to encode pipeline */
+               if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst), element_list)) {
+                       _mmcam_dbg_err("add encode elements error.");
+                       err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
+                       goto pipeline_creation_error;
+               }
+
+               /* link elements */
+               if (!_mmcamcorder_link_elements(element_list)) {
+                       _mmcam_dbg_err("encode element link error.");
+                       err = MM_ERROR_CAMCORDER_GST_LINK;
+                       goto pipeline_creation_error;
                }
        }
 
@@ -204,6 +198,14 @@ static int __mmcamcorder_create_audiop_with_encodebin(MMHandleType handle)
        gst_object_unref(srcpad);
        srcpad = NULL;
 
+       sinkpad = gst_element_get_static_pad(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, "sink");
+       MMCAMCORDER_ADD_BUFFER_PROBE(sinkpad, _MMCAMCORDER_HANDLER_AUDIOREC,
+               __mmcamcorder_muxed_dataprobe, hcamcorder);
+       MMCAMCORDER_ADD_EVENT_PROBE(sinkpad, _MMCAMCORDER_HANDLER_AUDIOREC,
+               __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 message callback  */
@@ -312,38 +314,6 @@ _mmcamcorder_destroy_audio_pipeline(MMHandleType handle)
 }
 
 
-/**
- * This function operates each command on audio mode.
- *
- * @param      c               [in]    Handle of camcorder context.
- * @param      command [in]    command type received from Multimedia Framework.
- *
- * @return     This function returns MM_ERROR_NONE on success, or the other values
- *                     on error.
- * @remark
- * @see                _mmcamcorder_set_functions()
- *
- */
- /* ADDED BY SISO */
-
-
-void* _MMCamcorderStartHelperFunc(void *handle)
-{
-       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
-       _mmcamcorder_set_state((MMHandleType)hcamcorder, hcamcorder->target_state);
-
-       return NULL;
-}
-
-void* _MMCamcorderStopHelperFunc(void *handle)
-{
-       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
-       _mmcamcorder_set_state((MMHandleType)hcamcorder, hcamcorder->target_state);
-
-       return NULL;
-}
-
-
 int
 _mmcamcorder_audio_command(MMHandleType handle, int command)
 {
@@ -403,25 +373,33 @@ _mmcamcorder_audio_command(MMHandleType handle, int command)
                                goto _ERR_CAMCORDER_AUDIO_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_AUDIO_COMMAND;
                        }
 
-                       info->filename = g_strdup(temp_filename);
-                       if (!info->filename) {
-                               _mmcam_dbg_err("STRDUP was failed");
-                               goto _ERR_CAMCORDER_AUDIO_COMMAND;
-                       }
+                       SAFE_G_FREE(info->filename);
+
+                       if (temp_filename) {
+                               info->filename = g_strdup(temp_filename);
+                               if (!info->filename) {
+                                       _mmcam_dbg_err("STRDUP was failed for [%s]", temp_filename);
+                                       goto _ERR_CAMCORDER_AUDIO_COMMAND;
+                               }
 
-                       _mmcam_dbg_log("Record start : set file name using attribute - %s\n ", info->filename);
+                               _mmcam_dbg_log("Record start : file name [%s]", info->filename);
 
-                       MMCAMCORDER_G_OBJECT_SET_POINTER(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);
+                       } 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);
+                       }
 
                        sc->ferror_send = FALSE;
                        sc->ferror_count = 0;
                        sc->bget_eos = FALSE;
+                       sc->muxed_stream_offset = 0;
                        info->filesize = 0;
 
                        /* set max size */
@@ -439,7 +417,15 @@ _mmcamcorder_audio_command(MMHandleType handle, int command)
                        /* TODO : check free space before recording start */
                        dir_name = g_path_get_dirname(info->filename);
                        if (dir_name) {
-                               err = _mmcamcorder_get_freespace(dir_name, hcamcorder->root_directory, &free_space);
+                               err = _mmcamcorder_get_storage_info(dir_name, hcamcorder->root_directory, &hcamcorder->storage_info);
+                               if (err != 0) {
+                                       _mmcam_dbg_err("get storage info failed");
+                                       g_free(dir_name);
+                                       dir_name = NULL;
+                                       return MM_ERROR_OUT_OF_STORAGE;
+                               }
+
+                               err = _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
 
                                _mmcam_dbg_warn("current space - %s [%" G_GUINT64_FORMAT "]", dir_name, free_space);
 
@@ -465,9 +451,10 @@ _mmcamcorder_audio_command(MMHandleType handle, int command)
                                err = -1;
                        }
 
-                       if ((err == -1) || free_space <= (_MMCAMCORDER_AUDIO_MINIMUM_SPACE+(5*1024))) {
+                       if (temp_filename &&
+                               (err == -1 || free_space <= _MMCAMCORDER_AUDIO_MINIMUM_SPACE)) {
                                _mmcam_dbg_err("OUT of STORAGE [err:%d or free space [%" G_GUINT64_FORMAT "] is smaller than [%d]",
-                                       err, free_space, (_MMCAMCORDER_AUDIO_MINIMUM_SPACE+(5*1024)));
+                                       err, free_space, _MMCAMCORDER_AUDIO_MINIMUM_SPACE);
                                return MM_ERROR_OUT_OF_STORAGE;
                        }
                }
@@ -545,7 +532,7 @@ _mmcamcorder_audio_command(MMHandleType handle, int command)
        case _MMCamcorder_CMD_COMMIT:
        {
                int count = 0;
-
+               guint64 free_space = 0;
                _mmcam_dbg_log("_MMCamcorder_CMD_COMMIT");
 
                if (info->b_commiting) {
@@ -570,6 +557,13 @@ _mmcamcorder_audio_command(MMHandleType handle, int command)
                        usleep(_MMCAMCORDER_FRAME_WAIT_TIME);
                }
 
+               _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
+               if (free_space < _MMCAMCORDER_AUDIO_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_AUDIO_COMMAND;
+               }
+
                if (audioSrc) {
                        if (gst_element_send_event(audioSrc, gst_event_new_eos()) == FALSE) {
                                _mmcam_dbg_err("send EOS failed");
@@ -747,6 +741,7 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_voicerecorder(GstPad *pad
 {
        mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
        double volume = 0.0;
+       int current_state = MM_CAMCORDER_STATE_NONE;
        int format = 0;
        int channel = 0;
        float curdcb = 0.0;
@@ -758,6 +753,12 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_voicerecorder(GstPad *pad
 
        mmf_return_val_if_fail(hcamcorder, GST_PAD_PROBE_OK);
 
+       current_state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
+       if (current_state < MM_CAMCORDER_STATE_PREPARE) {
+               _mmcam_dbg_warn("Not ready for stream callback");
+               return GST_PAD_PROBE_OK;
+       }
+
        memset(&mapinfo, 0x0, sizeof(GstMapInfo));
 
        /* Set volume to audio input */
@@ -785,16 +786,12 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_voicerecorder(GstPad *pad
        msg.param.rec_volume_dB = curdcb;
        _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
 
+       _MMCAMCORDER_LOCK_ASTREAM_CALLBACK(hcamcorder);
+
        /* CALL audio stream callback */
-       if ((hcamcorder->astream_cb) && buffer && mapinfo.data && mapinfo.size > 0) {
+       if (hcamcorder->astream_cb && buffer && mapinfo.data && mapinfo.size > 0) {
                MMCamcorderAudioStreamDataType stream;
 
-               if (_mmcamcorder_get_state((MMHandleType)hcamcorder) < MM_CAMCORDER_STATE_PREPARE) {
-                       _mmcam_dbg_warn("Not ready for stream callback");
-                       gst_buffer_unmap(buffer, &mapinfo);
-                       return GST_PAD_PROBE_OK;
-               }
-
                /*
                _mmcam_dbg_log("Call audio steramCb, data[%p], format[%d], channel[%d], length[%d], volume_dB[%f]",
                        GST_BUFFER_DATA(buffer), format, channel, GST_BUFFER_SIZE(buffer), curdcb);
@@ -807,15 +804,13 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_voicerecorder(GstPad *pad
                stream.timestamp = (unsigned int)(GST_BUFFER_PTS(buffer)/1000000);      /* nano -> msecond */
                stream.volume_dB = curdcb;
 
-               _MMCAMCORDER_LOCK_ASTREAM_CALLBACK(hcamcorder);
-
-               if (hcamcorder->astream_cb)
-                       hcamcorder->astream_cb(&stream, hcamcorder->astream_cb_param);
-
-               _MMCAMCORDER_UNLOCK_ASTREAM_CALLBACK(hcamcorder);
+               hcamcorder->astream_cb(&stream, hcamcorder->astream_cb_param);
        }
 
+       _MMCAMCORDER_UNLOCK_ASTREAM_CALLBACK(hcamcorder);
+
        gst_buffer_unmap(buffer, &mapinfo);
+
        return GST_PAD_PROBE_OK;
 }
 
@@ -827,7 +822,6 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_record(GstPad *pad, GstPa
        guint64 free_space = 0;
        guint64 buffer_size = 0;
        guint64 trailer_size = 0;
-       char *filename = NULL;
        unsigned long long remained_time = 0;
        int get_trailer_size = 0;
 
@@ -879,36 +873,21 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_record(GstPad *pad, GstPa
                trailer_size = 0; /* no trailer */
        }
 
-       filename = audioinfo->filename;
-
        /* to minimizing free space check overhead */
        count = count % _MMCAMCORDER_FREE_SPACE_CHECK_INTERVAL;
        if (count++ == 0) {
-               char *dir_name = g_path_get_dirname(filename);
                gint free_space_ret = 0;
+               storage_state_e storage_state = STORAGE_STATE_UNMOUNTABLE;
 
-               if (dir_name) {
-                       free_space_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]", filename);
-                       free_space_ret = -1;
-               }
-
-               /*_mmcam_dbg_log("check free space for recording");*/
-
-               switch (free_space_ret) {
-               case -2: /* file not exist */
-               case -1: /* failed to get free space */
+               /* check free space */
+               free_space_ret = _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
+               if (free_space_ret != 0) {
                        _mmcam_dbg_err("Error occured. [%d]", free_space_ret);
                        if (sc->ferror_count == 2 && sc->ferror_send == FALSE) {
                                sc->ferror_send = TRUE;
+
                                msg.id = MM_MESSAGE_CAMCORDER_ERROR;
-                               if (free_space_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 {
@@ -916,27 +895,56 @@ static GstPadProbeReturn __mmcamcorder_audio_dataprobe_record(GstPad *pad, GstPa
                        }
 
                        return GST_PAD_PROBE_DROP; /* skip this buffer */
+               }
+
+               if (free_space == 0) {
+                       /* check storage state */
+                       storage_get_state(hcamcorder->storage_info.id, &storage_state);
+
+                       _mmcam_dbg_warn("storage state %d", storage_state);
 
-               default: /* succeeded to get free space */
-                       /* check free space for recording */
-                       if (free_space < (guint64)(_MMCAMCORDER_AUDIO_MINIMUM_SPACE + buffer_size + trailer_size)) {
-                               _mmcam_dbg_warn("No more space for recording!!!");
-                               _mmcam_dbg_warn("Free Space : [%" G_GUINT64_FORMAT "], file size : [%" G_GUINT64_FORMAT "]",
-                                       free_space, audioinfo->filesize);
+                       if (storage_state == STORAGE_STATE_REMOVED ||
+                               storage_state == STORAGE_STATE_UNMOUNTABLE) {
+                               _mmcam_dbg_err("storage was removed!");
 
-                               if (audioinfo->bMuxing) {
-                                       MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", 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;
+
+                                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
                                } else {
-                                       MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_AQUE].gst, "empty-buffers", TRUE);
+                                       _MMCAMCORDER_UNLOCK(hcamcorder);
+                                       _mmcam_dbg_warn("error was already sent");
                                }
 
-                               sc->isMaxsizePausing = TRUE;
-                               msg.id = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE;
-                               _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
+                               return GST_PAD_PROBE_DROP;
+                       }
+               }
+
+               if (free_space < (guint64)(_MMCAMCORDER_AUDIO_MINIMUM_SPACE + buffer_size + trailer_size)) {
+                       _mmcam_dbg_warn("No more space for recording!!!");
+                       _mmcam_dbg_warn("Free Space : [%" G_GUINT64_FORMAT "], file size : [%" G_GUINT64_FORMAT "]",
+                               free_space, audioinfo->filesize);
 
-                               return GST_PAD_PROBE_DROP; /* skip this buffer */
+                       if (audioinfo->bMuxing) {
+                               MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
+                       } else {
+                               MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_AQUE].gst, "empty-buffers", TRUE);
                        }
-                       break;
+
+                       sc->isMaxsizePausing = TRUE;
+                       msg.id = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE;
+                       _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
+
+                       return GST_PAD_PROBE_DROP; /* skip this buffer */
                }
        }