2 * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 * @short_description: A client connection state
22 * @see_also: #GstRTSPServer, #GstRTSPThreadPool
24 * The client object handles the connection with a client for as long as a TCP
27 * A #GstRTSPWFDClient is created by #GstRTSPServer when a new connection is
28 * accepted and it inherits the #GstRTSPMountPoints, #GstRTSPSessionPool,
29 * #GstRTSPAuth and #GstRTSPThreadPool from the server.
31 * The client connection should be configured with the #GstRTSPConnection using
32 * gst_rtsp_wfd_client_set_connection() before it can be attached to a #GMainContext
33 * using gst_rtsp_wfd_client_attach(). From then on the client will handle requests
36 * Use gst_rtsp_wfd_client_session_filter() to iterate or modify all the
37 * #GstRTSPSession objects managed by the client object.
39 * Last reviewed on 2013-07-11 (1.0.0)
45 #include "rtsp-client-ext.h"
46 #include "rtsp-media-factory-wfd.h"
48 #include "rtsp-params.h"
49 #include "rtsp-media-ext.h"
50 #include "gstwfdmessage-ext.h"
52 #define GST_RTSP_EXT_CLIENT_GET_PRIVATE(obj) \
53 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_EXT_CLIENT, GstRTSPExtClientPrivate))
55 struct _GstRTSPExtClientPrivate
57 GstRTSPMediaExt *media;
59 guint prev_max_seqnum;
60 guint prev_fraction_lost;
61 guint32 prev_max_packets_lost;
63 guint consecutive_low_bitrate_count;
65 guint tizen_retransmission_rtp_port;
66 guint tizen_retransmission_rtcp_port;
67 guint tizen_fec_t_max;
68 guint tizen_fec_p_max;
69 guint tizen_latency_mode;
72 #define WFD_MOUNT_POINT "/wfd1.0/streamid=0"
73 #define UNSTABLE_NETWORK_INTERVAL 15
74 #define MIN_PORT_NUM 1024
75 #define MAX_PORT_NUM 65535
76 #define TIZEN_RETRANSMISSION_RTP_PORT_NONE 0
77 #define TIZEN_RETRANSMISSION_RTCP_PORT_NONE 0
78 #define MIN_FEC_T_NUM 2
79 #define MAX_FEC_T_NUM 100
80 #define MIN_FEC_P_NUM 2
81 #define MAX_FEC_P_NUM 100
82 #define TIZEN_T_MAX_NONE 0
83 #define TIZEN_P_MAX_NONE 0
84 #define TIZEN_USER_AGENT "TIZEN"
85 #define DEFAULT_WFD_TIMEOUT 60
87 GST_DEBUG_CATEGORY_STATIC (rtsp_ext_client_debug);
88 #define GST_CAT_DEFAULT rtsp_ext_client_debug
90 static gboolean ext_configure_client_media (GstRTSPClient * client,
91 GstRTSPMedia * media, GstRTSPStream * stream, GstRTSPContext * ctx);
92 static void handle_ext_stats (GstRTSPWFDClient * client, GstStructure * stats);
93 static gchar* handle_ext_m3_req_msg (GstRTSPWFDClient * client, gchar * data);
94 static void handle_ext_set_param_msg (GstRTSPWFDClient * client, gchar * data);
96 static void handle_ext_m3_res_msg (GstRTSPWFDClient * client, gchar * data);
97 static gchar* handle_ext_m4_req_msg (GstRTSPWFDClient * client, gchar * data);
99 static void gst_rtsp_ext_client_finalize (GObject * obj);
101 G_DEFINE_TYPE (GstRTSPExtClient, gst_rtsp_ext_client, GST_TYPE_RTSP_WFD_CLIENT);
104 gst_rtsp_ext_client_class_init (GstRTSPExtClientClass * klass)
106 GObjectClass *gobject_class;
107 GstRTSPClientClass *rtsp_client_class;
108 GstRTSPWFDClientClass *wfd_client_class;
110 g_type_class_add_private (klass, sizeof (GstRTSPExtClientPrivate));
112 gobject_class = G_OBJECT_CLASS (klass);
113 rtsp_client_class = GST_RTSP_CLIENT_CLASS (klass);
114 wfd_client_class = GST_RTSP_WFD_CLIENT_CLASS (klass);
116 gobject_class->finalize = gst_rtsp_ext_client_finalize;
118 rtsp_client_class->configure_client_media = ext_configure_client_media;
119 wfd_client_class->wfd_rtp_stats = handle_ext_stats;
120 wfd_client_class->wfd_handle_m3_req_msg = handle_ext_m3_req_msg;
121 wfd_client_class->wfd_handle_m3_res_msg = handle_ext_m3_res_msg;
122 wfd_client_class->wfd_handle_m4_req_msg = handle_ext_m4_req_msg;
123 wfd_client_class->wfd_handle_set_param_msg = handle_ext_set_param_msg;
125 GST_DEBUG_CATEGORY_INIT (rtsp_ext_client_debug, "rtspextclient", 0,
130 gst_rtsp_ext_client_init (GstRTSPExtClient * client)
132 GstRTSPExtClientPrivate *priv = GST_RTSP_EXT_CLIENT_GET_PRIVATE (client);
135 priv->resend_packets = 0;
136 priv->prev_max_seqnum = 0;
137 priv->prev_fraction_lost = 0;
138 priv->prev_max_packets_lost = 0;
139 priv->first_rtcp = FALSE;
140 priv->consecutive_low_bitrate_count = 0;
141 priv->tizen_retransmission_rtp_port = TIZEN_RETRANSMISSION_RTP_PORT_NONE;
142 priv->tizen_retransmission_rtcp_port = TIZEN_RETRANSMISSION_RTCP_PORT_NONE;
143 priv->tizen_fec_t_max = TIZEN_T_MAX_NONE;
144 priv->tizen_fec_p_max = TIZEN_P_MAX_NONE;
145 priv->tizen_latency_mode = GST_WFD_TIZEN_LATENCY_NONE;
147 GST_INFO_OBJECT (client, "Client is initialized");
152 /* A client is finalized when the connection is broken */
154 gst_rtsp_ext_client_finalize (GObject * obj)
156 GstRTSPExtClient *client = GST_RTSP_EXT_CLIENT (obj);
157 // GstRTSPExtClientPrivate *priv = GST_RTSP_EXT_CLIENT_GET_PRIVATE (client);
159 GST_INFO ("finalize client %p", client);
161 G_OBJECT_CLASS (gst_rtsp_ext_client_parent_class)->finalize (obj);
165 * gst_rtsp_ext_client_new:
167 * Create a new #GstRTSPExtClient instance.
169 * Returns: a new #GstRTSPExtClient
172 gst_rtsp_ext_client_new (void)
174 GstRTSPExtClient *result;
176 result = g_object_new (GST_TYPE_RTSP_EXT_CLIENT, NULL);
182 ext_configure_client_media (GstRTSPClient * client, GstRTSPMedia * media,
183 GstRTSPStream * stream, GstRTSPContext * ctx)
185 GstRTSPMediaExt* _media = NULL;
186 GstRTSPExtClient *_client = GST_RTSP_EXT_CLIENT (client);
187 GstRTSPExtClientPrivate *priv = GST_RTSP_EXT_CLIENT_GET_PRIVATE (_client);
189 _media = GST_RTSP_MEDIA_EXT (media);
191 if (GST_IS_RTSP_MEDIA_EXT (_media)) {
192 if (_media != priv->media) {
193 GST_ERROR_OBJECT (client, "Different media!");
194 priv->media = _media;
198 return GST_RTSP_WFD_CLIENT_CLASS (gst_rtsp_ext_client_parent_class)->
199 configure_client_media (client, media, stream, ctx);
203 _set_venc_bitrate (GstRTSPWFDClient * client, gint bitrate)
205 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
207 GstRTSPMediaFactory *factory = NULL;
208 GstRTSPMountPoints *mount_points = NULL;
213 if (!(mount_points = gst_rtsp_client_get_mount_points (parent_client))) {
215 GST_ERROR_OBJECT (client,
216 "Failed to set negotiated resolution: no mount points...");
217 goto no_mount_points;
220 path = g_strdup (WFD_MOUNT_POINT);
223 GST_ERROR_OBJECT (client,
224 "Failed to set negotiated resolution: no path...");
228 if (!(factory = gst_rtsp_mount_points_match (mount_points, path, &matched))) {
229 GST_ERROR_OBJECT (client,
230 "Failed to set negotiated resolution: no factory...");
235 gst_rtsp_media_factory_wfd_set_venc_bitrate (factory, bitrate);
238 g_object_unref (factory);
243 g_object_unref (mount_points);
249 _get_venc_bitrate (GstRTSPWFDClient * client, gint * bitrate)
251 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
253 GstRTSPMediaFactory *factory = NULL;
254 GstRTSPMountPoints *mount_points = NULL;
259 if (!(mount_points = gst_rtsp_client_get_mount_points (parent_client))) {
261 GST_ERROR_OBJECT (client,
262 "Failed to set negotiated resolution: no mount points...");
263 goto no_mount_points;
266 path = g_strdup (WFD_MOUNT_POINT);
269 GST_ERROR_OBJECT (client,
270 "Failed to set negotiated resolution: no path...");
274 if (!(factory = gst_rtsp_mount_points_match (mount_points, path, &matched))) {
275 GST_ERROR_OBJECT (client,
276 "Failed to set negotiated resolution: no factory...");
281 gst_rtsp_media_factory_wfd_get_venc_bitrate (factory, bitrate);
284 g_object_unref (factory);
289 g_object_unref (mount_points);
295 _get_config_bitrate (GstRTSPWFDClient * client, guint32 * min, guint32 * max)
297 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
299 GstRTSPMediaFactory *factory = NULL;
300 GstRTSPMountPoints *mount_points = NULL;
305 if (!(mount_points = gst_rtsp_client_get_mount_points (parent_client))) {
307 GST_ERROR_OBJECT (client,
308 "Failed to set negotiated resolution: no mount points...");
309 goto no_mount_points;
312 path = g_strdup (WFD_MOUNT_POINT);
315 GST_ERROR_OBJECT (client,
316 "Failed to set negotiated resolution: no path...");
320 if (!(factory = gst_rtsp_mount_points_match (mount_points, path, &matched))) {
321 GST_ERROR_OBJECT (client,
322 "Failed to set negotiated resolution: no factory...");
327 gst_rtsp_media_factory_wfd_get_config_bitrate (factory, min, max);
330 g_object_unref (factory);
335 g_object_unref (mount_points);
341 _bitrate_config (GstRTSPWFDClient * client, gint bitrate, guint32 min_bitrate)
343 GstRTSPExtClient *_client = GST_RTSP_EXT_CLIENT (client);
344 GstRTSPExtClientPrivate *priv = GST_RTSP_EXT_CLIENT_GET_PRIVATE (_client);
347 _get_venc_bitrate (client, &prev_bitrate);
349 if (prev_bitrate != bitrate) {
350 _set_venc_bitrate (client, bitrate);
351 GST_INFO_OBJECT (client, "[UDP] New Bitrate value [%d]", bitrate);
354 if (prev_bitrate == min_bitrate && prev_bitrate == bitrate)
355 priv->consecutive_low_bitrate_count++;
357 priv->consecutive_low_bitrate_count = 0;
359 if (priv->consecutive_low_bitrate_count >= UNSTABLE_NETWORK_INTERVAL) {
360 /* Network congestion happens. Add logic for popup warning or something else */
361 GST_WARNING_OBJECT (client, "Network unstable");
362 priv->consecutive_low_bitrate_count = 0;
369 handle_ext_stats (GstRTSPWFDClient * client, GstStructure * stats)
371 GstRTSPExtClient *_client = GST_RTSP_EXT_CLIENT (client);
372 GstRTSPExtClientPrivate *priv = GST_RTSP_EXT_CLIENT_GET_PRIVATE (_client);
373 guint latest_resend_packets = 0;
375 g_return_val_if_fail (priv != NULL, FALSE);
377 latest_resend_packets = gst_rtsp_media_ext_get_resent_packets (priv->media);
379 GST_INFO_OBJECT (client, "Re-sent RTP packets : %d", latest_resend_packets);
381 /* calculation to decide bitrate */
383 static gint32 next_k = 40;
384 static gint32 next_p = 0;
385 guint32 min_bitrate = 0;
386 guint32 max_bitrate = 0;
387 guint fraction_lost = 0;
388 guint max_seqnum = 0;
391 gint temp_fraction_lost = 0;
392 gint statistics_fraction_lost = 0;
393 gfloat thretholdValue = 0;
394 static gint fraction_lost_MA = 0;
396 gst_structure_get_uint (stats, "rb-fractionlost", &fraction_lost);
397 gst_structure_get_uint (stats, "rb-exthighestseq", &max_seqnum);
398 gst_structure_get_int (stats, "rb-packetslost", &packetslost);
400 _get_venc_bitrate (client, &bitrate);
401 GST_INFO_OBJECT (client, "[UDP] Current Bitrate value [%d]", bitrate);
403 _get_config_bitrate (client, &min_bitrate, &max_bitrate);
404 GST_INFO_OBJECT (client, "[UDP] min [%d], max [%d]", min_bitrate,
407 if (priv->resend_packets == latest_resend_packets)
409 priv->resend_packets = latest_resend_packets;
411 if (priv->prev_max_seqnum == max_seqnum)
414 if (priv->first_rtcp == FALSE) {
415 GST_DEBUG_OBJECT (client, "Ignoring first receiver report");
416 priv->prev_fraction_lost = 0;
417 priv->prev_max_packets_lost = packetslost;
418 priv->prev_max_seqnum = max_seqnum;
419 fraction_lost_MA = 0;
420 priv->first_rtcp = TRUE;
424 if (priv->prev_fraction_lost == 0)
425 thretholdValue = 1.0;
427 thretholdValue = 0.8;
429 if (fraction_lost > 0) {
430 temp_fraction_lost = fraction_lost * 100 / 256;
431 GST_DEBUG_OBJECT (client, "fraction lost from sink RR [%d]",
434 if ((max_seqnum > priv->prev_max_seqnum)
435 && (packetslost > priv->prev_max_packets_lost))
437 (((packetslost - priv->prev_max_packets_lost) * 100) / (max_seqnum -
438 priv->prev_max_seqnum));
439 GST_DEBUG_OBJECT (client, "fraction lost calculated [%d]",
442 statistics_fraction_lost =
443 (gint) (temp_fraction_lost * thretholdValue +
444 priv->prev_fraction_lost * (1 - thretholdValue));
446 (fraction_lost_MA * 7 + statistics_fraction_lost * 5) / 8;
448 if (fraction_lost_MA > 100)
449 fraction_lost_MA = 100;
451 GST_DEBUG_OBJECT (client,
452 "statistics fraction lost = %d, fraction lost MA = %d",
453 statistics_fraction_lost, fraction_lost_MA);
455 if (temp_fraction_lost > 0) {
456 guint32 temp_change_bandwith_amount = 0;
459 if (statistics_fraction_lost >= 5) {
460 temp_change_bandwith_amount = max_bitrate - min_bitrate;
462 } else if (temp_fraction_lost >= 3) {
463 temp_change_bandwith_amount = (max_bitrate - min_bitrate) / 2;
466 temp_change_bandwith_amount = (max_bitrate - min_bitrate) / 4;
470 GST_DEBUG_OBJECT (client,
471 "LOSS case, statistics fraction lost = %d percent, temp change"
472 "bandwith amount = %d bit", statistics_fraction_lost,
473 temp_change_bandwith_amount);
486 if (bitrate <= min_bitrate) {
487 bitrate = min_bitrate;
488 priv->prev_fraction_lost = statistics_fraction_lost;
489 priv->prev_max_packets_lost = packetslost;
493 bitrate -= temp_change_bandwith_amount;
495 if (bitrate < min_bitrate)
496 bitrate = min_bitrate;
498 } else if (0 == temp_fraction_lost && fraction_lost_MA < 1) {
501 if (0 == priv->prev_fraction_lost) {
502 bitrate += 512 * 1024;
505 bitrate += 100 * 1024;
509 if (bitrate > max_bitrate)
510 bitrate = max_bitrate;
523 if (bitrate >= max_bitrate) {
524 GST_DEBUG_OBJECT (client, "bitrate can not be increased");
525 bitrate = max_bitrate;
526 priv->prev_fraction_lost = statistics_fraction_lost;
527 priv->prev_max_seqnum = max_seqnum;
528 priv->prev_max_packets_lost = packetslost;
534 priv->prev_fraction_lost = statistics_fraction_lost;
535 priv->prev_max_seqnum = max_seqnum;
536 priv->prev_max_packets_lost = packetslost;
538 GST_INFO_OBJECT (client, "final bitrate is %d", bitrate);
541 _bitrate_config (client, bitrate, min_bitrate);
542 gst_rtsp_media_ext_set_next_param (priv->media, next_k, next_p);
547 handle_ext_m3_req_msg (GstRTSPWFDClient * client, gchar * data)
550 gchar *sink_user_agent = NULL;
551 GstWFDExtMessage *msg = NULL;
552 GstWFDResult wfd_res = GST_WFD_EINVAL;
553 gboolean is_appended = FALSE;
555 g_return_if_fail (client != NULL);
556 g_return_val_if_fail (data != NULL, NULL);
558 sink_user_agent = gst_rtsp_wfd_client_get_sink_user_agent (client);
560 if (sink_user_agent && strstr (sink_user_agent, TIZEN_USER_AGENT)) {
562 GST_INFO_OBJECT (client,
563 "Setting tizen extended features on wfd message...");
565 wfd_res = gst_wfd_ext_message_new (&msg);
566 if (wfd_res != GST_WFD_OK) {
567 GST_ERROR_OBJECT (client, "Failed to create wfd message...");
571 wfd_res = gst_wfd_ext_message_init (msg);
572 if (wfd_res != GST_WFD_OK) {
573 GST_ERROR_OBJECT (client, "Failed to init wfd message...");
577 GST_INFO_OBJECT (client,
578 "Setting tizen extended features on wfd message...");
580 wfd_res = gst_wfd_ext_message_set_tizen_retransmission (msg, 0, 0);
581 if (wfd_res != GST_WFD_OK) {
582 GST_ERROR_OBJECT (client,
583 "Failed to set tizen retransmission on wfd message...");
587 wfd_res = gst_wfd_ext_message_set_tizen_fec (msg, 0, 0);
588 if (wfd_res != GST_WFD_OK) {
589 GST_ERROR_OBJECT (client, "Failed to set tizen fec on wfd message...");
593 wfd_res = gst_wfd_ext_message_set_tizen_latency_mode (msg, 0);
594 if (wfd_res != GST_WFD_OK) {
595 GST_ERROR_OBJECT (client,
596 "Failed to set tizen latency mode on wfd message...");
600 tmp = gst_wfd_ext_message_param_names_as_text (msg);
602 data = g_strconcat (data, tmp, NULL);
606 GST_ERROR_OBJECT (client,
607 "Failed to gst_wfd_ext_message_param_names_as_text");
612 gst_wfd_ext_message_free (msg);
614 if (sink_user_agent != NULL)
615 g_free (sink_user_agent);
617 if (is_appended == FALSE)
624 gst_wfd_ext_message_free (msg);
626 if (sink_user_agent != NULL)
627 g_free (sink_user_agent);
633 handle_ext_m3_res_msg (GstRTSPWFDClient * client, gchar * data)
635 GstWFDExtMessage *msg = NULL;
636 GstRTSPExtClientPrivate *ext_priv = GST_RTSP_EXT_CLIENT_GET_PRIVATE (client);
637 GstWFDResult wfd_res = GST_WFD_EINVAL;
639 g_return_if_fail (ext_priv != NULL);
640 g_return_val_if_fail (data != NULL, NULL);
642 wfd_res = gst_wfd_ext_message_new (&msg);
643 if (wfd_res != GST_WFD_OK) {
644 GST_ERROR_OBJECT (client, "Failed to create wfd message...");
648 wfd_res = gst_wfd_ext_message_init (msg);
649 if (wfd_res != GST_WFD_OK) {
650 GST_ERROR_OBJECT (client, "Failed to init wfd message...");
655 gst_wfd_ext_message_parse_buffer ((const guint8 *) data, strlen (data),
657 if (wfd_res != GST_WFD_OK) {
658 GST_ERROR_OBJECT (client, "Failed to parse buffer...");
662 /* Get tizen extended features from WFD message. */
663 if (msg->tizen_retransmission) {
665 guint rtp_port = TIZEN_RETRANSMISSION_RTP_PORT_NONE;
666 guint rtcp_port = TIZEN_RETRANSMISSION_RTCP_PORT_NONE;
668 gst_wfd_ext_message_get_tizen_retransmission (msg, &rtp_port,
670 if (wfd_res != GST_WFD_OK) {
671 GST_ERROR_OBJECT (client,
672 "Failed to get tizen retransmission from wfd message...");
676 if (rtp_port >= MIN_PORT_NUM && rtp_port <= MAX_PORT_NUM)
677 ext_priv->tizen_retransmission_rtp_port = rtp_port;
679 if (rtcp_port >= MIN_PORT_NUM && rtcp_port <= MAX_PORT_NUM)
680 ext_priv->tizen_retransmission_rtcp_port = rtcp_port;
682 GST_DEBUG_OBJECT (client, "Tizen retransmission rtp_port[%d] rtcp_port[%d]",
683 ext_priv->tizen_retransmission_rtp_port,
684 ext_priv->tizen_retransmission_rtcp_port);
687 if (msg->tizen_fec) {
689 guint fec_t_max = TIZEN_T_MAX_NONE;
690 guint fec_p_max = TIZEN_P_MAX_NONE;
692 wfd_res = gst_wfd_ext_message_get_tizen_fec (msg, &fec_t_max, &fec_p_max);
693 if (wfd_res != GST_WFD_OK) {
694 GST_ERROR_OBJECT (client, "Failed to get tizen fec from wfd message...");
698 if (fec_t_max >= MIN_FEC_T_NUM && fec_t_max <= MAX_FEC_T_NUM)
699 ext_priv->tizen_fec_t_max = fec_t_max;
701 if (fec_p_max >= MIN_FEC_P_NUM && fec_p_max <= MAX_FEC_P_NUM)
702 ext_priv->tizen_fec_p_max = fec_p_max;
704 GST_DEBUG_OBJECT (client, "Tizen fec t_max[%d] p_max[%d]",
705 ext_priv->tizen_fec_t_max, ext_priv->tizen_fec_p_max);
708 if (msg->tizen_latency_mode) {
710 gst_wfd_ext_message_get_tizen_latency_mode (msg,
711 &ext_priv->tizen_latency_mode);
712 if (wfd_res != GST_WFD_OK) {
713 GST_ERROR_OBJECT (client,
714 "Failed to get tizen latency mode on wfd message...");
717 GST_DEBUG_OBJECT (client, "Tizen latency mode[%d]",
718 ext_priv->tizen_latency_mode);
722 gst_wfd_ext_message_free (msg);
728 gst_wfd_ext_message_free (msg);
734 media_ext_constructed (GstRTSPMediaFactory * factory, GstRTSPMedia * media,
735 GstRTSPExtClient * client)
737 GstRTSPExtClientPrivate *priv = GST_RTSP_EXT_CLIENT_GET_PRIVATE (client);
738 g_return_if_fail (priv != NULL);
740 priv->media = GST_RTSP_MEDIA_EXT (media);
742 if (priv->tizen_retransmission_rtp_port != TIZEN_RETRANSMISSION_RTP_PORT_NONE
743 && priv->tizen_retransmission_rtcp_port !=
744 TIZEN_RETRANSMISSION_RTCP_PORT_NONE) {
745 GST_DEBUG_OBJECT (client, "Tizen retransmission rtp_port[%d] rtcp_port[%d]",
746 priv->tizen_retransmission_rtp_port,
747 priv->tizen_retransmission_rtcp_port);
748 gst_rtsp_media_ext_set_extended_mode (priv->media, MEDIA_EXT_MODE_RESEND);
749 gst_rtsp_media_ext_set_retrans_port (priv->media,
750 priv->tizen_retransmission_rtp_port);
752 if (priv->tizen_fec_t_max != TIZEN_T_MAX_NONE
753 && priv->tizen_fec_p_max != TIZEN_P_MAX_NONE) {
754 GST_DEBUG_OBJECT (client, "Tizen fec t_max[%d] p_max[%d]",
755 priv->tizen_fec_t_max, priv->tizen_fec_p_max);
756 gst_rtsp_media_ext_set_extended_mode (priv->media, MEDIA_EXT_MODE_FEC);
757 gst_rtsp_media_ext_set_fec_value (priv->media, priv->tizen_fec_t_max,
758 priv->tizen_fec_p_max);
760 if (priv->tizen_latency_mode != GST_WFD_TIZEN_LATENCY_NONE) {
761 GST_DEBUG_OBJECT (client, "Tizen latency mode[%d]",
762 priv->tizen_latency_mode);
763 gst_rtsp_media_ext_set_latency_mode (priv->media, priv->tizen_latency_mode);
768 gst_wfd_ext_listen_media_constructed (GstRTSPWFDClient * client)
770 GstRTSPMediaFactory *factory = NULL;
771 GstRTSPMountPoints *mount_points = NULL;
774 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
776 GstRTSPExtClient *_client = GST_RTSP_EXT_CLIENT (client);
778 if (!(mount_points = gst_rtsp_client_get_mount_points (parent_client))) {
779 GST_ERROR_OBJECT (client,
780 "Failed to set negotiated resolution: no mount points...");
781 goto no_mount_points;
784 path = g_strdup (WFD_MOUNT_POINT);
786 GST_ERROR_OBJECT (client,
787 "Failed to set negotiated resolution: no path...");
791 if (!(factory = gst_rtsp_mount_points_match (mount_points, path, &matched))) {
792 GST_ERROR_OBJECT (client,
793 "Failed to set negotiated resolution: no factory...");
797 g_signal_connect (factory, "media-constructed",
798 (GCallback) media_ext_constructed, _client);
803 g_object_unref (mount_points);
809 handle_ext_set_param_msg (GstRTSPWFDClient * client, gchar * data)
811 GstRTSPExtClientPrivate *priv = GST_RTSP_EXT_CLIENT_GET_PRIVATE (client);
813 g_return_if_fail (priv != NULL);
814 g_return_val_if_fail (data != NULL, NULL);
820 handle_ext_m4_req_msg (GstRTSPWFDClient * client, gchar * data)
822 GstWFDExtMessage *msg = NULL;
824 GstRTSPExtClientPrivate *ext_priv = GST_RTSP_EXT_CLIENT_GET_PRIVATE (client);
825 GstWFDResult wfd_res = GST_WFD_EINVAL;
826 gboolean is_appended = FALSE;
828 g_return_if_fail (ext_priv != NULL);
829 g_return_val_if_fail (data != NULL, NULL);
831 wfd_res = gst_wfd_ext_message_new (&msg);
832 if (wfd_res != GST_WFD_OK) {
833 GST_ERROR_OBJECT (client, "Failed to create wfd message...");
837 wfd_res = gst_wfd_ext_message_init (msg);
838 if (wfd_res != GST_WFD_OK) {
839 GST_ERROR_OBJECT (client, "Failed to init wfd message...");
843 GST_INFO_OBJECT (client, "Setting extended features on wfd message...");
845 if (ext_priv->tizen_retransmission_rtp_port !=
846 TIZEN_RETRANSMISSION_RTP_PORT_NONE
847 && ext_priv->tizen_retransmission_rtcp_port !=
848 TIZEN_RETRANSMISSION_RTCP_PORT_NONE) {
851 gst_wfd_ext_message_set_tizen_retransmission (msg,
852 ext_priv->tizen_retransmission_rtp_port,
853 ext_priv->tizen_retransmission_rtcp_port);
854 if (wfd_res != GST_WFD_OK) {
855 GST_ERROR_OBJECT (client,
856 "Failed to set tizen retransmission on wfd message...");
859 GST_DEBUG_OBJECT (client, "Tizen retransmission rtp_port[%d] rtcp_port[%d]",
860 ext_priv->tizen_retransmission_rtp_port,
861 ext_priv->tizen_retransmission_rtcp_port);
864 if (ext_priv->tizen_fec_t_max != TIZEN_T_MAX_NONE
865 && ext_priv->tizen_fec_p_max != TIZEN_P_MAX_NONE) {
868 gst_wfd_ext_message_set_tizen_fec (msg, ext_priv->tizen_fec_t_max,
869 ext_priv->tizen_fec_p_max);
870 if (wfd_res != GST_WFD_OK) {
871 GST_ERROR_OBJECT (client, "Failed to set tizen fec on wfd message...");
874 GST_DEBUG_OBJECT (client, "Tizen fec t_max[%d] p_max[%d]",
875 ext_priv->tizen_fec_t_max, ext_priv->tizen_fec_p_max);
878 if (ext_priv->tizen_latency_mode != GST_WFD_TIZEN_LATENCY_NONE) {
881 gst_wfd_ext_message_set_tizen_latency_mode (msg,
882 ext_priv->tizen_latency_mode);
883 if (wfd_res != GST_WFD_OK) {
884 GST_ERROR_OBJECT (client,
885 "Failed to set tizen latency mode on wfd message...");
888 GST_DEBUG_OBJECT (client, "Tizen latency mode[%d]",
889 ext_priv->tizen_latency_mode);
892 tmp = gst_wfd_ext_message_as_text (msg);
894 data = g_strconcat (data, tmp, NULL);
898 GST_ERROR_OBJECT (client, "Failed to gst_wfd_ext_message_as_text");
903 gst_wfd_ext_message_free (msg);
905 gst_wfd_ext_listen_media_constructed (client);
907 if (is_appended == FALSE) {
919 gst_wfd_ext_message_free (msg);