From: backto.kim Date: Wed, 15 Jun 2022 03:27:20 +0000 (+0900) Subject: webrtc_source: Fix mute error for camera source which doesn't use tizen memory X-Git-Tag: submit/tizen_6.5/20220620.013835^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c79ae6fa24873130c8a03648c88e54fa3386852c;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_source: Fix mute error for camera source which doesn't use tizen memory [Version] 0.2.173 [Issue Type] Bug fix Change-Id: I9bffc47f70d5192f0b4d67e136709ab03a61532c --- diff --git a/include/webrtc_private.h b/include/webrtc_private.h index f97a5e55..a4a0cae4 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -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 { diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 819e6bf2..f53e1e36 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.2.172 +Version: 0.2.173 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc_private.c b/src/webrtc_private.c index aba1094f..45d99d81 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -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"); diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 0a01638d..00740a4f 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -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;