#define _MMCAMCORDER_AUDIO_MINIMUM_SPACE (100*1024)
#define _MMCAMCORDER_AUDIO_MARGIN_SPACE (1*1024)
#define _MMCAMCORDER_RETRIAL_COUNT 10
-#define _MMCAMCORDER_FRAME_WAIT_TIME 20000 /* micro second */
+#define _MMCAMCORDER_FRAME_WAIT_TIME 200000 /* micro second */
#define _MMCAMCORDER_FREE_SPACE_CHECK_INTERVAL 10
/*---------------------------------------------------------------------------------------
static GstPadProbeReturn __mmcamcorder_audio_dataprobe_voicerecorder(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
static GstPadProbeReturn __mmcamcorder_audio_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
static int __mmcamcorder_create_audiop_with_encodebin(MMHandleType handle);
-static void __mmcamcorder_audiorec_pad_added_cb(GstElement *element, GstPad *pad, MMHandleType handle);
+static gboolean __mmcamcorder_audio_add_metadata_info_m4a(MMHandleType handle);
/*=======================================================================================
| FUNCTION DEFINITIONS |
gst_object_unref(srcpad);
srcpad = NULL;
- if (info->bMuxing) {
- MMCAMCORDER_SIGNAL_CONNECT(sc->encode_element[_MMCAMCORDER_ENCSINK_MUX].gst,
- _MMCAMCORDER_HANDLER_AUDIOREC,
- "pad-added",
- __mmcamcorder_audiorec_pad_added_cb,
- hcamcorder);
- } else {
- srcpad = gst_element_get_static_pad(sc->encode_element[_MMCAMCORDER_ENCSINK_AENC].gst, "src");
- MMCAMCORDER_ADD_BUFFER_PROBE(srcpad, _MMCAMCORDER_HANDLER_AUDIOREC,
- __mmcamcorder_audio_dataprobe_record, hcamcorder);
- gst_object_unref(srcpad);
- srcpad = NULL;
- }
+ srcpad = gst_element_get_static_pad(sc->encode_element[_MMCAMCORDER_ENCSINK_AENC].gst, "src");
+ MMCAMCORDER_ADD_BUFFER_PROBE(srcpad, _MMCAMCORDER_HANDLER_AUDIOREC,
+ __mmcamcorder_audio_dataprobe_record, hcamcorder);
+ gst_object_unref(srcpad);
+ srcpad = NULL;
bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst));
hcamcorder->pipeline_cb_event_id = gst_bus_add_watch(bus, (GstBusFunc)_mmcamcorder_pipeline_cb_message, hcamcorder);
/* set sync callback */
- gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, hcamcorder, NULL);
+ gst_bus_set_sync_handler(bus, _mmcamcorder_encode_pipeline_bus_sync_callback, hcamcorder, NULL);
gst_object_unref(bus);
bus = NULL;
int cmd = command;
int ret = MM_ERROR_NONE;
int err = 0;
- int size=0;
guint64 free_space = 0;
- char *dir_name = NULL;
char *err_attr_name = NULL;
GstElement *pipeline = NULL;
guint imax_size = 0;
guint imax_time = 0;
char *temp_filename = NULL;
+ char *dir_name = NULL;
int file_system_type = 0;
+ int filename_length = 0;
+ int root_directory_length = 0;
if(sc->pipeline_time) {
gst_element_set_start_time(pipeline, sc->pipeline_time);
MMCAM_TARGET_MAX_SIZE, &imax_size,
MMCAM_TARGET_TIME_LIMIT, &imax_time,
MMCAM_FILE_FORMAT, &(info->fileformat),
- MMCAM_TARGET_FILENAME, &temp_filename, &size,
+ MMCAM_TARGET_FILENAME, &temp_filename, &filename_length,
+ MMCAM_ROOT_DIRECTORY, &hcamcorder->root_directory, &root_directory_length,
NULL);
if (ret != MM_ERROR_NONE) {
_mmcam_dbg_warn("failed to get attribute. (%s:%x)", err_attr_name, ret);
goto _ERR_CAMCORDER_AUDIO_COMMAND;
}
- info->filename = strdup(temp_filename);
+ info->filename = g_strdup(temp_filename);
if (!info->filename) {
_mmcam_dbg_err("STRDUP was failed");
goto _ERR_CAMCORDER_AUDIO_COMMAND;
_mmcam_dbg_log("Record start : set file name using attribute - %s\n ",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);
sc->ferror_send = FALSE;
sc->ferror_count = 0;
/* TODO : check free space before recording start */
dir_name = g_path_get_dirname(info->filename);
if (dir_name) {
- err = _mmcamcorder_get_freespace(dir_name, &free_space);
- _mmcam_dbg_warn("current space for recording - %s :[%" G_GUINT64_FORMAT "]" ,dir_name, free_space);
+ err = _mmcamcorder_get_freespace(dir_name, hcamcorder->root_directory, &free_space);
+
+ _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 */
if (info->filename) {
_mmcam_dbg_log("file delete(%s)", info->filename);
unlink(info->filename);
- g_free(info->filename);
- info->filename = NULL;
+ SAFE_G_FREE(info->filename);
}
break;
}
if (audioSrc) {
- ret = gst_element_send_event(audioSrc, gst_event_new_eos());
+ if (gst_element_send_event(audioSrc, gst_event_new_eos()) == FALSE) {
+ _mmcam_dbg_err("send EOS failed");
+ info->b_commiting = FALSE;
+ ret = MM_ERROR_CAMCORDER_INTERNAL;
+ goto _ERR_CAMCORDER_AUDIO_COMMAND;
+ }
+
+ _mmcam_dbg_log("send EOS done");
+
/* for pause -> commit case */
if (_mmcamcorder_get_state((MMHandleType)hcamcorder) == MM_CAMCORDER_STATE_PAUSED) {
ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
goto _ERR_CAMCORDER_AUDIO_COMMAND;
}
}
+ } else {
+ _mmcam_dbg_err("No audio stream source");
+ info->b_commiting = FALSE;
+ ret = MM_ERROR_CAMCORDER_INTERNAL;
+ goto _ERR_CAMCORDER_AUDIO_COMMAND;
}
/* wait until finishing EOS */
/* Send recording report message to application */
msg.id = MM_MESSAGE_CAMCORDER_AUDIO_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);
return FALSE;
}
- report->recording_filename = strdup(info->filename);
+/* START TAG HERE */
+ // MM_AUDIO_CODEC_AAC + MM_FILE_FORMAT_MP4
+ if(info->fileformat == MM_FILE_FORMAT_3GP || info->fileformat == MM_FILE_FORMAT_MP4){
+ __mmcamcorder_audio_add_metadata_info_m4a(handle);
+ }
+/* END TAG HERE */
+
+ report->recording_filename = g_strdup(info->filename);
msg.param.data= report;
- _mmcamcroder_send_message(handle, &msg);
+ _mmcamcorder_send_message(handle, &msg);
if (info->bMuxing) {
MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
sc->isMaxsizePausing = FALSE;
sc->isMaxtimePausing = FALSE;
- g_free(info->filename);
- info->filename = NULL;
+ SAFE_G_FREE(info->filename);
_mmcam_dbg_err("_MMCamcorder_CMD_COMMIT : end");
}
if (count > 0) {
- rms = sqrt( square_sum/count );
+ rms = sqrt( (double)square_sum/(double)count );
if (depthByte == 1) {
db = 20 * log10( rms/MAX_AMPLITUDE_MEAN_08BIT );
} else {
int err = MM_ERROR_UNKNOWN;
char *err_name = NULL;
GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
- GstMapInfo mapinfo = GST_MAP_INFO_INIT;
+ GstMapInfo mapinfo;
mmf_return_val_if_fail(hcamcorder, GST_PAD_PROBE_OK);
+ memset(&mapinfo, 0x0, sizeof(GstMapInfo));
+
/* Set volume to audio input */
err = mm_camcorder_get_attributes((MMHandleType)hcamcorder, &err_name,
MMCAM_AUDIO_VOLUME, &volume,
msg.id = MM_MESSAGE_CAMCORDER_CURRENT_VOLUME;
msg.param.rec_volume_dB = curdcb;
- _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+ _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
/* CALL audio stream callback */
if ((hcamcorder->astream_cb) && buffer && mapinfo.data && mapinfo.size > 0)
}
-static void
-__mmcamcorder_audiorec_pad_added_cb(GstElement *element, GstPad *pad, MMHandleType handle)
-{
- mmf_camcorder_t *hcamcorder= MMF_CAMCORDER(handle);
-
- _mmcam_dbg_log("ENTER(%s)", GST_PAD_NAME(pad));
- //FIXME : the name of audio sink pad of wavparse, oggmux doesn't have 'audio'. How could I handle the name?
- if((strstr(GST_PAD_NAME(pad), "audio")) || (strstr(GST_PAD_NAME(pad), "sink")))
- {
- MMCAMCORDER_ADD_BUFFER_PROBE(pad, _MMCAMCORDER_HANDLER_AUDIOREC,
- __mmcamcorder_audio_dataprobe_record, hcamcorder);
- }
- else
- {
- _mmcam_dbg_warn("Unknow pad is added, check it : [%s]", GST_PAD_NAME(pad));
- }
-
- return;
-}
-
-
static GstPadProbeReturn __mmcamcorder_audio_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
{
static int count = 0;
/* to minimizing free space check overhead */
count = count % _MMCAMCORDER_FREE_SPACE_CHECK_INTERVAL;
if (count++ == 0) {
- gint free_space_ret = _mmcamcorder_get_freespace(filename, &free_space);
+ char *dir_name = g_path_get_dirname(filename);
+ gint free_space_ret = 0;
+
+ 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");*/
} else {
msg.param.code = MM_ERROR_FILE_READ;
}
- _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+ _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
} else {
sc->ferror_count++;
}
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; /* skip this buffer */
}
msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
msg.param.recording_status.filesize = (unsigned long long)((audioinfo->filesize + trailer_size) >> 10);
msg.param.recording_status.remained_time = 0;
- _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+ _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
_mmcam_dbg_warn("Last filesize sent by message : %d", audioinfo->filesize + trailer_size);
sc->isMaxsizePausing = TRUE;
msg.id = MM_MESSAGE_CAMCORDER_MAX_SIZE;
- _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+ _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
/* skip this buffer */
return GST_PAD_PROBE_DROP;
sc->isMaxtimePausing = TRUE;
msg.id = MM_MESSAGE_CAMCORDER_TIME_LIMIT;
- _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+ _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
/* skip this buffer */
return GST_PAD_PROBE_DROP;
msg.param.recording_status.elapsed = (unsigned long long)rec_pipe_time;
msg.param.recording_status.filesize = (unsigned long long)((audioinfo->filesize + trailer_size) >> 10);
msg.param.recording_status.remained_time = remained_time;
- _mmcamcroder_send_message((MMHandleType)hcamcorder, &msg);
+ _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
return GST_PAD_PROBE_OK;
} else {
return GST_PAD_PROBE_DROP;
}
}
+
+/* START TAG HERE */
+static gboolean __mmcamcorder_audio_add_metadata_info_m4a(MMHandleType handle)
+{
+ FILE *f = NULL;
+ guchar buf[4];
+ guint64 udta_size = 0;
+ gint64 current_pos = 0;
+ gint64 moov_pos = 0;
+ gint64 udta_pos = 0;
+ // supporting audio geo tag for mobile
+ int gps_enable = 0;
+ gdouble longitude = 0;
+ gdouble latitude = 0;
+ gdouble altitude = 0;
+ _MMCamcorderLocationInfo geo_info = {0,0,0};
+ _MMCamcorderLocationInfo loc_info = {0,0,0};
+
+ char err_msg[128] = {'\0',};
+
+ _MMCamcorderAudioInfo *info = NULL;
+ mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+ _MMCamcorderSubContext *sc = NULL;
+
+ mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+ sc = MMF_CAMCORDER_SUBCONTEXT(handle);
+
+ mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+ mmf_return_val_if_fail(sc->info_audio, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+
+ info = sc->info_audio;
+ mm_camcorder_get_attributes(handle, NULL,
+ MMCAM_TAG_GPS_ENABLE, &gps_enable,
+ NULL);
+
+ if (gps_enable) {
+ mm_camcorder_get_attributes(handle, NULL,
+ MMCAM_TAG_LATITUDE, &latitude,
+ MMCAM_TAG_LONGITUDE, &longitude,
+ MMCAM_TAG_ALTITUDE, &altitude,
+ NULL);
+ loc_info.longitude = _mmcamcorder_double_to_fix(longitude);
+ loc_info.latitude = _mmcamcorder_double_to_fix(latitude);
+ loc_info.altitude = _mmcamcorder_double_to_fix(altitude);
+ geo_info.longitude = longitude *10000;
+ geo_info.latitude = latitude *10000;
+ geo_info.altitude = altitude *10000;
+ }
+
+ f = fopen64(info->filename, "rb+");
+ if (f == NULL) {
+ strerror_r(errno, err_msg, 128);
+ _mmcam_dbg_err("file open failed [%s]", err_msg);
+ return FALSE;
+ }
+
+ /* find udta container.
+ if, there are udta container, write loci box after that
+ else, make udta container and write loci box. */
+ if (_mmcamcorder_find_fourcc(f, MMCAM_FOURCC('u','d','t','a'), TRUE)) {
+ size_t nread = 0;
+
+ _mmcam_dbg_log("find udta container");
+
+ /* read size */
+ if (fseek(f, -8L, SEEK_CUR) != 0) {
+ goto fail;
+ }
+
+ udta_pos = ftello(f);
+ if (udta_pos < 0) {
+ goto ftell_fail;
+ }
+
+ nread = fread(&buf, sizeof(char), sizeof(buf), f);
+
+ _mmcam_dbg_log("recorded file fread %d", nread);
+
+ udta_size = _mmcamcorder_get_container_size(buf);
+
+ /* goto end of udta and write 'smta' box */
+ if (fseek(f, (udta_size-4L), SEEK_CUR) != 0) {
+ goto fail;
+ }
+
+ if (gps_enable) {
+ if (!_mmcamcorder_write_loci(f, loc_info)) {
+ goto fail;
+ }
+
+ if (!_mmcamcorder_write_geodata( f, geo_info )) {
+ goto fail;
+ }
+ }
+
+ current_pos = ftello(f);
+ if (current_pos < 0) {
+ goto ftell_fail;
+ }
+
+ if (!_mmcamcorder_update_size(f, udta_pos, current_pos)) {
+ goto fail;
+ }
+ } else {
+ _mmcam_dbg_log("No udta container");
+ if (fseek(f, 0, SEEK_END) != 0) {
+ goto fail;
+ }
+
+ if (!_mmcamcorder_write_udta(f, gps_enable, loc_info, geo_info)) {
+ goto fail;
+ }
+ }
+
+ /* find moov container.
+ update moov container size. */
+ if((current_pos = ftello(f))<0)
+ goto ftell_fail;
+
+ if (_mmcamcorder_find_fourcc(f, MMCAM_FOURCC('m','o','o','v'), TRUE)) {
+
+ _mmcam_dbg_log("found moov container");
+ if (fseek(f, -8L, SEEK_CUR) !=0) {
+ goto fail;
+ }
+
+ moov_pos = ftello(f);
+ if (moov_pos < 0) {
+ goto ftell_fail;
+ }
+
+ if (!_mmcamcorder_update_size(f, moov_pos, current_pos)) {
+ goto fail;
+ }
+
+
+ } else {
+ _mmcam_dbg_err("No 'moov' container");
+ goto fail;
+ }
+
+ fclose(f);
+
+ return TRUE;
+
+fail:
+ fclose(f);
+ return FALSE;
+
+ftell_fail:
+ _mmcam_dbg_err("ftell() returns negative value.");
+ fclose(f);
+ return FALSE;
+}
+
+/* END TAG HERE */
+