From d457ffa85b00d969ff4108eed5c260a37c567820 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Wed, 10 Jun 2020 10:06:18 +0900 Subject: [PATCH] Improve media_streamer_node_set_pad_format() to support the WebRTC - Newly add ms_webrtcbin_set_pad_format() and __ms_rtp_node_set_pad_format() - Add VP8 and OPUS type to ms_convert_mime_to_rtp_format(media_format_mimetype_e mime) - VP8 and OPUS can be convert to rtp format by this function [Version] 0.1.59 [Issue Type] New feature Change-Id: Idea5134bf8b5e4b6dda123413eb9a4f438dbb62d Signed-off-by: Hyunil --- include/media_streamer_gst_webrtc.h | 1 + packaging/capi-media-streamer.spec | 2 +- src/media_streamer_gst_webrtc.c | 58 +++++++++++++++++++++++++++++++ src/media_streamer_node.c | 69 +++++++++++++++++++++++-------------- src/media_streamer_util.c | 6 +++- 5 files changed, 109 insertions(+), 27 deletions(-) diff --git a/include/media_streamer_gst_webrtc.h b/include/media_streamer_gst_webrtc.h index 4409d53..dbaf3a9 100644 --- a/include/media_streamer_gst_webrtc.h +++ b/include/media_streamer_gst_webrtc.h @@ -46,6 +46,7 @@ int ms_webrtcbin_add_ice_candidate(media_streamer_node_s *webrtc_node, const cha int ms_webrtcbin_set_stun_server(media_streamer_node_s *webrtc_node, const char *stun_server_url); +int ms_webrtcbin_set_pad_format(GstElement *webrtc_container, const char *pad_name, media_format_h fmt); #ifdef __cplusplus } diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index 4f87b88..7a4f903 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -1,6 +1,6 @@ Name: capi-media-streamer Summary: A Media Streamer API -Version: 0.1.58 +Version: 0.1.59 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_streamer_gst_webrtc.c b/src/media_streamer_gst_webrtc.c index a0d3698..0bc478e 100644 --- a/src/media_streamer_gst_webrtc.c +++ b/src/media_streamer_gst_webrtc.c @@ -24,6 +24,64 @@ #include "media_streamer_gst_webrtc.h" #include "media_streamer_node.h" +int ms_webrtcbin_set_pad_format(GstElement *webrtc_container, const char *pad_name, media_format_h fmt) +{ + int ret = MEDIA_STREAMER_ERROR_NONE; + media_format_mimetype_e mime; + GstCaps *caps = NULL; + GstPad *sinkpad = NULL; + gchar *media = NULL; + gchar *caps_str = NULL; + const gchar *encoding_name = NULL; + gint payload = 0; + + ms_retvm_if(webrtc_container == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "webrtc_container is NULL"); + ms_retvm_if(pad_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "pad_name is NULL"); + ms_retvm_if(fmt == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "fmt is NULL"); + + ms_debug_fenter(); + + sinkpad = gst_element_get_static_pad(webrtc_container, pad_name); + if (!sinkpad) { + ms_error("[%s] doesn`t have valid pad [%s]", GST_ELEMENT_NAME(webrtc_container), pad_name); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + if (!media_format_get_video_info(fmt, &mime, NULL, NULL, NULL, NULL) && + g_strrstr(pad_name, MS_RTP_PAD_VIDEO_IN)) { + media = "video"; + payload = 96; + } else if (!media_format_get_audio_info(fmt, &mime, NULL, NULL, NULL, NULL) && + g_strrstr(pad_name, MS_RTP_PAD_AUDIO_IN)) { + media = "audio"; + payload = 97; + } else { + ms_error("format is not video or audio format"); + goto end; + } + encoding_name = ms_convert_mime_to_rtp_format(mime); + + caps = gst_caps_new_simple("application/x-rtp", + "media", G_TYPE_STRING, media, + "encoding-name", G_TYPE_STRING, encoding_name, + "payload", G_TYPE_INT, payload, NULL); + + if (!gst_pad_set_caps(sinkpad, caps)) { + ms_error("[%s]'s pad [%s] can't be set with the given format", GST_ELEMENT_NAME(webrtc_container), pad_name); + ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION; + goto end; + } + caps_str = gst_caps_to_string(caps); + ms_info("[%s]'s pad [%s] is set with the given format[%s]", GST_ELEMENT_NAME(webrtc_container), pad_name, caps_str); + MS_SAFE_GFREE(caps_str); + +end: + MS_SAFE_UNREF(sinkpad); + MS_SAFE_UNREF(caps); + + return ret; +} + static gchar *__make_ice_candidate_message(guint mlineindex, gchar *candidate) { JsonObject *ice, *msg; diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c index f0706f2..82ccef7 100644 --- a/src/media_streamer_node.c +++ b/src/media_streamer_node.c @@ -1838,6 +1838,44 @@ int ms_node_get_param_value(media_streamer_node_s *node, param_s *param, char ** return ret; } +static int __ms_rtp_node_set_pad_format(media_streamer_node_s *node, const char *pad_name, media_format_h fmt) +{ + int ret = MEDIA_STREAMER_ERROR_NONE; + media_format_mimetype_e mime; + gchar *rtp_caps_str = NULL; + + ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL"); + ms_retvm_if(node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node's element is NULL"); + ms_retvm_if(pad_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "pad_name is NULL"); + ms_retvm_if(fmt == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "fmt is NULL"); + + ms_debug_fenter(); + + /* It is needed to set 'application/x-rtp' for audio and video udpsrc */ + if (g_strrstr(pad_name, MS_RTP_PAD_VIDEO_IN)) { + ret = media_format_get_video_info(fmt, &mime, NULL, NULL, NULL, NULL); + if (MEDIA_FORMAT_ERROR_NONE == ret) { + rtp_caps_str = g_strdup_printf("application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=%s", ms_convert_mime_to_rtp_format(mime)); + param_s param = {MEDIA_STREAMER_PARAM_VIDEO_IN_FORMAT, MEDIA_STREAMER_PARAM_VIDEO_IN_FORMAT}; + ret = ms_node_set_param_value(node, ¶m, rtp_caps_str); + } + } else if (g_strrstr(pad_name, MS_RTP_PAD_AUDIO_IN)) { + int audio_channels, audio_samplerate; + ret = media_format_get_audio_info(fmt, &mime, &audio_channels, &audio_samplerate, NULL, NULL); + if (MEDIA_FORMAT_ERROR_NONE == ret) { + rtp_caps_str = g_strdup_printf("application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)AMR,encoding-params=(string)1,octet-align=(string)1"); + param_s param = {MEDIA_STREAMER_PARAM_AUDIO_IN_FORMAT, MEDIA_STREAMER_PARAM_AUDIO_IN_FORMAT}; + ret = ms_node_set_param_value(node, ¶m, rtp_caps_str); + } + } else { + ms_error("[%s]'s pad [%s] can't be set with the given format", GST_ELEMENT_NAME(node->gst_element), pad_name); + ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + MS_SAFE_GFREE(rtp_caps_str); + + return ret; +} + int ms_node_set_pad_format(media_streamer_node_s *node, const char *pad_name, media_format_h fmt) { int ret = MEDIA_STREAMER_ERROR_NONE; @@ -1845,35 +1883,16 @@ int ms_node_set_pad_format(media_streamer_node_s *node, const char *pad_name, me ms_debug_fenter(); ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL"); + ms_retvm_if(node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node's element is NULL"); ms_retvm_if(pad_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "pad_name is NULL"); ms_retvm_if(fmt == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "fmt is NULL"); - if (node->type == MEDIA_STREAMER_NODE_TYPE_RTP) { - media_format_mimetype_e mime; - gchar *rtp_caps_str = NULL; - - /* It is needed to set 'application/x-rtp' for audio and video udpsrc */ - if (g_strrstr(pad_name, MS_RTP_PAD_VIDEO_IN)) { - ret = media_format_get_video_info(fmt, &mime, NULL, NULL, NULL, NULL); - if (MEDIA_FORMAT_ERROR_NONE == ret) { - rtp_caps_str = g_strdup_printf("application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=%s", ms_convert_mime_to_rtp_format(mime)); - param_s param = {MEDIA_STREAMER_PARAM_VIDEO_IN_FORMAT, MEDIA_STREAMER_PARAM_VIDEO_IN_FORMAT}; - ret = ms_node_set_param_value(node, ¶m, rtp_caps_str); - } - } else if (g_strrstr(pad_name, MS_RTP_PAD_AUDIO_IN)) { - int audio_channels, audio_samplerate; - ret = media_format_get_audio_info(fmt, &mime, &audio_channels, &audio_samplerate, NULL, NULL); - if (MEDIA_FORMAT_ERROR_NONE == ret) { - rtp_caps_str = g_strdup_printf("application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)AMR,encoding-params=(string)1,octet-align=(string)1"); - param_s param = {MEDIA_STREAMER_PARAM_AUDIO_IN_FORMAT, MEDIA_STREAMER_PARAM_AUDIO_IN_FORMAT}; - ret = ms_node_set_param_value(node, ¶m, rtp_caps_str); - } - } - - MS_SAFE_GFREE(rtp_caps_str); - } else { + if (node->type == MEDIA_STREAMER_NODE_TYPE_RTP) + ret = __ms_rtp_node_set_pad_format(node, pad_name, fmt); + else if (node->type == MEDIA_STREAMER_NODE_TYPE_WEBRTC) + ret = ms_webrtcbin_set_pad_format(node->gst_element, pad_name, fmt); + else ret = ms_element_set_fmt(node->gst_element, pad_name, fmt); - } ms_debug_fleave(); diff --git a/src/media_streamer_util.c b/src/media_streamer_util.c index 87826d4..c9f5106 100644 --- a/src/media_streamer_util.c +++ b/src/media_streamer_util.c @@ -229,10 +229,14 @@ const gchar *ms_convert_mime_to_rtp_format(media_format_mimetype_e mime) case MEDIA_FORMAT_H264_MP: case MEDIA_FORMAT_H264_SP: return "H264"; + case MEDIA_FORMAT_VP8: + return "VP8"; + case MEDIA_FORMAT_OPUS: + return "OPUS"; case MEDIA_FORMAT_PCM: return "L16"; default: - ms_error("Invalid or Unsupported media format [%d].", mime); + ms_error("Invalid or Unsupported media format [0x%x].", mime); return NULL; } } -- 2.7.4