It doesn't support increasing framerate.
[Version] 0.3.246
[Issue Type] Improvement
Change-Id: Iea5ce0881ae55e1d881d847b88ff41dcede75a6f
int origin_height;
int width;
int height;
+ int origin_framerate;
int framerate;
} video_info;
struct {
void _set_caps_for_render(webrtc_gst_slot_s *source, GstCaps *caps, int av_idx);
void _unset_caps_for_render(webrtc_gst_slot_s *source, int av_idx);
int _update_caps_for_render_with_resolution(webrtc_gst_slot_s *source, int width, int height);
+int _update_caps_for_render_with_framerate(webrtc_gst_slot_s *source, int framerate);
void _set_need_decoding_for_loopback(webrtc_gst_slot_s *source, int av_idx, bool need_decoding);
void _destroy_looopback_render_pipeline(webrtc_gst_slot_s *source, int av_idx);
#define DEFAULT_ELEMENT_INPUT_SELECTOR "input-selector"
#define DEFAULT_ELEMENT_VIDEOCROP "videocrop"
#define DEFAULT_ELEMENT_VIDEOSCALE "videoscale"
+#define DEFAULT_ELEMENT_VIDEORATE "videorate"
#define DEFAULT_ELEMENT_FILESRC "filesrc"
#define ELEMENT_NAME_FIRST_CAPSFILTER "firstCapsfilter"
#define ELEMENT_NAME_AUDIO_APPSRC "audioAppsrc"
#define ELEMENT_NAME_VIDEO_APPSRC "videoAppsrc"
#define ELEMENT_NAME_VIDEOSCALE_CAPSFILTER "videoscaleCapsfilter"
+#define ELEMENT_NAME_VIDEORATE_CAPSFILTER "videorateCapsfilter"
typedef enum {
ELEMENT_APPSRC,
Name: capi-media-webrtc
Summary: A WebRTC library in Tizen Native API
-Version: 0.3.245
+Version: 0.3.246
Release: 0
Group: Multimedia/API
License: Apache-2.0
static GstPadProbeReturn __camerasrc_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
-static GstCaps *__make_video_raw_caps_with_framerate(webrtc_gst_slot_s *source, webrtc_ini_s *ini, int framerate)
-{
- GstCaps *caps = NULL;
-
- RET_VAL_IF(source == NULL, NULL, "source is NULL");
- RET_VAL_IF(ini == NULL, NULL, "ini is NULL");
-
- switch (source->type) {
- case WEBRTC_MEDIA_SOURCE_TYPE_CAMERA:
- case WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST:
- case WEBRTC_MEDIA_SOURCE_TYPE_SCREEN: {
- caps = gst_caps_new_simple(MEDIA_TYPE_VIDEO_RAW,
- "format", G_TYPE_STRING, _get_raw_format_from_ini(ini, source->type, MEDIA_TYPE_VIDEO),
- "framerate", GST_TYPE_FRACTION, framerate, 1,
- "width", G_TYPE_INT, source->video_info.width,
- "height", G_TYPE_INT, source->video_info.height,
- NULL);
- break;
- }
- default:
- LOG_ERROR_IF_REACHED("type(%d)", source->type);
- break;
- }
-
- return caps;
-}
-
//LCOV_EXCL_START
static bool __link_switch_srcs(GstElement *switch_element, GList *switch_src_list)
{
RET_VAL_IF(source == NULL, false, "source is NULL");
RET_VAL_IF(ini_source == NULL, false, "ini_source is NULL");
+ source->video_info.origin_framerate = ini_source->v_framerate;
source->video_info.framerate = ini_source->v_framerate;
+
source->video_info.origin_width = ini_source->v_width;
source->video_info.origin_height = ini_source->v_height;
_set_video_src_resolution(source, ini_source->v_width, ini_source->v_height);
webrtc_gst_slot_s *source;
GstElement *capsfilter;
bool drc_support;
+ GstCaps *new_caps = NULL;
RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "could not find source");
if (webrtc->state == WEBRTC_STATE_IDLE || drc_support) {
capsfilter = _find_element_in_bin(source->bin, ELEMENT_NAME_FIRST_CAPSFILTER);
+ if (capsfilter)
+ if (!(new_caps = _make_video_raw_caps_with_resolution(source, &webrtc->ini, width, height)))
+ return WEBRTC_ERROR_INVALID_OPERATION;
+
source->video_info.origin_width = width;
source->video_info.origin_height = height;
} else {
capsfilter = _find_element_in_bin(source->bin, ELEMENT_NAME_VIDEOSCALE_CAPSFILTER);
RET_VAL_IF(!capsfilter, WEBRTC_ERROR_INVALID_OPERATION, "not supported dynamic resolution change");
- }
- if (capsfilter) {
- GstCaps *new_caps;
+ new_caps = gst_caps_new_simple(MEDIA_TYPE_VIDEO_RAW,
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
+ NULL);
+ }
- if (!(new_caps = _make_video_raw_caps_with_resolution(source, &webrtc->ini, width, height)))
- return WEBRTC_ERROR_INVALID_OPERATION;
+ if (capsfilter && new_caps) {
PRINT_CAPS(new_caps, "capsfilter");
g_object_set(G_OBJECT(capsfilter), "caps", new_caps, NULL);
int _set_video_framerate(webrtc_s *webrtc, unsigned int source_id, int framerate)
{
+ int ret;
webrtc_gst_slot_s *source;
GstElement *capsfilter;
- GstCaps *new_caps = NULL;
RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "could not find source");
RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET), WEBRTC_ERROR_INVALID_PARAMETER, "this API does not support the media packet source");
RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_NULL), WEBRTC_ERROR_INVALID_PARAMETER, "this API does not support the null source");
- /* TODO: framerate reconfiguration implementation, until then it will return error. */
- RET_VAL_IF(webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_OPERATION, "for now, it is only supported in IDLE state");
+ if (webrtc->state == WEBRTC_STATE_IDLE) {
+ source->video_info.origin_framerate = framerate;
+ source->video_info.framerate = framerate;
- /* FIXME: check if the framerate is supported or not */
- if ((capsfilter = _find_element_in_bin(source->bin, ELEMENT_NAME_FIRST_CAPSFILTER))) {
- if (!(new_caps = __make_video_raw_caps_with_framerate(source, &webrtc->ini, framerate)))
- return WEBRTC_ERROR_INVALID_OPERATION;
- PRINT_CAPS(new_caps, "capsfilter");
+ return WEBRTC_ERROR_NONE;
+ }
+
+ RET_VAL_IF(framerate > source->video_info.origin_framerate, WEBRTC_ERROR_INVALID_OPERATION,
+ "it doesn't support increasing framerate. origin [%d] requested [%d]", source->video_info.origin_framerate, framerate);
+
+ if ((capsfilter = _find_element_in_bin(source->bin, ELEMENT_NAME_VIDEORATE_CAPSFILTER))) {
+ GstCaps *new_caps = gst_caps_new_simple(MEDIA_TYPE_VIDEO_RAW,
+ "framerate", GST_TYPE_FRACTION, framerate, 1,
+ NULL);
+ PRINT_CAPS(new_caps, ELEMENT_NAME_VIDEORATE_CAPSFILTER);
g_object_set(G_OBJECT(capsfilter), "caps", new_caps, NULL);
gst_caps_unref(new_caps);
-
}
+ ret = _update_caps_for_render_with_framerate(source, framerate);
+ RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to _update_caps_for_render_with_framerate()");
+
source->video_info.framerate = framerate;
LOG_INFO("webrtc[%p], source_id[%u], framerate[%d]", webrtc, source_id, framerate);
return WEBRTC_ERROR_NONE;
}
+static GstCaps *__make_video_raw_caps_with_framerate(webrtc_gst_slot_s *source, webrtc_ini_s *ini, int framerate)
+{
+ GstCaps *caps = NULL;
+
+ RET_VAL_IF(source == NULL, NULL, "source is NULL");
+ RET_VAL_IF(ini == NULL, NULL, "ini is NULL");
+
+ switch (source->type) {
+ case WEBRTC_MEDIA_SOURCE_TYPE_CAMERA:
+ case WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST:
+ case WEBRTC_MEDIA_SOURCE_TYPE_SCREEN: {
+ caps = gst_caps_new_simple(MEDIA_TYPE_VIDEO_RAW,
+ "format", G_TYPE_STRING, _get_raw_format_from_ini(ini, source->type, MEDIA_TYPE_VIDEO),
+ "framerate", GST_TYPE_FRACTION, framerate, 1,
+ "width", G_TYPE_INT, source->video_info.width,
+ "height", G_TYPE_INT, source->video_info.height,
+ NULL);
+ break;
+ }
+ default:
+ LOG_ERROR_IF_REACHED("type(%d)", source->type);
+ break;
+ }
+
+ return caps;
+}
+
+int _update_caps_for_render_with_framerate(webrtc_gst_slot_s *source, int framerate)
+{
+ GstCaps *new_caps;
+
+ RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
+
+ if (!(new_caps = __make_video_raw_caps_with_framerate(source, &source->webrtc->ini, framerate)))
+ return WEBRTC_ERROR_INVALID_OPERATION;
+ PRINT_CAPS(new_caps, "appsrc");
+
+ _unset_caps_for_render(source, AV_IDX_VIDEO);
+ _set_caps_for_render(source, new_caps, AV_IDX_VIDEO);
+
+ return WEBRTC_ERROR_NONE;
+}
+
void _set_need_decoding_for_loopback(webrtc_gst_slot_s *source, int av_idx, bool need_decoding)
{
RET_IF(source == NULL, "source is NULL");
if (!(source->media_types & MEDIA_TYPE_VIDEO))
return false;
+ if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE || source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET)
+ return false;
+
_get_video_encoded_support_from_ini(&webrtc->ini, source->type, &encoded_support);
if (encoded_support)
return false;
if (drc_support)
return false;
+ return true;
+}
+
+static bool __is_videorate_needed(webrtc_s *webrtc, webrtc_gst_slot_s *source)
+{
+ bool encoded_support;
+
+ RET_VAL_IF(webrtc == NULL, false, "webrtc is NULL");
+ RET_VAL_IF(source == NULL, false, "source is NULL");
+
+ if (!(source->media_types & MEDIA_TYPE_VIDEO))
+ return false;
+
if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE || source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET)
return false;
+ _get_video_encoded_support_from_ini(&webrtc->ini, source->type, &encoded_support);
+ if (encoded_support)
+ return false;
+
return true;
}
goto error;
APPEND_ELEMENT(*element_list, videoscaleCapsfilter);
- if ((caps = __make_default_raw_caps(source, &webrtc->ini))) {
- PRINT_CAPS(caps, ELEMENT_NAME_VIDEOSCALE_CAPSFILTER);
- g_object_set(G_OBJECT(videoscaleCapsfilter), "caps", caps, NULL);
+ caps = gst_caps_new_simple(MEDIA_TYPE_VIDEO_RAW,
+ "width", G_TYPE_INT, source->video_info.width,
+ "height", G_TYPE_INT, source->video_info.height,
+ NULL);
- gst_caps_unref(caps_for_render);
- caps_for_render = caps;
- }
+ PRINT_CAPS(caps, ELEMENT_NAME_VIDEOSCALE_CAPSFILTER);
+ g_object_set(G_OBJECT(videoscaleCapsfilter), "caps", caps, NULL);
+ gst_caps_unref(caps);
gst_object_unref(pad_for_render);
pad_for_render = gst_element_get_static_pad(videoscaleCapsfilter, "src");
}
- if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_SCREEN && !source->zerocopy_enabled) {
+ if (__is_videorate_needed(webrtc, source)) {
+ GstElement *videorate;
+ GstElement *videorateCapsfilter;
GstCaps *caps;
- if (!(videocrop = _create_element(DEFAULT_ELEMENT_VIDEOCROP, ELEMENT_NAME_VIDEOCROP)))
+ if (!(videorate = _create_element(DEFAULT_ELEMENT_VIDEORATE, NULL)))
goto error;
- APPEND_ELEMENT(*element_list, videocrop);
+ APPEND_ELEMENT(*element_list, videorate);
- if ((caps = __make_default_raw_caps(source, &webrtc->ini))) {
- PRINT_CAPS(caps, ELEMENT_NAME_VIDEOSCALE_CAPSFILTER);
+ if (!(videorateCapsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_VIDEORATE_CAPSFILTER)))
+ goto error;
+ APPEND_ELEMENT(*element_list, videorateCapsfilter);
- gst_caps_unref(caps_for_render);
- caps_for_render = caps;
- }
+ caps = gst_caps_new_simple(MEDIA_TYPE_VIDEO_RAW,
+ "framerate", GST_TYPE_FRACTION, source->video_info.framerate, 1,
+ NULL);
+
+ PRINT_CAPS(caps, ELEMENT_NAME_VIDEORATE_CAPSFILTER);
+ g_object_set(G_OBJECT(videorateCapsfilter), "caps", caps, NULL);
+ gst_caps_unref(caps);
+
+ gst_object_unref(pad_for_render);
+ pad_for_render = gst_element_get_static_pad(videorateCapsfilter, "src");
+ }
+
+ if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_SCREEN && !source->zerocopy_enabled) {
+ if (!(videocrop = _create_element(DEFAULT_ELEMENT_VIDEOCROP, ELEMENT_NAME_VIDEOCROP)))
+ goto error;
+ APPEND_ELEMENT(*element_list, videocrop);
gst_object_unref(pad_for_render);
pad_for_render = gst_element_get_static_pad(videocrop, "src");