2 * Copyright (C) 2015 Samsung Electronics Hyunjun Ko <zzoon.ko@samsung.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-wfd.h"
46 #include "rtsp-media-factory-wfd.h"
48 #include "rtsp-params.h"
50 #define GST_RTSP_WFD_CLIENT_GET_PRIVATE(obj) \
51 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_WFD_CLIENT, GstRTSPWFDClientPrivate))
53 typedef struct _GstRTSPClientRTPStats GstRTSPClientRTPStats;
55 struct _GstRTSPClientRTPStats
57 GstRTSPStream *stream;
58 guint64 last_sent_bytes;
63 /* Info in RR (Receiver Report) */
65 guint32 cumulative_lost_num;
67 guint32 arrival_jitter;
74 struct _GstRTSPWFDClientPrivate
76 GstRTSPWFDClientSendFunc send_func; /* protected by send_lock */
77 gpointer send_data; /* protected by send_lock */
78 GDestroyNotify send_notify; /* protected by send_lock */
80 /* used to cache the media in the last requested DESCRIBE so that
81 * we can pick it up in the next SETUP immediately */
95 /* Parameters for WIFI-DISPLAY */
104 guint64 cNativeResolution;
105 guint64 video_resolution_supported;
106 gint video_native_resolution;
107 guint64 cCEAResolution;
108 guint64 cVESAResolution;
109 guint64 cHHResolution;
115 guint32 cInterleaved;
116 guint32 cmin_slice_size;
117 guint32 cslice_enc_params;
118 guint cframe_rate_control;
126 gboolean protection_enabled;
127 GstWFDHDCPProtection hdcp_version;
128 guint32 hdcp_tcpport;
130 gboolean edid_supported;
134 gboolean keep_alive_flag;
135 GMutex keep_alive_lock;
138 GstRTSPClientRTPStats stats;
140 guint stats_timer_id;
141 gboolean rtcp_stats_enabled;
143 gchar *sink_user_agent;
146 #define DEFAULT_WFD_TIMEOUT 60
147 #define WFD_MOUNT_POINT "/wfd1.0/streamid=0"
151 SIGNAL_WFD_OPTIONS_REQUEST,
152 SIGNAL_WFD_GET_PARAMETER_REQUEST,
153 SIGNAL_WFD_KEEP_ALIVE_FAIL,
154 SIGNAL_WFD_PLAYING_DONE,
155 SIGNAL_WFD_RTP_STATS,
156 SIGNAL_WFD_M3_REQ_MSG,
157 SIGNAL_WFD_M3_RES_MSG,
158 SIGNAL_WFD_M4_REQ_MSG,
159 SIGNAL_WFD_SET_PARAM_MSG,
163 GST_DEBUG_CATEGORY_STATIC (rtsp_wfd_client_debug);
164 #define GST_CAT_DEFAULT rtsp_wfd_client_debug
166 static guint gst_rtsp_client_wfd_signals[SIGNAL_WFD_LAST] = { 0 };
168 static void gst_rtsp_wfd_client_get_property (GObject * object, guint propid,
169 GValue * value, GParamSpec * pspec);
170 static void gst_rtsp_wfd_client_set_property (GObject * object, guint propid,
171 const GValue * value, GParamSpec * pspec);
172 static void gst_rtsp_wfd_client_finalize (GObject * obj);
174 static gboolean handle_wfd_options_request (GstRTSPClient * client,
175 GstRTSPContext * ctx);
176 static gboolean handle_wfd_set_param_request (GstRTSPClient * client,
177 GstRTSPContext * ctx);
178 static gboolean handle_wfd_get_param_request (GstRTSPClient * client,
179 GstRTSPContext * ctx);
181 static void send_generic_wfd_response (GstRTSPWFDClient * client,
182 GstRTSPStatusCode code, GstRTSPContext * ctx);
183 static gchar *wfd_make_path_from_uri (GstRTSPClient * client,
184 const GstRTSPUrl * uri);
185 static void wfd_options_request_done (GstRTSPWFDClient * client,
186 GstRTSPContext * ctx);
187 static void wfd_get_param_request_done (GstRTSPWFDClient * client,
188 GstRTSPContext * ctx);
189 static void handle_wfd_response (GstRTSPClient * client, GstRTSPContext * ctx);
190 static void handle_wfd_play (GstRTSPClient * client, GstRTSPContext * ctx);
191 static void wfd_set_keep_alive_condition (GstRTSPWFDClient * client);
192 static gboolean wfd_ckeck_keep_alive_response (gpointer userdata);
193 static gboolean keep_alive_condition (gpointer userdata);
194 static gboolean wfd_configure_client_media (GstRTSPClient * client,
195 GstRTSPMedia * media, GstRTSPStream * stream, GstRTSPContext * ctx);
197 GstRTSPResult prepare_trigger_request (GstRTSPWFDClient * client,
198 GstRTSPMessage * request, GstWFDTriggerType trigger_type, gchar * url);
201 prepare_response (GstRTSPWFDClient * client, GstRTSPMessage * request,
202 GstRTSPMessage * response, GstRTSPMethod method);
204 static GstRTSPResult handle_M1_message (GstRTSPWFDClient * client);
205 static GstRTSPResult handle_M3_message (GstRTSPWFDClient * client);
206 static GstRTSPResult handle_M4_message (GstRTSPWFDClient * client);
207 static GstRTSPResult handle_M16_message (GstRTSPWFDClient * client);
209 G_DEFINE_TYPE (GstRTSPWFDClient, gst_rtsp_wfd_client, GST_TYPE_RTSP_CLIENT);
212 gst_rtsp_wfd_client_class_init (GstRTSPWFDClientClass * klass)
214 GObjectClass *gobject_class;
215 GstRTSPClientClass *rtsp_client_class;
217 g_type_class_add_private (klass, sizeof (GstRTSPWFDClientPrivate));
219 gobject_class = G_OBJECT_CLASS (klass);
220 rtsp_client_class = GST_RTSP_CLIENT_CLASS (klass);
222 gobject_class->get_property = gst_rtsp_wfd_client_get_property;
223 gobject_class->set_property = gst_rtsp_wfd_client_set_property;
224 gobject_class->finalize = gst_rtsp_wfd_client_finalize;
226 //klass->create_sdp = create_sdp;
227 //klass->configure_client_transport = default_configure_client_transport;
228 //klass->params_set = default_params_set;
229 //klass->params_get = default_params_get;
231 rtsp_client_class->handle_options_request = handle_wfd_options_request;
232 rtsp_client_class->handle_set_param_request = handle_wfd_set_param_request;
233 rtsp_client_class->handle_get_param_request = handle_wfd_get_param_request;
234 rtsp_client_class->make_path_from_uri = wfd_make_path_from_uri;
235 rtsp_client_class->configure_client_media = wfd_configure_client_media;
237 rtsp_client_class->handle_response = handle_wfd_response;
238 rtsp_client_class->play_request = handle_wfd_play;
240 gst_rtsp_client_wfd_signals[SIGNAL_WFD_OPTIONS_REQUEST] =
241 g_signal_new ("wfd-options-request", G_TYPE_FROM_CLASS (klass),
242 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPWFDClientClass,
243 wfd_options_request), NULL, NULL, g_cclosure_marshal_VOID__POINTER,
244 G_TYPE_NONE, 1, GST_TYPE_RTSP_CONTEXT);
246 gst_rtsp_client_wfd_signals[SIGNAL_WFD_GET_PARAMETER_REQUEST] =
247 g_signal_new ("wfd-get-parameter-request", G_TYPE_FROM_CLASS (klass),
248 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPWFDClientClass,
249 wfd_get_param_request), NULL, NULL, g_cclosure_marshal_VOID__POINTER,
250 G_TYPE_NONE, 1, GST_TYPE_RTSP_CONTEXT);
252 gst_rtsp_client_wfd_signals[SIGNAL_WFD_KEEP_ALIVE_FAIL] =
253 g_signal_new ("wfd-keep-alive-fail", G_TYPE_FROM_CLASS (klass),
254 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPWFDClientClass,
255 wfd_keep_alive_fail), NULL, NULL, g_cclosure_marshal_generic,
256 G_TYPE_NONE, 0, G_TYPE_NONE);
258 gst_rtsp_client_wfd_signals[SIGNAL_WFD_PLAYING_DONE] =
259 g_signal_new ("wfd-playing-done", G_TYPE_FROM_CLASS (klass),
260 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPWFDClientClass,
261 wfd_playing_done), NULL, NULL, g_cclosure_marshal_generic,
262 G_TYPE_NONE, 0, G_TYPE_NONE);
264 gst_rtsp_client_wfd_signals[SIGNAL_WFD_RTP_STATS] =
265 g_signal_new ("wfd-rtp-stats", G_TYPE_FROM_CLASS (klass),
266 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPWFDClientClass,
267 wfd_rtp_stats), NULL, NULL, g_cclosure_marshal_generic,
268 G_TYPE_NONE, 1, GST_TYPE_STRUCTURE);
270 gst_rtsp_client_wfd_signals[SIGNAL_WFD_M3_REQ_MSG] =
271 g_signal_new ("wfd-m3-request-msg", G_TYPE_FROM_CLASS (klass),
272 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPWFDClientClass,
273 wfd_handle_m3_req_msg), NULL, NULL, g_cclosure_marshal_generic,
274 G_TYPE_STRING, 1, G_TYPE_STRING);
276 gst_rtsp_client_wfd_signals[SIGNAL_WFD_M3_RES_MSG] =
277 g_signal_new ("wfd-m3-response-msg", G_TYPE_FROM_CLASS (klass),
278 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPWFDClientClass,
279 wfd_handle_m3_res_msg), NULL, NULL, g_cclosure_marshal_generic,
280 G_TYPE_NONE, 1, G_TYPE_STRING);
282 gst_rtsp_client_wfd_signals[SIGNAL_WFD_M4_REQ_MSG] =
283 g_signal_new ("wfd-m4-request-msg", G_TYPE_FROM_CLASS (klass),
284 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPWFDClientClass,
285 wfd_handle_m4_req_msg), NULL, NULL, g_cclosure_marshal_generic,
286 G_TYPE_STRING, 1, G_TYPE_STRING);
288 gst_rtsp_client_wfd_signals[SIGNAL_WFD_SET_PARAM_MSG] =
289 g_signal_new ("wfd-set-param-msg", G_TYPE_FROM_CLASS (klass),
290 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPWFDClientClass,
291 wfd_handle_set_param_msg), NULL, NULL, g_cclosure_marshal_generic,
292 G_TYPE_NONE, 1, G_TYPE_STRING);
294 klass->wfd_options_request = wfd_options_request_done;
295 klass->wfd_get_param_request = wfd_get_param_request_done;
296 klass->configure_client_media = wfd_configure_client_media;
298 GST_DEBUG_CATEGORY_INIT (rtsp_wfd_client_debug, "rtspwfdclient", 0,
303 gst_rtsp_wfd_client_init (GstRTSPWFDClient * client)
305 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
307 g_return_if_fail (priv != NULL);
310 priv->protection_enabled = FALSE;
311 priv->video_native_resolution = GST_WFD_VIDEO_CEA_RESOLUTION;
312 priv->video_resolution_supported = GST_WFD_CEA_640x480P60;
313 priv->audio_codec = GST_WFD_AUDIO_AAC;
314 priv->keep_alive_flag = FALSE;
316 g_mutex_init (&priv->keep_alive_lock);
317 g_mutex_init (&priv->stats_lock);
319 priv->host_address = NULL;
321 priv->stats_timer_id = -1;
322 priv->rtcp_stats_enabled = FALSE;
323 memset (&priv->stats, 0x00, sizeof (GstRTSPClientRTPStats));
324 priv->sink_user_agent = NULL;
326 GST_INFO_OBJECT (client, "Client is initialized");
329 /* A client is finalized when the connection is broken */
331 gst_rtsp_wfd_client_finalize (GObject * obj)
333 GstRTSPWFDClient *client = GST_RTSP_WFD_CLIENT (obj);
334 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
336 g_return_if_fail (GST_IS_RTSP_WFD_CLIENT (obj));
337 g_return_if_fail (priv != NULL);
339 GST_INFO ("finalize client %p", client);
341 if (priv->host_address)
342 g_free (priv->host_address);
344 if (priv->stats_timer_id > 0)
345 g_source_remove (priv->stats_timer_id);
347 if (priv->sink_user_agent) {
348 g_free (priv->sink_user_agent);
349 priv->sink_user_agent = NULL;
352 g_mutex_clear (&priv->keep_alive_lock);
353 g_mutex_clear (&priv->stats_lock);
354 G_OBJECT_CLASS (gst_rtsp_wfd_client_parent_class)->finalize (obj);
358 gst_rtsp_wfd_client_get_property (GObject * object, guint propid,
359 GValue * value, GParamSpec * pspec)
361 //GstRTSPWFDClient *client = GST_RTSP_WFD_CLIENT (object);
365 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
370 gst_rtsp_wfd_client_set_property (GObject * object, guint propid,
371 const GValue * value, GParamSpec * pspec)
373 //GstRTSPWFDClient *client = GST_RTSP_WFD_CLIENT (object);
377 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
382 * gst_rtsp_wfd_client_new:
384 * Create a new #GstRTSPWFDClient instance.
386 * Returns: a new #GstRTSPWFDClient
389 gst_rtsp_wfd_client_new (void)
391 GstRTSPWFDClient *result;
393 result = g_object_new (GST_TYPE_RTSP_WFD_CLIENT, NULL);
399 gst_rtsp_wfd_client_start_wfd (GstRTSPWFDClient * client)
401 GstRTSPResult res = GST_RTSP_OK;
402 GST_INFO_OBJECT (client, "gst_rtsp_wfd_client_start_wfd");
404 res = handle_M1_message (client);
405 if (res < GST_RTSP_OK) {
406 GST_ERROR_OBJECT (client, "handle_M1_message failed : %d", res);
413 wfd_display_rtp_stats (gpointer userdata)
418 GstRTSPWFDClient *client = NULL;
419 GstRTSPWFDClientPrivate *priv = NULL;
421 client = (GstRTSPWFDClient *) userdata;
422 priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
425 GST_ERROR ("No priv");
429 g_mutex_lock (&priv->stats_lock);
431 seqnum = gst_rtsp_stream_get_current_seqnum (priv->stats.stream);
432 bytes = gst_rtsp_stream_get_udp_sent_bytes (priv->stats.stream);
434 GST_INFO ("----------------------------------------------------\n");
435 GST_INFO ("Sent RTP packets : %d", seqnum - priv->stats.last_seqnum);
436 GST_INFO ("Sent Bytes of RTP packets : %lld bytes",
437 bytes - priv->stats.last_sent_bytes);
439 priv->stats.last_seqnum = seqnum;
440 priv->stats.last_sent_bytes = bytes;
442 if (priv->rtcp_stats_enabled) {
443 GST_INFO ("Fraction Lost: %d", priv->stats.fraction_lost);
444 GST_INFO ("Cumulative number of packets lost: %d",
445 priv->stats.cumulative_lost_num);
446 GST_INFO ("Extended highest sequence number received: %d",
447 priv->stats.max_seqnum);
448 GST_INFO ("Interarrival Jitter: %d", priv->stats.arrival_jitter);
449 GST_INFO ("Round trip time : %d", priv->stats.rtt);
452 GST_INFO ("----------------------------------------------------\n");
454 g_mutex_unlock (&priv->stats_lock);
460 on_rtcp_stats (GstRTSPStream * stream, GstStructure * stats,
461 GstRTSPClient * client)
463 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
465 guint fraction_lost, exthighestseq, jitter, lsr, dlsr, rtt;
471 g_mutex_lock (&priv->stats_lock);
473 gst_structure_get_uint (stats, "rb-fractionlost", &fraction_lost);
474 gst_structure_get_int (stats, "rb-packetslost", &packetslost);
475 gst_structure_get_uint (stats, "rb-exthighestseq", &exthighestseq);
476 gst_structure_get_uint (stats, "rb-jitter", &jitter);
477 gst_structure_get_uint (stats, "rb-lsr", &lsr);
478 gst_structure_get_uint (stats, "rb-dlsr", &dlsr);
479 gst_structure_get_uint (stats, "rb-round-trip", &rtt);
481 if (!priv->rtcp_stats_enabled)
482 priv->rtcp_stats_enabled = TRUE;
484 priv->stats.stream = stream;
485 priv->stats.fraction_lost = (guint8) fraction_lost;
486 priv->stats.cumulative_lost_num += (guint32) fraction_lost;
487 priv->stats.max_seqnum = (guint16) exthighestseq;
488 priv->stats.arrival_jitter = (guint32) jitter;
489 priv->stats.lsr = (guint32) lsr;
490 priv->stats.dlsr = (guint32) dlsr;
491 priv->stats.rtt = (guint32) rtt;
493 g_mutex_unlock (&priv->stats_lock);
494 g_signal_emit (client, gst_rtsp_client_wfd_signals[SIGNAL_WFD_RTP_STATS], 0,
499 wfd_configure_client_media (GstRTSPClient * client, GstRTSPMedia * media,
500 GstRTSPStream * stream, GstRTSPContext * ctx)
503 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
505 priv->stats.stream = stream;
506 g_signal_connect (stream, "rtcp-statistics", (GCallback) on_rtcp_stats,
510 return GST_RTSP_CLIENT_CLASS (gst_rtsp_wfd_client_parent_class)->
511 configure_client_media (client, media, stream, ctx);
515 wfd_options_request_done (GstRTSPWFDClient * client, GstRTSPContext * ctx)
517 GstRTSPResult res = GST_RTSP_OK;
518 GstRTSPWFDClientClass *klass = GST_RTSP_WFD_CLIENT_GET_CLASS (client);
520 g_return_if_fail (klass != NULL);
522 GST_INFO_OBJECT (client, "M2 done..");
524 res = handle_M3_message (client);
525 if (res < GST_RTSP_OK) {
526 GST_ERROR_OBJECT (client, "handle_M3_message failed : %d", res);
529 if (klass->prepare_resource) {
530 klass->prepare_resource (client, ctx);
537 wfd_get_param_request_done (GstRTSPWFDClient * client, GstRTSPContext * ctx)
539 GstRTSPResult res = GST_RTSP_OK;
540 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
541 GstRTSPWFDClientClass *klass = GST_RTSP_WFD_CLIENT_GET_CLASS (client);
543 g_return_if_fail (priv != NULL && klass != NULL);
545 priv->m3_done = TRUE;
546 GST_INFO_OBJECT (client, "M3 done..");
548 res = handle_M4_message (client);
549 if (res < GST_RTSP_OK) {
550 GST_ERROR_OBJECT (client, "handle_M4_message failed : %d", res);
553 if (klass->confirm_resource) {
554 klass->confirm_resource (client, ctx);
561 wfd_get_prefered_audio_codec (guint8 srcAudioCodec, guint sinkAudioCodec)
565 for (i = 0; i < 8; i++) {
566 if (((sinkAudioCodec << i) & 0x80)
567 && ((srcAudioCodec << i) & 0x80)) {
568 codec = (0x01 << (7 - i));
576 wfd_get_prefered_resolution (guint64 srcResolution,
577 guint64 sinkResolution,
578 GstWFDVideoNativeResolution native,
580 guint32 * cMaxHeight, guint32 * cFramerate, guint32 * interleaved)
583 guint64 resolution = 0;
584 for (i = 0; i < 32; i++) {
585 if (((sinkResolution << i) & 0x80000000)
586 && ((srcResolution << i) & 0x80000000)) {
587 resolution = ((guint64) 0x00000001 << (31 - i));
592 case GST_WFD_VIDEO_CEA_RESOLUTION:
594 switch (resolution) {
595 case GST_WFD_CEA_640x480P60:
601 case GST_WFD_CEA_720x480P60:
607 case GST_WFD_CEA_720x480I60:
613 case GST_WFD_CEA_720x576P50:
619 case GST_WFD_CEA_720x576I50:
625 case GST_WFD_CEA_1280x720P30:
631 case GST_WFD_CEA_1280x720P60:
637 case GST_WFD_CEA_1920x1080P30:
643 case GST_WFD_CEA_1920x1080P60:
649 case GST_WFD_CEA_1920x1080I60:
655 case GST_WFD_CEA_1280x720P25:
661 case GST_WFD_CEA_1280x720P50:
667 case GST_WFD_CEA_1920x1080P25:
673 case GST_WFD_CEA_1920x1080P50:
679 case GST_WFD_CEA_1920x1080I50:
685 case GST_WFD_CEA_1280x720P24:
691 case GST_WFD_CEA_1920x1080P24:
706 case GST_WFD_VIDEO_VESA_RESOLUTION:
708 switch (resolution) {
709 case GST_WFD_VESA_800x600P30:
715 case GST_WFD_VESA_800x600P60:
721 case GST_WFD_VESA_1024x768P30:
727 case GST_WFD_VESA_1024x768P60:
733 case GST_WFD_VESA_1152x864P30:
739 case GST_WFD_VESA_1152x864P60:
745 case GST_WFD_VESA_1280x768P30:
751 case GST_WFD_VESA_1280x768P60:
757 case GST_WFD_VESA_1280x800P30:
763 case GST_WFD_VESA_1280x800P60:
769 case GST_WFD_VESA_1360x768P30:
775 case GST_WFD_VESA_1360x768P60:
781 case GST_WFD_VESA_1366x768P30:
787 case GST_WFD_VESA_1366x768P60:
793 case GST_WFD_VESA_1280x1024P30:
799 case GST_WFD_VESA_1280x1024P60:
805 case GST_WFD_VESA_1400x1050P30:
811 case GST_WFD_VESA_1400x1050P60:
817 case GST_WFD_VESA_1440x900P30:
823 case GST_WFD_VESA_1440x900P60:
829 case GST_WFD_VESA_1600x900P30:
835 case GST_WFD_VESA_1600x900P60:
841 case GST_WFD_VESA_1600x1200P30:
847 case GST_WFD_VESA_1600x1200P60:
853 case GST_WFD_VESA_1680x1024P30:
859 case GST_WFD_VESA_1680x1024P60:
865 case GST_WFD_VESA_1680x1050P30:
871 case GST_WFD_VESA_1680x1050P60:
877 case GST_WFD_VESA_1920x1200P30:
883 case GST_WFD_VESA_1920x1200P60:
898 case GST_WFD_VIDEO_HH_RESOLUTION:
901 switch (resolution) {
902 case GST_WFD_HH_800x480P30:
907 case GST_WFD_HH_800x480P60:
912 case GST_WFD_HH_854x480P30:
917 case GST_WFD_HH_854x480P60:
922 case GST_WFD_HH_864x480P30:
927 case GST_WFD_HH_864x480P60:
932 case GST_WFD_HH_640x360P30:
937 case GST_WFD_HH_640x360P60:
942 case GST_WFD_HH_960x540P30:
947 case GST_WFD_HH_960x540P60:
952 case GST_WFD_HH_848x480P30:
957 case GST_WFD_HH_848x480P60:
983 wfd_make_path_from_uri (GstRTSPClient * client, const GstRTSPUrl * uri)
987 GST_DEBUG_OBJECT (client, "Got URI host : %s", uri->host);
988 GST_DEBUG_OBJECT (client, "Got URI abspath : %s", uri->abspath);
990 path = g_strdup ("/wfd1.0/streamid=0");
996 handle_wfd_play (GstRTSPClient * client, GstRTSPContext * ctx)
998 GstRTSPWFDClient *_client = GST_RTSP_WFD_CLIENT (client);
999 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
1001 g_return_if_fail (priv != NULL);
1003 wfd_set_keep_alive_condition (_client);
1005 priv->stats_timer_id = g_timeout_add (2000, wfd_display_rtp_stats, _client);
1007 g_signal_emit (client,
1008 gst_rtsp_client_wfd_signals[SIGNAL_WFD_PLAYING_DONE], 0, NULL);
1012 handle_wfd_response (GstRTSPClient * client, GstRTSPContext * ctx)
1014 GstRTSPResult res = GST_RTSP_OK;
1015 guint8 *data = NULL;
1018 GstRTSPWFDClient *_client = GST_RTSP_WFD_CLIENT (client);
1019 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
1021 g_return_if_fail (priv != NULL);
1023 GST_INFO_OBJECT (_client, "Handling response..");
1026 GST_ERROR_OBJECT (_client, "Context is NULL");
1030 if (!ctx->response) {
1031 GST_ERROR_OBJECT (_client, "Response is NULL");
1035 if (priv->sink_user_agent == NULL) {
1036 gchar *user_agent = NULL;
1037 gst_rtsp_message_get_header (ctx->response, GST_RTSP_HDR_USER_AGENT,
1039 priv->sink_user_agent = g_strdup (user_agent);
1041 GST_INFO_OBJECT (_client, "sink user_agent : %s", priv->sink_user_agent);
1044 /* parsing the GET_PARAMTER response */
1045 res = gst_rtsp_message_get_body (ctx->response, (guint8 **) & data, &size);
1046 if (res != GST_RTSP_OK) {
1047 GST_ERROR_OBJECT (_client, "Failed to get body of response...");
1051 GST_INFO_OBJECT (_client, "Response body is %d", size);
1053 if (!priv->m3_done) {
1054 GstWFDResult wfd_res;
1055 GstWFDMessage *msg = NULL;
1056 /* Parse M3 response from sink */
1057 wfd_res = gst_wfd_message_new (&msg);
1058 if (wfd_res != GST_WFD_OK) {
1059 GST_ERROR_OBJECT (client, "Failed to create wfd message...");
1063 wfd_res = gst_wfd_message_init (msg);
1064 if (wfd_res != GST_WFD_OK) {
1065 GST_ERROR_OBJECT (client, "Failed to init wfd message...");
1069 wfd_res = gst_wfd_message_parse_buffer (data, size, msg);
1071 GST_DEBUG_OBJECT (client, "M3 response server side message body: %s",
1072 gst_wfd_message_as_text (msg));
1074 /* Get the audio formats supported by WFDSink */
1075 if (msg->audio_codecs) {
1077 gst_wfd_message_get_supported_audio_format (msg, &priv->caCodec,
1078 &priv->cFreq, &priv->cChanels, &priv->cBitwidth, &priv->caLatency);
1079 if (wfd_res != GST_WFD_OK) {
1080 GST_WARNING_OBJECT (client,
1081 "Failed to get wfd support audio formats...");
1086 /* Get the Video formats supported by WFDSink */
1088 gst_wfd_message_get_supported_video_format (msg, &priv->cvCodec,
1089 &priv->cNative, &priv->cNativeResolution,
1090 (guint64 *) & priv->cCEAResolution,
1091 (guint64 *) & priv->cVESAResolution,
1092 (guint64 *) & priv->cHHResolution, &priv->cProfile, &priv->cLevel,
1093 &priv->cvLatency, &priv->cMaxHeight, &priv->cMaxWidth,
1094 &priv->cmin_slice_size, &priv->cslice_enc_params,
1095 &priv->cframe_rate_control);
1096 if (wfd_res != GST_WFD_OK) {
1097 GST_WARNING_OBJECT (client,
1098 "Failed to get wfd supported video formats...");
1102 if (msg->client_rtp_ports) {
1103 /* Get the RTP ports preferred by WFDSink */
1105 gst_wfd_message_get_prefered_rtp_ports (msg, &priv->ctrans,
1106 &priv->cprofile, &priv->clowertrans, &priv->crtp_port0,
1108 if (wfd_res != GST_WFD_OK) {
1109 GST_WARNING_OBJECT (client,
1110 "Failed to get wfd prefered RTP ports...");
1115 if (msg->display_edid) {
1116 guint32 edid_block_count = 0;
1117 gchar *edid_payload = NULL;
1118 priv->edid_supported = FALSE;
1119 /* Get the display edid preferred by WFDSink */
1120 GST_DEBUG_OBJECT (client, "Going to gst_wfd_message_get_display_edid");
1122 gst_wfd_message_get_display_edid (msg, &priv->edid_supported,
1123 &edid_block_count, &edid_payload);
1124 if (wfd_res != GST_WFD_OK) {
1125 GST_ERROR_OBJECT (client, "Failed to get wfd display edid...");
1128 GST_DEBUG_OBJECT (client, " edid supported: %d edid_block_count: %d",
1129 priv->edid_supported, edid_block_count);
1130 if (priv->edid_supported) {
1131 priv->edid_hres = 0;
1132 priv->edid_vres = 0;
1134 (guint32) (((edid_payload[54 + 4] >> 4) << 8) | edid_payload[54 +
1137 (guint32) (((edid_payload[54 + 7] >> 4) << 8) | edid_payload[54 +
1139 GST_DEBUG_OBJECT (client, " edid supported Hres: %d Wres: %d",
1140 priv->edid_hres, priv->edid_vres);
1141 if ((priv->edid_hres < 640) || (priv->edid_vres < 480)
1142 || (priv->edid_hres > 1920) || (priv->edid_vres > 1080)) {
1143 priv->edid_hres = 0;
1144 priv->edid_vres = 0;
1145 priv->edid_supported = FALSE;
1146 GST_WARNING_OBJECT (client, " edid invalid resolutions");
1151 if (msg->content_protection) {
1153 /*Get the hdcp version and tcp port by WFDSink */
1155 gst_wfd_message_get_contentprotection_type (msg,
1156 &priv->hdcp_version, &priv->hdcp_tcpport);
1157 GST_DEBUG ("hdcp version =%d, tcp port = %d", priv->hdcp_version,
1158 priv->hdcp_tcpport);
1159 if (priv->hdcp_version > 0 && priv->hdcp_tcpport > 0)
1160 priv->protection_enabled = TRUE;
1162 if (wfd_res != GST_WFD_OK) {
1163 GST_WARNING_OBJECT (client,
1164 "Failed to get wfd content protection...");
1168 GST_WARNING_OBJECT (client, "Don't use content protection");
1172 g_signal_emit (client,
1173 gst_rtsp_client_wfd_signals[SIGNAL_WFD_M3_RES_MSG], 0, data);
1175 g_signal_emit (_client,
1176 gst_rtsp_client_wfd_signals[SIGNAL_WFD_GET_PARAMETER_REQUEST], 0,
1179 /* TODO-WFD: Handle another GET_PARAMETER response with body */
1181 } else if (size == 0) {
1182 if (!priv->m1_done) {
1183 GST_INFO_OBJECT (_client, "M1 response is done");
1184 priv->m1_done = TRUE;
1185 } else if (!priv->m4_done) {
1186 GST_INFO_OBJECT (_client, "M4 response is done");
1187 priv->m4_done = TRUE;
1189 gst_rtsp_wfd_client_trigger_request (_client, WFD_TRIGGER_SETUP);
1191 g_mutex_lock (&priv->keep_alive_lock);
1192 if (priv->keep_alive_flag == FALSE) {
1193 GST_INFO_OBJECT (_client, "M16 response is done");
1194 priv->keep_alive_flag = TRUE;
1196 g_mutex_unlock (&priv->keep_alive_lock);
1207 handle_wfd_options_request (GstRTSPClient * client, GstRTSPContext * ctx)
1209 GstRTSPResult res = GST_RTSP_OK;
1210 GstRTSPMethod options;
1213 gchar *user_agent = NULL;
1215 GstRTSPWFDClient *_client = GST_RTSP_WFD_CLIENT (client);
1217 options = GST_RTSP_OPTIONS |
1221 GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | GST_RTSP_TEARDOWN;
1223 str = gst_rtsp_options_as_text (options);
1225 /*append WFD specific method */
1226 tmp = g_strdup (", org.wfa.wfd1.0");
1227 g_strlcat (str, tmp, strlen (tmp) + strlen (str) + 1);
1229 gst_rtsp_message_init_response (ctx->response, GST_RTSP_STS_OK,
1230 gst_rtsp_status_as_text (GST_RTSP_STS_OK), ctx->request);
1232 gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_PUBLIC, str);
1239 gst_rtsp_message_get_header (ctx->request, GST_RTSP_HDR_USER_AGENT,
1241 if (res == GST_RTSP_OK) {
1242 gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_USER_AGENT,
1248 res = gst_rtsp_client_send_message (client, NULL, ctx->response);
1249 if (res != GST_RTSP_OK) {
1250 GST_ERROR_OBJECT (client, "gst_rtsp_client_send_message failed : %d", res);
1254 GST_DEBUG_OBJECT (client, "Sent M2 response...");
1256 g_signal_emit (_client,
1257 gst_rtsp_client_wfd_signals[SIGNAL_WFD_OPTIONS_REQUEST], 0, ctx);
1263 handle_wfd_get_param_request (GstRTSPClient * client, GstRTSPContext * ctx)
1265 GstRTSPResult res = GST_RTSP_OK;
1266 guint8 *data = NULL;
1269 GstRTSPWFDClient *_client = GST_RTSP_WFD_CLIENT (client);
1271 /* parsing the GET_PARAMTER request */
1272 res = gst_rtsp_message_get_body (ctx->request, (guint8 **) & data, &size);
1273 if (res != GST_RTSP_OK) {
1274 GST_ERROR_OBJECT (_client, "Failed to get body of request...");
1279 send_generic_wfd_response (_client, GST_RTSP_STS_OK, ctx);
1281 /* TODO-WFD: Handle other GET_PARAMETER request from sink */
1288 handle_wfd_set_param_request (GstRTSPClient * client, GstRTSPContext * ctx)
1290 GstRTSPResult res = GST_RTSP_OK;
1291 guint8 *data = NULL;
1294 GstRTSPWFDClient *_client = GST_RTSP_WFD_CLIENT (client);
1296 res = gst_rtsp_message_get_body (ctx->request, &data, &size);
1297 if (res != GST_RTSP_OK)
1301 /* no body, keep-alive request */
1302 send_generic_wfd_response (_client, GST_RTSP_STS_OK, ctx);
1305 GST_INFO_OBJECT (_client, "SET_PARAMETER Request : %s(%d)", data, size);
1306 if (g_strcmp0 ((const gchar *) data, "wfd_idr_request"))
1307 send_generic_wfd_response (_client, GST_RTSP_STS_OK, ctx);
1309 send_generic_wfd_response (_client, GST_RTSP_STS_OK, ctx);
1310 g_signal_emit (client,
1311 gst_rtsp_client_wfd_signals[SIGNAL_WFD_SET_PARAM_MSG], 0, data);
1323 GST_ERROR ("_client %p: bad request", _client);
1324 send_generic_wfd_response (_client, GST_RTSP_STS_BAD_REQUEST, ctx);
1331 gst_rtsp_wfd_client_parse_methods (GstRTSPWFDClient * client,
1332 GstRTSPMessage * response)
1334 GstRTSPHeaderField field;
1339 gboolean found_wfd_method = FALSE;
1341 /* reset supported methods */
1342 client->supported_methods = 0;
1344 /* Try Allow Header first */
1345 field = GST_RTSP_HDR_ALLOW;
1348 gst_rtsp_message_get_header (response, field, &respoptions, indx);
1349 if (indx == 0 && !respoptions) {
1350 /* if no Allow header was found then try the Public header... */
1351 field = GST_RTSP_HDR_PUBLIC;
1352 gst_rtsp_message_get_header (response, field, &respoptions, indx);
1357 /* If we get here, the server gave a list of supported methods, parse
1358 * them here. The string is like:
1360 * OPTIONS, PLAY, SETUP, ...
1362 options = g_strsplit (respoptions, ",", 0);
1364 for (i = 0; options[i]; i++) {
1368 stripped = g_strstrip (options[i]);
1369 method = gst_rtsp_find_method (stripped);
1371 if (!g_ascii_strcasecmp ("org.wfa.wfd1.0", stripped))
1372 found_wfd_method = TRUE;
1374 /* keep bitfield of supported methods */
1375 if (method != GST_RTSP_INVALID)
1376 client->supported_methods |= method;
1378 g_strfreev (options);
1383 if (!found_wfd_method) {
1384 GST_ERROR_OBJECT (client,
1385 "WFD client is not supporting WFD mandatory message : org.wfa.wfd1.0...");
1386 goto no_required_methods;
1389 /* Checking mandatory method */
1390 if (!(client->supported_methods & GST_RTSP_SET_PARAMETER)) {
1391 GST_ERROR_OBJECT (client,
1392 "WFD client is not supporting WFD mandatory message : SET_PARAMETER...");
1393 goto no_required_methods;
1396 /* Checking mandatory method */
1397 if (!(client->supported_methods & GST_RTSP_GET_PARAMETER)) {
1398 GST_ERROR_OBJECT (client,
1399 "WFD client is not supporting WFD mandatory message : GET_PARAMETER...");
1400 goto no_required_methods;
1403 if (!(client->supported_methods & GST_RTSP_OPTIONS)) {
1404 GST_INFO_OBJECT (client, "assuming OPTIONS is supported by client...");
1405 client->supported_methods |= GST_RTSP_OPTIONS;
1411 no_required_methods:
1413 GST_ELEMENT_ERROR (client, RESOURCE, OPEN_READ, (NULL),
1414 ("WFD Client does not support mandatory methods."));
1434 } GstWFDMessageType;
1437 _set_negotiated_audio_codec (GstRTSPWFDClient * client, guint audio_codec)
1439 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
1441 GstRTSPMediaFactory *factory = NULL;
1442 GstRTSPMountPoints *mount_points = NULL;
1445 gboolean ret = TRUE;
1447 if (!(mount_points = gst_rtsp_client_get_mount_points (parent_client))) {
1449 GST_ERROR_OBJECT (client,
1450 "Failed to set negotiated audio codec: no mount points...");
1451 goto no_mount_points;
1454 path = g_strdup (WFD_MOUNT_POINT);
1457 GST_ERROR_OBJECT (client,
1458 "Failed to set negotiated audio codec: no path...");
1462 if (!(factory = gst_rtsp_mount_points_match (mount_points, path, &matched))) {
1463 GST_ERROR_OBJECT (client,
1464 "Failed to set negotiated audio codec: no factory...");
1469 gst_rtsp_media_factory_wfd_set_audio_codec (factory, audio_codec);
1472 g_object_unref (factory);
1477 g_object_unref (mount_points);
1483 _set_negotiated_resolution (GstRTSPWFDClient * client,
1484 guint32 width, guint32 height)
1486 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
1488 GstRTSPMediaFactory *factory = NULL;
1489 GstRTSPMountPoints *mount_points = NULL;
1492 gboolean ret = TRUE;
1494 if (!(mount_points = gst_rtsp_client_get_mount_points (parent_client))) {
1496 GST_ERROR_OBJECT (client,
1497 "Failed to set negotiated resolution: no mount points...");
1498 goto no_mount_points;
1501 path = g_strdup (WFD_MOUNT_POINT);
1504 GST_ERROR_OBJECT (client,
1505 "Failed to set negotiated resolution: no path...");
1509 if (!(factory = gst_rtsp_mount_points_match (mount_points, path, &matched))) {
1510 GST_ERROR_OBJECT (client,
1511 "Failed to set negotiated resolution: no factory...");
1516 gst_rtsp_media_factory_wfd_set_negotiated_resolution (factory, width, height);
1519 g_object_unref (factory);
1524 g_object_unref (mount_points);
1530 _set_wfd_message_body (GstRTSPWFDClient * client, GstWFDMessageType msg_type,
1531 gchar ** data, guint * len)
1533 GString *buf = NULL;
1534 GstWFDMessage *msg = NULL;
1535 GstWFDResult wfd_res = GST_WFD_EINVAL;
1536 GstRTSPWFDClientPrivate *priv = NULL;
1537 priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
1539 g_return_if_fail (priv != NULL);
1541 buf = g_string_new ("");
1542 g_return_if_fail (buf != NULL);
1544 if (msg_type == M3_REQ_MSG) {
1545 /* create M3 request to be sent */
1546 wfd_res = gst_wfd_message_new (&msg);
1547 if (wfd_res != GST_WFD_OK) {
1548 GST_ERROR_OBJECT (client, "Failed to create wfd message...");
1552 wfd_res = gst_wfd_message_init (msg);
1553 if (wfd_res != GST_WFD_OK) {
1554 GST_ERROR_OBJECT (client, "Failed to init wfd message...");
1558 /* set the supported audio formats by the WFD server */
1560 gst_wfd_message_set_supported_audio_format (msg, GST_WFD_AUDIO_UNKNOWN,
1561 GST_WFD_FREQ_UNKNOWN, GST_WFD_CHANNEL_UNKNOWN, 0, 0);
1562 if (wfd_res != GST_WFD_OK) {
1563 GST_ERROR_OBJECT (client,
1564 "Failed to set supported audio formats on wfd message...");
1568 /* set the supported Video formats by the WFD server */
1570 gst_wfd_message_set_supported_video_format (msg, GST_WFD_VIDEO_UNKNOWN,
1571 GST_WFD_VIDEO_CEA_RESOLUTION, GST_WFD_CEA_UNKNOWN, GST_WFD_CEA_UNKNOWN,
1572 GST_WFD_VESA_UNKNOWN, GST_WFD_HH_UNKNOWN, GST_WFD_H264_UNKNOWN_PROFILE,
1573 GST_WFD_H264_LEVEL_UNKNOWN, 0, 0, 0, 0, 0, 0);
1574 if (wfd_res != GST_WFD_OK) {
1575 GST_ERROR_OBJECT (client,
1576 "Failed to set supported video formats on wfd message...");
1580 wfd_res = gst_wfd_message_set_display_edid (msg, 0, 0, NULL);
1581 if (wfd_res != GST_WFD_OK) {
1582 GST_ERROR_OBJECT (client,
1583 "Failed to set display edid type on wfd message...");
1587 if (priv->protection_enabled) {
1589 gst_wfd_message_set_contentprotection_type (msg, GST_WFD_HDCP_NONE,
1591 if (wfd_res != GST_WFD_OK) {
1592 GST_ERROR_OBJECT (client,
1593 "Failed to set supported content protection type on wfd message...");
1598 /* set the preffered RTP ports for the WFD server */
1600 gst_wfd_messge_set_prefered_rtp_ports (msg, GST_WFD_RTSP_TRANS_UNKNOWN,
1601 GST_WFD_RTSP_PROFILE_UNKNOWN, GST_WFD_RTSP_LOWER_TRANS_UNKNOWN, 0, 0);
1602 if (wfd_res != GST_WFD_OK) {
1603 GST_ERROR_OBJECT (client,
1604 "Failed to set supported video formats on wfd message...");
1608 *data = gst_wfd_message_param_names_as_text (msg);
1609 if (*data == NULL) {
1610 GST_ERROR_OBJECT (client, "Failed to get wfd message as text...");
1613 gchar *append_data = NULL;
1615 g_signal_emit (client, gst_rtsp_client_wfd_signals[SIGNAL_WFD_M3_REQ_MSG],
1616 0, *data, &append_data);
1620 *data = append_data;
1623 *len = strlen (*data);
1625 } else if (msg_type == M4_REQ_MSG) {
1626 GstRTSPUrl *url = NULL;
1628 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
1629 GstRTSPConnection *connection =
1630 gst_rtsp_client_get_connection (parent_client);
1632 /* Parameters for the preffered audio formats */
1633 GstWFDAudioFormats taudiocodec = GST_WFD_AUDIO_UNKNOWN;
1634 GstWFDAudioFreq taudiofreq = GST_WFD_FREQ_UNKNOWN;
1635 GstWFDAudioChannels taudiochannels = GST_WFD_CHANNEL_UNKNOWN;
1637 /* Parameters for the preffered video formats */
1638 GstWFDVideoCEAResolution tcCEAResolution = GST_WFD_CEA_UNKNOWN;
1639 GstWFDVideoVESAResolution tcVESAResolution = GST_WFD_VESA_UNKNOWN;
1640 GstWFDVideoHHResolution tcHHResolution = GST_WFD_HH_UNKNOWN;
1641 GstWFDVideoH264Profile tcProfile;
1642 GstWFDVideoH264Level tcLevel;
1643 guint64 resolution_supported = 0;
1645 url = gst_rtsp_connection_get_url (connection);
1647 GST_ERROR_OBJECT (client, "Failed to get connection URL");
1651 /* Logic to negotiate with information of M3 response */
1652 /* create M4 request to be sent */
1653 wfd_res = gst_wfd_message_new (&msg);
1654 if (wfd_res != GST_WFD_OK) {
1655 GST_ERROR_OBJECT (client, "Failed to create wfd message...");
1659 wfd_res = gst_wfd_message_init (msg);
1660 if (wfd_res != GST_WFD_OK) {
1661 GST_ERROR_OBJECT (client, "Failed to init wfd message...");
1665 g_string_append_printf (buf, "rtsp://");
1667 if (priv->host_address) {
1668 g_string_append (buf, priv->host_address);
1670 GST_ERROR_OBJECT (client, "Failed to get host address");
1672 g_string_free (buf, TRUE);
1676 g_string_append_printf (buf, "/wfd1.0/streamid=0");
1678 gst_wfd_message_set_presentation_url (msg, g_string_free (buf, FALSE),
1681 if (wfd_res != GST_WFD_OK) {
1682 GST_ERROR_OBJECT (client, "Failed to set presentation url");
1687 wfd_get_prefered_audio_codec (priv->audio_codec, priv->caCodec);
1688 priv->caCodec = taudiocodec;
1689 if (!_set_negotiated_audio_codec (client, priv->caCodec)) {
1690 GST_ERROR_OBJECT (client, "Failed to set negotiated "
1691 "audio codec to media factory...");
1694 if (priv->cFreq & GST_WFD_FREQ_48000)
1695 taudiofreq = GST_WFD_FREQ_48000;
1696 else if (priv->cFreq & GST_WFD_FREQ_44100)
1697 taudiofreq = GST_WFD_FREQ_44100;
1698 priv->cFreq = taudiofreq;
1700 /* TODO-WFD: Currently only 2 channels is present */
1701 if (priv->cChanels & GST_WFD_CHANNEL_8)
1702 taudiochannels = GST_WFD_CHANNEL_2;
1703 else if (priv->cChanels & GST_WFD_CHANNEL_6)
1704 taudiochannels = GST_WFD_CHANNEL_2;
1705 else if (priv->cChanels & GST_WFD_CHANNEL_4)
1706 taudiochannels = GST_WFD_CHANNEL_2;
1707 else if (priv->cChanels & GST_WFD_CHANNEL_2)
1708 taudiochannels = GST_WFD_CHANNEL_2;
1709 priv->cChanels = taudiochannels;
1712 gst_wfd_message_set_prefered_audio_format (msg, taudiocodec, taudiofreq,
1713 taudiochannels, priv->cBitwidth, priv->caLatency);
1714 if (wfd_res != GST_WFD_OK) {
1715 GST_ERROR_OBJECT (priv, "Failed to set preffered audio formats...");
1719 /* Set the preffered video formats */
1720 priv->cvCodec = GST_WFD_VIDEO_H264;
1721 priv->cProfile = tcProfile = GST_WFD_H264_BASE_PROFILE;
1722 priv->cLevel = tcLevel = GST_WFD_H264_LEVEL_3_1;
1724 resolution_supported = priv->video_resolution_supported;
1726 /* TODO-WFD: Need to verify this logic
1727 if(priv->edid_supported) {
1728 if (priv->edid_hres < 1920) resolution_supported = resolution_supported & 0x8C7F;
1729 if (priv->edid_hres < 1280) resolution_supported = resolution_supported & 0x1F;
1730 if (priv->edid_hres < 720) resolution_supported = resolution_supported & 0x01;
1734 if (priv->video_native_resolution == GST_WFD_VIDEO_CEA_RESOLUTION) {
1736 wfd_get_prefered_resolution (resolution_supported,
1737 priv->cCEAResolution, priv->video_native_resolution, &priv->cMaxWidth,
1738 &priv->cMaxHeight, &priv->cFramerate, &priv->cInterleaved);
1740 ("wfd negotiated resolution: %08x, width: %d, height: %d, framerate: %d, interleaved: %d",
1741 tcCEAResolution, priv->cMaxWidth, priv->cMaxHeight, priv->cFramerate,
1742 priv->cInterleaved);
1743 } else if (priv->video_native_resolution == GST_WFD_VIDEO_VESA_RESOLUTION) {
1745 wfd_get_prefered_resolution (resolution_supported,
1746 priv->cVESAResolution, priv->video_native_resolution,
1747 &priv->cMaxWidth, &priv->cMaxHeight, &priv->cFramerate,
1748 &priv->cInterleaved);
1750 ("wfd negotiated resolution: %08x, width: %d, height: %d, framerate: %d, interleaved: %d",
1751 tcVESAResolution, priv->cMaxWidth, priv->cMaxHeight, priv->cFramerate,
1752 priv->cInterleaved);
1753 } else if (priv->video_native_resolution == GST_WFD_VIDEO_HH_RESOLUTION) {
1755 wfd_get_prefered_resolution (resolution_supported,
1756 priv->cHHResolution, priv->video_native_resolution, &priv->cMaxWidth,
1757 &priv->cMaxHeight, &priv->cFramerate, &priv->cInterleaved);
1759 ("wfd negotiated resolution: %08x, width: %d, height: %d, framerate: %d, interleaved: %d",
1760 tcHHResolution, priv->cMaxWidth, priv->cMaxHeight, priv->cFramerate,
1761 priv->cInterleaved);
1764 if (!_set_negotiated_resolution (client, priv->cMaxWidth, priv->cMaxHeight)) {
1765 GST_ERROR_OBJECT (client, "Failed to set negotiated "
1766 "resolution to media factory...");
1770 gst_wfd_message_set_prefered_video_format (msg, priv->cvCodec,
1771 priv->video_native_resolution, GST_WFD_CEA_UNKNOWN, tcCEAResolution,
1772 tcVESAResolution, tcHHResolution, tcProfile, tcLevel, priv->cvLatency,
1773 priv->cMaxWidth, priv->cMaxHeight, priv->cmin_slice_size,
1774 priv->cslice_enc_params, priv->cframe_rate_control);
1776 if (wfd_res != GST_WFD_OK) {
1777 GST_ERROR_OBJECT (client, "Failed to set preffered video formats...");
1781 /* set the preffered RTP ports for the WFD server */
1783 gst_wfd_messge_set_prefered_rtp_ports (msg, GST_WFD_RTSP_TRANS_RTP,
1784 GST_WFD_RTSP_PROFILE_AVP, GST_WFD_RTSP_LOWER_TRANS_UDP,
1785 priv->crtp_port0, priv->crtp_port1);
1786 if (wfd_res != GST_WFD_OK) {
1787 GST_ERROR_OBJECT (client,
1788 "Failed to set supported video formats on wfd message...");
1792 *data = gst_wfd_message_as_text (msg);
1793 if (*data == NULL) {
1794 GST_ERROR_OBJECT (client, "Failed to get wfd message as text...");
1797 gchar *append_data = NULL;
1799 g_signal_emit (client,
1800 gst_rtsp_client_wfd_signals[SIGNAL_WFD_M4_REQ_MSG], 0, *data,
1805 *data = append_data;
1807 *len = strlen (*data);
1809 } else if (msg_type == M5_REQ_MSG) {
1810 g_string_append (buf, "wfd_trigger_method: SETUP");
1811 g_string_append (buf, "\r\n");
1813 *data = g_string_free (buf, FALSE);
1814 } else if (msg_type == TEARDOWN_TRIGGER) {
1815 g_string_append (buf, "wfd_trigger_method: TEARDOWN");
1816 g_string_append (buf, "\r\n");
1818 *data = g_string_free (buf, FALSE);
1819 } else if (msg_type == PLAY_TRIGGER) {
1820 g_string_append (buf, "wfd_trigger_method: PLAY");
1821 g_string_append (buf, "\r\n");
1823 *data = g_string_free (buf, FALSE);
1824 } else if (msg_type == PAUSE_TRIGGER) {
1825 g_string_append (buf, "wfd_trigger_method: PAUSE");
1826 g_string_append (buf, "\r\n");
1828 *data = g_string_free (buf, FALSE);
1843 * gst_prepare_request:
1844 * @client: client object
1845 * @request : requst message to be prepared
1846 * @method : RTSP method of the request
1847 * @url : url need to be in the request
1848 * @message_type : WFD message type
1849 * @trigger_type : trigger method to be used for M5 mainly
1851 * Prepares request based on @method & @message_type
1853 * Returns: a #GstRTSPResult.
1856 gst_prepare_request (GstRTSPWFDClient * client, GstRTSPMessage * request,
1857 GstRTSPMethod method, gchar * url)
1859 GstRTSPResult res = GST_RTSP_OK;
1862 if (method == GST_RTSP_GET_PARAMETER || method == GST_RTSP_SET_PARAMETER) {
1864 url = g_strdup ("rtsp://localhost/wfd1.0");
1867 GST_DEBUG_OBJECT (client, "Preparing request: %d", method);
1869 /* initialize the request */
1870 res = gst_rtsp_message_init_request (request, method, url);
1872 if (method == GST_RTSP_GET_PARAMETER || method == GST_RTSP_SET_PARAMETER) {
1877 GST_ERROR ("init request failed");
1882 /* Prepare OPTIONS request to send */
1883 case GST_RTSP_OPTIONS:{
1884 /* add wfd specific require filed "org.wfa.wfd1.0" */
1885 str = g_strdup ("org.wfa.wfd1.0");
1886 res = gst_rtsp_message_add_header (request, GST_RTSP_HDR_REQUIRE, str);
1888 GST_ERROR ("Failed to add header");
1897 /* Prepare GET_PARAMETER request */
1898 case GST_RTSP_GET_PARAMETER:{
1903 /* add content type */
1905 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
1908 GST_ERROR ("Failed to add header");
1912 _set_wfd_message_body (client, M3_REQ_MSG, &msg, &msglen);
1913 msglength = g_string_new ("");
1914 g_string_append_printf (msglength, "%d", msglen);
1915 GST_DEBUG ("M3 server side message body: %s", msg);
1917 /* add content-length type */
1919 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
1920 g_string_free (msglength, FALSE));
1921 if (res != GST_RTSP_OK) {
1922 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1926 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
1927 if (res != GST_RTSP_OK) {
1928 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1936 /* Prepare SET_PARAMETER request */
1937 case GST_RTSP_SET_PARAMETER:{
1942 /* add content type */
1944 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
1946 if (res != GST_RTSP_OK) {
1947 GST_ERROR_OBJECT (client, "Failed to add header to rtsp request...");
1951 _set_wfd_message_body (client, M4_REQ_MSG, &msg, &msglen);
1952 msglength = g_string_new ("");
1953 g_string_append_printf (msglength, "%d", msglen);
1954 GST_DEBUG ("M4 server side message body: %s", msg);
1956 /* add content-length type */
1958 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
1959 g_string_free (msglength, FALSE));
1960 if (res != GST_RTSP_OK) {
1961 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1965 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
1966 if (res != GST_RTSP_OK) {
1967 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1982 return GST_RTSP_ERROR;
1986 prepare_trigger_request (GstRTSPWFDClient * client, GstRTSPMessage * request,
1987 GstWFDTriggerType trigger_type, gchar * url)
1989 GstRTSPResult res = GST_RTSP_OK;
1991 /* initialize the request */
1992 res = gst_rtsp_message_init_request (request, GST_RTSP_SET_PARAMETER, url);
1994 GST_ERROR ("init request failed");
1998 switch (trigger_type) {
1999 case WFD_TRIGGER_SETUP:{
2004 /* add content type */
2006 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
2008 if (res != GST_RTSP_OK) {
2009 GST_ERROR_OBJECT (client, "Failed to add header to rtsp request...");
2013 _set_wfd_message_body (client, M5_REQ_MSG, &msg, &msglen);
2014 msglength = g_string_new ("");
2015 g_string_append_printf (msglength, "%d", msglen);
2016 GST_DEBUG ("M5 server side message body: %s", msg);
2018 /* add content-length type */
2020 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
2021 g_string_free (msglength, FALSE));
2022 if (res != GST_RTSP_OK) {
2023 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2027 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
2028 if (res != GST_RTSP_OK) {
2029 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2036 case WFD_TRIGGER_TEARDOWN:{
2041 /* add content type */
2043 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
2045 if (res != GST_RTSP_OK) {
2046 GST_ERROR_OBJECT (client, "Failed to add header to rtsp request...");
2050 _set_wfd_message_body (client, TEARDOWN_TRIGGER, &msg, &msglen);
2051 msglength = g_string_new ("");
2052 g_string_append_printf (msglength, "%d", msglen);
2053 GST_DEBUG ("Trigger TEARDOWN server side message body: %s", msg);
2055 /* add content-length type */
2057 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
2058 g_string_free (msglength, FALSE));
2059 if (res != GST_RTSP_OK) {
2060 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2064 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
2065 if (res != GST_RTSP_OK) {
2066 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2073 case WFD_TRIGGER_PLAY:{
2078 /* add content type */
2080 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
2082 if (res != GST_RTSP_OK) {
2083 GST_ERROR_OBJECT (client, "Failed to add header to rtsp request...");
2087 _set_wfd_message_body (client, PLAY_TRIGGER, &msg, &msglen);
2088 msglength = g_string_new ("");
2089 g_string_append_printf (msglength, "%d", msglen);
2090 GST_DEBUG ("Trigger PLAY server side message body: %s", msg);
2092 /* add content-length type */
2094 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
2095 g_string_free (msglength, FALSE));
2096 if (res != GST_RTSP_OK) {
2097 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2101 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
2102 if (res != GST_RTSP_OK) {
2103 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2110 case WFD_TRIGGER_PAUSE:{
2115 /* add content type */
2117 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
2119 if (res != GST_RTSP_OK) {
2120 GST_ERROR_OBJECT (client, "Failed to add header to rtsp request...");
2124 _set_wfd_message_body (client, PAUSE_TRIGGER, &msg, &msglen);
2125 msglength = g_string_new ("");
2126 g_string_append_printf (msglength, "%d", msglen);
2127 GST_DEBUG ("Trigger PAUSE server side message body: %s", msg);
2129 /* add content-length type */
2131 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
2132 g_string_free (msglength, FALSE));
2133 if (res != GST_RTSP_OK) {
2134 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2138 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
2139 if (res != GST_RTSP_OK) {
2140 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2147 /* TODO-WFD: implement to handle other trigger type */
2160 gst_send_request (GstRTSPWFDClient * client, GstRTSPSession * session,
2161 GstRTSPMessage * request)
2163 GstRTSPResult res = GST_RTSP_OK;
2164 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
2166 /* remove any previous header */
2167 gst_rtsp_message_remove_header (request, GST_RTSP_HDR_SESSION, -1);
2169 /* add the new session header for new session ids */
2172 const gchar *sessionid = NULL;
2175 sessionid = gst_rtsp_session_get_sessionid (session);
2176 GST_INFO_OBJECT (client, "Session id : %s", sessionid);
2178 timeout = gst_rtsp_session_get_timeout (session);
2179 if (timeout != DEFAULT_WFD_TIMEOUT)
2180 str = g_strdup_printf ("%s; timeout=%d", sessionid, timeout);
2182 str = g_strdup (sessionid);
2184 gst_rtsp_message_take_header (request, GST_RTSP_HDR_SESSION, str);
2187 if (gst_debug_category_get_threshold (rtsp_wfd_client_debug) >= GST_LEVEL_LOG) {
2188 gst_rtsp_message_dump (request);
2191 res = gst_rtsp_client_send_message (parent_client, session, request);
2192 if (res != GST_RTSP_OK) {
2193 GST_ERROR_OBJECT (client, "gst_rtsp_client_send_message failed : %d", res);
2196 gst_rtsp_message_unset (request);
2201 * @client: client object
2202 * @request : requst message received
2203 * @response : response to be prepare based on request
2204 * @method : RTSP method
2206 * prepare response to the request based on @method & @message_type
2208 * Returns: a #GstRTSPResult.
2211 prepare_response (GstRTSPWFDClient * client, GstRTSPMessage * request,
2212 GstRTSPMessage * response, GstRTSPMethod method)
2214 GstRTSPResult res = GST_RTSP_OK;
2217 /* prepare OPTIONS response */
2218 case GST_RTSP_OPTIONS:{
2219 GstRTSPMethod options;
2222 gchar *user_agent = NULL;
2224 options = GST_RTSP_OPTIONS |
2228 GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | GST_RTSP_TEARDOWN;
2230 str = gst_rtsp_options_as_text (options);
2232 /*append WFD specific method */
2233 tmp = g_strdup (", org.wfa.wfd1.0");
2234 g_strlcat (str, tmp, strlen (tmp) + strlen (str) + 1);
2236 gst_rtsp_message_init_response (response, GST_RTSP_STS_OK,
2237 gst_rtsp_status_as_text (GST_RTSP_STS_OK), request);
2239 gst_rtsp_message_add_header (response, GST_RTSP_HDR_PUBLIC, str);
2244 gst_rtsp_message_get_header (request, GST_RTSP_HDR_USER_AGENT,
2246 if (res == GST_RTSP_OK) {
2247 gst_rtsp_message_add_header (response, GST_RTSP_HDR_USER_AGENT,
2254 GST_ERROR_OBJECT (client, "Unhandled method...");
2255 return GST_RTSP_EINVAL;
2263 send_generic_wfd_response (GstRTSPWFDClient * client, GstRTSPStatusCode code,
2264 GstRTSPContext * ctx)
2266 GstRTSPResult res = GST_RTSP_OK;
2267 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
2269 gst_rtsp_message_init_response (ctx->response, code,
2270 gst_rtsp_status_as_text (code), ctx->request);
2272 res = gst_rtsp_client_send_message (parent_client, NULL, ctx->response);
2273 if (res != GST_RTSP_OK) {
2274 GST_ERROR_OBJECT (client, "gst_rtsp_client_send_message failed : %d", res);
2279 static GstRTSPResult
2280 handle_M1_message (GstRTSPWFDClient * client)
2282 GstRTSPResult res = GST_RTSP_OK;
2283 GstRTSPMessage request = { 0 };
2285 res = gst_prepare_request (client, &request, GST_RTSP_OPTIONS, (gchar *) "*");
2286 if (GST_RTSP_OK != res) {
2287 GST_ERROR_OBJECT (client, "Failed to prepare M1 request....\n");
2291 GST_DEBUG_OBJECT (client, "Sending M1 request.. (OPTIONS request)");
2293 gst_send_request (client, NULL, &request);
2299 * handle_M3_message:
2300 * @client: client object
2302 * Handles M3 WFD message.
2303 * This API will send M3 message (GET_PARAMETER) to WFDSink to query supported formats by the WFDSink.
2304 * After getting supported formats info, this API will set those values on WFDConfigMessage obj
2306 * Returns: a #GstRTSPResult.
2308 static GstRTSPResult
2309 handle_M3_message (GstRTSPWFDClient * client)
2311 GstRTSPResult res = GST_RTSP_OK;
2312 GstRTSPMessage request = { 0 };
2313 GstRTSPUrl *url = NULL;
2314 gchar *url_str = NULL;
2316 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
2317 GstRTSPConnection *connection =
2318 gst_rtsp_client_get_connection (parent_client);
2320 url = gst_rtsp_connection_get_url (connection);
2322 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2323 res = GST_RTSP_ERROR;
2327 url_str = gst_rtsp_url_get_request_uri (url);
2328 if (url_str == NULL) {
2329 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2330 res = GST_RTSP_ERROR;
2334 res = gst_prepare_request (client, &request, GST_RTSP_GET_PARAMETER, url_str);
2335 if (GST_RTSP_OK != res) {
2336 GST_ERROR_OBJECT (client, "Failed to prepare M3 request....\n");
2340 GST_DEBUG_OBJECT (client, "Sending GET_PARAMETER request message (M3)...");
2342 gst_send_request (client, NULL, &request);
2350 static GstRTSPResult
2351 handle_M4_message (GstRTSPWFDClient * client)
2353 GstRTSPResult res = GST_RTSP_OK;
2354 GstRTSPMessage request = { 0 };
2355 GstRTSPUrl *url = NULL;
2356 gchar *url_str = NULL;
2358 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
2359 GstRTSPConnection *connection =
2360 gst_rtsp_client_get_connection (parent_client);
2362 url = gst_rtsp_connection_get_url (connection);
2364 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2365 res = GST_RTSP_ERROR;
2369 url_str = gst_rtsp_url_get_request_uri (url);
2370 if (url_str == NULL) {
2371 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2372 res = GST_RTSP_ERROR;
2376 res = gst_prepare_request (client, &request, GST_RTSP_SET_PARAMETER, url_str);
2377 if (GST_RTSP_OK != res) {
2378 GST_ERROR_OBJECT (client, "Failed to prepare M4 request....\n");
2382 GST_DEBUG_OBJECT (client, "Sending SET_PARAMETER request message (M4)...");
2384 gst_send_request (client, NULL, &request);
2393 gst_rtsp_wfd_client_trigger_request (GstRTSPWFDClient * client,
2394 GstWFDTriggerType type)
2396 GstRTSPResult res = GST_RTSP_OK;
2397 GstRTSPMessage request = { 0 };
2398 GstRTSPUrl *url = NULL;
2399 gchar *url_str = NULL;
2401 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
2402 GstRTSPConnection *connection =
2403 gst_rtsp_client_get_connection (parent_client);
2405 url = gst_rtsp_connection_get_url (connection);
2407 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2408 res = GST_RTSP_ERROR;
2412 url_str = gst_rtsp_url_get_request_uri (url);
2413 if (url_str == NULL) {
2414 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2415 res = GST_RTSP_ERROR;
2419 res = prepare_trigger_request (client, &request, type, url_str);
2420 if (GST_RTSP_OK != res) {
2421 GST_ERROR_OBJECT (client, "Failed to prepare M5 request....\n");
2425 GST_DEBUG_OBJECT (client, "Sending trigger request message...: %d", type);
2427 gst_send_request (client, NULL, &request);
2436 gst_rtsp_wfd_client_set_video_supported_resolution (GstRTSPWFDClient * client,
2437 guint64 supported_reso)
2439 GstRTSPResult res = GST_RTSP_OK;
2440 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2442 g_return_val_if_fail (priv != NULL, GST_RTSP_EINVAL);
2444 priv->video_resolution_supported = supported_reso;
2445 GST_DEBUG ("Resolution : %" G_GUINT64_FORMAT, supported_reso);
2451 gst_rtsp_wfd_client_set_video_native_resolution (GstRTSPWFDClient * client,
2452 guint64 native_reso)
2454 GstRTSPResult res = GST_RTSP_OK;
2455 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2457 g_return_val_if_fail (priv != NULL, GST_RTSP_EINVAL);
2459 priv->video_native_resolution = native_reso;
2460 GST_DEBUG ("Native Resolution : %" G_GUINT64_FORMAT, native_reso);
2466 gst_rtsp_wfd_client_set_audio_codec (GstRTSPWFDClient * client,
2469 GstRTSPResult res = GST_RTSP_OK;
2470 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2472 g_return_val_if_fail (priv != NULL, GST_RTSP_EINVAL);
2474 priv->audio_codec = audio_codec;
2475 GST_DEBUG ("Audio codec : %d", audio_codec);
2481 wfd_ckeck_keep_alive_response (gpointer userdata)
2483 GstRTSPWFDClient *client = (GstRTSPWFDClient *) userdata;
2484 GstRTSPWFDClientPrivate *priv = NULL;
2489 priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2490 g_return_val_if_fail (priv != NULL, GST_RTSP_EINVAL);
2492 if (priv->keep_alive_flag) {
2496 GST_INFO ("%p: source error notification", client);
2498 g_signal_emit (client,
2499 gst_rtsp_client_wfd_signals[SIGNAL_WFD_KEEP_ALIVE_FAIL], 0, NULL);
2504 /*Sending keep_alive (M16) message.
2505 Without calling gst_prepare_request function.*/
2506 static GstRTSPResult
2507 handle_M16_message (GstRTSPWFDClient * client)
2509 GstRTSPResult res = GST_RTSP_OK;
2510 GstRTSPMessage request = { 0 };
2511 gchar *url_str = NULL;
2513 url_str = g_strdup ("rtsp://localhost/wfd1.0");
2516 gst_rtsp_message_init_request (&request, GST_RTSP_GET_PARAMETER, url_str);
2518 GST_ERROR ("init request failed");
2523 gst_send_request (client, NULL, &request);
2528 /*CHecking whether source has got response of any request.
2529 * If yes, keep alive message is sent otherwise error message
2530 * will be displayed.*/
2532 keep_alive_condition (gpointer userdata)
2534 GstRTSPWFDClient *client;
2535 GstRTSPWFDClientPrivate *priv;
2537 client = (GstRTSPWFDClient *) userdata;
2541 priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2543 g_return_val_if_fail (priv != NULL, FALSE);
2545 g_mutex_lock (&priv->keep_alive_lock);
2546 if (!priv->keep_alive_flag) {
2547 g_timeout_add (5000, wfd_ckeck_keep_alive_response, client);
2550 GST_DEBUG_OBJECT (client, "have received last keep alive message response");
2553 GST_DEBUG ("sending keep alive message");
2554 res = handle_M16_message (client);
2555 if (res == GST_RTSP_OK) {
2556 priv->keep_alive_flag = FALSE;
2558 GST_ERROR_OBJECT (client, "Failed to send Keep Alive Message");
2559 g_mutex_unlock (&priv->keep_alive_lock);
2563 g_mutex_unlock (&priv->keep_alive_lock);
2568 wfd_set_keep_alive_condition (GstRTSPWFDClient * client)
2570 g_timeout_add ((DEFAULT_WFD_TIMEOUT - 5) * 1000, keep_alive_condition,
2575 gst_rtsp_wfd_client_set_host_address (GstRTSPWFDClient * client,
2576 const gchar * address)
2578 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2580 g_return_if_fail (priv != NULL);
2582 if (priv->host_address) {
2583 g_free (priv->host_address);
2586 priv->host_address = g_strdup (address);
2590 gst_rtsp_wfd_client_get_audio_codec (GstRTSPWFDClient * client)
2592 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2593 g_return_val_if_fail (priv != NULL, 0);
2595 return priv->caCodec;
2599 gst_rtsp_wfd_client_get_audio_freq (GstRTSPWFDClient * client)
2601 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2602 g_return_val_if_fail (priv != NULL, 0);
2608 gst_rtsp_wfd_client_get_audio_channels (GstRTSPWFDClient * client)
2610 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2611 g_return_val_if_fail (priv != NULL, 0);
2613 return priv->cChanels;
2617 gst_rtsp_wfd_client_get_audio_bit_width (GstRTSPWFDClient * client)
2619 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2620 g_return_val_if_fail (priv != NULL, 0);
2622 return priv->cBitwidth;
2626 gst_rtsp_wfd_client_get_audio_latency (GstRTSPWFDClient * client)
2628 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2629 g_return_val_if_fail (priv != NULL, 0);
2631 return priv->caLatency;
2635 gst_rtsp_wfd_client_get_video_codec (GstRTSPWFDClient * client)
2637 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2638 g_return_val_if_fail (priv != NULL, 0);
2640 return priv->cvCodec;
2644 gst_rtsp_wfd_client_get_video_native (GstRTSPWFDClient * client)
2646 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2647 g_return_val_if_fail (priv != NULL, 0);
2649 return priv->cNative;
2653 gst_rtsp_wfd_client_get_video_native_resolution (GstRTSPWFDClient * client)
2655 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2656 g_return_val_if_fail (priv != NULL, 0);
2658 return priv->cNativeResolution;
2662 gst_rtsp_wfd_client_get_video_cea_resolution (GstRTSPWFDClient * client)
2664 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2665 g_return_val_if_fail (priv != NULL, 0);
2667 return priv->cCEAResolution;
2671 gst_rtsp_wfd_client_get_video_vesa_resolution (GstRTSPWFDClient * client)
2673 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2674 g_return_val_if_fail (priv != NULL, 0);
2676 return priv->cVESAResolution;
2680 gst_rtsp_wfd_client_get_video_hh_resolution (GstRTSPWFDClient * client)
2682 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2683 g_return_val_if_fail (priv != NULL, 0);
2685 return priv->cHHResolution;
2689 gst_rtsp_wfd_client_get_video_profile (GstRTSPWFDClient * client)
2691 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2692 g_return_val_if_fail (priv != NULL, 0);
2694 return priv->cProfile;
2698 gst_rtsp_wfd_client_get_video_level (GstRTSPWFDClient * client)
2700 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2701 g_return_val_if_fail (priv != NULL, 0);
2703 return priv->cLevel;
2707 gst_rtsp_wfd_client_get_video_latency (GstRTSPWFDClient * client)
2709 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2710 g_return_val_if_fail (priv != NULL, 0);
2712 return priv->cvLatency;
2716 gst_rtsp_wfd_client_get_video_max_height (GstRTSPWFDClient * client)
2718 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2719 g_return_val_if_fail (priv != NULL, 0);
2721 return priv->cMaxHeight;
2725 gst_rtsp_wfd_client_get_video_max_width (GstRTSPWFDClient * client)
2727 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2728 g_return_val_if_fail (priv != NULL, 0);
2730 return priv->cMaxWidth;
2734 gst_rtsp_wfd_client_get_video_framerate (GstRTSPWFDClient * client)
2736 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2737 g_return_val_if_fail (priv != NULL, 0);
2739 return priv->cFramerate;
2743 gst_rtsp_wfd_client_get_video_min_slice_size (GstRTSPWFDClient * client)
2745 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2746 g_return_val_if_fail (priv != NULL, 0);
2748 return priv->cmin_slice_size;
2752 gst_rtsp_wfd_client_get_video_slice_enc_params (GstRTSPWFDClient * client)
2754 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2755 g_return_val_if_fail (priv != NULL, 0);
2757 return priv->cslice_enc_params;
2761 gst_rtsp_wfd_client_get_video_framerate_control (GstRTSPWFDClient * client)
2763 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2764 g_return_val_if_fail (priv != NULL, 0);
2766 return priv->cframe_rate_control;
2770 gst_rtsp_wfd_client_get_rtp_port0 (GstRTSPWFDClient * client)
2772 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2773 g_return_val_if_fail (priv != NULL, 0);
2775 return priv->crtp_port0;
2779 gst_rtsp_wfd_client_get_rtp_port1 (GstRTSPWFDClient * client)
2781 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2782 g_return_val_if_fail (priv != NULL, 0);
2784 return priv->crtp_port1;
2788 gst_rtsp_wfd_client_get_edid_supported (GstRTSPWFDClient * client)
2790 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2791 g_return_val_if_fail (priv != NULL, 0);
2793 return priv->edid_supported;
2797 gst_rtsp_wfd_client_get_edid_hresolution (GstRTSPWFDClient * client)
2799 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2800 g_return_val_if_fail (priv != NULL, 0);
2802 return priv->edid_hres;
2806 gst_rtsp_wfd_client_get_edid_vresolution (GstRTSPWFDClient * client)
2808 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2809 g_return_val_if_fail (priv != NULL, 0);
2811 return priv->edid_vres;
2815 gst_rtsp_wfd_client_get_protection_enabled (GstRTSPWFDClient * client)
2817 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2818 g_return_val_if_fail (priv != NULL, 0);
2820 return priv->protection_enabled;
2824 gst_rtsp_wfd_client_set_audio_freq (GstRTSPWFDClient * client, guint freq)
2826 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2827 g_return_if_fail (priv != NULL);
2833 gst_rtsp_wfd_client_set_edid_supported (GstRTSPWFDClient * client,
2836 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2837 g_return_if_fail (priv != NULL);
2839 priv->edid_supported = supported;
2843 gst_rtsp_wfd_client_set_edid_hresolution (GstRTSPWFDClient * client,
2846 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2847 g_return_if_fail (priv != NULL);
2849 priv->edid_hres = reso;
2853 gst_rtsp_wfd_client_set_edid_vresolution (GstRTSPWFDClient * client,
2856 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2857 g_return_if_fail (priv != NULL);
2859 priv->edid_vres = reso;
2863 gst_rtsp_wfd_client_set_protection_enabled (GstRTSPWFDClient * client,
2866 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2867 g_return_if_fail (priv != NULL);
2869 priv->protection_enabled = enable;
2873 gst_rtsp_wfd_client_set_hdcp_version (GstRTSPWFDClient * client,
2874 GstWFDHDCPProtection version)
2876 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2877 g_return_if_fail (priv != NULL);
2879 priv->hdcp_version = version;
2883 gst_rtsp_wfd_client_set_hdcp_port (GstRTSPWFDClient * client, guint32 port)
2885 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2886 g_return_if_fail (priv != NULL);
2888 priv->hdcp_tcpport = port;
2892 gst_rtsp_wfd_client_set_keep_alive_flag (GstRTSPWFDClient * client,
2895 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2896 g_return_if_fail (priv != NULL);
2898 g_mutex_lock (&priv->keep_alive_lock);
2899 if (priv->keep_alive_flag == !(flag))
2900 priv->keep_alive_flag = flag;
2901 g_mutex_unlock (&priv->keep_alive_lock);
2905 gst_rtsp_wfd_client_set_aud_codec (GstRTSPWFDClient * client, guint acodec)
2907 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2908 g_return_if_fail (priv != NULL);
2910 priv->caCodec = acodec;
2914 gst_rtsp_wfd_client_set_audio_channels (GstRTSPWFDClient * client,
2917 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2918 g_return_if_fail (priv != NULL);
2920 priv->cChanels = channels;
2924 gst_rtsp_wfd_client_set_audio_bit_width (GstRTSPWFDClient * client,
2927 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2928 g_return_if_fail (priv != NULL);
2930 priv->cBitwidth = bwidth;
2934 gst_rtsp_wfd_client_set_audio_latency (GstRTSPWFDClient * client, guint latency)
2936 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2937 g_return_if_fail (priv != NULL);
2939 priv->caLatency = latency;
2943 gst_rtsp_wfd_client_set_video_codec (GstRTSPWFDClient * client, guint vcodec)
2945 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2946 g_return_if_fail (priv != NULL);
2948 priv->cvCodec = vcodec;
2952 gst_rtsp_wfd_client_set_video_native (GstRTSPWFDClient * client, guint native)
2954 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2955 g_return_if_fail (priv != NULL);
2957 priv->cNative = native;
2961 gst_rtsp_wfd_client_set_vid_native_resolution (GstRTSPWFDClient * client,
2964 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2965 g_return_if_fail (priv != NULL);
2967 priv->cNativeResolution = res;
2971 gst_rtsp_wfd_client_set_video_cea_resolution (GstRTSPWFDClient * client,
2974 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2975 g_return_if_fail (priv != NULL);
2977 priv->cCEAResolution = res;
2981 gst_rtsp_wfd_client_set_video_vesa_resolution (GstRTSPWFDClient * client,
2984 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2985 g_return_if_fail (priv != NULL);
2987 priv->cVESAResolution = res;
2991 gst_rtsp_wfd_client_set_video_hh_resolution (GstRTSPWFDClient * client,
2994 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2995 g_return_if_fail (priv != NULL);
2997 priv->cHHResolution = res;
3001 gst_rtsp_wfd_client_set_video_profile (GstRTSPWFDClient * client, guint profile)
3003 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3004 g_return_if_fail (priv != NULL);
3006 priv->cProfile = profile;
3010 gst_rtsp_wfd_client_set_video_level (GstRTSPWFDClient * client, guint level)
3012 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3013 g_return_if_fail (priv != NULL);
3015 priv->cLevel = level;
3019 gst_rtsp_wfd_client_set_video_latency (GstRTSPWFDClient * client, guint latency)
3021 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3022 g_return_if_fail (priv != NULL);
3024 priv->cvLatency = latency;
3028 gst_rtsp_wfd_client_set_video_max_height (GstRTSPWFDClient * client,
3031 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3032 g_return_if_fail (priv != NULL);
3034 priv->cMaxHeight = height;
3038 gst_rtsp_wfd_client_set_video_max_width (GstRTSPWFDClient * client,
3041 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3042 g_return_if_fail (priv != NULL);
3044 priv->cMaxWidth = width;
3048 gst_rtsp_wfd_client_set_video_framerate (GstRTSPWFDClient * client,
3051 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3052 g_return_if_fail (priv != NULL);
3054 priv->cFramerate = framerate;
3058 gst_rtsp_wfd_client_set_video_min_slice_size (GstRTSPWFDClient * client,
3061 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3062 g_return_if_fail (priv != NULL);
3064 priv->cmin_slice_size = slice_size;
3068 gst_rtsp_wfd_client_set_video_slice_enc_params (GstRTSPWFDClient * client,
3071 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3072 g_return_if_fail (priv != NULL);
3074 priv->cslice_enc_params = enc_params;
3078 gst_rtsp_wfd_client_set_video_framerate_control (GstRTSPWFDClient * client,
3081 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3082 g_return_if_fail (priv != NULL);
3084 priv->cframe_rate_control = framerate;
3088 gst_rtsp_wfd_client_set_rtp_port0 (GstRTSPWFDClient * client, guint32 port)
3090 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3091 g_return_if_fail (priv != NULL);
3093 priv->crtp_port0 = port;
3097 gst_rtsp_wfd_client_set_rtp_port1 (GstRTSPWFDClient * client, guint32 port)
3099 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3100 g_return_if_fail (priv != NULL);
3102 priv->crtp_port1 = port;
3106 gst_rtsp_wfd_client_get_sink_user_agent (GstRTSPWFDClient * client)
3109 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
3110 g_return_val_if_fail (priv != NULL, NULL);
3112 if (priv->sink_user_agent != NULL)
3113 str = g_strdup (priv->sink_user_agent);