#define MEDIA_STREAMER_PARAM_PORT "port"
/**
+ * @brief Definition for RTP packet latency of jitterbuffers of rtpbin or WebRTC node.
+ * @details Default amount of ms to buffer in the jitterbuffers.\n
+ * Data type is string and default value is "200".
+ * @since_tizen 6.0
+ * @see media_streamer_node_get_params()
+ */
+#define MEDIA_STREAMER_PARAM_RTP_LATENCY "rtp-latency"
+
+/**
* @brief Definition for video port parameter of source node.
* @details The port to receive the video packets from.\n
* Data type is integer.
#define MEDIA_STREAMER_PARAM_PLAYLIST_LOCATION "playlist-location"
/**
+ * @brief Definition for maximum lateness of sink node.
+ * @details The maximum number of nanoseconds that a buffer can be late before it is dropped (-1 unlimited).\n
+ * The range is from "-1" to "9223372036854775807".\n
+ * Data type is string and default value is "5000000".
+ * @since_tizen 6.0
+ * @see media_streamer_node_get_params()
+ */
+#define MEDIA_STREAMER_PARAM_SINK_MAX_LATENESS "max-lateness"
+
+/**
* @brief Definition for the name of the sink pad that receives video data.
* @since_tizen 6.0
* @remarks A node of #MEDIA_STREAMER_NODE_TYPE_RTP or #MEDIA_STREAMER_NODE_TYPE_WEBRTC type has this pad.
#define DEFAULT_AUDIO_RESAMPLE "audioresample"
#define DEFAULT_APP_SINK "appsink"
+/* RTP */
+#define DEFAULT_MEDIA_STREAMER_RTP_LATENCY 200
+
/* udp streaming */
#define DEFAULT_UDP_SOURCE "udpsrc"
#define DEFAULT_FILE_SOURCE "filesrc"
#define WEBRTC_RTP_TRANSCEIVER_DIRECTION_INACTIVE "inactive"
#define WEBRTC_RTP_TRANSCEIVER_DIRECTION_UNKNOWN "unknown"
#define DEFAULT_WEBRTC_RTP_TRANSCEIVER_DIRECTION WEBRTC_RTP_TRANSCEIVER_DIRECTION_UNKNOWN
-#define WEBRTC_DEFAULT_VIDEO_RTP_FORMAT "application/x-rtp,media=video,clock-rate=90000,encoding-name=VP8,payload=96"
-#define WEBRTC_DEFAULT_AUDIO_RTP_FORMAT "application/x-rtp,media=audio,encoding-name=OPUS,payload=97"
+#define WEBRTC_DEFAULT_VIDEO_RTP_FORMAT "application/x-rtp,media=video,clock-rate=90000,encoding-name=H264,payload=96"
+#define WEBRTC_DEFAULT_AUDIO_RTP_FORMAT "application/x-rtp,media=audio,clock-rate=48000,encoding-name=OPUS,payload=97"
#define MEDIA_STREAMER_DEFAULT_CAMERA_FORMAT "video/x-raw,format=I420,width=352,height=288"
#define MEDIA_STREAMER_DEFAULT_AUDIO_RAW_FORMAT "audio/x-raw,channels=1,rate=8000,format=S16LE"
PARAM_DATA_TYPE_NUMBER
},
{
+ MEDIA_STREAMER_PARAM_RTP_LATENCY,
+ "rtp-latency",
+ PROP_NAME_RTP_LATENCY,
+ PARAM_DATA_TYPE_NUMBER
+ },
+ {
MEDIA_STREAMER_PARAM_VIDEO_IN_PORT,
"video_in_port",
PROP_NAME_VIDEO_IN_PORT,
PARAM_DATA_TYPE_STRING
},
{
+ MEDIA_STREAMER_PARAM_SINK_MAX_LATENESS,
+ "max-lateness",
+ PROP_NAME_MAX_LATENESS,
+ PARAM_DATA_TYPE_NUMBER
+ },
+ {
NULL,
NULL,
PROP_NAME_MAX,
}
//LCOV_EXCL_START
+static int __ms_node_get_rtp_latency(media_streamer_node_s *node, int *latency)
+{
+ GValue *val = NULL;
+
+ ms_retvm_if(!node || !node->gst_element, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is null");
+ ms_retvm_if(!latency, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "latency is null");
+ ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_WEBRTC &&
+ node->type != MEDIA_STREAMER_NODE_TYPE_RTP, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type");
+
+ val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_RTP_LATENCY);
+ if (!val) {
+ ms_error("Failed to get [%s] val from [%s]", MEDIA_STREAMER_PARAM_RTP_LATENCY, GST_ELEMENT_NAME(node->gst_element));
+ return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+ }
+
+ if (!(*latency = g_value_get_int(val))) {
+ ms_error("Failed to g_value_get_int()");
+ return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+ }
+
+ ms_info("RTP latency is [%d]", *latency);
+
+ return MEDIA_STREAMER_ERROR_NONE;
+}
+
static int __ms_webrtc_node_check_transceiver_direction_param_value(media_streamer_node_s *node, param_s *param, const gchar *param_value)
{
GstWebRTCRTPTransceiverDirection direction;
ret = __ms_param_value_set(val, param->data_type, param_value);
break;
+ case PROP_NAME_RTP_LATENCY:
+ ret = __ms_param_value_set(val, param->data_type, param_value);
+ break;
+
default:
ms_error("failed to set property, undefined param name[%s]", param->param_name);
return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
GstGhostPad *ghost_pad = NULL;
GstElement *audio_filter = NULL;
GstCaps *audio_caps = NULL;
+ gint latency = DEFAULT_MEDIA_STREAMER_RTP_LATENCY;
ms_debug_fenter();
ms_signal_create(&node->sig_list, rtpbin, "pad-added", G_CALLBACK(ms_rtpbin_pad_added_cb), node);
+ if (__ms_node_get_rtp_latency(node, &latency) != MEDIA_STREAMER_ERROR_NONE) {
+ ms_error("Failed to get rtp latency");
+ return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+ }
+ g_object_set(G_OBJECT(rtpbin), "latency", latency, NULL);
+
val = (GValue *)g_object_get_data(G_OBJECT(node->gst_element), MEDIA_STREAMER_PARAM_HOST);
host = g_value_get_string(val);
{
int ret = MEDIA_STREAMER_ERROR_NONE;
GstElement *webrtcbin = NULL;
+ GstElement *rtpbin = NULL;
GObject *send_channel = NULL;
gboolean is_offerer = FALSE;
+ gint latency = DEFAULT_MEDIA_STREAMER_RTP_LATENCY;
media_streamer_webrtc_callbacks_s *_callbacks = NULL;
ms_debug_fenter();
ms_signal_create(&node->sig_list, webrtcbin, "on-data-channel", G_CALLBACK(ms_webrtcbin_on_data_channel_cb), ms_streamer);
ms_signal_create(&node->sig_list, webrtcbin, "pad-added", G_CALLBACK(ms_webrtcbin_pad_added_cb), node);
+ if (__ms_node_get_rtp_latency(node, &latency) != MEDIA_STREAMER_ERROR_NONE) {
+ ms_error("Failed to get rtp latency");
+ return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+ }
+
+ rtpbin = gst_bin_get_by_name(GST_BIN(webrtcbin), "rtpbin");
+ g_object_set(G_OBJECT(rtpbin), "latency", latency, NULL);
+ gst_object_unref(rtpbin);
+
ms_generate_dots(node->gst_element, "webrtc_prepared");
ms_debug_fleave();
case PROP_NAME_ROTATE:
case PROP_NAME_FLIP:
case PROP_NAME_DISPLAY_GEOMETRY_METHOD:
+ case PROP_NAME_MAX_LATENESS:
g_object_set(node->gst_element, param->prop_name, ms_get_number_from_string(param_value), NULL);
break;
return MEDIA_STREAMER_ERROR_NONE;
}
-//LCOV_EXCL_STOP
\ No newline at end of file
+//LCOV_EXCL_STOP