/*---------------------------------------------------------------------------------------
| 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
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;
_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);
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) {
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)
_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;
}
}
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 */
}
-/**
- * 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)
{
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 */
/* 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);
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;
}
}
case _MMCamcorder_CMD_COMMIT:
{
int count = 0;
-
+ guint64 free_space = 0;
_mmcam_dbg_log("_MMCamcorder_CMD_COMMIT");
if (info->b_commiting) {
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");
{
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;
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 */
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);
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;
}
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;
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 {
}
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 */
}
}