From dbe5026107e9f3bf131bef297b6814c21bcab5e6 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Thu, 3 Sep 2015 18:00:19 +0900 Subject: [PATCH] Update code for capture in recording error handling Change-Id: I6727305b81e964c80855df7c141bd7a829e451c0 Signed-off-by: Jeongmo Yang --- src/include/mm_camcorder_internal.h | 1 + src/mm_camcorder_internal.c | 14 ++++++- src/mm_camcorder_stillshot.c | 19 ++++++--- src/mm_camcorder_util.c | 34 +++++++++++++++- src/mm_camcorder_videorec.c | 78 +++++++++++++++++++++++++------------ 5 files changed, 114 insertions(+), 32 deletions(-) diff --git a/src/include/mm_camcorder_internal.h b/src/include/mm_camcorder_internal.h index b9a44b8..4d1e072 100644 --- a/src/include/mm_camcorder_internal.h +++ b/src/include/mm_camcorder_internal.h @@ -513,6 +513,7 @@ typedef enum { _MMCAMCORDER_TASK_THREAD_STATE_SOUND_PLAY_START, _MMCAMCORDER_TASK_THREAD_STATE_SOUND_SOLO_PLAY_START, _MMCAMCORDER_TASK_THREAD_STATE_ENCODE_PIPE_CREATE, + _MMCAMCORDER_TASK_THREAD_STATE_CHECK_CAPTURE_IN_RECORDING, _MMCAMCORDER_TASK_THREAD_STATE_EXIT, } _MMCamcorderTaskThreadState; diff --git a/src/mm_camcorder_internal.c b/src/mm_camcorder_internal.c index 69e7bd8..eaf78d2 100644 --- a/src/mm_camcorder_internal.c +++ b/src/mm_camcorder_internal.c @@ -1309,7 +1309,19 @@ int _mmcamcorder_capture_start(MMHandleType handle) ret = MM_ERROR_CAMCORDER_DEVICE_BUSY; goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK; } else { - hcamcorder->capture_in_recording = TRUE; + pthread_mutex_lock(&(hcamcorder->task_thread_lock)); + if (hcamcorder->task_thread_state == _MMCAMCORDER_TASK_THREAD_STATE_NONE) { + hcamcorder->capture_in_recording = TRUE; + hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_CHECK_CAPTURE_IN_RECORDING; + _mmcam_dbg_log("send signal for capture in recording"); + pthread_cond_signal(&(hcamcorder->task_thread_cond)); + pthread_mutex_unlock(&(hcamcorder->task_thread_lock)); + } else { + _mmcam_dbg_err("task thread busy : %d", hcamcorder->task_thread_state); + pthread_mutex_unlock(&(hcamcorder->task_thread_lock)); + ret = MM_ERROR_CAMCORDER_INVALID_STATE; + goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK; + } } } diff --git a/src/mm_camcorder_stillshot.c b/src/mm_camcorder_stillshot.c index fb5fb8c..129d90b 100644 --- a/src/mm_camcorder_stillshot.c +++ b/src/mm_camcorder_stillshot.c @@ -1190,6 +1190,20 @@ static void __mmcamcorder_image_capture_cb(GstElement *element, GstSample *sampl } else if (!info->played_capture_sound) { _mmcamcorder_sound_solo_play((MMHandleType)hcamcorder, _MMCAMCORDER_FILEPATH_CAPTURE_SND, FALSE); } + } else { + /* Handle capture in recording case */ + hcamcorder->capture_in_recording = FALSE; + + pthread_mutex_lock(&(hcamcorder->task_thread_lock)); + + if (hcamcorder->task_thread_state == _MMCAMCORDER_TASK_THREAD_STATE_CHECK_CAPTURE_IN_RECORDING) { + _mmcam_dbg_log("send signal for capture in recording"); + pthread_cond_signal(&(hcamcorder->task_thread_cond)); + } else { + _mmcam_dbg_warn("unexpected task thread state : %d", hcamcorder->task_thread_state); + } + + pthread_mutex_unlock(&(hcamcorder->task_thread_lock)); } /* init capture data */ @@ -1627,11 +1641,6 @@ error: } } - /* Handle capture in recording case */ - if (hcamcorder->capture_in_recording) { - hcamcorder->capture_in_recording = FALSE; - } - _mmcam_dbg_err("END"); return; diff --git a/src/mm_camcorder_util.c b/src/mm_camcorder_util.c index 111e7b3..3c0b1a3 100644 --- a/src/mm_camcorder_util.c +++ b/src/mm_camcorder_util.c @@ -47,7 +47,8 @@ /*----------------------------------------------------------------------- | LOCAL VARIABLE DEFINITIONS for internal | -----------------------------------------------------------------------*/ -#define TIME_STRING_MAX_LEN 64 +#define TIME_STRING_MAX_LEN 64 +#define __MMCAMCORDER_CAPTURE_WAIT_TIMEOUT 5 #define FPUTC_CHECK(x_char, x_file)\ {\ @@ -1840,6 +1841,37 @@ void *_mmcamcorder_util_task_thread_func(void *data) _mmcam_dbg_log("_mmcamcorder_video_prepare_record return 0x%x", ret); hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_NONE; break; + case _MMCAMCORDER_TASK_THREAD_STATE_CHECK_CAPTURE_IN_RECORDING: + { + struct timespec timeout; + struct timeval tv; + + gettimeofday(&tv, NULL); + timeout.tv_sec = tv.tv_sec + __MMCAMCORDER_CAPTURE_WAIT_TIMEOUT; + timeout.tv_nsec = tv.tv_usec * 1000; + + _mmcam_dbg_warn("wait for capture data in recording. wait signal..."); + + if (!pthread_cond_timedwait(&(hcamcorder->task_thread_cond), &(hcamcorder->task_thread_lock), &timeout)) { + _mmcam_dbg_warn("signal received"); + } else { + _MMCamcorderMsgItem message; + + memset(&message, 0x0, sizeof(_MMCamcorderMsgItem)); + + _mmcam_dbg_err("capture data wait time out, send error message"); + + message.id = MM_MESSAGE_CAMCORDER_ERROR; + message.param.code = MM_ERROR_CAMCORDER_RESPONSE_TIMEOUT; + + _mmcamcorder_send_message((MMHandleType)hcamcorder, &message); + + hcamcorder->capture_in_recording = FALSE; + } + + hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_NONE; + } + break; default: _mmcam_dbg_warn("invalid task thread state %d", hcamcorder->task_thread_state); hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_EXIT; diff --git a/src/mm_camcorder_videorec.c b/src/mm_camcorder_videorec.c index 61868be..6a61fac 100644 --- a/src/mm_camcorder_videorec.c +++ b/src/mm_camcorder_videorec.c @@ -463,6 +463,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; @@ -828,8 +829,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; @@ -841,11 +840,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); } @@ -855,11 +854,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); } @@ -878,6 +877,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; @@ -945,12 +959,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; @@ -963,36 +976,48 @@ 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); } - - usleep(_MMCAMCORDER_FRAME_WAIT_TIME); } + + usleep(_MMCAMCORDER_FRAME_WAIT_TIME); } /* block push buffer */ @@ -1039,6 +1064,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: -- 2.7.4