From: Jeongmo Yang Date: Tue, 23 Jan 2024 02:01:49 +0000 (+0900) Subject: Support videofilter2 element and preview callback for it X-Git-Tag: accepted/tizen/unified/20240701.191820^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c2b562e0b2ffd47eca538c6fd2e8f564f66a84e9;p=platform%2Fcore%2Fmultimedia%2Flibmm-camcorder.git Support videofilter2 element and preview callback for it - The added preview callback is used for new internal API : camera_set_media_packet_preview_internal_cb() - Clean up code for video stream callback [Version] 1.1.0 [Issue Type] New feature Change-Id: I3f03bc570cab07cb1674193f62085a21f348ed68 Signed-off-by: Jeongmo Yang --- diff --git a/packaging/libmm-camcorder.spec b/packaging/libmm-camcorder.spec index 8ef8884..cd0770c 100755 --- a/packaging/libmm-camcorder.spec +++ b/packaging/libmm-camcorder.spec @@ -1,6 +1,6 @@ Name: libmm-camcorder Summary: Camera and recorder library -Version: 1.0.1 +Version: 1.1.0 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_camcorder.h b/src/include/mm_camcorder.h index 9f6ec75..400c16f 100644 --- a/src/include/mm_camcorder.h +++ b/src/include/mm_camcorder.h @@ -1258,6 +1258,11 @@ extern "C" { */ #define MMCAM_SUPPORT_MEDIA_PACKET_PREVIEW_CB "support-media-packet-preview-cb" +/** +* Support media packet internal callback +*/ +#define MMCAM_SUPPORT_MEDIA_PACKET_PREVIEW_INTERNAL_CB "support-media-packet-preview-internal-cb" + /** * Support user buffer for zero copy */ @@ -1380,6 +1385,11 @@ extern "C" { */ #define MMCAM_EXTRA_PREVIEW_ENABLE "extra-preview-enable" +/** + * Flag for video stream callback + */ +#define MMCAM_VIDEO_STREAM_CALLBACK_FLAG "video-stream-callback-flag" + /*======================================================================================= @@ -1734,6 +1744,24 @@ enum MMCamcorderLogLevel { MM_CAMCORDER_LOG_LEVEL_VERBOSE }; +/** + * An enumeration for flag of video stream callback + */ +enum MMCamcorderVideoStreamCallbackFlag { + MM_CAMCORDER_VIDEO_STREAM_CALLBACK_FLAG_NONE = 0x00000000, /**< No preview callback */ + MM_CAMCORDER_VIDEO_STREAM_CALLBACK_FLAG_NORMAL = 0x0000000F, /**< Normal preview callback */ + MM_CAMCORDER_VIDEO_STREAM_CALLBACK_FLAG_INTERNAL = 0x000000F0 /**< Internal preview callback */ +}; + +/** + * An enumeration for video stream id + */ +enum MMCamcorderVideoStreamID { + MM_CAMCORDER_VIDEO_STREAM_ID_INTERNAL = -3, /**< Stream ID for internal preview */ + MM_CAMCORDER_VIDEO_STREAM_ID_NORMAL = -1, /**< Stream ID for normal preview */ + MM_CAMCORDER_VIDEO_STREAM_ID_EXTRA_MIN = 0 /**< Minimum stream ID for extra preview */ +}; + /********************************** * Attribute info * @@ -3531,6 +3559,9 @@ int mm_camcorder_manage_external_storage_state(MMHandleType camcorder, int stora /* get log level */ int mm_camcorder_get_log_level(void); +/* video stream callback */ +int mm_camcorder_set_video_stream_callback_flag(MMHandleType camcorder, gboolean enable, int flag); + /* extra preview */ int mm_camcorder_set_extra_preview_device_type(MMHandleType camcorder, int stream_id, int device_type); int mm_camcorder_set_extra_preview_stream_format(MMHandleType camcorder, int stream_id, int pixel_format, int width, int height, int fps); diff --git a/src/include/mm_camcorder_attribute.h b/src/include/mm_camcorder_attribute.h index 9bd5f5c..7015e4d 100644 --- a/src/include/mm_camcorder_attribute.h +++ b/src/include/mm_camcorder_attribute.h @@ -198,7 +198,9 @@ typedef enum { MM_CAM_CAMERA_FOCUS_LEVEL, /* 140 */ MM_CAM_SUPPORT_EXTRA_PREVIEW, MM_CAM_REQUEST_CODEC_CONFIG, - MM_CAM_FILTER_WB_TEMPERATURE, + MM_CAM_SUPPORT_MEDIA_PACKET_PREVIEW_INTERNAL_CB, + MM_CAM_VIDEO_STREAM_CALLBACK_FLAG, + MM_CAM_FILTER_WB_TEMPERATURE, /* 145 */ MM_CAM_FILTER_WB_TEMPERATURE_STEP, MM_CAM_CAMERA_GAIN, MM_CAM_CAMERA_GAIN_STEP, diff --git a/src/include/mm_camcorder_configure.h b/src/include/mm_camcorder_configure.h index 26c9df6..8b265cc 100644 --- a/src/include/mm_camcorder_configure.h +++ b/src/include/mm_camcorder_configure.h @@ -47,6 +47,7 @@ do { \ #define CONFIGURE_MAIN_FILE "mmfw_camcorder.ini" #define CONFIGURE_CTRL_FILE_PREFIX "mmfw_camcorder_camera" +#define CONFIGURE_FIELD_NAME_LENGTH 24 /*======================================================================================= | ENUM DEFINITIONS | diff --git a/src/include/mm_camcorder_gstcommon.h b/src/include/mm_camcorder_gstcommon.h index fa742c9..dd994fc 100644 --- a/src/include/mm_camcorder_gstcommon.h +++ b/src/include/mm_camcorder_gstcommon.h @@ -185,6 +185,7 @@ gboolean _mmcamcorder_invoke_video_stream_cb(MMHandleType handle, GstSample *sam GstPadProbeReturn __mmcamcorder_muxed_dataprobe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); GstPadProbeReturn __mmcamcorder_eventprobe_monitor(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); int _mmcamcorder_request_codec_config(GstElement *videosrc_element); +int _mmcamcorder_set_video_stream_callback_flag(MMHandleType handle, gboolean enable, int flag); #ifdef _MMCAMCORDER_PRODUCT_TV bool __mmcamcorder_find_max_resolution(MMHandleType handle, gint *max_width, gint *max_height); #endif /* _MMCAMCORDER_PRODUCT_TV */ diff --git a/src/include/mm_camcorder_internal.h b/src/include/mm_camcorder_internal.h index 76f98b2..be6f5a6 100644 --- a/src/include/mm_camcorder_internal.h +++ b/src/include/mm_camcorder_internal.h @@ -428,6 +428,11 @@ do { \ #define _MMCAMCORDER_TRYLOCK_VSTREAM_CALLBACK(handle) _MMCAMCORDER_TRYLOCK_FUNC(_MMCAMCORDER_GET_VSTREAM_CALLBACK_LOCK(handle)) #define _MMCAMCORDER_UNLOCK_VSTREAM_CALLBACK(handle) _MMCAMCORDER_UNLOCK_FUNC(_MMCAMCORDER_GET_VSTREAM_CALLBACK_LOCK(handle)) +#define _MMCAMCORDER_GET_VSTREAM_CALLBACK_FLAG_LOCK(handle) (_MMCAMCORDER_CAST_MTSAFE(handle).vstream_cb_flag_lock) +#define _MMCAMCORDER_LOCK_VSTREAM_CALLBACK_FLAG(handle) _MMCAMCORDER_LOCK_FUNC(_MMCAMCORDER_GET_VSTREAM_CALLBACK_FLAG_LOCK(handle)) +#define _MMCAMCORDER_TRYLOCK_VSTREAM_CALLBACK_FLAG(handle) _MMCAMCORDER_TRYLOCK_FUNC(_MMCAMCORDER_GET_VSTREAM_CALLBACK_FLAG_LOCK(handle)) +#define _MMCAMCORDER_UNLOCK_VSTREAM_CALLBACK_FLAG(handle) _MMCAMCORDER_UNLOCK_FUNC(_MMCAMCORDER_GET_VSTREAM_CALLBACK_FLAG_LOCK(handle)) + #define _MMCAMCORDER_GET_ASTREAM_CALLBACK_LOCK(handle) (_MMCAMCORDER_CAST_MTSAFE(handle).astream_cb_lock) #define _MMCAMCORDER_LOCK_ASTREAM_CALLBACK(handle) _MMCAMCORDER_LOCK_FUNC(_MMCAMCORDER_GET_ASTREAM_CALLBACK_LOCK(handle)) #define _MMCAMCORDER_TRYLOCK_ASTREAM_CALLBACK(handle) _MMCAMCORDER_TRYLOCK_FUNC(_MMCAMCORDER_GET_ASTREAM_CALLBACK_LOCK(handle)) @@ -541,6 +546,8 @@ typedef enum { _MMCAMCORDER_VIDEOSRC_CAPS, _MMCAMCORDER_VIDEOSRC_FILT, _MMCAMCORDER_VIDEOSRC_QUE, + _MMCAMCORDER_VIDEOSRC_FILT2, + _MMCAMCORDER_VIDEOSRC_QUE2, _MMCAMCORDER_VIDEOSRC_PARSE, _MMCAMCORDER_VIDEOSRC_DECODE, @@ -665,6 +672,7 @@ typedef struct { GMutex message_cb_lock; /**< Mutex (for message callback) */ GMutex vcapture_cb_lock; /**< Mutex (for video capture callback) */ GMutex vstream_cb_lock; /**< Mutex (for video stream callback) */ + GMutex vstream_cb_flag_lock; /**< Mutex (for video stream callback flag) */ GMutex astream_cb_lock; /**< Mutex (for audio stream callback) */ GMutex mstream_cb_lock; /**< Mutex (for muxed stream callback) */ GMutex vedecision_cb_lock; /**< Mutex (for video encode decision callback) */ @@ -809,6 +817,7 @@ typedef struct mmf_camcorder { int use_zero_copy_format; /**< Whether use zero copy format for camera input */ int use_videoconvert; /**< Whether use videoconvert element for display */ int support_media_packet_preview_cb; /**< Whether support zero copy format for camera input */ + int support_media_packet_preview_internal_cb; /**< Whether support zero copy format for camera input (internal) */ int support_user_buffer; /**< Whether support user allocated buffer for zero copy */ int capture_mode; /**< Capture mode */ int shutter_sound_policy; /**< shutter sound policy */ diff --git a/src/mm_camcorder.c b/src/mm_camcorder.c index 226e626..d400958 100644 --- a/src/mm_camcorder.c +++ b/src/mm_camcorder.c @@ -310,6 +310,14 @@ int mm_camcorder_set_video_stream_callback(MMHandleType camcorder, mm_camcorder_ } +int mm_camcorder_set_video_stream_callback_flag(MMHandleType camcorder, gboolean enable, int flag) +{ + mmf_return_val_if_fail(camcorder, MM_ERROR_CAMCORDER_INVALID_ARGUMENT); + + return _mmcamcorder_set_video_stream_callback_flag(camcorder, enable, flag); +} + + int mm_camcorder_set_audio_stream_callback(MMHandleType camcorder, mm_camcorder_audio_stream_callback callback, void* user_data) { mmf_return_val_if_fail((void *)camcorder, MM_ERROR_CAMCORDER_INVALID_ARGUMENT); diff --git a/src/mm_camcorder_attribute.c b/src/mm_camcorder_attribute.c index 4fc6e1f..62799d7 100644 --- a/src/mm_camcorder_attribute.c +++ b/src/mm_camcorder_attribute.c @@ -61,6 +61,7 @@ static int readonly_attributes[] = { MM_CAM_SUPPORT_ZSL_CAPTURE, MM_CAM_SUPPORT_ZERO_COPY_FORMAT, MM_CAM_SUPPORT_MEDIA_PACKET_PREVIEW_CB, + MM_CAM_SUPPORT_MEDIA_PACKET_PREVIEW_INTERNAL_CB, MM_CAM_PLATFORM_PRIVILEGE_CAMERA, MM_CAM_VIDEOSRC_ELEMENT_NAME, MM_CAM_AUDIOSRC_ELEMENT_NAME @@ -1721,6 +1722,28 @@ _mmcamcorder_alloc_attribute(MMHandleType handle) {.int_max = TRUE}, _mmcamcorder_commit_request_codec_config, }, + { + MM_CAM_SUPPORT_MEDIA_PACKET_PREVIEW_INTERNAL_CB, + "support-media-packet-preview-internal-cb", + MM_ATTRS_TYPE_INT, + MM_ATTRS_FLAG_RW, + {(void*)FALSE}, + MM_ATTRS_VALID_TYPE_INT_RANGE, + {.int_min = FALSE}, + {.int_max = TRUE}, + NULL, + }, + { + MM_CAM_VIDEO_STREAM_CALLBACK_FLAG, + "video-stream-callback-flag", + MM_ATTRS_TYPE_INT, + MM_ATTRS_FLAG_RW, + {(void*)MM_CAMCORDER_VIDEO_STREAM_CALLBACK_FLAG_NONE}, + MM_ATTRS_VALID_TYPE_INT_RANGE, + {.int_min = 0}, + {.int_max = _MMCAMCORDER_MAX_INT}, + NULL, + }, { MM_CAM_FILTER_WB_TEMPERATURE, "filter-wb-temperature", diff --git a/src/mm_camcorder_configure.c b/src/mm_camcorder_configure.c index 20618ad..12d0699 100644 --- a/src/mm_camcorder_configure.c +++ b/src/mm_camcorder_configure.c @@ -830,7 +830,12 @@ int _mmcamcorder_conf_init(MMHandleType handle, int type, camera_conf *configure { "VideoFilterCropX", CONFIGURE_VALUE_INT, {.value_int = 0} }, /* The VideoFilterElement is existed and these values are valid, they will be set to "crop" property. */ { "VideoFilterCropY", CONFIGURE_VALUE_INT, {.value_int = 0} }, { "VideoFilterCropW", CONFIGURE_VALUE_INT, {.value_int = 0} }, - { "VideoFilterCropH", CONFIGURE_VALUE_INT, {.value_int = 0} } + { "VideoFilterCropH", CONFIGURE_VALUE_INT, {.value_int = 0} }, + { "VideoFilter2Element", CONFIGURE_VALUE_ELEMENT, {NULL} }, + { "VideoFilter2CropX", CONFIGURE_VALUE_INT, {.value_int = 0} }, + { "VideoFilter2CropY", CONFIGURE_VALUE_INT, {.value_int = 0} }, + { "VideoFilter2CropW", CONFIGURE_VALUE_INT, {.value_int = 0} }, + { "VideoFilter2CropH", CONFIGURE_VALUE_INT, {.value_int = 0} } }; /* [Strobe] matching table */ diff --git a/src/mm_camcorder_gstcommon.c b/src/mm_camcorder_gstcommon.c index e234924..4a24732 100644 --- a/src/mm_camcorder_gstcommon.c +++ b/src/mm_camcorder_gstcommon.c @@ -150,7 +150,9 @@ static gboolean videocodec_fileformat_compatibility_table[MM_VIDEO_CODEC_NUM][MM * @remarks * @see __mmcamcorder_create_preview_pipeline() */ + static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); +static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview2(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); static int __mmcamcorder_get_amrnb_bitrate_mode(int bitrate); @@ -585,6 +587,74 @@ _INVOKE_VIDEO_STREAM_CB_DONE: } +static gboolean __mmcamcorder_add_videofilter_element(mmf_camcorder_t *hcamcorder, + GList *element_list, const char *conf_prefix, + const char *filter_nick, _MMCAMCORDER_PREVIEW_PIPELINE_ELELMENT filter_index, + const char *queue_nick, _MMCAMCORDER_PREVIEW_PIPELINE_ELELMENT queue_index) +{ + int i = 0; + int err = MM_ERROR_NONE; + int videofilt_crop_rect[_MMCAMCORDER_CROP_ARRAY_LENGTH] = {0, }; + char conf_name_element[CONFIGURE_FIELD_NAME_LENGTH] = {'\0',}; + char conf_name_crop[_MMCAMCORDER_CROP_ARRAY_LENGTH][CONFIGURE_FIELD_NAME_LENGTH] = {{'\0',}, }; + const char *conf_postfix_crop[_MMCAMCORDER_CROP_ARRAY_LENGTH] = { + "CropX", + "CropY", + "CropW", + "CropH" + }; + + _MMCamcorderSubContext *sc = NULL; + type_element *videofilt_element = NULL; + const char *videofilt_name = NULL; + + mmf_return_val_if_fail(hcamcorder, FALSE); + mmf_return_val_if_fail(element_list, FALSE); + mmf_return_val_if_fail(filter_nick && filter_index > _MMCAMCORDER_NONE, FALSE); + + sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder); + mmf_return_val_if_fail(sc, FALSE); + + snprintf(conf_name_element, sizeof(conf_name_element), "%sElement", conf_prefix); + + _mmcamcorder_conf_get_element_and_name((MMHandleType)hcamcorder, + hcamcorder->conf_ctrl, CONFIGURE_CATEGORY_CTRL_CAMERA, conf_name_element, + &videofilt_element, &videofilt_name); + + if (!videofilt_element || !videofilt_name) { + MMCAM_LOG_INFO("No configure for %s", conf_name_element); + return TRUE; + } + + _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, filter_index, videofilt_name, filter_nick, element_list, err); + _mmcamcorder_conf_set_value_element_property(sc->element[filter_index].gst, videofilt_element); + + for (i = 0 ; i < _MMCAMCORDER_CROP_ARRAY_LENGTH ; i++) { + snprintf(conf_name_crop[i], sizeof(conf_name_crop[i]), "%s%s", conf_prefix, conf_postfix_crop[i]); + _mmcamcorder_conf_get_value_int((MMHandleType)hcamcorder, hcamcorder->conf_ctrl, + CONFIGURE_CATEGORY_CTRL_CAMERA, + conf_name_crop[i], &videofilt_crop_rect[i]); + } + + if (videofilt_crop_rect[0] >= 0 && videofilt_crop_rect[1] >= 0 && + videofilt_crop_rect[2] > 0 && videofilt_crop_rect[3] > 0) { + _mmcamcorder_set_property_array_int(sc->element[filter_index].gst, + "crop", videofilt_crop_rect, _MMCAMCORDER_CROP_ARRAY_LENGTH); + } + + MMCAM_LOG_INFO("queue_nick[%p], queue_index[%d]", queue_nick, queue_index); + + if (queue_nick && queue_index > _MMCAMCORDER_NONE) + _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, queue_index, "queue", queue_nick, element_list, err); + + return TRUE; + +pipeline_creation_error: + MMCAM_LOG_ERROR("failed[0x%x]", err); + return FALSE; +} + + int _mmcamcorder_create_preview_elements(MMHandleType handle) { int err = MM_ERROR_NONE; @@ -600,7 +670,6 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle) int anti_shake = 0; int display_surface_type = MM_DISPLAY_SURFACE_NULL; const char *videosrc_name = NULL; - const char *videofilt_name = NULL; const char *videosink_name = NULL; const char *videoconvert_name = NULL; const char *videodecoder_name = NULL; @@ -623,7 +692,6 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle) mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle); _MMCamcorderSubContext *sc = NULL; type_element *videosrc_element = NULL; - type_element *videofilt_element = NULL; type_int_array *input_index = NULL; mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED); @@ -769,36 +837,20 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle) &hcamcorder->recreate_decoder); } - _mmcamcorder_conf_get_element_and_name((MMHandleType)hcamcorder, - hcamcorder->conf_ctrl, CONFIGURE_CATEGORY_CTRL_CAMERA, "VideoFilterElement", - &videofilt_element, &videofilt_name); - if (videofilt_element && videofilt_name) { - int videofilt_crop_rect[_MMCAMCORDER_CROP_ARRAY_LENGTH] = {0, }; - const char *conf_name[_MMCAMCORDER_CROP_ARRAY_LENGTH] = { - "VideoFilterCropX", - "VideoFilterCropY", - "VideoFilterCropW", - "VideoFilterCropH" - }; - - _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSRC_FILT, videofilt_name, "vsrc_f", element_list, err); - _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, videofilt_element); - - for (i = 0 ; i < _MMCAMCORDER_CROP_ARRAY_LENGTH ; i++) { - _mmcamcorder_conf_get_value_int((MMHandleType)hcamcorder, hcamcorder->conf_ctrl, - CONFIGURE_CATEGORY_CTRL_CAMERA, - conf_name[i], &videofilt_crop_rect[i]); - } - - if (videofilt_crop_rect[0] >= 0 && videofilt_crop_rect[1] >= 0 && - videofilt_crop_rect[2] > 0 && videofilt_crop_rect[3] > 0) { - _mmcamcorder_set_property_array_int(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, - "crop", videofilt_crop_rect, _MMCAMCORDER_CROP_ARRAY_LENGTH); - } + if (!__mmcamcorder_add_videofilter_element(hcamcorder, element_list, "VideoFilter", + "vsrc_f", _MMCAMCORDER_VIDEOSRC_FILT, NULL, _MMCAMCORDER_NONE)) { + MMCAM_LOG_ERROR("add videofilter failed for VideoFilterElement"); + goto pipeline_creation_error; } _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSRC_QUE, "queue", "vsrc_q", element_list, err); + if (!__mmcamcorder_add_videofilter_element(hcamcorder, element_list, "VideoFilter2", + "vsrc_f2", _MMCAMCORDER_VIDEOSRC_FILT2, "vsrc_q2", _MMCAMCORDER_VIDEOSRC_QUE2)) { + MMCAM_LOG_ERROR("add videofilter failed for VideoFilter2Element"); + goto pipeline_creation_error; + } + if (display_surface_type != MM_DISPLAY_SURFACE_NULL && _mmcamcorder_is_encoded_preview_pixel_format(sc->info_image->preview_format)) { switch (sc->info_image->preview_format) { @@ -949,7 +1001,10 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle) pipeline_creation_error: _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_VIDEOSRC_SRC); _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_VIDEOSRC_CAPS); + _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_VIDEOSRC_FILT); _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_VIDEOSRC_QUE); + _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_VIDEOSRC_FILT2); + _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_VIDEOSRC_QUE2); _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_VIDEOSRC_CAP_CAPS); _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_VIDEOSRC_CAP_SINK); _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_VIDEOSRC_DECODE); @@ -1786,22 +1841,35 @@ int _mmcamcorder_create_preview_pipeline(MMHandleType handle) goto pipeline_creation_error; /* Set data probe function */ - if (sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst) { - MMCAM_LOG_INFO("add video dataprobe to videosrc queue"); - srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "src"); - } else { + if (!sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst) { MMCAM_LOG_ERROR("there is no queue plugin"); goto pipeline_creation_error; } - if (srcpad) { + MMCAM_LOG_INFO("add video dataprobe to videosrc queue"); + srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "src"); + if (!srcpad) { + MMCAM_LOG_ERROR("failed to get srcpad"); + goto pipeline_creation_error; + } + + MMCAMCORDER_ADD_BUFFER_PROBE(srcpad, _MMCAMCORDER_HANDLER_PREVIEW, + __mmcamcorder_video_dataprobe_preview, hcamcorder); + + gst_object_unref(srcpad); + + if (sc->element[_MMCAMCORDER_VIDEOSRC_QUE2].gst) { + MMCAM_LOG_INFO("add video dataprobe2 to videosrc queue2"); + srcpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_QUE2].gst, "src"); + if (!srcpad) { + MMCAM_LOG_ERROR("failed to get srcpad"); + goto pipeline_creation_error; + } + MMCAMCORDER_ADD_BUFFER_PROBE(srcpad, _MMCAMCORDER_HANDLER_PREVIEW, - __mmcamcorder_video_dataprobe_preview, hcamcorder); + __mmcamcorder_video_dataprobe_preview2, hcamcorder); gst_object_unref(srcpad); - } else { - MMCAM_LOG_ERROR("failed to get srcpad"); - goto pipeline_creation_error; } /* set dataprobe for video recording if it does not support dual stream. */ @@ -2155,18 +2223,62 @@ static guint32 _mmcamcorder_get_structure_fourcc(const GstStructure *structure) return GST_MAKE_FOURCC('N', 'O', 'N', 'E'); } + +static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview_common(mmf_camcorder_t *hcamcorder, + GstPad *pad, GstBuffer *buffer, int stream_id, int flag_mask) +{ + int flag_current = 0; + int ret_attr = MM_ERROR_NONE; + _MMCamcorderSubContext *sc = NULL; + g_autoptr(GstSample) sample = NULL; + g_autoptr(GstCaps) caps = NULL; + + mmf_return_val_if_fail(hcamcorder, GST_PAD_PROBE_DROP); + mmf_return_val_if_fail(gst_buffer_n_memory(buffer), GST_PAD_PROBE_DROP); + + sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder); + mmf_return_val_if_fail(sc, GST_PAD_PROBE_DROP); + + /* The first H.264 frame should not be skipped for vstream cb. */ + if (hcamcorder->state < MM_CAMCORDER_STATE_PREPARE && + !_mmcamcorder_is_encoded_preview_pixel_format(sc->info_image->preview_format)) { + MMCAM_LOG_WARNING("Not ready for stream callback[stream_id:%d]", stream_id); + return GST_PAD_PROBE_OK; + } + + ret_attr = mm_camcorder_get_attributes((MMHandleType)hcamcorder, NULL, + MMCAM_VIDEO_STREAM_CALLBACK_FLAG, &flag_current, + NULL); + if (ret_attr != MM_ERROR_NONE) { + MMCAM_LOG_WARNING("get preview callback flag failed[0x%x]", ret_attr); + return GST_PAD_PROBE_OK; + } + + MMCAM_LOG_DEBUG("flag [current:0x%08x,mask:0x%08x]", flag_current, flag_mask); + + if (!(flag_current & flag_mask)) + return GST_PAD_PROBE_OK; + + /* make sample with buffer and caps */ + caps = gst_pad_get_current_caps(pad); + mmf_return_val_if_fail(caps, GST_PAD_PROBE_OK); + + sample = gst_sample_new(buffer, caps, NULL, NULL); + mmf_return_val_if_fail(sample, GST_PAD_PROBE_OK); + + return _mmcamcorder_invoke_video_stream_cb((MMHandleType)hcamcorder, sample, TRUE, stream_id) ? \ + GST_PAD_PROBE_OK : GST_PAD_PROBE_DROP; +} + + static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstPadProbeInfo *info, gpointer u_data) { - gboolean ret = TRUE; mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data); _MMCamcorderSubContext *sc = NULL; GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info); - GstSample *sample = NULL; - GstCaps *caps = NULL; - mmf_return_val_if_fail(buffer, GST_PAD_PROBE_DROP); - mmf_return_val_if_fail(gst_buffer_n_memory(buffer), GST_PAD_PROBE_DROP); mmf_return_val_if_fail(hcamcorder, GST_PAD_PROBE_DROP); + mmf_return_val_if_fail(gst_buffer_n_memory(buffer), GST_PAD_PROBE_DROP); sc = MMF_CAMCORDER_SUBCONTEXT(u_data); mmf_return_val_if_fail(sc, GST_PAD_PROBE_DROP); @@ -2189,29 +2301,19 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstP if (hcamcorder->measure_preview_fps && hcamcorder->state >= MM_CAMCORDER_STATE_PREPARE) _mmcamcorder_measure_fps(&sc->kpi); - /* The first H.264 frame should not be skipped for vstream cb. */ - if (hcamcorder->state < MM_CAMCORDER_STATE_PREPARE && - !_mmcamcorder_is_encoded_preview_pixel_format(sc->info_image->preview_format)) { - MMCAM_LOG_WARNING("Not ready for stream callback"); - return GST_PAD_PROBE_OK; - } - - /* make sample with buffer and caps */ - caps = gst_pad_get_current_caps(pad); - mmf_return_val_if_fail(caps, GST_PAD_PROBE_OK); - - sample = gst_sample_new(buffer, caps, NULL, NULL); - gst_caps_unref(caps); - mmf_return_val_if_fail(sample, GST_PAD_PROBE_OK); - - ret = _mmcamcorder_invoke_video_stream_cb((MMHandleType)hcamcorder, sample, TRUE, -1); + return __mmcamcorder_video_dataprobe_preview_common(hcamcorder, + pad, buffer, + MM_CAMCORDER_VIDEO_STREAM_ID_NORMAL, + MM_CAMCORDER_VIDEO_STREAM_CALLBACK_FLAG_NORMAL); +} - gst_sample_unref(sample); - if (ret) - return GST_PAD_PROBE_OK; - else - return GST_PAD_PROBE_DROP; +static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview2(GstPad *pad, GstPadProbeInfo *info, gpointer u_data) +{ + return __mmcamcorder_video_dataprobe_preview_common(MMF_CAMCORDER(u_data), + pad, GST_PAD_PROBE_INFO_BUFFER(info), + MM_CAMCORDER_VIDEO_STREAM_ID_INTERNAL, + MM_CAMCORDER_VIDEO_STREAM_CALLBACK_FLAG_INTERNAL); } @@ -3275,6 +3377,49 @@ bool _mmcamcorder_recreate_decoder_for_encoded_preview(MMHandleType handle) return TRUE; } + +int _mmcamcorder_set_video_stream_callback_flag(MMHandleType handle, gboolean enable, int flag) +{ + int ret = MM_ERROR_NONE; + int flag_current = MM_CAMCORDER_VIDEO_STREAM_CALLBACK_FLAG_NONE; + int flag_new = MM_CAMCORDER_VIDEO_STREAM_CALLBACK_FLAG_NONE; + + MMCAM_LOG_INFO("enable[%d], flag[0x%08x]", enable, flag); + + _MMCAMCORDER_LOCK_VSTREAM_CALLBACK_FLAG(handle); + + ret = mm_camcorder_get_attributes(handle, NULL, + MMCAM_VIDEO_STREAM_CALLBACK_FLAG, &flag_current, + NULL); + if (ret != MM_ERROR_NONE) { + MMCAM_LOG_ERROR("get vstream callback flag failed[0x%x]", ret); + goto _SET_VIDEO_STREAM_CALLBACK_FLAG_DONE; + } + + MMCAM_LOG_INFO("current flag[0x%08x]", flag_current); + + if (enable) + flag_new = flag_current | flag; + else + flag_new = flag_current & ~flag; + + ret = mm_camcorder_set_attributes(handle, NULL, + MMCAM_VIDEO_STREAM_CALLBACK_FLAG, flag_new, + NULL); + if (ret != MM_ERROR_NONE) { + MMCAM_LOG_ERROR("set vstream callback flag[0x%x] failed[0x%x]", flag_new, ret); + goto _SET_VIDEO_STREAM_CALLBACK_FLAG_DONE; + } + + MMCAM_LOG_INFO("new flag[0x%08x]", flag_new); + +_SET_VIDEO_STREAM_CALLBACK_FLAG_DONE: + _MMCAMCORDER_UNLOCK_VSTREAM_CALLBACK_FLAG(handle); + + return ret; +} + + #ifdef _MMCAMCORDER_PRODUCT_TV bool __mmcamcorder_find_max_resolution(MMHandleType handle, gint *max_width, gint *max_height) { diff --git a/src/mm_camcorder_internal.c b/src/mm_camcorder_internal.c index b9f0f7e..8496cc1 100644 --- a/src/mm_camcorder_internal.c +++ b/src/mm_camcorder_internal.c @@ -136,6 +136,7 @@ static gint __mmcamcorder_init_handle(mmf_camcorder_t **hcamcorder, int device_t g_mutex_init(&(new_handle->mtsafe).message_cb_lock); g_mutex_init(&(new_handle->mtsafe).vcapture_cb_lock); g_mutex_init(&(new_handle->mtsafe).vstream_cb_lock); + g_mutex_init(&(new_handle->mtsafe).vstream_cb_flag_lock); g_mutex_init(&(new_handle->mtsafe).astream_cb_lock); g_mutex_init(&(new_handle->mtsafe).mstream_cb_lock); g_mutex_init(&(new_handle->mtsafe).vedecision_cb_lock); @@ -247,6 +248,7 @@ static void __mmcamcorder_deinit_handle(mmf_camcorder_t *hcamcorder) g_mutex_clear(&(hcamcorder->mtsafe).message_cb_lock); g_mutex_clear(&(hcamcorder->mtsafe).vcapture_cb_lock); g_mutex_clear(&(hcamcorder->mtsafe).vstream_cb_lock); + g_mutex_clear(&(hcamcorder->mtsafe).vstream_cb_flag_lock); g_mutex_clear(&(hcamcorder->mtsafe).astream_cb_lock); g_mutex_clear(&(hcamcorder->mtsafe).mstream_cb_lock); g_mutex_clear(&(hcamcorder->mtsafe).vedecision_cb_lock); @@ -327,6 +329,7 @@ static gint __mmcamcorder_init_configure_video_capture(mmf_camcorder_t *hcamcord char conf_file_name[__MMCAMCORDER_CONF_FILENAME_LENGTH] = {'\0',}; const char *platform_privilege_camera = NULL; MMCamAttrsInfo fps_info; + type_element *videofilt2_element = NULL; #ifdef _MMCAMCORDER_CAMERA_CONF_MGR_SUPPORT camera_conf_error_e ret_conf = CAMERA_CONF_MGR_ERROR_NONE; char devicetype[__MMCAMCORDER_CONF_FILENAME_LENGTH] = {'\0',}; @@ -504,8 +507,15 @@ static gint __mmcamcorder_init_configure_video_capture(mmf_camcorder_t *hcamcord "PlayCaptureSound", &play_capture_sound); + _mmcamcorder_conf_get_element((MMHandleType)hcamcorder, hcamcorder->conf_ctrl, + CONFIGURE_CATEGORY_CTRL_CAMERA, + "VideoFilter2Element", + &videofilt2_element); + hcamcorder->support_media_packet_preview_internal_cb = videofilt2_element ? TRUE : FALSE; + MMCAM_LOG_INFO("Support user buffer[%d]", hcamcorder->support_user_buffer); MMCAM_LOG_INFO("Support media packet preview cb[%d]", hcamcorder->support_media_packet_preview_cb); + MMCAM_LOG_INFO("Support media packet preview internal cb[%d]", hcamcorder->support_media_packet_preview_internal_cb); MMCAM_LOG_INFO("Support extra preview[%d]", hcamcorder->extra_preview.is_supported); MMCAM_LOG_INFO("Extra preview mode[%d]", hcamcorder->extra_preview.mode); MMCAM_LOG_INFO("Capture mode[%d]", hcamcorder->capture_mode); @@ -564,6 +574,7 @@ static gint __mmcamcorder_init_configure_video_capture(mmf_camcorder_t *hcamcord MMCAM_SUPPORT_ZSL_CAPTURE, hcamcorder->support_zsl_capture, MMCAM_SUPPORT_ZERO_COPY_FORMAT, hcamcorder->use_zero_copy_format, MMCAM_SUPPORT_MEDIA_PACKET_PREVIEW_CB, hcamcorder->support_media_packet_preview_cb, + MMCAM_SUPPORT_MEDIA_PACKET_PREVIEW_INTERNAL_CB, hcamcorder->support_media_packet_preview_internal_cb, MMCAM_SUPPORT_USER_BUFFER, hcamcorder->support_user_buffer, MMCAM_SUPPORT_EXTRA_PREVIEW, hcamcorder->extra_preview.is_supported, MMCAM_CAMERA_FPS, fps_info.int_array.def, @@ -1867,9 +1878,6 @@ int _mmcamcorder_set_video_stream_callback(MMHandleType handle, mm_camcorder_vid mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED); - if (callback == NULL) - MMCAM_LOG_WARNING("Video Stream Callback is disabled, because application sets it to NULL"); - _MMCAMCORDER_LOCK_VSTREAM_CALLBACK(hcamcorder); hcamcorder->vstream_cb = callback; diff --git a/src/mm_camcorder_sound.c b/src/mm_camcorder_sound.c index b67af9f..90f1add 100644 --- a/src/mm_camcorder_sound.c +++ b/src/mm_camcorder_sound.c @@ -222,7 +222,7 @@ void _mmcamcorder_sound_solo_play_wait(MMHandleType handle) g_mutex_lock(&info->sync_mutex); - MMCAM_LOG_INFO("is_playing[%d]", info->is_playing); + MMCAM_LOG_INFO("START - is_playing[%d]", info->is_playing); while (info->is_playing) { MMCAM_LOG_INFO("Wait for signal");