Support videofilter2 element and preview callback for it 31/313531/1 accepted/tizen/unified/20240701.191820 accepted/tizen/unified/dev/20240702.054028 accepted/tizen/unified/x/20240702.031217
authorJeongmo Yang <jm80.yang@samsung.com>
Tue, 23 Jan 2024 02:01:49 +0000 (11:01 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Thu, 27 Jun 2024 02:46:51 +0000 (11:46 +0900)
- 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 <jm80.yang@samsung.com>
12 files changed:
packaging/libmm-camcorder.spec
src/include/mm_camcorder.h
src/include/mm_camcorder_attribute.h
src/include/mm_camcorder_configure.h
src/include/mm_camcorder_gstcommon.h
src/include/mm_camcorder_internal.h
src/mm_camcorder.c
src/mm_camcorder_attribute.c
src/mm_camcorder_configure.c
src/mm_camcorder_gstcommon.c
src/mm_camcorder_internal.c
src/mm_camcorder_sound.c

index 8ef8884..cd0770c 100755 (executable)
@@ -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
index 9f6ec75..400c16f 100644 (file)
@@ -1259,6 +1259,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
 */
 #define MMCAM_SUPPORT_USER_BUFFER               "support-user-buffer"
@@ -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);
index 9bd5f5c..7015e4d 100644 (file)
@@ -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,
index 26c9df6..8b265cc 100644 (file)
@@ -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                                                                     |
index fa742c9..dd994fc 100644 (file)
@@ -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 */
index 76f98b2..be6f5a6 100644 (file)
@@ -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 */
index 226e626..d400958 100644 (file)
@@ -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);
index 4fc6e1f..62799d7 100644 (file)
@@ -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
@@ -1722,6 +1723,28 @@ _mmcamcorder_alloc_attribute(MMHandleType handle)
                        _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",
                        MM_ATTRS_TYPE_INT,
index 20618ad..12d0699 100644 (file)
@@ -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 */
index e234924..4a24732 100644 (file)
@@ -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)
 {
index b9f0f7e..8496cc1 100644 (file)
@@ -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;
index b67af9f..90f1add 100644 (file)
@@ -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");