webrtc_source: Fix mute error for camera source which doesn't use tizen memory 60/275860/14
authorbackto.kim <backto.kim@samsung.com>
Fri, 3 Jun 2022 07:02:38 +0000 (16:02 +0900)
committerhj kim <backto.kim@samsung.com>
Thu, 16 Jun 2022 08:55:28 +0000 (17:55 +0900)
[Version] 0.3.125
[Issue Type] Bug fix

Change-Id: I8b05ef9e7029fb22f15928290b7a4326a28cd2e4

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

index b02c6f6c3ae4768bf55557883cbd6fb1b57d4d8a..7a487940fc0d6a1d5cab0aeed597267dd6da7c62 100644 (file)
@@ -495,6 +495,7 @@ typedef struct _webrtc_gst_slot_s {
                webrtc_transceiver_direction_e direction;
                GstPad *src_pad;
                gulong src_pad_probe_id;
+               gchar *raw_format;
                bool pause;
                bool mute;
                bool inbandfec;
index 77c3f36cc09c33cae1b52d6a7558dd51a3dd0d9c..0b6a079d7ceb849fa47e622fcc5426783b1820e3 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.3.124
+Version:    0.3.125
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 9bf1988fcc7a8a290af531c80b3f61b2bda3d675..2d621e55bab02816df2ff33a2d96cdb5c7b28683 100644 (file)
@@ -1231,9 +1231,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 6fc850d640b1c414d5b64a5f9a4e7045fac514cc..c4cef647d1c79ead42a30f95308b8434ac74d8b4 100644 (file)
@@ -1346,6 +1346,7 @@ static int __build_screensrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 
        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;
@@ -1420,7 +1421,7 @@ static int __mute_by_manipulating_buffer(webrtc_gst_slot_s *source, GstElement *
        RET_VAL_IF(src_pad == NULL, WEBRTC_ERROR_INVALID_OPERATION, "src_pad is NULL");
 
        if (mute && source->camerasrc_probe_id == 0) {
-               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()");
                        return WEBRTC_ERROR_INVALID_OPERATION;
@@ -1573,6 +1574,8 @@ static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 
        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;
@@ -1719,6 +1722,7 @@ static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool us
 
        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 : ELEMENT_NAME_AUDIO_SRC)))
@@ -1755,6 +1759,7 @@ static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 
        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;
@@ -1968,7 +1973,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_block_probe_cb(GstPad *pad,  GstPadProbeInfo *info, gpointer u_data)
+static GstPadProbeReturn __fakesink_block_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
 {
        webrtc_gst_slot_s *source = u_data;
        gchar *media_type = NULL;
@@ -1982,7 +1987,7 @@ static GstPadProbeReturn __fakesink_block_probe_cb(GstPad *pad,  GstPadProbeInfo
        return GST_PAD_PROBE_OK;
 }
 
-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 *caps = NULL;
@@ -2703,6 +2708,8 @@ void _source_slot_destroy_cb(gpointer data)
 
                if (source->av[i].transceiver)
                        gst_object_unref(source->av[i].transceiver);
+
+               g_free(source->av[i].raw_format);
        }
 
        gst_bin_remove(GST_BIN(gst_element_get_parent(source->bin)), GST_ELEMENT(source->bin));
@@ -2772,9 +2779,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) {
@@ -3360,7 +3367,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;
@@ -3708,39 +3715,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;
@@ -4481,10 +4508,10 @@ int _set_screen_source_crop(webrtc_s *webrtc, unsigned int source_id, int x, int
        RET_VAL_IF(width == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "width is NULL");
        RET_VAL_IF(height == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "height is NULL");
 
-       screen_source =  gst_bin_get_by_name(source->bin, ELEMENT_NAME_SCREENSRC);
+       screen_source = gst_bin_get_by_name(source->bin, ELEMENT_NAME_SCREENSRC);
        RET_VAL_IF(screen_source == NULL, WEBRTC_ERROR_INVALID_OPERATION, "sreen_source is NULL");
 
-       videocrop =  gst_bin_get_by_name(source->bin, ELEMENT_NAME_VIDEOCROP);
+       videocrop = gst_bin_get_by_name(source->bin, ELEMENT_NAME_VIDEOCROP);
        RET_VAL_IF(videocrop == NULL, WEBRTC_ERROR_INVALID_OPERATION, "videocrop is NULL");
 
        LOG_INFO("set source crop x:%d, y:%d, width:%d, height:%d, mode:%s", x, y, w, h, (portrait_mode) ? "portrait" : "landscape");
@@ -4540,10 +4567,10 @@ int _unset_screen_source_crop(webrtc_s *webrtc, unsigned int source_id)
        RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
        RET_VAL_IF(source->type != WEBRTC_MEDIA_SOURCE_TYPE_SCREEN, WEBRTC_ERROR_INVALID_PARAMETER, "source type is not screen");
 
-       screen_source =  gst_bin_get_by_name(source->bin, ELEMENT_NAME_SCREENSRC);
+       screen_source = gst_bin_get_by_name(source->bin, ELEMENT_NAME_SCREENSRC);
        RET_VAL_IF(screen_source == NULL, WEBRTC_ERROR_INVALID_OPERATION, "sreen_source is NULL");
 
-       videocrop =  gst_bin_get_by_name(source->bin, ELEMENT_NAME_VIDEOCROP);
+       videocrop = gst_bin_get_by_name(source->bin, ELEMENT_NAME_VIDEOCROP);
        RET_VAL_IF(videocrop == NULL, WEBRTC_ERROR_INVALID_OPERATION, "videocrop is NULL");
 
        g_object_get(G_OBJECT(videocrop),
index e346a82dc694fbc48a88db1368baa36e5ff4e121..5e1517c602d4334b3307770bfda6a40c168bcde1 100644 (file)
@@ -297,7 +297,7 @@ void display_menu_webrtc_media_source(void)
 {
        switch (get_appdata()->menu_status) {
        case CURRENT_STATUS_ADD_MEDIA_SOURCE:
-        if (get_appdata()->input_count == 0)
+               if (get_appdata()->input_count == 0)
                    g_print("*** input media source type.(1:audiotest, 2:videotest, 3:mic, 4:camera, 5:screen, 6:file, 7:media packet, 8:custom audio, 9:custom video)\n");
                else if (get_appdata()->input_count == 1)
                        g_print("*** input value to enable AEC. (1:enable 0:disable)\n");