From: backto.kim Date: Fri, 3 Jun 2022 07:02:38 +0000 (+0900) Subject: webrtc_source: Fix mute error for camera source which doesn't use tizen memory X-Git-Tag: submit/tizen/20220623.232237~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ec10ecd15d97b3c74172cbfa2624836f7722d03d;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_source: Fix mute error for camera source which doesn't use tizen memory [Version] 0.3.125 [Issue Type] Bug fix Change-Id: I8b05ef9e7029fb22f15928290b7a4326a28cd2e4 --- diff --git a/include/webrtc_private.h b/include/webrtc_private.h index b02c6f6c..7a487940 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -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; diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 77c3f36c..0b6a079d 100644 --- a/packaging/capi-media-webrtc.spec +++ b/packaging/capi-media-webrtc.spec @@ -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 diff --git a/src/webrtc_private.c b/src/webrtc_private.c index 9bf1988f..2d621e55 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -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"); diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 6fc850d6..c4cef647 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -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), diff --git a/test/webrtc_test_menu.c b/test/webrtc_test_menu.c index e346a82d..5e1517c6 100644 --- a/test/webrtc_test_menu.c +++ b/test/webrtc_test_menu.c @@ -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");