#define _MMCAMCORDER_FRAME_WAIT_TIME 200000 /* ms */
#define _OFFSET_COMPOSITION_MATRIX 40L
#define _GOP_GEN_INTERVAL 1000000000 /*nano seconds*/
+#define _MMCAMCORDER_VIDEO_MINIMUM_SPACE (_MMCAMCORDER_MINIMUM_SPACE << 1) /* byte */
/*---------------------------------------------------------------------------------------
| LOCAL FUNCTION PROTOTYPES: |
{
int i = 0;
int err = MM_ERROR_NONE;
- int audio_disable = FALSE;
const char* gst_element_rsink_name = NULL;
GstBus *bus = NULL;
/* get audio disable */
mm_camcorder_get_attributes(handle, NULL,
- MMCAM_AUDIO_DISABLE, &audio_disable,
+ MMCAM_AUDIO_DISABLE, &sc->audio_disable,
NULL);
- if (sc->is_modified_rate || audio_disable)
- sc->audio_disable = TRUE;
- else
- sc->audio_disable = FALSE;
+ _mmcam_dbg_log("MMCAM_AUDIO_DISABLE %d, is_modified_rate %d",
+ sc->audio_disable, sc->is_modified_rate);
- _mmcam_dbg_log("AUDIO DISABLE : %d (is_modified_rate %d, audio_disable %d)",
- sc->audio_disable, sc->is_modified_rate, audio_disable);
+ sc->audio_disable |= sc->is_modified_rate;
if (sc->audio_disable == FALSE) {
/* create audiosrc bin */
&RecordsinkElement);
_mmcamcorder_conf_get_value_element_name(RecordsinkElement, &gst_element_rsink_name);
+ if (!gst_element_rsink_name) {
+ _mmcam_dbg_err("failed to get recordsink name");
+ err = MM_ERROR_CAMCORDER_INTERNAL;
+ goto pipeline_creation_error;
+ }
+
/* set data probe function */
/* register message cb */
GstPad *reqpad = NULL;
mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
_MMCamcorderSubContext *sc = NULL;
+#ifdef _MMCAMCORDER_MM_RM_SUPPORT
+ int ret = MM_ERROR_NONE;
+#endif /* _MMCAMCORDER_MM_RM_SUPPORT */
mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
/* _mmcamcorder_remove_element_handle(handle, (void *)sc->encode_element,
_MMCAMCORDER_ENCODE_MAIN_PIPE, _MMCAMCORDER_ENCSINK_SINK); */
- _mmcam_dbg_log("Encoder pipeline removed");
+ _mmcam_dbg_warn("Encoder pipeline removed");
+
+#ifdef _MMCAMCORDER_MM_RM_SUPPORT
+ _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
+
+ _mmcam_dbg_warn("lock resource - cb calling %d", hcamcorder->is_release_cb_calling);
+
+ if (hcamcorder->is_release_cb_calling == FALSE) {
+ /* release resource */
+ ret = mm_resource_manager_mark_for_release(hcamcorder->resource_manager,
+ hcamcorder->video_encoder_resource);
+ if (ret == MM_RESOURCE_MANAGER_ERROR_NONE)
+ hcamcorder->video_encoder_resource = NULL;
+
+ _mmcam_dbg_warn("mark resource for release 0x%x", ret);
+
+ ret = mm_resource_manager_commit(hcamcorder->resource_manager);
+
+ _mmcam_dbg_warn("commit resource release 0x%x", ret);
+ }
+
+ _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+
+ _mmcam_dbg_warn("unlock resource");
+#endif /* _MMCAMCORDER_MM_RM_SUPPORT */
}
return MM_ERROR_NONE;
/* Recording */
_mmcam_dbg_log("Record Start - dual stream %d", info->support_dual_stream);
+#ifdef _MMCAMCORDER_MM_RM_SUPPORT
+ _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
+
+ /* prepare resource manager for H/W encoder */
+ if (hcamcorder->video_encoder_resource == NULL) {
+ ret = mm_resource_manager_mark_for_acquire(hcamcorder->resource_manager,
+ MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER,
+ MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
+ &hcamcorder->video_encoder_resource);
+ if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+ _mmcam_dbg_err("could not prepare for encoder resource");
+ ret = MM_ERROR_RESOURCE_INTERNAL;
+ _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+ goto _ERR_CAMCORDER_VIDEO_COMMAND;
+ }
+ } else {
+ _mmcam_dbg_log("encoder already acquired");
+ }
+
+ /* acquire resources */
+ ret = mm_resource_manager_commit(hcamcorder->resource_manager);
+ if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+ _mmcam_dbg_err("could not acquire resources");
+ ret = MM_ERROR_RESOURCE_INTERNAL;
+ _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+ goto _ERR_CAMCORDER_VIDEO_COMMAND;
+ }
+
+ _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+#endif /* _MMCAMCORDER_MM_RM_SUPPORT */
+
/* init record_dual_stream */
info->record_dual_stream = FALSE;
goto _ERR_CAMCORDER_VIDEO_COMMAND;
}
- if (temp_filename == NULL) {
- _mmcam_dbg_err("filename is not set");
+ if (!temp_filename && !hcamcorder->mstream_cb) {
+ _mmcam_dbg_err("filename is not set and muxed stream cb is NULL");
ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
goto _ERR_CAMCORDER_VIDEO_COMMAND;
}
if (imax_time <= 0)
info->max_time = 0; /* do not check */
else
- info->max_time = ((guint64)imax_time) * 1000; /* to millisecond */
+ info->max_time = (guint64)((double)imax_time * (double)1000 * motion_rate); /* to millisecond */
dir_name = g_path_get_dirname(temp_filename);
if (dir_name) {
/* MSDOS_SUPER_MAGIC : 0x4d44 */
if (file_system_type == MSDOS_SUPER_MAGIC &&
(info->max_size == 0 || info->max_size > FAT32_FILE_SYSTEM_MAX_SIZE)) {
- _mmcam_dbg_warn("FAT32 and too large max[%"G_GUINT64_FORMAT"], set max as %"G_GUINT64_FORMAT,
+ _mmcam_dbg_warn("FAT32 and too large max[%"G_GUINT64_FORMAT"], set max as %lu",
info->max_size, FAT32_FILE_SYSTEM_MAX_SIZE);
info->max_size = FAT32_FILE_SYSTEM_MAX_SIZE;
} else {
ret_free_space = -1;
}
- if ((ret_free_space == -1) || free_space <= (_MMCAMCORDER_MINIMUM_SPACE<<1)) {
+ if (temp_filename &&
+ (ret_free_space == -1 || free_space <= _MMCAMCORDER_VIDEO_MINIMUM_SPACE)) {
_mmcam_dbg_err("OUT of STORAGE [ret_free_space:%d or free space [%" G_GUINT64_FORMAT "] is smaller than [%d]",
- ret_free_space, free_space, (_MMCAMCORDER_MINIMUM_SPACE<<1));
+ ret_free_space, free_space, _MMCAMCORDER_VIDEO_MINIMUM_SPACE);
return MM_ERROR_OUT_OF_STORAGE;
}
}
case _MMCamcorder_CMD_COMMIT:
{
+ guint64 free_space;
+
if (info->b_commiting) {
_mmcam_dbg_err("now on commiting previous file!!(command : %d)", command);
return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
if (hcamcorder->capture_in_recording) {
gint64 end_time = g_get_monotonic_time() + (200 * G_TIME_SPAN_MILLISECOND);
- if (_MMCAMCORDER_CMD_WAIT_UNTIL(handle, end_time)) {
- _mmcam_dbg_warn("signal received");
- } else {
+ if (!_MMCAMCORDER_CMD_WAIT_UNTIL(handle, end_time))
_mmcam_dbg_warn("timeout");
- }
} else {
usleep(_MMCAMCORDER_FRAME_WAIT_TIME);
}
info->push_encoding_buffer = PUSH_ENCODING_BUFFER_STOP;
_mmcam_dbg_log("block push buffer to appsrc");
+ _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
+ if (free_space < _MMCAMCORDER_MINIMUM_SPACE) {
+ _mmcam_dbg_warn("_MMCamcorder_CMD_COMMIT out of storage [%" G_GUINT64_FORMAT "]", free_space);
+ ret = MM_ERROR_OUT_OF_STORAGE;
+ goto _ERR_CAMCORDER_VIDEO_COMMAND;
+ }
+
if (sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst != NULL) {
if (gst_element_send_event(sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst, gst_event_new_eos())) {
_mmcam_dbg_warn("VIDEO: send eos to appsrc done");
_mmcam_dbg_err("");
- if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_FOCUS) {
- /* Play record stop sound */
- _mmcamcorder_sound_solo_play(handle, _MMCAMCORDER_SAMPLE_SOUND_NAME_REC_STOP, FALSE);
- } else {
- _mmcam_dbg_warn("Play stop sound through pulseaudio");
-
- _mmcamcorder_sound_init(handle);
-
- _mmcamcorder_sound_play((MMHandleType)hcamcorder, _MMCAMCORDER_SAMPLE_SOUND_NAME_REC_STOP, TRUE);
-
- _mmcamcorder_sound_finalize(handle);
- }
+ /* Play record stop sound */
+ _mmcamcorder_sound_solo_play(handle, _MMCAMCORDER_SAMPLE_SOUND_NAME_REC_STOP, FALSE);
/* remove blocking part */
MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", FALSE);
if (enabletag && !(sc->ferror_send)) {
ret = __mmcamcorder_add_metadata((MMHandleType)hcamcorder, info->fileformat);
- if (ret) {
- _mmcam_dbg_log("Writing location information SUCCEEDED !!");
- } else {
- _mmcam_dbg_err("Writing location information FAILED !!");
- }
+ _mmcam_dbg_log("Writing location information [%s] !!", ret ? "SUCCEEDED" : "FAILED");
}
/* Check file size */
info->restart_preview = FALSE;
/* recover preview size */
- _mmcamcorder_set_camera_resolution(handle, info->preview_width, info->preview_height);
+ if (!_mmcamcorder_set_camera_resolution(handle, info->preview_width, info->preview_height)) {
+ msg.id = MM_MESSAGE_CAMCORDER_ERROR;
+ msg.param.code = MM_ERROR_CAMCORDER_INTERNAL;
+ _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
+ _mmcam_dbg_err("Failed to set camera resolution %dx%d",
+ info->preview_width, info->preview_height);
+ }
ret = _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_MAIN_PIPE].gst, GST_STATE_PLAYING);
/* Do not return when error is occurred.
info->filesize = 0;
info->b_commiting = FALSE;
- if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_FOCUS) {
- /* check recording stop sound */
- _mmcamcorder_sound_solo_play_wait(handle);
- }
+ /* check recording stop sound */
+ _mmcamcorder_sound_solo_play_wait(handle);
_mmcam_dbg_err("_MMCamcorder_CMD_COMMIT : end");
}
/* get trailer size */
- if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4) {
+ if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4)
MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
- } else {
+ else
trailer_size = 0;
- }
/* check max size of recorded file */
max_size = videoinfo->filesize + buffer_size + trailer_size + _MMCAMCORDER_MMS_MARGIN_SPACE;
}
/* get trailer size */
- if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4) {
+ if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4)
MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
- } else {
+ else
trailer_size = 0;
- }
/* check free space */
ret = _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
}
/* get queued buffer size */
- if (sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst) {
+ if (sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst)
MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst, "current-level-bytes", &aq_size);
- }
- if (sc->encode_element[_MMCAMCORDER_ENCSINK_VENC_QUE].gst) {
+ if (sc->encode_element[_MMCAMCORDER_ENCSINK_VENC_QUE].gst)
MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_VENC_QUE].gst, "current-level-bytes", &vq_size);
- }
queued_buffer = aq_size + vq_size;
rec_pipe_time = GST_TIME_AS_MSECONDS(b_time);
- if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4) {
+ if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4)
MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
- } else {
+ else
trailer_size = 0;
- }
/* check max time */
if (videoinfo->max_time > 0 && rec_pipe_time > videoinfo->max_time) {
- _mmcam_dbg_warn("Current time : [%" G_GUINT64_FORMAT "], Maximum time : [%" G_GUINT64_FORMAT "]", \
- rec_pipe_time, videoinfo->max_time);
+ _mmcam_dbg_warn("Time current [%" G_GUINT64_FORMAT "], Max [%" G_GUINT64_FORMAT "], motion rate [%lf]", \
+ rec_pipe_time, videoinfo->max_time, videoinfo->record_motion_rate);
if (!sc->isMaxtimePausing) {
MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
rec_pipe_time = GST_TIME_AS_MSECONDS(GST_BUFFER_PTS(buffer));
- if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4) {
+ if (videoinfo->fileformat == MM_FILE_FORMAT_3GP || videoinfo->fileformat == MM_FILE_FORMAT_MP4)
MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_MUX].gst, "expected-trailer-size", &trailer_size);
- } else {
+ else
trailer_size = 0;
- }
/* calculate remained time can be recorded */
if (videoinfo->max_time > 0 && videoinfo->max_time < (remained_time + rec_pipe_time)) {
}
if (videoinfo->max_time > 0 && rec_pipe_time > videoinfo->max_time) {
- _mmcam_dbg_warn("Current time : [%" G_GUINT64_FORMAT "], Maximum time : [%" G_GUINT64_FORMAT "]", \
- rec_pipe_time, videoinfo->max_time);
+ _mmcam_dbg_warn("Time current [%" G_GUINT64_FORMAT "], Max [%" G_GUINT64_FORMAT "], motion rate [%lf]", \
+ rec_pipe_time, videoinfo->max_time, videoinfo->record_motion_rate);
if (!sc->isMaxtimePausing) {
MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
/* add orientation info */
if (fseeko(f, internal_pos, SEEK_SET) < 0) {
- _mmcam_dbg_err("fseek failed : errno %d", errno);
+ _mmcam_dbg_err("fseeko failed : errno %d", errno);
goto fail;
}
_mmcam_dbg_log("found [tkhd] tag");
/* seek to start position of composition matrix */
- fseek(f, _OFFSET_COMPOSITION_MATRIX, SEEK_CUR);
-
- /* update composition matrix for orientation */
- _mmcamcorder_update_composition_matrix(f, orientation);
+ if (fseek(f, _OFFSET_COMPOSITION_MATRIX, SEEK_CUR) == 0) {
+ /* update composition matrix for orientation */
+ _mmcamcorder_update_composition_matrix(f, orientation);
+ } else {
+ _mmcam_dbg_err("fseek failed : errno %d", errno);
+ goto fail;
+ }
} else {
_mmcam_dbg_err("No 'moov' container");
goto fail;
int _mmcamcorder_video_prepare_record(MMHandleType handle)
{
int ret = MM_ERROR_NONE;
+ int size = 0;
+ char *temp_filename = NULL;
_MMCamcorderVideoInfo *info = NULL;
_MMCamcorderSubContext *sc = NULL;
if (ret != MM_ERROR_NONE)
goto _ERR_PREPARE_RECORD;
- if (info->filename == NULL) {
- char *temp_filename = NULL;
- int size = 0;
-
- mm_camcorder_get_attributes(handle, NULL,
- MMCAM_TARGET_FILENAME, &temp_filename, &size,
- NULL);
- if (temp_filename)
- info->filename = g_strdup(temp_filename);
+ SAFE_G_FREE(info->filename);
+ mm_camcorder_get_attributes(handle, NULL,
+ MMCAM_TARGET_FILENAME, &temp_filename, &size,
+ NULL);
+ if (temp_filename) {
+ info->filename = g_strdup(temp_filename);
if (!info->filename) {
_mmcam_dbg_err("strdup[src:%p] was failed", temp_filename);
goto _ERR_PREPARE_RECORD;
}
- }
- _mmcam_dbg_log("Record file name [%s]", info->filename);
+ _mmcam_dbg_log("Record file name [%s]", info->filename);
+ MMCAMCORDER_G_OBJECT_SET_POINTER(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, "location", info->filename);
+ } else {
+ _mmcam_dbg_log("Recorded data will be written in [%s]", _MMCamcorder_FILENAME_NULL);
+ MMCAMCORDER_G_OBJECT_SET_POINTER(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, "location", _MMCamcorder_FILENAME_NULL);
+ }
- MMCAMCORDER_G_OBJECT_SET_POINTER(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, "location", info->filename);
MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", 0);
/* Adjust display FPS */