Functions are added as below.
- webrtc_set_video_source_resolution()
- webrtc_get_video_source_resolution()
Test cases for these are added in webrtc_test.
[Version] 0.1.160
[Issue Type] API
Change-Id: Iea0ec96d4e05f900cd4d83e9480e38fb604ad1ab
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
* @retval #WEBRTC_ERROR_INVALID_STATE Invalid state
* @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE.
* @see webrtc_remove_media_source()
+ * @see webrtc_set_video_source_resolution()
+ * @see webrtc_get_video_source_resolution()
*/
int webrtc_add_media_source(webrtc_h webrtc, webrtc_media_source_type_e type, unsigned int *source_id);
*/
int webrtc_remove_media_source(webrtc_h webrtc, unsigned int source_id);
+/**
+ * @brief Sets a video source resolution.
+ * @details The following media source types are for the video source:\n
+ * #WEBRTC_MEDIA_SOURCE_TYPE_CAMERA\n
+ * #WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST\n
+ * #WEBRTC_MEDIA_SOURCE_TYPE_SCREEN
+ * @since_tizen 6.5
+ * @param[in] webrtc WebRTC handle
+ * @param[in] source_id The video source id
+ * @param[in] width The video width
+ * @param[in] height The video height
+ * @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
+ * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state
+ * @pre Add media source to @a webrtc to get @a source_id by calling webrtc_add_media_source().
+ * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE.
+ * @see webrtc_add_media_source()
+ * @see webrtc_get_video_source_resolution()
+ */
+int webrtc_set_video_source_resolution(webrtc_h webrtc, unsigned int source_id, int width, int height);
+
+/**
+ * @brief Gets the video source resolution.
+ * @details The following media source types are for the video source:\n
+ * #WEBRTC_MEDIA_SOURCE_TYPE_CAMERA\n
+ * #WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST\n
+ * #WEBRTC_MEDIA_SOURCE_TYPE_SCREEN
+ * @since_tizen 6.5
+ * @param[in] webrtc WebRTC handle
+ * @param[in] source_id The video source id
+ * @param[out] width The video width
+ * @param[out] height The video height
+ * @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 Add media source to @a webrtc to get @a source_id by calling webrtc_add_media_source().
+ * @see webrtc_add_media_source()
+ * @see webrtc_set_video_source_resolution()
+ */
+int webrtc_get_video_source_resolution(webrtc_h webrtc, unsigned int source_id, int *width, int *height);
+
/**
* @brief Sets a callback function to be invoked when the buffer state of media packet source is changed.
* @since_tizen 6.5
webrtc_media_source_type_e type;
int media_types; /* values of media_type_e combined with bitwise 'or' */
int mlines[2]; /* index 0 for audio, 1 for video */
+ struct {
+ int width;
+ int height;
+ } video_info;
media_format_h media_format;
bool zerocopy_enabled;
GstAllocator *allocator;
int _gst_pipeline_set_state(webrtc_s *webrtc, GstState state);
int _add_media_source(webrtc_s *webrtc, webrtc_media_source_type_e type, unsigned int *source_id);
int _remove_media_source(webrtc_s *webrtc, unsigned int source_id);
+int _set_video_source_resolution(webrtc_s *webrtc, unsigned int source_id, int width, int height);
+int _get_video_source_resolution(webrtc_s *webrtc, unsigned int source_id, int *width, int *height);
int _set_media_format(webrtc_s *webrtc, unsigned int source_id, media_format_h format);
bool _check_if_format_is_set_to_packet_sources(webrtc_s *webrtc);
int _push_media_packet(webrtc_s *webrtc, unsigned int source_id, media_packet_h packet);
Name: capi-media-webrtc
Summary: A WebRTC library in Tizen Native API
-Version: 0.1.159
+Version: 0.1.160
Release: 0
Group: Multimedia/API
License: Apache-2.0
return ret;
}
+int webrtc_set_video_source_resolution(webrtc_h webrtc, unsigned int source_id, int width, int height)
+{
+ int ret = WEBRTC_ERROR_NONE;
+ webrtc_s *_webrtc = (webrtc_s*)webrtc;
+
+ RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(width <= 0, WEBRTC_ERROR_INVALID_PARAMETER, "width <= 0");
+ RET_VAL_IF(height <= 0, WEBRTC_ERROR_INVALID_PARAMETER, "height <= 0");
+
+ g_mutex_lock(&_webrtc->mutex);
+
+ RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be IDLE");
+
+ ret = _set_video_source_resolution(webrtc, source_id, width, height);
+
+ g_mutex_unlock(&_webrtc->mutex);
+
+ return ret;
+}
+
+int webrtc_get_video_source_resolution(webrtc_h webrtc, unsigned int source_id, int *width, int *height)
+{
+ int ret = WEBRTC_ERROR_NONE;
+ webrtc_s *_webrtc = (webrtc_s*)webrtc;
+
+ RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(width == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "width is NULL");
+ RET_VAL_IF(height == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "height is NULL");
+
+ g_mutex_lock(&_webrtc->mutex);
+
+ ret = _get_video_source_resolution(webrtc, source_id, width, height);
+
+ g_mutex_unlock(&_webrtc->mutex);
+
+ return ret;
+}
+
int webrtc_media_packet_source_set_buffer_state_changed_cb(webrtc_h webrtc, unsigned int source_id, webrtc_media_packet_source_buffer_state_changed_cb callback, void *user_data)
{
webrtc_s *_webrtc = (webrtc_s*)webrtc;
#define DEFAULT_ELEMENT_CAPSFILTER "capsfilter"
#define DEFAULT_ELEMENT_QUEUE "queue"
+#define ELEMENT_NAME_FIRST_CAPSFILTER "firstCapsfilter"
+
typedef enum {
CODEC_TYPE_OPUS,
CODEC_TYPE_VORBIS,
}
}
+static GstCaps *__make_video_raw_caps_with_resolution(webrtc_gst_slot_s *source, webrtc_ini_s *ini, int width, int height)
+{
+ GstCaps *caps = NULL;
+ ini_item_media_source_s *ini_source;
+
+ RET_VAL_IF(source == NULL, NULL, "source is NULL");
+ RET_VAL_IF(ini == NULL, NULL, "ini is NULL");
+
+ ini_source = _ini_get_source_by_type(ini, source->type);
+ if (ini_source == NULL)
+ ini_source = &ini->media_source;
+
+ 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, ini_source->v_raw_format,
+ "framerate", GST_TYPE_FRACTION, ini_source->v_framerate, 1,
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
+ NULL);
+ source->video_info.width = width;
+ source->video_info.height = height;
+ break;
+ default:
+ LOG_ERROR_IF_REACHED("type(%d)", source->type);
+ break;
+ }
+
+ return caps;
+}
+
static GstCaps *__make_default_raw_caps(webrtc_gst_slot_s *source, webrtc_ini_s *ini)
{
GstCaps *caps = NULL;
"width", G_TYPE_INT, ini_source->v_width,
"height", G_TYPE_INT, ini_source->v_height,
NULL);
+ source->video_info.width = ini_source->v_width;
+ source->video_info.height = ini_source->v_height;
break;
case WEBRTC_MEDIA_SOURCE_TYPE_MIC:
"width", G_TYPE_INT, width,
"height", G_TYPE_INT, height,
NULL);
+
} else {
LOG_ERROR_IF_REACHED("source->media_types(0x%x)", source->media_types);
}
"width", G_TYPE_INT, ini_source->v_width,
"height", G_TYPE_INT, ini_source->v_height,
NULL);
+ source->video_info.width = ini_source->v_width;
+ source->video_info.height = ini_source->v_height;
break;
case WEBRTC_MEDIA_SOURCE_TYPE_MIC:
RET_VAL_IF(capsfilter2 == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "capsfilter2 is NULL");
if (capsfilter) {
- if (!(*capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, NULL))) {
+ if (!(*capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_FIRST_CAPSFILTER))) {
LOG_ERROR("failed to create capsfilter");
return WEBRTC_ERROR_INVALID_OPERATION;
}
return ret;
}
+int _set_video_source_resolution(webrtc_s *webrtc, unsigned int source_id, int width, int height)
+{
+ webrtc_gst_slot_s *source;
+ GstElement *capsfilter;
+ GstCaps *new_caps = NULL;
+ gchar *caps_str;
+
+ 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->media_types & MEDIA_TYPE_VIDEO) == 0x0, WEBRTC_ERROR_INVALID_PARAMETER, "it's not a video 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");
+
+ /* it targets the capsfilter element right after the source element */
+ capsfilter = __find_element_in_bin(source->bin, ELEMENT_NAME_FIRST_CAPSFILTER);
+ RET_VAL_IF(capsfilter == NULL, WEBRTC_ERROR_INVALID_OPERATION, "could not find the first capsfilter");
+
+ /* FIXME: check if the [width x height] is supported or not */
+
+ if (!(new_caps = __make_video_raw_caps_with_resolution(source, &webrtc->ini, width, height)))
+ return WEBRTC_ERROR_INVALID_OPERATION;
+
+ caps_str = gst_caps_to_string(new_caps);
+ LOG_INFO("capsfilter caps[%s]", caps_str);
+ g_free(caps_str);
+
+ g_object_set(G_OBJECT(capsfilter), "caps", new_caps, NULL);
+ gst_caps_unref(new_caps);
+
+ return WEBRTC_ERROR_NONE;
+}
+
+int _get_video_source_resolution(webrtc_s *webrtc, unsigned int source_id, int *width, int *height)
+{
+ webrtc_gst_slot_s *source;
+
+ RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(width == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "width is NULL");
+ RET_VAL_IF(height == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "height 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->media_types & MEDIA_TYPE_VIDEO) == 0x0, WEBRTC_ERROR_INVALID_PARAMETER, "it's not a video 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");
+
+ *width = source->video_info.width;
+ *height = source->video_info.height;
+
+ LOG_INFO("source_id[%u], [%dx%d]", source_id, *width, *height);
+
+ return WEBRTC_ERROR_NONE;
+}
+
int _set_media_format(webrtc_s *webrtc, unsigned int source_id, media_format_h format)
{
int ret;
CURRENT_STATUS_MAINMENU,
CURRENT_STATUS_ADD_MEDIA_SOURCE,
CURRENT_STATUS_REMOVE_MEDIA_SOURCE,
+ CURRENT_STATUS_SET_VIDEO_SOURCE_RESOLUTION,
+ CURRENT_STATUS_GET_VIDEO_SOURCE_RESOLUTION,
CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_BUFFER_STATE_CHANGED_CB,
CURRENT_STATUS_MEDIA_PACKET_SOURCE_UNSET_BUFFER_STATE_CHANGED_CB,
CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_FORMAT,
}
}
+static void _webrtc_set_video_source_resolution(int index, unsigned int source_id, int width, int height)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ ret = webrtc_set_video_source_resolution(g_conns[index].webrtc, source_id, width, height);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_print("failed to webrtc_set_video_source_resolution(), source_id[%u], ret[0x%x]\n", source_id, ret);
+ else
+ g_print("webrtc_set_video_source_resolution() success, source_id[%u], [%dx%d]\n", source_id, width, height);
+}
+
+static void _webrtc_get_video_source_resolution(int index, unsigned int source_id)
+{
+ int ret = WEBRTC_ERROR_NONE;
+ int width;
+ int height;
+
+ ret = webrtc_get_video_source_resolution(g_conns[index].webrtc, source_id, &width, &height);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_print("failed to webrtc_set_video_source_resolution(), source_id[%u], ret[0x%x]\n", source_id, ret);
+ else
+ g_print("webrtc_get_video_source_resolution() success, source_id[%u], [%dx%d]\n", source_id, width, height);
+}
+
#define VIDEO_WIDTH 352
#define VIDEO_HEIGHT 288
#define VIDEO_FRAME_RATE 30
} else if (strncmp(cmd, "r", 1) == 0) {
g_conns[g_conn_index].menu_state = CURRENT_STATUS_REMOVE_MEDIA_SOURCE;
+ } else if (strncmp(cmd, "v", 1) == 0) {
+ g_conns[g_conn_index].menu_state = CURRENT_STATUS_SET_VIDEO_SOURCE_RESOLUTION;
+
+ } else if (strncmp(cmd, "l", 1) == 0) {
+ g_conns[g_conn_index].menu_state = CURRENT_STATUS_GET_VIDEO_SOURCE_RESOLUTION;
+
} else if (strncmp(cmd, "s", 1) == 0) {
_webrtc_start(g_conn_index);
g_print("g. Get state\n");
g_print("a. Add media source\t");
g_print("r. Remove media source\n");
+ g_print("v. Set video source resolution\t");
+ g_print("l. Get video source resolution\n");
g_print("sf. Set media format to media packet source\n");
g_print("gd. Get transceiver direction\t");
g_print("td. Set transceiver direction\n");
} else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_REMOVE_MEDIA_SOURCE) {
g_print("*** input media source id to remove.\n");
+ } else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_SET_VIDEO_SOURCE_RESOLUTION) {
+ if (g_conns[g_conn_index].cnt == 0)
+ g_print("*** input source id.\n");
+ else if (g_conns[g_conn_index].cnt == 1)
+ g_print("*** input width.\n");
+ else if (g_conns[g_conn_index].cnt == 2)
+ g_print("*** input height.\n");
+
+ } else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_GET_VIDEO_SOURCE_RESOLUTION) {
+ g_print("*** input source id.\n");
+
} else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_BUFFER_STATE_CHANGED_CB) {
g_print("*** input media packet source id to set buffer state changed callback.\n");
reset_menu_state();
break;
}
+ case CURRENT_STATUS_SET_VIDEO_SOURCE_RESOLUTION: {
+ static unsigned int id;
+ static int width;
+ static int height;
+ value = atoi(cmd);
+
+ switch (g_conns[g_conn_index].cnt) {
+ case 0:
+ id = value;
+ g_conns[g_conn_index].cnt++;
+ break;
+ case 1:
+ width = value;
+ g_conns[g_conn_index].cnt++;
+ break;
+ case 2:
+ height = value;
+ _webrtc_set_video_source_resolution(g_conn_index, id, width, height);
+ id = width = height = 0;
+ g_conns[g_conn_index].cnt = 0;
+ reset_menu_state();
+ break;
+ }
+ break;
+ }
+ case CURRENT_STATUS_GET_VIDEO_SOURCE_RESOLUTION: {
+ value = atoi(cmd);
+ _webrtc_get_video_source_resolution(g_conn_index, value);
+ reset_menu_state();
+ break;
+ }
case CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_BUFFER_STATE_CHANGED_CB: {
value = atoi(cmd);
_webrtc_media_packet_source_set_buffer_state_changed_cb(g_conn_index, value);