webrtc_source: Fix mute error for camera source which doesn't use tizen memory 39/276339/3 accepted/tizen/6.5/unified/20220621.140310 submit/tizen_6.5/20220620.013835
authorbackto.kim <backto.kim@samsung.com>
Wed, 15 Jun 2022 03:27:20 +0000 (12:27 +0900)
committerhj kim <backto.kim@samsung.com>
Fri, 17 Jun 2022 03:42:29 +0000 (12:42 +0900)
[Version] 0.2.173
[Issue Type] Bug fix

Change-Id: I9bffc47f70d5192f0b4d67e136709ab03a61532c

include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc_private.c
src/webrtc_source.c

index f97a5e5530e169c78fb434753d5d14a2fa31aa1b..a4a0cae4c8e2be75852a440ca36d1345d6324850 100644 (file)
@@ -482,6 +482,7 @@ typedef struct _webrtc_gst_slot_s {
                int mline;
                GstPad *src_pad;
                gulong src_pad_probe_id;
+               gchar *raw_format;
                bool pause;
                unsigned int payload_id;
                struct {
index 819e6bf2f811d69f18c06c96f25329826787437f..f53e1e3688caeadaa738680e66739e09a42582d2 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.2.172
+Version:    0.2.173
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index aba1094f6e2cd28c17ff81896b8afa03398d4073..45d99d81f3cf3884643e6f725b7bd35c4e461833 100644 (file)
@@ -1075,9 +1075,9 @@ int _add_no_target_ghostpad_to_slot(webrtc_gst_slot_s *slot, bool is_src, GstPad
        RET_VAL_IF(new_pad == NULL, WEBRTC_ERROR_INVALID_OPERATION, "new_pad is NULL");
 
        if (slot->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE) {
-               if ((slot->media_types & MEDIA_TYPE_AUDIO) &&  !__is_existing_pad(slot, "audio"))
+               if ((slot->media_types & MEDIA_TYPE_AUDIO) && !__is_existing_pad(slot, "audio"))
                        pad_name = g_strdup_printf("audio_src_%u", slot->id);
-               else if ((slot->media_types & MEDIA_TYPE_VIDEO) &&  !__is_existing_pad(slot, "video"))
+               else if ((slot->media_types & MEDIA_TYPE_VIDEO) && !__is_existing_pad(slot, "video"))
                        pad_name = g_strdup_printf("video_src_%u", slot->id);
 
                RET_VAL_IF(pad_name == NULL, WEBRTC_ERROR_INVALID_OPERATION, "fail to get pad_name");
index 0a01638d27cc3f19ab0a75664cb9c270b3b6d560..00740a4fd5be3cd2da2031249c23e93a94ca2258 100644 (file)
@@ -1282,6 +1282,7 @@ static GstElement *__find_element_in_bin(GstBin *bin, const gchar *name)
 static int __build_screensrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 {
        int ret = WEBRTC_ERROR_NONE;
+       const ini_item_media_source_s *ini_source;
        GstElement *screensrc;
        GstElement *videoconvert;
        GstElement *videotestsrc;
@@ -1295,11 +1296,17 @@ static int __build_screensrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
        RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
        RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
 
+       if (!(ini_source = _ini_get_source_by_type(&webrtc->ini, source->type))) {
+               LOG_ERROR("ini_source is NULL");
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+
        ret = _add_no_target_ghostpad_to_slot(source, true, &src_pad);
        RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to _add_no_target_ghostpad_to_slot()");
 
        source->media_types = MEDIA_TYPE_VIDEO;
        source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
+       source->av[AV_IDX_VIDEO].raw_format = g_strdup(ini_source->v_raw_format);
 
        if (!(screensrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_SCREEN), ELEMENT_NAME_SCREENSRC)))
                return WEBRTC_ERROR_INVALID_OPERATION;
@@ -1379,6 +1386,7 @@ exit:
 static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 {
        int ret = WEBRTC_ERROR_NONE;
+       const ini_item_media_source_s *ini_source;
        GstElement *camerasrc;
        GstElement *capsfilter;
        GList *element_list = NULL;
@@ -1388,11 +1396,18 @@ static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
        RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
        RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
 
+       if (!(ini_source = _ini_get_source_by_type(&webrtc->ini, source->type))) {
+               LOG_ERROR("ini_source is NULL");
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+
        ret = _add_no_target_ghostpad_to_slot(source, true, &src_pad);
        RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to _add_no_target_ghostpad_to_slot()");
 
        source->media_types = MEDIA_TYPE_VIDEO;
        source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
+       source->av[AV_IDX_VIDEO].raw_format = g_strdup(ini_source->v_raw_format);
+
 #ifndef TIZEN_TV
        if (webrtc->ini.resource_acquisition.camera)
                webrtc->resource.need_to_acquire[MM_RESOURCE_MANAGER_RES_TYPE_CAMERA] = true;
@@ -1447,6 +1462,7 @@ exit:
 static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool use_mic)
 {
        int ret = WEBRTC_ERROR_NONE;
+       const ini_item_media_source_s *ini_source;
        const char *source_factory_name;
        GstElement *audiosrc;
        GstElement *volume;
@@ -1458,11 +1474,17 @@ static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool us
        RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
        RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
 
+       if (!(ini_source = _ini_get_source_by_type(&webrtc->ini, source->type))) {
+               LOG_ERROR("ini_source is NULL");
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+
        ret = _add_no_target_ghostpad_to_slot(source, true, &src_pad);
        RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to _add_no_target_ghostpad_to_slot()");
 
        source->media_types = MEDIA_TYPE_AUDIO;
        source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
+       source->av[AV_IDX_AUDIO].raw_format = g_strdup(ini_source->a_raw_format);
 
        source_factory_name = __get_source_element(webrtc, use_mic ? WEBRTC_MEDIA_SOURCE_TYPE_MIC : WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST);
        if (!(audiosrc = _create_element(source_factory_name, use_mic ? ELEMENT_NAME_MIC_SRC: NULL)))
@@ -1515,6 +1537,7 @@ exit:
 static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 {
        int ret = WEBRTC_ERROR_NONE;
+       const ini_item_media_source_s *ini_source;
        GstElement *videotestsrc;
        GstElement *capsfilter;
        GList *element_list = NULL;
@@ -1524,11 +1547,17 @@ static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
        RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
        RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
 
+       if (!(ini_source = _ini_get_source_by_type(&webrtc->ini, source->type))) {
+               LOG_ERROR("ini_source is NULL");
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+
        ret = _add_no_target_ghostpad_to_slot(source, true, &src_pad);
        RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to _add_no_target_ghostpad_to_slot()");
 
        source->media_types = MEDIA_TYPE_VIDEO;
        source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
+       source->av[AV_IDX_VIDEO].raw_format = g_strdup(ini_source->v_raw_format);
 
        if (!(videotestsrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST), ELEMENT_NAME_VIDEO_SRC)))
                return WEBRTC_ERROR_INVALID_OPERATION;
@@ -1823,7 +1852,7 @@ static void __filesrc_pipeline_video_stream_handoff_cb(GstElement *object, GstBu
                LOG_ERROR("failed to 'push-buffer', gst_ret[0x%x]", gst_ret);
 }
 
-static GstPadProbeReturn __fakesink_probe_cb(GstPad *pad,  GstPadProbeInfo *info, gpointer u_data)
+static GstPadProbeReturn __fakesink_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
 {
        webrtc_gst_slot_s *source = u_data;
        GstCaps *new_cap = NULL;
@@ -2539,6 +2568,8 @@ void _source_slot_destroy_cb(gpointer data)
                        gst_element_set_state(source->av[i].render.pipeline, GST_STATE_NULL);
                        SAFE_GST_OBJECT_UNREF(source->av[i].render.pipeline);
                }
+
+               g_free(source->av[i].raw_format);
        }
 
        gst_bin_remove(GST_BIN(gst_element_get_parent(source->bin)), GST_ELEMENT(source->bin));
@@ -2608,9 +2639,9 @@ static int __link_source_with_webrtcbin(webrtc_gst_slot_s *source, GstElement *w
        }
 
        if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE) {
-               if ((source->media_types & MEDIA_TYPE_AUDIO) &&  !__is_linked_pad(source, "audio"))
+               if ((source->media_types & MEDIA_TYPE_AUDIO) && !__is_linked_pad(source, "audio"))
                        srcpad_name = g_strdup_printf("audio_src_%u", source->id);
-               else if ((source->media_types & MEDIA_TYPE_VIDEO) &&  !__is_linked_pad(source, "video"))
+               else if ((source->media_types & MEDIA_TYPE_VIDEO) && !__is_linked_pad(source, "video"))
                        srcpad_name = g_strdup_printf("video_src_%u", source->id);
 
                if (!srcpad_name) {
@@ -3177,7 +3208,7 @@ int _set_media_path(webrtc_s *webrtc, unsigned int source_id, const char *path)
        if (access(path, R_OK) < 0) {
                if (errno == EACCES || errno == EPERM) {
                        LOG_ERROR("Fail to open path: Permission Denied [%s]", path);
-                       return  WEBRTC_ERROR_PERMISSION_DENIED;
+                       return WEBRTC_ERROR_PERMISSION_DENIED;
                } else {
                        LOG_ERROR("Fail to open path: Invalid Path [%s] errno[%d]", path, errno);
                        return WEBRTC_ERROR_INVALID_PARAMETER;
@@ -3525,39 +3556,59 @@ exit:
 }
 
 //LCOV_EXCL_START
-static GstPadProbeReturn __camerasrc_probe_cb(GstPad *pad,  GstPadProbeInfo *info, gpointer u_data)
+static GstPadProbeReturn __camerasrc_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
 {
+       webrtc_gst_slot_s *source = u_data;
        GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
        GstMemory *mem = NULL;
-       tbm_surface_h src_tsurface;
-       tbm_surface_info_s ts_info;
-       int ret = TBM_SURFACE_ERROR_NONE;
-       unsigned int i = 0;
 
+       RET_VAL_IF(source == NULL, GST_PAD_PROBE_OK, "source is NULL");
        RET_VAL_IF(buffer == NULL, GST_PAD_PROBE_OK, "buffer is NULL");
        RET_VAL_IF(gst_buffer_get_size(buffer) == 0, GST_PAD_PROBE_OK, "empty buffer");
 
        mem = gst_buffer_peek_memory(buffer, 0);
        RET_VAL_IF(mem == NULL, GST_PAD_PROBE_OK, "mem is NULL");
 
-       src_tsurface = (tbm_surface_h)gst_tizen_memory_get_surface(mem);
-       if (!src_tsurface) {
-               LOG_ERROR("failed to gst_tizen_memory_get_surface()");
-               return GST_PAD_PROBE_OK;
-       }
+       if (gst_is_tizen_memory(mem)) {
+               tbm_surface_h src_tsurface = NULL;
+               tbm_surface_info_s ts_info;
+               unsigned int i = 0;
 
-       ret = tbm_surface_get_info(src_tsurface, &ts_info);
-       if (ret != TBM_SURFACE_ERROR_NONE) {
-               LOG_ERROR("failed to tbm_surface_get_info() [%d]", ret);
-               return GST_PAD_PROBE_OK;
-       }
+               src_tsurface = (tbm_surface_h)gst_tizen_memory_get_surface(mem);
+               RET_VAL_IF(src_tsurface == NULL, GST_PAD_PROBE_OK, "failed to gst_tizen_memory_get_surface()");
 
-       /* fill the buffer with black (NV12, YUV, RGB) */
-       for (i = 0 ; i < ts_info.num_planes ; i++) {
-               if (i == 0)
-                       memset(ts_info.planes[i].ptr, 0x00, ts_info.planes[i].size);
-               else
-                       memset(ts_info.planes[i].ptr, 0x80, ts_info.planes[i].size);
+               if (tbm_surface_get_info(src_tsurface, &ts_info) != TBM_SURFACE_ERROR_NONE) {
+                       LOG_ERROR("failed to tbm_surface_get_info()");
+                       return GST_PAD_PROBE_OK;
+               }
+
+               /* fill the buffer with black */
+               if (g_strrstr(source->av[AV_IDX_VIDEO].raw_format, "SR32")) { /*RGB*/
+                       for (i = 0 ; i < ts_info.num_planes ; i++)
+                               memset(ts_info.planes[i].ptr, 0x00, ts_info.planes[i].size);
+               } else { /*YUV*/
+                       for (i = 0 ; i < ts_info.num_planes ; i++)
+                               memset(ts_info.planes[i].ptr, (i == 0) ? 0x10 : 0x80, ts_info.planes[i].size);
+               }
+       } else {
+               GstMapInfo map_info;
+               memset(&map_info, 0x0, sizeof(GstMapInfo));
+               gsize mem_size = gst_memory_get_sizes(mem, NULL, NULL);
+
+               if (!gst_memory_map(mem, &map_info, GST_MAP_READWRITE)) {
+                       LOG_ERROR("failed to gst_memory_map()");
+                       return GST_PAD_PROBE_OK;
+               }
+
+               /* fill the buffer with black */
+               if (g_strrstr(source->av[AV_IDX_VIDEO].raw_format, "I420") || (g_strrstr(source->av[AV_IDX_VIDEO].raw_format, "NV12"))) {
+                       memset(map_info.data, 0x10, mem_size * 2 / 3);
+                       memset(map_info.data + mem_size * 2 / 3, 0x80, mem_size / 3);
+               } else {
+                       memset(map_info.data, 0x00, mem_size);
+               }
+
+               gst_memory_unmap(mem, &map_info);
        }
 
        return GST_PAD_PROBE_OK;
@@ -3582,7 +3633,7 @@ static int __mute_camerasrc(webrtc_gst_slot_s *source, bool mute)
                        LOG_ERROR("fail to change to mute");
                        ret = WEBRTC_ERROR_INVALID_OPERATION;
                } else {
-                       source->camerasrc_probe_id = gst_pad_add_probe(src_pad, GST_PAD_PROBE_TYPE_BUFFER, __camerasrc_probe_cb, NULL, NULL);
+                       source->camerasrc_probe_id = gst_pad_add_probe(src_pad, GST_PAD_PROBE_TYPE_BUFFER, __camerasrc_probe_cb, source, NULL);
                        if (source->camerasrc_probe_id == 0) {
                                LOG_ERROR("failed to gst_pad_add_probe()");
                                ret = WEBRTC_ERROR_INVALID_OPERATION;