*/
int webrtc_set_ecore_wl_display(webrtc_h webrtc, unsigned int track_id, void *ecore_wl_window);
+/**
+ * @internal
+ * @brief Sets a display surface id to the video track to be rendered.
+ * @since_tizen 7.0
+ * @remarks Call this function within webrtc_track_added_cb(), otherwise #WEBRTC_ERROR_INVALID_OPERATION will be returned.\n
+ * If webrtc_set_encoded_video_frame_cb() has been called, it will return #WEBRTC_ERROR_INVALID_OPERATION.
+ * @param[in] webrtc WebRTC handle
+ * @param[in] track_id The track id
+ * @param[in] surface_id The display surface id
+ * @param[in] x The start X coordinate of the display surface
+ * @param[in] y The start Y coordinate of the display surface
+ * @param[in] width Width of the display surface
+ * @param[in] height Height of the display surface
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation
+ * @pre webrtc_track_added_cb() must be set by calling webrtc_set_track_added_cb().
+ * @see webrtc_set_track_added_cb()
+ * @see webrtc_unset_track_added_cb()
+ * @see webrtc_set_display_mode()
+ * @see webrtc_get_display_mode()
+ * @see webrtc_set_display_visible()
+ * @see webrtc_get_display_visible()
+ */
+int webrtc_set_display_surface_id(webrtc_h webrtc, unsigned int track_id, int surface_id, int x, int y, int width, int height);
+
/**
* @internal
* @brief Sets mute to the audio track.
void *surface;
int type;
int overlay_surface_id;
+ int x;
+ int y;
+ int w;
+ int h;
GMutex mutex;
mm_display_interface_h mm_display;
int _add_forwarding_sink_bin(webrtc_s *webrtc, GstPad *src_pad, bool is_audio);
int _set_stream_info_to_sink(webrtc_s *webrtc, unsigned int track_id, sound_stream_info_h stream_info);
int _set_display_to_sink(webrtc_s *webrtc, unsigned int track_id, unsigned int type, void *display);
+int _set_display_surface_id_to_sink(webrtc_s *webrtc, unsigned int track_id, int surface_id, int x, int y, int width, int height);
int _set_display_mode_to_sink(webrtc_s *webrtc, unsigned int track_id, webrtc_display_mode_e mode);
int _get_display_mode_from_sink(webrtc_s *webrtc, unsigned int track_id, webrtc_display_mode_e *mode);
int _set_display_visible_to_sink(webrtc_s *webrtc, unsigned int track_id, bool visible);
/* display */
void _video_stream_decoded_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data);
int _apply_display(webrtc_display_s *display);
-webrtc_display_s *_alloc_display(void);
+webrtc_display_s *_alloc_display(bool use_mm_display);
void _release_display(webrtc_display_s *display);
void _set_display_type_and_surface(webrtc_display_s *display, webrtc_display_type_e type, void *surface);
+void _set_display_surface_id(webrtc_display_s *display, int surface_id, int x, int y, int w, int h);
int _set_display_mode(webrtc_display_s *display, webrtc_display_mode_e mode);
int _get_display_mode(webrtc_display_s *display, webrtc_display_mode_e *mode);
int _set_display_visible(webrtc_display_s *display, bool visible);
Name: capi-media-webrtc
Summary: A WebRTC library in Tizen Native API
-Version: 0.3.291
+Version: 0.3.292
Release: 0
Group: Multimedia/API
License: Apache-2.0
RET_VAL_IF(display->type != WEBRTC_DISPLAY_TYPE_OVERLAY && display->type != WEBRTC_DISPLAY_TYPE_ECORE_WL,
WEBRTC_ERROR_INVALID_OPERATION, "invalid display type(%d)", display->type);
+ if (display->overlay_surface_id > 0) {
+ /* NOTE: In this case, we did not create mm_display handle, therefore just skip it. */
+ LOG_DEBUG("already have overlay_surface_id[%d], skip it", display->overlay_surface_id);
+ return WEBRTC_ERROR_NONE;
+ }
+
if (display->type == WEBRTC_DISPLAY_TYPE_ECORE_WL)
type = MM_DISPLAY_TYPE_OVERLAY_EXT;
return ret;
}
-webrtc_display_s *_alloc_display(void)
+webrtc_display_s *_alloc_display(bool use_mm_display)
{
webrtc_display_s *display = g_new0(webrtc_display_s, 1);
- if (mm_display_interface_init(&display->mm_display) != MM_ERROR_NONE) {
+ if (use_mm_display && mm_display_interface_init(&display->mm_display) != MM_ERROR_NONE) {
LOG_ERROR("failed to mm_display_interface_init()");
g_free(display);
return NULL;
display->mode = WEBRTC_DISPLAY_MODE_LETTER_BOX;
display->visible = true;
- LOG_DEBUG("alloc display[%p, mm_display:%p, mode:%u, visible:%u]",
- display, display->mm_display, display->mode, display->visible);
+ LOG_DEBUG("use_mm_display[%d], display[%p, mm_display:%p, mode:%u, visible:%u]",
+ use_mm_display, display, display->mm_display, display->mode, display->visible);
return display;
}
LOG_INFO("display[%p, type:%d, surface:%p]", display, type, surface);
}
+void _set_display_surface_id(webrtc_display_s *display, int surface_id, int x, int y, int w, int h)
+{
+ g_autoptr(GMutexLocker) locker = NULL;
+
+ RET_IF(display == NULL, "display is NULL");
+
+ locker = g_mutex_locker_new(&display->mutex);
+
+ display->overlay_surface_id = surface_id;
+ display->x = x;
+ display->y = y;
+ display->w = w;
+ display->h = h;
+
+ LOG_INFO("display[%p, surface_id:%d, x:%d, y:%d, w:%d, h:%d]", display, surface_id, x, y, w, h);
+}
+
void _release_display(webrtc_display_s *display)
{
RET_IF(display == NULL, "display is NULL");
return ret;
}
+int webrtc_set_display_surface_id(webrtc_h webrtc, unsigned int track_id, int surface_id, int x, int y, int width, int height)
+{
+ g_autoptr(GMutexLocker) locker = NULL;
+ webrtc_s *_webrtc = (webrtc_s *)webrtc;
+
+ RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(track_id == 0, WEBRTC_ERROR_INVALID_PARAMETER, "track id is 0");
+
+ locker = g_mutex_locker_new(&_webrtc->mutex);
+
+ RET_VAL_IF(_webrtc->track_added_cb.callback == NULL, WEBRTC_ERROR_INVALID_OPERATION, "track added callback was not set");
+ RET_VAL_IF(_webrtc->encoded_video_frame_cb.callback, WEBRTC_ERROR_INVALID_OPERATION, "encoded video frame callback was set");
+ RET_VAL_IF(!_is_owner_of_track_build_context(_webrtc, track_id), WEBRTC_ERROR_INVALID_OPERATION,
+ "this function should be called within the track added callback");
+
+ return _set_display_surface_id_to_sink(webrtc, track_id, surface_id, x, y, width, height);
+}
+
int webrtc_set_audio_mute(webrtc_h webrtc, unsigned int track_id, bool mute)
{
g_autoptr(GMutexLocker) locker = NULL;
/* FIXME: The order of setting property and display is important when 'use-tbm' is true. The reverse does not work */
gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(videosink), sink->display->overlay_surface_id);
+ LOG_DEBUG("overlay_surface_id[%d]", sink->display->overlay_surface_id);
+ if (sink->display->w > 0 && sink->display->h > 0) {
+ gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(videosink), sink->display->x, sink->display->y,
+ sink->display->w, sink->display->h);
+ LOG_DEBUG("render rectangle[x:%d, y:%d, w:%d, h:%d]", sink->display->x, sink->display->y,
+ sink->display->w, sink->display->h);
+ }
if (!g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(videosink)), "display-geometry-method")) {
LOG_ERROR("could not find 'display-geometry-method' property");
goto exit;
RET_VAL_IF((sink->media_types & MEDIA_TYPE_VIDEO) == 0x0, WEBRTC_ERROR_INVALID_OPERATION, "it's not a video track");
if (sink->display == NULL) {
- sink->display = _alloc_display();
+ sink->display = _alloc_display(true);
RET_VAL_IF(sink->display == NULL, WEBRTC_ERROR_INVALID_OPERATION, "sink->display is NULL");
}
return WEBRTC_ERROR_NONE;
}
+int _set_display_surface_id_to_sink(webrtc_s *webrtc, unsigned int track_id, int surface_id, int x, int y, int width, int height)
+{
+ webrtc_gst_slot_s *sink;
+
+ RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(track_id == 0, WEBRTC_ERROR_INVALID_PARAMETER, "track id is 0");
+ RET_VAL_IF(width <= 0 || height <= 0, WEBRTC_ERROR_INVALID_PARAMETER, "invalid width or height");
+
+ sink = __find_sink_slot_by_id(webrtc, track_id);
+ RET_VAL_IF(sink == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "sink is NULL");
+ RET_VAL_IF(sink->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
+ RET_VAL_IF(sink->encoded_frame_cb != NULL, WEBRTC_ERROR_INVALID_OPERATION, "it may be a forwarding sink for encoded frame callback");
+ RET_VAL_IF((sink->media_types & MEDIA_TYPE_VIDEO) == 0x0, WEBRTC_ERROR_INVALID_OPERATION, "it's not a video track");
+
+ if (sink->display == NULL) {
+ sink->display = _alloc_display(false);
+ RET_VAL_IF(sink->display == NULL, WEBRTC_ERROR_INVALID_OPERATION, "sink->display is NULL");
+ }
+
+ LOG_INFO("webrtc[%p] track_id[%u]", webrtc, track_id);
+
+ _set_display_surface_id(sink->display, surface_id, x, y, width, height);
+
+ return WEBRTC_ERROR_NONE;
+}
+
int _set_display_mode_to_sink(webrtc_s *webrtc, unsigned int track_id, webrtc_display_mode_e mode)
{
webrtc_gst_slot_s *sink;
RET_VAL_IF(source->av[AV_IDX_VIDEO].render.pipeline, WEBRTC_ERROR_INVALID_OPERATION, "video loopback has already been set");
if (source->display == NULL) {
- source->display = _alloc_display();
+ source->display = _alloc_display(true);
RET_VAL_IF(source->display == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source->display is NULL");
}