From 52703ccf09070235d275963b605fa4c7b4ff9cd2 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Thu, 30 Jun 2016 17:31:27 +0900 Subject: [PATCH] [Release version 0.10.59] Update code for recording commit function - avoid time out of sound play EOS waiting Change-Id: I699e8bf9727a8809b9f57416b99529f49bb5de6a Signed-off-by: Jeongmo Yang --- packaging/libmm-camcorder.spec | 2 +- src/include/mm_camcorder_internal.h | 8 +-- src/mm_camcorder_audiorec.c | 2 +- src/mm_camcorder_gstcommon.c | 101 ++++++++----------------------- src/mm_camcorder_internal.c | 117 ++++++++++++++++++++++++++---------- src/mm_camcorder_videorec.c | 3 + 6 files changed, 121 insertions(+), 112 deletions(-) diff --git a/packaging/libmm-camcorder.spec b/packaging/libmm-camcorder.spec index 7673b34..de98d1d 100644 --- a/packaging/libmm-camcorder.spec +++ b/packaging/libmm-camcorder.spec @@ -2,7 +2,7 @@ Name: libmm-camcorder Summary: Camera and recorder library -Version: 0.10.58 +Version: 0.10.59 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_camcorder_internal.h b/src/include/mm_camcorder_internal.h index 5cd6fca..77e1099 100644 --- a/src/include/mm_camcorder_internal.h +++ b/src/include/mm_camcorder_internal.h @@ -1160,21 +1160,21 @@ gboolean _mmcamcorder_pipeline_cb_message(GstBus *bus, GstMessage *message, gpoi GstBusSyncReply _mmcamcorder_pipeline_bus_sync_callback(GstBus *bus, GstMessage *message, gpointer data); /** - * This function is callback function of main pipeline. + * This function is callback function of encode pipeline. * Once this function is registered with certain pipeline using gst_bus_set_sync_handler(), * this callback will be called every time when there is upcomming message from pipeline. - * Basically, this function is used as sync error handling function, now. + * Basically, this function is used for EOS and error handling now. * * @param[in] bus pointer of buf that called this function. * @param[in] message callback message from pipeline. * @param[in] data user data. * @return This function returns true on success, or false value with error * @remarks + * @see __mmcamcorder_create_recorder_pipeline() * @see __mmcamcorder_create_audiop_with_encodebin() * */ -GstBusSyncReply _mmcamcorder_audio_pipeline_bus_sync_callback(GstBus *bus, GstMessage *message, gpointer data); - +GstBusSyncReply _mmcamcorder_encode_pipeline_bus_sync_callback(GstBus *bus, GstMessage *message, gpointer data); /** * This function create main pipeline according to type. diff --git a/src/mm_camcorder_audiorec.c b/src/mm_camcorder_audiorec.c index 4cfbb72..db7c319 100644 --- a/src/mm_camcorder_audiorec.c +++ b/src/mm_camcorder_audiorec.c @@ -209,7 +209,7 @@ static int __mmcamcorder_create_audiop_with_encodebin(MMHandleType handle) 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, _mmcamcorder_audio_pipeline_bus_sync_callback, hcamcorder, NULL); + gst_bus_set_sync_handler(bus, _mmcamcorder_encode_pipeline_bus_sync_callback, hcamcorder, NULL); gst_object_unref(bus); bus = NULL; diff --git a/src/mm_camcorder_gstcommon.c b/src/mm_camcorder_gstcommon.c index a5efb16..ac17df3 100644 --- a/src/mm_camcorder_gstcommon.c +++ b/src/mm_camcorder_gstcommon.c @@ -1908,12 +1908,7 @@ int __mmcamcorder_get_amrnb_bitrate_mode(int bitrate) int _mmcamcorder_get_eos_message(MMHandleType handle) { - double elapsed = 0.0; - - GstMessage *gMessage = NULL; - GstBus *bus = NULL; - GstClockTime timeout = 1 * GST_SECOND; /* maximum waiting time */ - GTimer *timer = NULL; + int64_t end_time; int ret = MM_ERROR_NONE; mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle); @@ -1923,84 +1918,40 @@ int _mmcamcorder_get_eos_message(MMHandleType handle) sc = MMF_CAMCORDER_SUBCONTEXT(handle); mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED); - _mmcam_dbg_log(""); + _mmcam_dbg_log("START"); - bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst)); - timer = g_timer_new(); + _MMCAMCORDER_LOCK(handle); - if (sc && !(sc->bget_eos)) { - while (TRUE) { - elapsed = g_timer_elapsed(timer, NULL); + if (sc->bget_eos == FALSE) { + end_time = g_get_monotonic_time() + 3 * G_TIME_SPAN_SECOND; + if (_MMCAMCORDER_WAIT_UNTIL(handle, end_time)) { + _mmcam_dbg_log("EOS signal received"); + } else { + _mmcam_dbg_err("EOS wait time out"); + } + } else { + _mmcam_dbg_log("already got EOS"); + } - /*_mmcam_dbg_log("elapsed:%f sec", elapsed);*/ + _MMCAMCORDER_UNLOCK(handle); - if (elapsed > _MMCAMCORDER_WAIT_EOS_TIME) { - _mmcam_dbg_warn("Timeout. EOS isn't received."); - ret = MM_ERROR_CAMCORDER_RESPONSE_TIMEOUT; - break; + if (hcamcorder->error_code == MM_ERROR_NONE) { + if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) { + mmf_return_val_if_fail(sc->info_video, MM_ERROR_CAMCORDER_NOT_INITIALIZED); + if (sc->info_video->b_commiting) { + _mmcamcorder_video_handle_eos((MMHandleType)hcamcorder); } - - gMessage = gst_bus_timed_pop(bus, timeout); - if (gMessage != NULL) { - _mmcam_dbg_log("Get message(%x).", GST_MESSAGE_TYPE(gMessage)); - - if (GST_MESSAGE_TYPE(gMessage) == GST_MESSAGE_ERROR) { - GError *err; - gchar *debug; - gst_message_parse_error(gMessage, &err, &debug); - - switch (err->code) { - case GST_RESOURCE_ERROR_WRITE: - _mmcam_dbg_err("File write error"); - ret = MM_ERROR_FILE_WRITE; - break; - case GST_RESOURCE_ERROR_NO_SPACE_LEFT: - _mmcam_dbg_err("No left space"); - ret = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE; - break; - case GST_RESOURCE_ERROR_OPEN_WRITE: - _mmcam_dbg_err("Out of storage"); - ret = MM_ERROR_OUT_OF_STORAGE; - break; - case GST_RESOURCE_ERROR_SEEK: - _mmcam_dbg_err("File read(seek)"); - ret = MM_ERROR_FILE_READ; - break; - default: - _mmcam_dbg_err("Resource error(%d)", err->code); - ret = MM_ERROR_CAMCORDER_GST_RESOURCE; - break; - } - - g_error_free (err); - g_free (debug); - - gst_message_unref(gMessage); - break; - } - - _mmcamcorder_pipeline_cb_message(bus, gMessage, (void*)hcamcorder); - - if (GST_MESSAGE_TYPE(gMessage) == GST_MESSAGE_EOS || sc->bget_eos) { - gst_message_unref(gMessage); - break; - } - gst_message_unref(gMessage); - } else { - _mmcam_dbg_log("timeout of gst_bus_timed_pop()"); - if (sc->bget_eos) { - _mmcam_dbg_log("Get EOS in another thread."); - break; - } + } else { + mmf_return_val_if_fail(sc->info_audio, MM_ERROR_CAMCORDER_NOT_INITIALIZED); + if (sc->info_audio->b_commiting) { + _mmcamcorder_audio_handle_eos((MMHandleType)hcamcorder); } } + } else { + ret = hcamcorder->error_code; + _mmcam_dbg_err("error 0x%x", ret); } - g_timer_destroy(timer); - timer = NULL; - gst_object_unref(bus); - bus = NULL; - _mmcam_dbg_log("END"); return ret; diff --git a/src/mm_camcorder_internal.c b/src/mm_camcorder_internal.c index 870347a..80783a6 100644 --- a/src/mm_camcorder_internal.c +++ b/src/mm_camcorder_internal.c @@ -1911,6 +1911,9 @@ int _mmcamcorder_commit(MMHandleType handle) goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK; } + /* initialize error code */ + hcamcorder->error_code = MM_ERROR_NONE; + ret = hcamcorder->command((MMHandleType)hcamcorder, _MMCamcorder_CMD_COMMIT); if (ret != MM_ERROR_NONE) { goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK; @@ -2774,26 +2777,8 @@ gboolean _mmcamcorder_pipeline_cb_message(GstBus *bus, GstMessage *message, gpoi break; case GST_MESSAGE_EOS: { - _mmcam_dbg_log ("Got EOS from element \"%s\".", - GST_STR_NULL(GST_ELEMENT_NAME(GST_MESSAGE_SRC(message)))); - - sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder); - mmf_return_val_if_fail(sc, TRUE); - - if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) { - mmf_return_val_if_fail(sc->info_video, TRUE); - if (sc->info_video->b_commiting) { - _mmcamcorder_video_handle_eos((MMHandleType)hcamcorder); - } - } else { - mmf_return_val_if_fail(sc->info_audio, TRUE); - if (sc->info_audio->b_commiting) { - _mmcamcorder_audio_handle_eos((MMHandleType)hcamcorder); - } - } - - sc->bget_eos = TRUE; - + _mmcam_dbg_err("Got EOS from element \"%s\"... but should not be reached here!", + GST_STR_NULL(GST_ELEMENT_NAME(GST_MESSAGE_SRC(message)))); break; } case GST_MESSAGE_ERROR: @@ -3121,8 +3106,7 @@ GstBusSyncReply _mmcamcorder_pipeline_bus_sync_callback(GstBus *bus, GstMessage int capture_done = FALSE; if (gst_structure_get_int(gst_message_get_structure(message), "capture-done", &capture_done)) { - sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder); - if (sc && sc->info_image) { + if (sc->info_image) { /* play capture sound */ _mmcamcorder_sound_solo_play((MMHandleType)hcamcorder, _MMCAMCORDER_SAMPLE_SOUND_NAME_CAPTURE01, FALSE); } @@ -3133,6 +3117,7 @@ GstBusSyncReply _mmcamcorder_pipeline_bus_sync_callback(GstBus *bus, GstMessage } return GST_BUS_PASS; + DROP_MESSAGE: gst_message_unref(message); message = NULL; @@ -3141,7 +3126,7 @@ DROP_MESSAGE: } -GstBusSyncReply _mmcamcorder_audio_pipeline_bus_sync_callback(GstBus *bus, GstMessage *message, gpointer data) +GstBusSyncReply _mmcamcorder_encode_pipeline_bus_sync_callback(GstBus *bus, GstMessage *message, gpointer data) { GstElement *element = NULL; GError *err = NULL; @@ -3156,7 +3141,20 @@ GstBusSyncReply _mmcamcorder_audio_pipeline_bus_sync_callback(GstBus *bus, GstMe sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder); mmf_return_val_if_fail(sc, GST_BUS_PASS); - if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) { + if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_EOS) { + _mmcam_dbg_log("got EOS from pipeline"); + + _MMCAMCORDER_LOCK(hcamcorder); + + sc->bget_eos = TRUE; + _MMCAMCORDER_SIGNAL(hcamcorder); + + _MMCAMCORDER_UNLOCK(hcamcorder); + + goto DROP_MESSAGE; + } else if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) { + _MMCamcorderMsgItem msg; + /* parse error message */ gst_message_parse_error(message, &err, &debug_info); @@ -3174,11 +3172,9 @@ GstBusSyncReply _mmcamcorder_audio_pipeline_bus_sync_callback(GstBus *bus, GstMe /* set videosrc element to compare */ element = GST_ELEMENT_CAST(sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst); - /* check domain[RESOURCE] and element[VIDEOSRC] */ + /* check domain[RESOURCE] and element[AUDIOSRC] */ if (err->domain == GST_RESOURCE_ERROR && GST_ELEMENT_CAST(message->src) == element) { - _MMCamcorderMsgItem msg; - switch (err->code) { case GST_RESOURCE_ERROR_OPEN_READ_WRITE: case GST_RESOURCE_ERROR_OPEN_WRITE: @@ -3195,20 +3191,79 @@ GstBusSyncReply _mmcamcorder_audio_pipeline_bus_sync_callback(GstBus *bus, GstMe _mmcam_dbg_err(" error : sc->error_occurs %d", hcamcorder->error_occurs); - g_error_free(err); - gst_message_unref(message); - message = NULL; + goto DROP_MESSAGE; + default: + break; + } + } else { + gboolean b_commiting = FALSE; - return GST_BUS_DROP; + if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) { + mmf_return_val_if_fail(sc->info_video, GST_BUS_PASS); + b_commiting = sc->info_video->b_commiting; + } else { + mmf_return_val_if_fail(sc->info_audio, GST_BUS_PASS); + b_commiting = sc->info_audio->b_commiting; + } + + _MMCAMCORDER_LOCK(hcamcorder); + + switch (err->code) { + case GST_RESOURCE_ERROR_WRITE: + _mmcam_dbg_err("File write error"); + hcamcorder->error_code = MM_ERROR_FILE_WRITE; + break; + case GST_RESOURCE_ERROR_NO_SPACE_LEFT: + _mmcam_dbg_err("No left space"); + hcamcorder->error_code = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE; + break; + case GST_RESOURCE_ERROR_OPEN_WRITE: + _mmcam_dbg_err("Out of storage"); + hcamcorder->error_code = MM_ERROR_OUT_OF_STORAGE; + break; + case GST_RESOURCE_ERROR_SEEK: + _mmcam_dbg_err("File read(seek)"); + hcamcorder->error_code = MM_ERROR_FILE_READ; + break; default: + _mmcam_dbg_err("Resource error(%d)", err->code); + hcamcorder->error_code = MM_ERROR_CAMCORDER_GST_RESOURCE; break; } + + if (b_commiting) { + _MMCAMCORDER_SIGNAL(hcamcorder); + _MMCAMCORDER_UNLOCK(hcamcorder); + } else { + _MMCAMCORDER_UNLOCK(hcamcorder); + + msg.id = MM_MESSAGE_CAMCORDER_ERROR; + msg.param.code = hcamcorder->error_code; + + _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg); + } } + goto DROP_MESSAGE; + } + + if (err) { g_error_free(err); + err = NULL; } return GST_BUS_PASS; + +DROP_MESSAGE: + if (err) { + g_error_free(err); + err = NULL; + } + + gst_message_unref(message); + message = NULL; + + return GST_BUS_DROP; } diff --git a/src/mm_camcorder_videorec.c b/src/mm_camcorder_videorec.c index 5bf1f7c..47fcb39 100644 --- a/src/mm_camcorder_videorec.c +++ b/src/mm_camcorder_videorec.c @@ -288,6 +288,9 @@ int _mmcamcorder_create_recorder_pipeline(MMHandleType handle) /* register pipeline message callback */ hcamcorder->encode_pipeline_cb_event_id = gst_bus_add_watch(bus, (GstBusFunc)_mmcamcorder_pipeline_cb_message, hcamcorder); + /* set sync handler */ + gst_bus_set_sync_handler(bus, _mmcamcorder_encode_pipeline_bus_sync_callback, (gpointer)hcamcorder, NULL); + gst_object_unref(bus); bus = NULL; -- 2.7.4