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 {
56 GstRTSPStream *stream;
57 guint64 last_sent_bytes;
62 /* Info in RR (Receiver Report) */
64 guint32 cumulative_lost_num;
66 guint32 arrival_jitter;
73 struct _GstRTSPWFDClientPrivate
75 GstRTSPWFDClientSendFunc send_func; /* protected by send_lock */
76 gpointer send_data; /* protected by send_lock */
77 GDestroyNotify send_notify; /* protected by send_lock */
79 /* used to cache the media in the last requested DESCRIBE so that
80 * we can pick it up in the next SETUP immediately */
94 /* Parameters for WIFI-DISPLAY */
103 guint64 cNativeResolution;
104 guint64 video_resolution_supported;
105 gint video_native_resolution;
106 guint64 cCEAResolution;
107 guint64 cVESAResolution;
108 guint64 cHHResolution;
114 guint32 cInterleaved;
115 guint32 cmin_slice_size;
116 guint32 cslice_enc_params;
117 guint cframe_rate_control;
125 gboolean protection_enabled;
126 GstWFDHDCPProtection hdcp_version;
127 guint32 hdcp_tcpport;
129 gboolean edid_supported;
133 gboolean keep_alive_flag;
134 GMutex keep_alive_lock;
137 GstRTSPClientRTPStats stats;
139 guint stats_timer_id;
140 gboolean rtcp_stats_enabled;
143 #define DEFAULT_WFD_TIMEOUT 60
144 #define WFD_MOUNT_POINT "/wfd1.0/streamid=0"
148 SIGNAL_WFD_OPTIONS_REQUEST,
149 SIGNAL_WFD_GET_PARAMETER_REQUEST,
150 SIGNAL_WFD_KEEP_ALIVE_FAIL,
151 SIGNAL_WFD_PLAYING_DONE,
155 GST_DEBUG_CATEGORY_STATIC (rtsp_wfd_client_debug);
156 #define GST_CAT_DEFAULT rtsp_wfd_client_debug
158 static guint gst_rtsp_client_wfd_signals[SIGNAL_WFD_LAST] = { 0 };
160 static void gst_rtsp_wfd_client_get_property (GObject * object, guint propid,
161 GValue * value, GParamSpec * pspec);
162 static void gst_rtsp_wfd_client_set_property (GObject * object, guint propid,
163 const GValue * value, GParamSpec * pspec);
164 static void gst_rtsp_wfd_client_finalize (GObject * obj);
166 static gboolean handle_wfd_options_request (GstRTSPClient * client,
167 GstRTSPContext * ctx);
168 static gboolean handle_wfd_set_param_request (GstRTSPClient * client,
169 GstRTSPContext * ctx);
170 static gboolean handle_wfd_get_param_request (GstRTSPClient * client,
171 GstRTSPContext * ctx);
173 static void send_generic_wfd_response (GstRTSPWFDClient * client,
174 GstRTSPStatusCode code, GstRTSPContext * ctx);
175 static gchar *wfd_make_path_from_uri (GstRTSPClient * client,
176 const GstRTSPUrl * uri);
177 static void wfd_options_request_done (GstRTSPWFDClient * client, GstRTSPContext *ctx);
178 static void wfd_get_param_request_done (GstRTSPWFDClient * client, GstRTSPContext *ctx);
179 static void handle_wfd_response (GstRTSPClient * client, GstRTSPContext * ctx);
180 static void handle_wfd_play (GstRTSPClient * client, GstRTSPContext * ctx);
181 static void wfd_set_keep_alive_condition(GstRTSPWFDClient * client);
182 static gboolean wfd_ckeck_keep_alive_response (gpointer userdata);
183 static gboolean keep_alive_condition(gpointer userdata);
184 static gboolean wfd_configure_client_media (GstRTSPClient * client, GstRTSPMedia * media,
185 GstRTSPStream * stream, GstRTSPContext * ctx);
187 GstRTSPResult prepare_trigger_request (GstRTSPWFDClient * client,
188 GstRTSPMessage * request, GstWFDTriggerType trigger_type, gchar * url);
191 prepare_response (GstRTSPWFDClient * client, GstRTSPMessage * request,
192 GstRTSPMessage * response, GstRTSPMethod method);
194 static GstRTSPResult handle_M1_message (GstRTSPWFDClient * client);
195 static GstRTSPResult handle_M3_message (GstRTSPWFDClient * client);
196 static GstRTSPResult handle_M4_message (GstRTSPWFDClient * client);
197 static GstRTSPResult handle_M16_message (GstRTSPWFDClient * client);
199 G_DEFINE_TYPE (GstRTSPWFDClient, gst_rtsp_wfd_client, GST_TYPE_RTSP_CLIENT);
202 gst_rtsp_wfd_client_class_init (GstRTSPWFDClientClass * klass)
204 GObjectClass *gobject_class;
205 GstRTSPClientClass *rtsp_client_class;
207 g_type_class_add_private (klass, sizeof (GstRTSPWFDClientPrivate));
209 gobject_class = G_OBJECT_CLASS (klass);
210 rtsp_client_class = GST_RTSP_CLIENT_CLASS (klass);
212 gobject_class->get_property = gst_rtsp_wfd_client_get_property;
213 gobject_class->set_property = gst_rtsp_wfd_client_set_property;
214 gobject_class->finalize = gst_rtsp_wfd_client_finalize;
216 //klass->create_sdp = create_sdp;
217 //klass->configure_client_transport = default_configure_client_transport;
218 //klass->params_set = default_params_set;
219 //klass->params_get = default_params_get;
221 rtsp_client_class->handle_options_request = handle_wfd_options_request;
222 rtsp_client_class->handle_set_param_request = handle_wfd_set_param_request;
223 rtsp_client_class->handle_get_param_request = handle_wfd_get_param_request;
224 rtsp_client_class->make_path_from_uri = wfd_make_path_from_uri;
225 rtsp_client_class->configure_client_media = wfd_configure_client_media;
227 rtsp_client_class->handle_response = handle_wfd_response;
228 rtsp_client_class->play_request = handle_wfd_play;
230 gst_rtsp_client_wfd_signals[SIGNAL_WFD_OPTIONS_REQUEST] =
231 g_signal_new ("wfd-options-request", G_TYPE_FROM_CLASS (klass),
232 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPWFDClientClass,
233 wfd_options_request), NULL, NULL, g_cclosure_marshal_VOID__POINTER,
234 G_TYPE_NONE, 1, GST_TYPE_RTSP_CONTEXT);
236 gst_rtsp_client_wfd_signals[SIGNAL_WFD_GET_PARAMETER_REQUEST] =
237 g_signal_new ("wfd-get-parameter-request", G_TYPE_FROM_CLASS (klass),
238 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPWFDClientClass,
239 wfd_get_param_request), NULL, NULL, g_cclosure_marshal_VOID__POINTER,
240 G_TYPE_NONE, 1, GST_TYPE_RTSP_CONTEXT);
242 gst_rtsp_client_wfd_signals[SIGNAL_WFD_KEEP_ALIVE_FAIL] =
243 g_signal_new ("wfd-keep-alive-fail", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
244 G_STRUCT_OFFSET (GstRTSPWFDClientClass, wfd_keep_alive_fail), NULL, NULL,
245 g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
247 gst_rtsp_client_wfd_signals[SIGNAL_WFD_PLAYING_DONE] =
248 g_signal_new ("wfd-playing-done", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
249 G_STRUCT_OFFSET (GstRTSPWFDClientClass, wfd_playing_done), NULL, NULL,
250 g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
252 klass->wfd_options_request = wfd_options_request_done;
253 klass->wfd_get_param_request = wfd_get_param_request_done;
255 GST_DEBUG_CATEGORY_INIT (rtsp_wfd_client_debug, "rtspwfdclient", 0,
260 gst_rtsp_wfd_client_init (GstRTSPWFDClient * client)
262 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
264 g_return_if_fail (priv != NULL);
267 priv->protection_enabled = FALSE;
268 priv->video_native_resolution = GST_WFD_VIDEO_CEA_RESOLUTION;
269 priv->video_resolution_supported = GST_WFD_CEA_640x480P60;
270 priv->audio_codec = GST_WFD_AUDIO_AAC;
271 priv->keep_alive_flag = FALSE;
273 g_mutex_init (&priv->keep_alive_lock);
274 g_mutex_init (&priv->stats_lock);
276 priv->host_address = NULL;
278 priv->stats_timer_id = -1;
279 priv->rtcp_stats_enabled = FALSE;
280 memset (&priv->stats, 0x00, sizeof (GstRTSPClientRTPStats));
282 GST_INFO_OBJECT (client, "Client is initialized");
285 /* A client is finalized when the connection is broken */
287 gst_rtsp_wfd_client_finalize (GObject * obj)
289 GstRTSPWFDClient *client = GST_RTSP_WFD_CLIENT (obj);
290 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
292 g_return_if_fail (GST_IS_RTSP_WFD_CLIENT (obj));
293 g_return_if_fail (priv != NULL);
295 GST_INFO ("finalize client %p", client);
297 if (priv->host_address)
298 g_free (priv->host_address);
300 if (priv->stats_timer_id > 0)
301 g_source_remove(priv->stats_timer_id);
303 g_mutex_clear (&priv->keep_alive_lock);
304 g_mutex_clear (&priv->stats_lock);
305 G_OBJECT_CLASS (gst_rtsp_wfd_client_parent_class)->finalize (obj);
309 gst_rtsp_wfd_client_get_property (GObject * object, guint propid,
310 GValue * value, GParamSpec * pspec)
312 //GstRTSPWFDClient *client = GST_RTSP_WFD_CLIENT (object);
316 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
321 gst_rtsp_wfd_client_set_property (GObject * object, guint propid,
322 const GValue * value, GParamSpec * pspec)
324 //GstRTSPWFDClient *client = GST_RTSP_WFD_CLIENT (object);
328 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
333 * gst_rtsp_wfd_client_new:
335 * Create a new #GstRTSPWFDClient instance.
337 * Returns: a new #GstRTSPWFDClient
340 gst_rtsp_wfd_client_new (void)
342 GstRTSPWFDClient *result;
344 result = g_object_new (GST_TYPE_RTSP_WFD_CLIENT, NULL);
350 gst_rtsp_wfd_client_start_wfd (GstRTSPWFDClient * client)
352 GstRTSPResult res = GST_RTSP_OK;
353 GST_INFO_OBJECT (client, "gst_rtsp_wfd_client_start_wfd");
355 res = handle_M1_message (client);
356 if (res < GST_RTSP_OK) {
357 GST_ERROR_OBJECT (client, "handle_M1_message failed : %d", res);
364 wfd_display_rtp_stats (gpointer userdata)
369 GstRTSPWFDClient *client = NULL;
370 GstRTSPWFDClientPrivate *priv = NULL;
372 client = (GstRTSPWFDClient *) userdata;
373 priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
376 GST_ERROR("No priv");
380 g_mutex_lock(&priv->stats_lock);
382 seqnum = gst_rtsp_stream_get_current_seqnum (priv->stats.stream);
383 bytes = gst_rtsp_stream_get_udp_sent_bytes (priv->stats.stream);
385 GST_INFO ("----------------------------------------------------\n");
386 GST_INFO ("Sent RTP packets : %d", seqnum - priv->stats.last_seqnum);
387 GST_INFO ("Sent Bytes of RTP packets : %lld bytes", bytes - priv->stats.last_sent_bytes);
389 priv->stats.last_seqnum = seqnum;
390 priv->stats.last_sent_bytes = bytes;
392 if (priv->rtcp_stats_enabled) {
393 GST_INFO ("Fraction Lost: %d", priv->stats.fraction_lost);
394 GST_INFO ("Cumulative number of packets lost: %d", priv->stats.cumulative_lost_num);
395 GST_INFO ("Extended highest sequence number received: %d", priv->stats.max_seqnum);
396 GST_INFO ("Interarrival Jitter: %d", priv->stats.arrival_jitter);
397 GST_INFO ("Round trip time : %d", priv->stats.rtt);
400 GST_INFO ("----------------------------------------------------\n");
402 g_mutex_unlock(&priv->stats_lock);
408 on_rtcp_stats (GstRTSPStream *stream, GstStructure *stats, GstRTSPClient *client)
410 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
412 guint fraction_lost, exthighestseq, jitter, lsr, dlsr, rtt;
417 g_mutex_lock(&priv->stats_lock);
419 gst_structure_get_uint (stats, "rb-fractionlost", &fraction_lost);
420 gst_structure_get_int (stats, "rb-packetslost", &packetslost);
421 gst_structure_get_uint (stats, "rb-exthighestseq", &exthighestseq);
422 gst_structure_get_uint (stats, "rb-jitter", &jitter);
423 gst_structure_get_uint (stats, "rb-lsr", &lsr);
424 gst_structure_get_uint (stats, "rb-dlsr", &dlsr);
425 gst_structure_get_uint (stats, "rb-round-trip", &rtt);
427 if (!priv->rtcp_stats_enabled)
428 priv->rtcp_stats_enabled = TRUE;
430 priv->stats.stream = stream;
431 priv->stats.fraction_lost = (guint8)fraction_lost;
432 priv->stats.cumulative_lost_num += (guint32)fraction_lost;
433 priv->stats.max_seqnum = (guint16)exthighestseq;
434 priv->stats.arrival_jitter = (guint32)jitter;
435 priv->stats.lsr = (guint32)lsr;
436 priv->stats.dlsr = (guint32)dlsr;
437 priv->stats.rtt = (guint32)rtt;
439 g_mutex_unlock(&priv->stats_lock);
443 wfd_configure_client_media (GstRTSPClient * client, GstRTSPMedia * media,
444 GstRTSPStream * stream, GstRTSPContext * ctx)
447 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
449 priv->stats.stream = stream;
450 g_signal_connect (stream, "rtcp-statistics", (GCallback) on_rtcp_stats, client);
453 return GST_RTSP_CLIENT_CLASS (gst_rtsp_wfd_client_parent_class)->configure_client_media (client, media, stream, ctx);
456 wfd_options_request_done (GstRTSPWFDClient * client, GstRTSPContext *ctx)
458 GstRTSPResult res = GST_RTSP_OK;
459 GstRTSPWFDClientClass *klass = GST_RTSP_WFD_CLIENT_GET_CLASS (client);
461 g_return_if_fail (klass != NULL);
463 GST_INFO_OBJECT (client, "M2 done..");
465 res = handle_M3_message (client);
466 if (res < GST_RTSP_OK) {
467 GST_ERROR_OBJECT (client, "handle_M3_message failed : %d", res);
470 if (klass->prepare_resource) {
471 klass->prepare_resource (client, ctx);
478 wfd_get_param_request_done (GstRTSPWFDClient * client, GstRTSPContext *ctx)
480 GstRTSPResult res = GST_RTSP_OK;
481 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
482 GstRTSPWFDClientClass *klass = GST_RTSP_WFD_CLIENT_GET_CLASS (client);
484 g_return_if_fail (priv != NULL && klass != NULL);
486 priv->m3_done = TRUE;
487 GST_INFO_OBJECT (client, "M3 done..");
489 res = handle_M4_message (client);
490 if (res < GST_RTSP_OK) {
491 GST_ERROR_OBJECT (client, "handle_M4_message failed : %d", res);
494 if (klass->confirm_resource) {
495 klass->confirm_resource (client, ctx);
502 wfd_get_prefered_audio_codec (guint8 srcAudioCodec,
503 guint sinkAudioCodec)
507 for (i = 0; i < 8; i++) {
508 if (((sinkAudioCodec << i) & 0x80)
509 && ((srcAudioCodec << i) & 0x80)) {
510 codec = (0x01 << (7 - i));
518 wfd_get_prefered_resolution (guint64 srcResolution,
519 guint64 sinkResolution,
520 GstWFDVideoNativeResolution native,
522 guint32 * cMaxHeight, guint32 * cFramerate, guint32 * interleaved)
525 guint64 resolution = 0;
526 for (i = 0; i < 32; i++) {
527 if (((sinkResolution << i) & 0x80000000)
528 && ((srcResolution << i) & 0x80000000)) {
529 resolution = ((guint64) 0x00000001 << (31 - i));
534 case GST_WFD_VIDEO_CEA_RESOLUTION:
536 switch (resolution) {
537 case GST_WFD_CEA_640x480P60:
543 case GST_WFD_CEA_720x480P60:
549 case GST_WFD_CEA_720x480I60:
555 case GST_WFD_CEA_720x576P50:
561 case GST_WFD_CEA_720x576I50:
567 case GST_WFD_CEA_1280x720P30:
573 case GST_WFD_CEA_1280x720P60:
579 case GST_WFD_CEA_1920x1080P30:
585 case GST_WFD_CEA_1920x1080P60:
591 case GST_WFD_CEA_1920x1080I60:
597 case GST_WFD_CEA_1280x720P25:
603 case GST_WFD_CEA_1280x720P50:
609 case GST_WFD_CEA_1920x1080P25:
615 case GST_WFD_CEA_1920x1080P50:
621 case GST_WFD_CEA_1920x1080I50:
627 case GST_WFD_CEA_1280x720P24:
633 case GST_WFD_CEA_1920x1080P24:
648 case GST_WFD_VIDEO_VESA_RESOLUTION:
650 switch (resolution) {
651 case GST_WFD_VESA_800x600P30:
657 case GST_WFD_VESA_800x600P60:
663 case GST_WFD_VESA_1024x768P30:
669 case GST_WFD_VESA_1024x768P60:
675 case GST_WFD_VESA_1152x864P30:
681 case GST_WFD_VESA_1152x864P60:
687 case GST_WFD_VESA_1280x768P30:
693 case GST_WFD_VESA_1280x768P60:
699 case GST_WFD_VESA_1280x800P30:
705 case GST_WFD_VESA_1280x800P60:
711 case GST_WFD_VESA_1360x768P30:
717 case GST_WFD_VESA_1360x768P60:
723 case GST_WFD_VESA_1366x768P30:
729 case GST_WFD_VESA_1366x768P60:
735 case GST_WFD_VESA_1280x1024P30:
741 case GST_WFD_VESA_1280x1024P60:
747 case GST_WFD_VESA_1400x1050P30:
753 case GST_WFD_VESA_1400x1050P60:
759 case GST_WFD_VESA_1440x900P30:
765 case GST_WFD_VESA_1440x900P60:
771 case GST_WFD_VESA_1600x900P30:
777 case GST_WFD_VESA_1600x900P60:
783 case GST_WFD_VESA_1600x1200P30:
789 case GST_WFD_VESA_1600x1200P60:
795 case GST_WFD_VESA_1680x1024P30:
801 case GST_WFD_VESA_1680x1024P60:
807 case GST_WFD_VESA_1680x1050P30:
813 case GST_WFD_VESA_1680x1050P60:
819 case GST_WFD_VESA_1920x1200P30:
825 case GST_WFD_VESA_1920x1200P60:
840 case GST_WFD_VIDEO_HH_RESOLUTION:
843 switch (resolution) {
844 case GST_WFD_HH_800x480P30:
849 case GST_WFD_HH_800x480P60:
854 case GST_WFD_HH_854x480P30:
859 case GST_WFD_HH_854x480P60:
864 case GST_WFD_HH_864x480P30:
869 case GST_WFD_HH_864x480P60:
874 case GST_WFD_HH_640x360P30:
879 case GST_WFD_HH_640x360P60:
884 case GST_WFD_HH_960x540P30:
889 case GST_WFD_HH_960x540P60:
894 case GST_WFD_HH_848x480P30:
899 case GST_WFD_HH_848x480P60:
925 wfd_make_path_from_uri (GstRTSPClient * client, const GstRTSPUrl * uri)
929 GST_DEBUG_OBJECT (client, "Got URI host : %s", uri->host);
930 GST_DEBUG_OBJECT (client, "Got URI abspath : %s", uri->abspath);
932 path = g_strdup ("/wfd1.0/streamid=0");
938 handle_wfd_play (GstRTSPClient * client, GstRTSPContext * ctx)
940 GstRTSPWFDClient *_client = GST_RTSP_WFD_CLIENT (client);
941 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
943 g_return_if_fail (priv != NULL);
945 wfd_set_keep_alive_condition(_client);
947 priv->stats_timer_id = g_timeout_add (2000, wfd_display_rtp_stats, _client);
949 g_signal_emit (client,
950 gst_rtsp_client_wfd_signals[SIGNAL_WFD_PLAYING_DONE], 0, NULL);
954 handle_wfd_response (GstRTSPClient * client, GstRTSPContext * ctx)
956 GstRTSPResult res = GST_RTSP_OK;
960 GstRTSPWFDClient *_client = GST_RTSP_WFD_CLIENT (client);
961 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
963 g_return_if_fail (priv != NULL);
965 GST_INFO_OBJECT (_client, "Handling response..");
968 GST_ERROR_OBJECT (_client, "Context is NULL");
972 if (!ctx->response) {
973 GST_ERROR_OBJECT (_client, "Response is NULL");
977 /* parsing the GET_PARAMTER response */
978 res = gst_rtsp_message_get_body (ctx->response, (guint8 **) & data, &size);
979 if (res != GST_RTSP_OK) {
980 GST_ERROR_OBJECT (_client, "Failed to get body of response...");
984 GST_INFO_OBJECT (_client, "Response body is %d", size);
986 if (!priv->m3_done) {
987 GstWFDResult wfd_res;
988 GstWFDMessage *msg = NULL;
989 /* Parse M3 response from sink */
990 wfd_res = gst_wfd_message_new (&msg);
991 if (wfd_res != GST_WFD_OK) {
992 GST_ERROR_OBJECT (client, "Failed to create wfd message...");
996 wfd_res = gst_wfd_message_init (msg);
997 if (wfd_res != GST_WFD_OK) {
998 GST_ERROR_OBJECT (client, "Failed to init wfd message...");
1002 wfd_res = gst_wfd_message_parse_buffer (data, size, msg);
1004 GST_DEBUG_OBJECT (client, "M3 response server side message body: %s",
1005 gst_wfd_message_as_text (msg));
1007 /* Get the audio formats supported by WFDSink */
1008 if (msg->audio_codecs) {
1010 gst_wfd_message_get_supported_audio_format (msg, &priv->caCodec,
1011 &priv->cFreq, &priv->cChanels, &priv->cBitwidth, &priv->caLatency);
1012 if (wfd_res != GST_WFD_OK) {
1013 GST_WARNING_OBJECT (client,
1014 "Failed to get wfd support audio formats...");
1019 /* Get the Video formats supported by WFDSink */
1021 gst_wfd_message_get_supported_video_format (msg, &priv->cvCodec,
1022 &priv->cNative, &priv->cNativeResolution,
1023 (guint64 *) & priv->cCEAResolution,
1024 (guint64 *) & priv->cVESAResolution,
1025 (guint64 *) & priv->cHHResolution, &priv->cProfile, &priv->cLevel,
1026 &priv->cvLatency, &priv->cMaxHeight, &priv->cMaxWidth,
1027 &priv->cmin_slice_size, &priv->cslice_enc_params,
1028 &priv->cframe_rate_control);
1029 if (wfd_res != GST_WFD_OK) {
1030 GST_WARNING_OBJECT (client,
1031 "Failed to get wfd supported video formats...");
1035 if (msg->client_rtp_ports) {
1036 /* Get the RTP ports preferred by WFDSink */
1038 gst_wfd_message_get_prefered_rtp_ports (msg, &priv->ctrans,
1039 &priv->cprofile, &priv->clowertrans, &priv->crtp_port0,
1041 if (wfd_res != GST_WFD_OK) {
1042 GST_WARNING_OBJECT (client,
1043 "Failed to get wfd prefered RTP ports...");
1048 if (msg->display_edid) {
1049 guint32 edid_block_count = 0;
1050 gchar *edid_payload = NULL;
1051 priv->edid_supported = FALSE;
1052 /* Get the display edid preferred by WFDSink */
1053 GST_DEBUG_OBJECT (client, "Going to gst_wfd_message_get_display_edid");
1055 gst_wfd_message_get_display_edid (msg, &priv->edid_supported,
1056 &edid_block_count, &edid_payload);
1057 if (wfd_res != GST_WFD_OK) {
1058 GST_ERROR_OBJECT (client, "Failed to get wfd display edid...");
1061 GST_DEBUG_OBJECT (client, " edid supported: %d edid_block_count: %d",
1062 priv->edid_supported, edid_block_count);
1063 if (priv->edid_supported) {
1064 priv->edid_hres = 0;
1065 priv->edid_vres = 0;
1067 (guint32) (((edid_payload[54 + 4] >> 4) << 8) | edid_payload[54 +
1070 (guint32) (((edid_payload[54 + 7] >> 4) << 8) | edid_payload[54 +
1072 GST_DEBUG_OBJECT (client, " edid supported Hres: %d Wres: %d",
1073 priv->edid_hres, priv->edid_vres);
1074 if ((priv->edid_hres < 640) || (priv->edid_vres < 480)
1075 || (priv->edid_hres > 1920) || (priv->edid_vres > 1080)) {
1076 priv->edid_hres = 0;
1077 priv->edid_vres = 0;
1078 priv->edid_supported = FALSE;
1079 GST_WARNING_OBJECT (client, " edid invalid resolutions");
1084 if (msg->content_protection) {
1086 /*Get the hdcp version and tcp port by WFDSink */
1088 gst_wfd_message_get_contentprotection_type (msg,
1089 &priv->hdcp_version, &priv->hdcp_tcpport);
1090 GST_DEBUG ("hdcp version =%d, tcp port = %d", priv->hdcp_version,
1091 priv->hdcp_tcpport);
1092 if (priv->hdcp_version > 0 && priv->hdcp_tcpport > 0)
1093 priv->protection_enabled = TRUE;
1095 if (wfd_res != GST_WFD_OK) {
1096 GST_WARNING_OBJECT (client,
1097 "Failed to get wfd content protection...");
1101 GST_WARNING_OBJECT (client, "Don't use content protection");
1105 g_signal_emit (_client,
1106 gst_rtsp_client_wfd_signals[SIGNAL_WFD_GET_PARAMETER_REQUEST], 0,
1109 /* TODO-WFD: Handle another GET_PARAMETER response with body */
1111 } else if (size == 0) {
1112 if (!priv->m1_done) {
1113 GST_INFO_OBJECT (_client, "M1 response is done");
1114 priv->m1_done = TRUE;
1115 } else if (!priv->m4_done) {
1116 GST_INFO_OBJECT (_client, "M4 response is done");
1117 priv->m4_done = TRUE;
1119 gst_rtsp_wfd_client_trigger_request (_client, WFD_TRIGGER_SETUP);
1121 g_mutex_lock(&priv->keep_alive_lock);
1122 if (priv->keep_alive_flag == FALSE) {
1123 GST_INFO_OBJECT (_client, "M16 response is done");
1124 priv->keep_alive_flag = TRUE;
1126 g_mutex_unlock(&priv->keep_alive_lock);
1137 handle_wfd_options_request (GstRTSPClient * client, GstRTSPContext * ctx)
1139 GstRTSPResult res = GST_RTSP_OK;
1140 GstRTSPMethod options;
1143 gchar *user_agent = NULL;
1145 GstRTSPWFDClient *_client = GST_RTSP_WFD_CLIENT (client);
1147 options = GST_RTSP_OPTIONS |
1151 GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | GST_RTSP_TEARDOWN;
1153 str = gst_rtsp_options_as_text (options);
1155 /*append WFD specific method */
1156 tmp = g_strdup (", org.wfa.wfd1.0");
1157 g_strlcat (str, tmp, strlen (tmp) + strlen (str) + 1);
1159 gst_rtsp_message_init_response (ctx->response, GST_RTSP_STS_OK,
1160 gst_rtsp_status_as_text (GST_RTSP_STS_OK), ctx->request);
1162 gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_PUBLIC, str);
1169 gst_rtsp_message_get_header (ctx->request, GST_RTSP_HDR_USER_AGENT,
1171 if (res == GST_RTSP_OK) {
1172 gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_USER_AGENT,
1178 res = gst_rtsp_client_send_message (client, NULL, ctx->response);
1179 if (res != GST_RTSP_OK) {
1180 GST_ERROR_OBJECT (client, "gst_rtsp_client_send_message failed : %d", res);
1184 GST_DEBUG_OBJECT (client, "Sent M2 response...");
1186 g_signal_emit (_client,
1187 gst_rtsp_client_wfd_signals[SIGNAL_WFD_OPTIONS_REQUEST], 0, ctx);
1193 handle_wfd_get_param_request (GstRTSPClient * client, GstRTSPContext * ctx)
1195 GstRTSPResult res = GST_RTSP_OK;
1196 guint8 *data = NULL;
1199 GstRTSPWFDClient *_client = GST_RTSP_WFD_CLIENT (client);
1201 /* parsing the GET_PARAMTER request */
1202 res = gst_rtsp_message_get_body (ctx->request, (guint8 **) & data, &size);
1203 if (res != GST_RTSP_OK) {
1204 GST_ERROR_OBJECT (_client, "Failed to get body of request...");
1209 send_generic_wfd_response (_client, GST_RTSP_STS_OK, ctx);
1211 /* TODO-WFD: Handle other GET_PARAMETER request from sink */
1218 handle_wfd_set_param_request (GstRTSPClient * client, GstRTSPContext * ctx)
1220 GstRTSPResult res = GST_RTSP_OK;
1221 guint8 *data = NULL;
1224 GstRTSPWFDClient *_client = GST_RTSP_WFD_CLIENT (client);
1226 res = gst_rtsp_message_get_body (ctx->request, &data, &size);
1227 if (res != GST_RTSP_OK)
1231 /* no body, keep-alive request */
1232 send_generic_wfd_response (_client, GST_RTSP_STS_OK, ctx);
1235 GST_INFO_OBJECT (_client, "SET_PARAMETER Request : %s(%d)", data, size);
1236 if (g_strcmp0 ((const gchar *) data, "wfd_idr_request"))
1237 send_generic_wfd_response (_client, GST_RTSP_STS_OK, ctx);
1240 /* TODO-WFD : Handle other set param request */
1241 send_generic_wfd_response (_client, GST_RTSP_STS_OK, ctx);
1253 GST_ERROR ("_client %p: bad request", _client);
1254 send_generic_wfd_response (_client, GST_RTSP_STS_BAD_REQUEST, ctx);
1261 gst_rtsp_wfd_client_parse_methods (GstRTSPWFDClient * client,
1262 GstRTSPMessage * response)
1264 GstRTSPHeaderField field;
1269 gboolean found_wfd_method = FALSE;
1271 /* reset supported methods */
1272 client->supported_methods = 0;
1274 /* Try Allow Header first */
1275 field = GST_RTSP_HDR_ALLOW;
1278 gst_rtsp_message_get_header (response, field, &respoptions, indx);
1279 if (indx == 0 && !respoptions) {
1280 /* if no Allow header was found then try the Public header... */
1281 field = GST_RTSP_HDR_PUBLIC;
1282 gst_rtsp_message_get_header (response, field, &respoptions, indx);
1287 /* If we get here, the server gave a list of supported methods, parse
1288 * them here. The string is like:
1290 * OPTIONS, PLAY, SETUP, ...
1292 options = g_strsplit (respoptions, ",", 0);
1294 for (i = 0; options[i]; i++) {
1298 stripped = g_strstrip (options[i]);
1299 method = gst_rtsp_find_method (stripped);
1301 if (!g_ascii_strcasecmp ("org.wfa.wfd1.0", stripped))
1302 found_wfd_method = TRUE;
1304 /* keep bitfield of supported methods */
1305 if (method != GST_RTSP_INVALID)
1306 client->supported_methods |= method;
1308 g_strfreev (options);
1313 if (!found_wfd_method) {
1314 GST_ERROR_OBJECT (client,
1315 "WFD client is not supporting WFD mandatory message : org.wfa.wfd1.0...");
1316 goto no_required_methods;
1319 /* Checking mandatory method */
1320 if (!(client->supported_methods & GST_RTSP_SET_PARAMETER)) {
1321 GST_ERROR_OBJECT (client,
1322 "WFD client is not supporting WFD mandatory message : SET_PARAMETER...");
1323 goto no_required_methods;
1326 /* Checking mandatory method */
1327 if (!(client->supported_methods & GST_RTSP_GET_PARAMETER)) {
1328 GST_ERROR_OBJECT (client,
1329 "WFD client is not supporting WFD mandatory message : GET_PARAMETER...");
1330 goto no_required_methods;
1333 if (!(client->supported_methods & GST_RTSP_OPTIONS)) {
1334 GST_INFO_OBJECT (client, "assuming OPTIONS is supported by client...");
1335 client->supported_methods |= GST_RTSP_OPTIONS;
1341 no_required_methods:
1343 GST_ELEMENT_ERROR (client, RESOURCE, OPEN_READ, (NULL),
1344 ("WFD Client does not support mandatory methods."));
1364 } GstWFDMessageType;
1367 _set_negotiated_audio_codec (GstRTSPWFDClient *client,
1370 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
1372 GstRTSPMediaFactory *factory = NULL;
1373 GstRTSPMountPoints *mount_points = NULL;
1376 gboolean ret = TRUE;
1378 if (!(mount_points = gst_rtsp_client_get_mount_points (parent_client))) {
1380 GST_ERROR_OBJECT (client, "Failed to set negotiated audio codec: no mount points...");
1381 goto no_mount_points;
1384 path = g_strdup(WFD_MOUNT_POINT);
1387 GST_ERROR_OBJECT (client, "Failed to set negotiated audio codec: no path...");
1391 if (!(factory = gst_rtsp_mount_points_match (mount_points,
1393 GST_ERROR_OBJECT (client, "Failed to set negotiated audio codec: no factory...");
1398 gst_rtsp_media_factory_wfd_set_audio_codec (factory,
1402 g_object_unref(factory);
1407 g_object_unref(mount_points);
1413 _set_negotiated_resolution(GstRTSPWFDClient *client,
1414 guint32 width, guint32 height)
1416 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
1418 GstRTSPMediaFactory *factory = NULL;
1419 GstRTSPMountPoints *mount_points = NULL;
1422 gboolean ret = TRUE;
1424 if (!(mount_points = gst_rtsp_client_get_mount_points (parent_client))) {
1426 GST_ERROR_OBJECT (client, "Failed to set negotiated resolution: no mount points...");
1427 goto no_mount_points;
1430 path = g_strdup(WFD_MOUNT_POINT);
1433 GST_ERROR_OBJECT (client, "Failed to set negotiated resolution: no path...");
1437 if (!(factory = gst_rtsp_mount_points_match (mount_points,
1439 GST_ERROR_OBJECT (client, "Failed to set negotiated resolution: no factory...");
1444 gst_rtsp_media_factory_wfd_set_negotiated_resolution(factory,
1448 g_object_unref(factory);
1453 g_object_unref(mount_points);
1459 _set_wfd_message_body (GstRTSPWFDClient * client, GstWFDMessageType msg_type,
1460 gchar ** data, guint * len)
1462 GString *buf = NULL;
1463 GstWFDMessage *msg = NULL;
1464 GstWFDResult wfd_res = GST_WFD_EINVAL;
1465 GstRTSPWFDClientPrivate *priv = NULL;
1466 priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
1468 g_return_if_fail (priv != NULL);
1470 buf = g_string_new ("");
1471 g_return_if_fail (buf != NULL);
1473 if (msg_type == M3_REQ_MSG) {
1474 /* create M3 request to be sent */
1475 wfd_res = gst_wfd_message_new (&msg);
1476 if (wfd_res != GST_WFD_OK) {
1477 GST_ERROR_OBJECT (client, "Failed to create wfd message...");
1481 wfd_res = gst_wfd_message_init (msg);
1482 if (wfd_res != GST_WFD_OK) {
1483 GST_ERROR_OBJECT (client, "Failed to init wfd message...");
1487 /* set the supported audio formats by the WFD server */
1489 gst_wfd_message_set_supported_audio_format (msg, GST_WFD_AUDIO_UNKNOWN,
1490 GST_WFD_FREQ_UNKNOWN, GST_WFD_CHANNEL_UNKNOWN, 0, 0);
1491 if (wfd_res != GST_WFD_OK) {
1492 GST_ERROR_OBJECT (client,
1493 "Failed to set supported audio formats on wfd message...");
1497 /* set the supported Video formats by the WFD server */
1499 gst_wfd_message_set_supported_video_format (msg, GST_WFD_VIDEO_UNKNOWN,
1500 GST_WFD_VIDEO_CEA_RESOLUTION, GST_WFD_CEA_UNKNOWN, GST_WFD_CEA_UNKNOWN,
1501 GST_WFD_VESA_UNKNOWN, GST_WFD_HH_UNKNOWN, GST_WFD_H264_UNKNOWN_PROFILE,
1502 GST_WFD_H264_LEVEL_UNKNOWN, 0, 0, 0, 0, 0, 0);
1503 if (wfd_res != GST_WFD_OK) {
1504 GST_ERROR_OBJECT (client,
1505 "Failed to set supported video formats on wfd message...");
1509 wfd_res = gst_wfd_message_set_display_edid (msg, 0, 0, NULL);
1510 if (wfd_res != GST_WFD_OK) {
1511 GST_ERROR_OBJECT (client,
1512 "Failed to set display edid type on wfd message...");
1516 if (priv->protection_enabled) {
1518 gst_wfd_message_set_contentprotection_type (msg, GST_WFD_HDCP_NONE,
1520 if (wfd_res != GST_WFD_OK) {
1521 GST_ERROR_OBJECT (client,
1522 "Failed to set supported content protection type on wfd message...");
1527 /* set the preffered RTP ports for the WFD server */
1529 gst_wfd_messge_set_prefered_rtp_ports (msg, GST_WFD_RTSP_TRANS_UNKNOWN,
1530 GST_WFD_RTSP_PROFILE_UNKNOWN, GST_WFD_RTSP_LOWER_TRANS_UNKNOWN, 0, 0);
1531 if (wfd_res != GST_WFD_OK) {
1532 GST_ERROR_OBJECT (client,
1533 "Failed to set supported video formats on wfd message...");
1537 *data = gst_wfd_message_param_names_as_text (msg);
1538 if (*data == NULL) {
1539 GST_ERROR_OBJECT (client, "Failed to get wfd message as text...");
1542 *len = strlen (*data);
1544 } else if (msg_type == M4_REQ_MSG) {
1545 GstRTSPUrl *url = NULL;
1547 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
1548 GstRTSPConnection *connection =
1549 gst_rtsp_client_get_connection (parent_client);
1551 /* Parameters for the preffered audio formats */
1552 GstWFDAudioFormats taudiocodec = GST_WFD_AUDIO_UNKNOWN;
1553 GstWFDAudioFreq taudiofreq = GST_WFD_FREQ_UNKNOWN;
1554 GstWFDAudioChannels taudiochannels = GST_WFD_CHANNEL_UNKNOWN;
1556 /* Parameters for the preffered video formats */
1557 GstWFDVideoCEAResolution tcCEAResolution = GST_WFD_CEA_UNKNOWN;
1558 GstWFDVideoVESAResolution tcVESAResolution = GST_WFD_VESA_UNKNOWN;
1559 GstWFDVideoHHResolution tcHHResolution = GST_WFD_HH_UNKNOWN;
1560 GstWFDVideoH264Profile tcProfile;
1561 GstWFDVideoH264Level tcLevel;
1562 guint64 resolution_supported = 0;
1564 url = gst_rtsp_connection_get_url (connection);
1566 GST_ERROR_OBJECT (client, "Failed to get connection URL");
1570 /* Logic to negotiate with information of M3 response */
1571 /* create M4 request to be sent */
1572 wfd_res = gst_wfd_message_new (&msg);
1573 if (wfd_res != GST_WFD_OK) {
1574 GST_ERROR_OBJECT (client, "Failed to create wfd message...");
1578 wfd_res = gst_wfd_message_init (msg);
1579 if (wfd_res != GST_WFD_OK) {
1580 GST_ERROR_OBJECT (client, "Failed to init wfd message...");
1584 g_string_append_printf (buf, "rtsp://");
1586 if (priv->host_address) {
1587 g_string_append (buf, priv->host_address);
1589 GST_ERROR_OBJECT (client, "Failed to get host address");
1590 if (buf) g_string_free (buf, TRUE);
1594 g_string_append_printf (buf, "/wfd1.0/streamid=0");
1596 gst_wfd_message_set_presentation_url (msg, g_string_free (buf, FALSE),
1599 if (wfd_res != GST_WFD_OK) {
1600 GST_ERROR_OBJECT (client, "Failed to set presentation url");
1604 taudiocodec = wfd_get_prefered_audio_codec (priv->audio_codec, priv->caCodec);
1605 priv->caCodec = taudiocodec;
1606 if (!_set_negotiated_audio_codec(client, priv->caCodec)) {
1607 GST_ERROR_OBJECT (client, "Failed to set negotiated "
1608 "audio codec to media factory...");
1611 if (priv->cFreq & GST_WFD_FREQ_48000)
1612 taudiofreq = GST_WFD_FREQ_48000;
1613 else if (priv->cFreq & GST_WFD_FREQ_44100)
1614 taudiofreq = GST_WFD_FREQ_44100;
1615 priv->cFreq = taudiofreq;
1617 /* TODO-WFD: Currently only 2 channels is present */
1618 if (priv->cChanels & GST_WFD_CHANNEL_8)
1619 taudiochannels = GST_WFD_CHANNEL_2;
1620 else if (priv->cChanels & GST_WFD_CHANNEL_6)
1621 taudiochannels = GST_WFD_CHANNEL_2;
1622 else if (priv->cChanels & GST_WFD_CHANNEL_4)
1623 taudiochannels = GST_WFD_CHANNEL_2;
1624 else if (priv->cChanels & GST_WFD_CHANNEL_2)
1625 taudiochannels = GST_WFD_CHANNEL_2;
1626 priv->cChanels = taudiochannels;
1629 gst_wfd_message_set_prefered_audio_format (msg, taudiocodec, taudiofreq,
1630 taudiochannels, priv->cBitwidth, priv->caLatency);
1631 if (wfd_res != GST_WFD_OK) {
1632 GST_ERROR_OBJECT (priv, "Failed to set preffered audio formats...");
1636 /* Set the preffered video formats */
1637 priv->cvCodec = GST_WFD_VIDEO_H264;
1638 priv->cProfile = tcProfile = GST_WFD_H264_BASE_PROFILE;
1639 priv->cLevel = tcLevel = GST_WFD_H264_LEVEL_3_1;
1641 resolution_supported = priv->video_resolution_supported;
1643 /* TODO-WFD: Need to verify this logic
1644 if(priv->edid_supported) {
1645 if (priv->edid_hres < 1920) resolution_supported = resolution_supported & 0x8C7F;
1646 if (priv->edid_hres < 1280) resolution_supported = resolution_supported & 0x1F;
1647 if (priv->edid_hres < 720) resolution_supported = resolution_supported & 0x01;
1651 if (priv->video_native_resolution == GST_WFD_VIDEO_CEA_RESOLUTION) {
1653 wfd_get_prefered_resolution (resolution_supported,
1654 priv->cCEAResolution, priv->video_native_resolution, &priv->cMaxWidth,
1655 &priv->cMaxHeight, &priv->cFramerate, &priv->cInterleaved);
1657 ("wfd negotiated resolution: %08x, width: %d, height: %d, framerate: %d, interleaved: %d",
1658 tcCEAResolution, priv->cMaxWidth, priv->cMaxHeight, priv->cFramerate,
1659 priv->cInterleaved);
1660 } else if (priv->video_native_resolution == GST_WFD_VIDEO_VESA_RESOLUTION) {
1662 wfd_get_prefered_resolution (resolution_supported,
1663 priv->cVESAResolution, priv->video_native_resolution,
1664 &priv->cMaxWidth, &priv->cMaxHeight, &priv->cFramerate,
1665 &priv->cInterleaved);
1667 ("wfd negotiated resolution: %08x, width: %d, height: %d, framerate: %d, interleaved: %d",
1668 tcVESAResolution, priv->cMaxWidth, priv->cMaxHeight, priv->cFramerate,
1669 priv->cInterleaved);
1670 } else if (priv->video_native_resolution == GST_WFD_VIDEO_HH_RESOLUTION) {
1672 wfd_get_prefered_resolution (resolution_supported,
1673 priv->cHHResolution, priv->video_native_resolution, &priv->cMaxWidth,
1674 &priv->cMaxHeight, &priv->cFramerate, &priv->cInterleaved);
1676 ("wfd negotiated resolution: %08x, width: %d, height: %d, framerate: %d, interleaved: %d",
1677 tcHHResolution, priv->cMaxWidth, priv->cMaxHeight, priv->cFramerate,
1678 priv->cInterleaved);
1681 if (!_set_negotiated_resolution(client, priv->cMaxWidth,
1682 priv->cMaxHeight)) {
1683 GST_ERROR_OBJECT (client, "Failed to set negotiated "
1684 "resolution to media factory...");
1688 gst_wfd_message_set_prefered_video_format (msg, priv->cvCodec,
1689 priv->video_native_resolution, GST_WFD_CEA_UNKNOWN, tcCEAResolution,
1690 tcVESAResolution, tcHHResolution, tcProfile, tcLevel, priv->cvLatency,
1691 priv->cMaxWidth, priv->cMaxHeight, priv->cmin_slice_size,
1692 priv->cslice_enc_params, priv->cframe_rate_control);
1694 if (wfd_res != GST_WFD_OK) {
1695 GST_ERROR_OBJECT (client, "Failed to set preffered video formats...");
1699 /* set the preffered RTP ports for the WFD server */
1701 gst_wfd_messge_set_prefered_rtp_ports (msg, GST_WFD_RTSP_TRANS_RTP,
1702 GST_WFD_RTSP_PROFILE_AVP, GST_WFD_RTSP_LOWER_TRANS_UDP, priv->crtp_port0, priv->crtp_port1);
1703 if (wfd_res != GST_WFD_OK) {
1704 GST_ERROR_OBJECT (client,
1705 "Failed to set supported video formats on wfd message...");
1709 *data = gst_wfd_message_as_text (msg);
1710 if (*data == NULL) {
1711 GST_ERROR_OBJECT (client, "Failed to get wfd message as text...");
1714 *len = strlen (*data);
1716 } else if (msg_type == M5_REQ_MSG) {
1717 g_string_append (buf, "wfd_trigger_method: SETUP");
1718 g_string_append (buf, "\r\n");
1720 *data = g_string_free (buf, FALSE);
1721 } else if (msg_type == TEARDOWN_TRIGGER) {
1722 g_string_append (buf, "wfd_trigger_method: TEARDOWN");
1723 g_string_append (buf, "\r\n");
1725 *data = g_string_free (buf, FALSE);
1726 } else if (msg_type == PLAY_TRIGGER) {
1727 g_string_append (buf, "wfd_trigger_method: PLAY");
1728 g_string_append (buf, "\r\n");
1730 *data = g_string_free (buf, FALSE);
1731 } else if (msg_type == PAUSE_TRIGGER) {
1732 g_string_append (buf, "wfd_trigger_method: PAUSE");
1733 g_string_append (buf, "\r\n");
1735 *data = g_string_free (buf, FALSE);
1750 * gst_prepare_request:
1751 * @client: client object
1752 * @request : requst message to be prepared
1753 * @method : RTSP method of the request
1754 * @url : url need to be in the request
1755 * @message_type : WFD message type
1756 * @trigger_type : trigger method to be used for M5 mainly
1758 * Prepares request based on @method & @message_type
1760 * Returns: a #GstRTSPResult.
1763 gst_prepare_request (GstRTSPWFDClient * client, GstRTSPMessage * request,
1764 GstRTSPMethod method, gchar * url)
1766 GstRTSPResult res = GST_RTSP_OK;
1769 if (method == GST_RTSP_GET_PARAMETER || method == GST_RTSP_SET_PARAMETER) {
1771 url = g_strdup ("rtsp://localhost/wfd1.0");
1774 GST_DEBUG_OBJECT (client, "Preparing request: %d", method);
1776 /* initialize the request */
1777 res = gst_rtsp_message_init_request (request, method, url);
1779 if (method == GST_RTSP_GET_PARAMETER || method == GST_RTSP_SET_PARAMETER) {
1784 GST_ERROR ("init request failed");
1789 /* Prepare OPTIONS request to send */
1790 case GST_RTSP_OPTIONS:{
1791 /* add wfd specific require filed "org.wfa.wfd1.0" */
1792 str = g_strdup ("org.wfa.wfd1.0");
1793 res = gst_rtsp_message_add_header (request, GST_RTSP_HDR_REQUIRE, str);
1795 GST_ERROR ("Failed to add header");
1804 /* Prepare GET_PARAMETER request */
1805 case GST_RTSP_GET_PARAMETER:{
1810 /* add content type */
1812 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
1815 GST_ERROR ("Failed to add header");
1819 _set_wfd_message_body (client, M3_REQ_MSG, &msg, &msglen);
1820 msglength = g_string_new ("");
1821 g_string_append_printf (msglength, "%d", msglen);
1822 GST_DEBUG ("M3 server side message body: %s", msg);
1824 /* add content-length type */
1826 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
1827 g_string_free (msglength, FALSE));
1828 if (res != GST_RTSP_OK) {
1829 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1833 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
1834 if (res != GST_RTSP_OK) {
1835 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1843 /* Prepare SET_PARAMETER request */
1844 case GST_RTSP_SET_PARAMETER:{
1849 /* add content type */
1851 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
1853 if (res != GST_RTSP_OK) {
1854 GST_ERROR_OBJECT (client, "Failed to add header to rtsp request...");
1858 _set_wfd_message_body (client, M4_REQ_MSG, &msg, &msglen);
1859 msglength = g_string_new ("");
1860 g_string_append_printf (msglength, "%d", msglen);
1861 GST_DEBUG ("M4 server side message body: %s", msg);
1863 /* add content-length type */
1865 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
1866 g_string_free (msglength, FALSE));
1867 if (res != GST_RTSP_OK) {
1868 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1872 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
1873 if (res != GST_RTSP_OK) {
1874 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1889 return GST_RTSP_ERROR;
1893 prepare_trigger_request (GstRTSPWFDClient * client, GstRTSPMessage * request,
1894 GstWFDTriggerType trigger_type, gchar * url)
1896 GstRTSPResult res = GST_RTSP_OK;
1898 /* initialize the request */
1899 res = gst_rtsp_message_init_request (request, GST_RTSP_SET_PARAMETER, url);
1901 GST_ERROR ("init request failed");
1905 switch (trigger_type) {
1906 case WFD_TRIGGER_SETUP:{
1911 /* add content type */
1913 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
1915 if (res != GST_RTSP_OK) {
1916 GST_ERROR_OBJECT (client, "Failed to add header to rtsp request...");
1920 _set_wfd_message_body (client, M5_REQ_MSG, &msg, &msglen);
1921 msglength = g_string_new ("");
1922 g_string_append_printf (msglength, "%d", msglen);
1923 GST_DEBUG ("M5 server side message body: %s", msg);
1925 /* add content-length type */
1927 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
1928 g_string_free (msglength, FALSE));
1929 if (res != GST_RTSP_OK) {
1930 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1934 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
1935 if (res != GST_RTSP_OK) {
1936 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1943 case WFD_TRIGGER_TEARDOWN:{
1948 /* add content type */
1950 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
1952 if (res != GST_RTSP_OK) {
1953 GST_ERROR_OBJECT (client, "Failed to add header to rtsp request...");
1957 _set_wfd_message_body (client, TEARDOWN_TRIGGER, &msg, &msglen);
1958 msglength = g_string_new ("");
1959 g_string_append_printf (msglength, "%d", msglen);
1960 GST_DEBUG ("Trigger TEARDOWN server side message body: %s", msg);
1962 /* add content-length type */
1964 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
1965 g_string_free (msglength, FALSE));
1966 if (res != GST_RTSP_OK) {
1967 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1971 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
1972 if (res != GST_RTSP_OK) {
1973 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
1980 case WFD_TRIGGER_PLAY:{
1985 /* add content type */
1987 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
1989 if (res != GST_RTSP_OK) {
1990 GST_ERROR_OBJECT (client, "Failed to add header to rtsp request...");
1994 _set_wfd_message_body (client, PLAY_TRIGGER, &msg, &msglen);
1995 msglength = g_string_new ("");
1996 g_string_append_printf (msglength, "%d", msglen);
1997 GST_DEBUG ("Trigger PLAY server side message body: %s", msg);
1999 /* add content-length type */
2001 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
2002 g_string_free (msglength, FALSE));
2003 if (res != GST_RTSP_OK) {
2004 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2008 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
2009 if (res != GST_RTSP_OK) {
2010 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2017 case WFD_TRIGGER_PAUSE:{
2022 /* add content type */
2024 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_TYPE,
2026 if (res != GST_RTSP_OK) {
2027 GST_ERROR_OBJECT (client, "Failed to add header to rtsp request...");
2031 _set_wfd_message_body (client, PAUSE_TRIGGER, &msg, &msglen);
2032 msglength = g_string_new ("");
2033 g_string_append_printf (msglength, "%d", msglen);
2034 GST_DEBUG ("Trigger PAUSE server side message body: %s", msg);
2036 /* add content-length type */
2038 gst_rtsp_message_add_header (request, GST_RTSP_HDR_CONTENT_LENGTH,
2039 g_string_free (msglength, FALSE));
2040 if (res != GST_RTSP_OK) {
2041 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2045 res = gst_rtsp_message_set_body (request, (guint8 *) msg, msglen);
2046 if (res != GST_RTSP_OK) {
2047 GST_ERROR_OBJECT (client, "Failed to add header to rtsp message...");
2054 /* TODO-WFD: implement to handle other trigger type */
2067 gst_send_request (GstRTSPWFDClient * client, GstRTSPSession * session,
2068 GstRTSPMessage * request)
2070 GstRTSPResult res = GST_RTSP_OK;
2071 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
2073 /* remove any previous header */
2074 gst_rtsp_message_remove_header (request, GST_RTSP_HDR_SESSION, -1);
2076 /* add the new session header for new session ids */
2079 const gchar *sessionid = NULL;
2082 sessionid = gst_rtsp_session_get_sessionid (session);
2083 GST_INFO_OBJECT (client, "Session id : %s", sessionid);
2085 timeout = gst_rtsp_session_get_timeout (session);
2086 if (timeout != DEFAULT_WFD_TIMEOUT)
2087 str = g_strdup_printf ("%s; timeout=%d", sessionid, timeout);
2089 str = g_strdup (sessionid);
2091 gst_rtsp_message_take_header (request, GST_RTSP_HDR_SESSION, str);
2094 if (gst_debug_category_get_threshold (rtsp_wfd_client_debug) >= GST_LEVEL_LOG) {
2095 gst_rtsp_message_dump (request);
2098 res = gst_rtsp_client_send_message (parent_client, session, request);
2099 if (res != GST_RTSP_OK) {
2100 GST_ERROR_OBJECT (client, "gst_rtsp_client_send_message failed : %d", res);
2103 gst_rtsp_message_unset (request);
2108 * @client: client object
2109 * @request : requst message received
2110 * @response : response to be prepare based on request
2111 * @method : RTSP method
2113 * prepare response to the request based on @method & @message_type
2115 * Returns: a #GstRTSPResult.
2118 prepare_response (GstRTSPWFDClient * client, GstRTSPMessage * request,
2119 GstRTSPMessage * response, GstRTSPMethod method)
2121 GstRTSPResult res = GST_RTSP_OK;
2124 /* prepare OPTIONS response */
2125 case GST_RTSP_OPTIONS:{
2126 GstRTSPMethod options;
2129 gchar *user_agent = NULL;
2131 options = GST_RTSP_OPTIONS |
2135 GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | GST_RTSP_TEARDOWN;
2137 str = gst_rtsp_options_as_text (options);
2139 /*append WFD specific method */
2140 tmp = g_strdup (", org.wfa.wfd1.0");
2141 g_strlcat (str, tmp, strlen (tmp) + strlen (str) + 1);
2143 gst_rtsp_message_init_response (response, GST_RTSP_STS_OK,
2144 gst_rtsp_status_as_text (GST_RTSP_STS_OK), request);
2146 gst_rtsp_message_add_header (response, GST_RTSP_HDR_PUBLIC, str);
2151 gst_rtsp_message_get_header (request, GST_RTSP_HDR_USER_AGENT,
2153 if (res == GST_RTSP_OK) {
2154 gst_rtsp_message_add_header (response, GST_RTSP_HDR_USER_AGENT,
2161 GST_ERROR_OBJECT (client, "Unhandled method...");
2162 return GST_RTSP_EINVAL;
2170 send_generic_wfd_response (GstRTSPWFDClient * client, GstRTSPStatusCode code,
2171 GstRTSPContext * ctx)
2173 GstRTSPResult res = GST_RTSP_OK;
2174 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
2176 gst_rtsp_message_init_response (ctx->response, code,
2177 gst_rtsp_status_as_text (code), ctx->request);
2179 res = gst_rtsp_client_send_message (parent_client, NULL, ctx->response);
2180 if (res != GST_RTSP_OK) {
2181 GST_ERROR_OBJECT (client, "gst_rtsp_client_send_message failed : %d", res);
2186 static GstRTSPResult
2187 handle_M1_message (GstRTSPWFDClient * client)
2189 GstRTSPResult res = GST_RTSP_OK;
2190 GstRTSPMessage request = { 0 };
2192 res = gst_prepare_request (client, &request, GST_RTSP_OPTIONS, (gchar *) "*");
2193 if (GST_RTSP_OK != res) {
2194 GST_ERROR_OBJECT (client, "Failed to prepare M1 request....\n");
2198 GST_DEBUG_OBJECT (client, "Sending M1 request.. (OPTIONS request)");
2200 gst_send_request (client, NULL, &request);
2206 * handle_M3_message:
2207 * @client: client object
2209 * Handles M3 WFD message.
2210 * This API will send M3 message (GET_PARAMETER) to WFDSink to query supported formats by the WFDSink.
2211 * After getting supported formats info, this API will set those values on WFDConfigMessage obj
2213 * Returns: a #GstRTSPResult.
2215 static GstRTSPResult
2216 handle_M3_message (GstRTSPWFDClient * client)
2218 GstRTSPResult res = GST_RTSP_OK;
2219 GstRTSPMessage request = { 0 };
2220 GstRTSPUrl *url = NULL;
2221 gchar *url_str = NULL;
2223 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
2224 GstRTSPConnection *connection =
2225 gst_rtsp_client_get_connection (parent_client);
2227 url = gst_rtsp_connection_get_url (connection);
2229 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2230 res = GST_RTSP_ERROR;
2234 url_str = gst_rtsp_url_get_request_uri (url);
2235 if (url_str == NULL) {
2236 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2237 res = GST_RTSP_ERROR;
2241 res = gst_prepare_request (client, &request, GST_RTSP_GET_PARAMETER, url_str);
2242 if (GST_RTSP_OK != res) {
2243 GST_ERROR_OBJECT (client, "Failed to prepare M3 request....\n");
2247 GST_DEBUG_OBJECT (client, "Sending GET_PARAMETER request message (M3)...");
2249 gst_send_request (client, NULL, &request);
2257 static GstRTSPResult
2258 handle_M4_message (GstRTSPWFDClient * client)
2260 GstRTSPResult res = GST_RTSP_OK;
2261 GstRTSPMessage request = { 0 };
2262 GstRTSPUrl *url = NULL;
2263 gchar *url_str = NULL;
2265 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
2266 GstRTSPConnection *connection =
2267 gst_rtsp_client_get_connection (parent_client);
2269 url = gst_rtsp_connection_get_url (connection);
2271 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2272 res = GST_RTSP_ERROR;
2276 url_str = gst_rtsp_url_get_request_uri (url);
2277 if (url_str == NULL) {
2278 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2279 res = GST_RTSP_ERROR;
2283 res = gst_prepare_request (client, &request, GST_RTSP_SET_PARAMETER, url_str);
2284 if (GST_RTSP_OK != res) {
2285 GST_ERROR_OBJECT (client, "Failed to prepare M4 request....\n");
2289 GST_DEBUG_OBJECT (client, "Sending SET_PARAMETER request message (M4)...");
2291 gst_send_request (client, NULL, &request);
2300 gst_rtsp_wfd_client_trigger_request (GstRTSPWFDClient * client,
2301 GstWFDTriggerType type)
2303 GstRTSPResult res = GST_RTSP_OK;
2304 GstRTSPMessage request = { 0 };
2305 GstRTSPUrl *url = NULL;
2306 gchar *url_str = NULL;
2308 GstRTSPClient *parent_client = GST_RTSP_CLIENT_CAST (client);
2309 GstRTSPConnection *connection =
2310 gst_rtsp_client_get_connection (parent_client);
2312 url = gst_rtsp_connection_get_url (connection);
2314 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2315 res = GST_RTSP_ERROR;
2319 url_str = gst_rtsp_url_get_request_uri (url);
2320 if (url_str == NULL) {
2321 GST_ERROR_OBJECT (client, "Failed to get connection URL");
2322 res = GST_RTSP_ERROR;
2326 res = prepare_trigger_request (client, &request, type, url_str);
2327 if (GST_RTSP_OK != res) {
2328 GST_ERROR_OBJECT (client, "Failed to prepare M5 request....\n");
2332 GST_DEBUG_OBJECT (client, "Sending trigger request message...: %d", type);
2334 gst_send_request (client, NULL, &request);
2343 gst_rtsp_wfd_client_set_video_supported_resolution (GstRTSPWFDClient * client,
2344 guint64 supported_reso)
2346 GstRTSPResult res = GST_RTSP_OK;
2347 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2349 g_return_val_if_fail (priv != NULL, GST_RTSP_EINVAL);
2351 priv->video_resolution_supported = supported_reso;
2352 GST_DEBUG ("Resolution : %"G_GUINT64_FORMAT, supported_reso);
2358 gst_rtsp_wfd_client_set_video_native_resolution (GstRTSPWFDClient * client,
2359 guint64 native_reso)
2361 GstRTSPResult res = GST_RTSP_OK;
2362 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2364 g_return_val_if_fail (priv != NULL, GST_RTSP_EINVAL);
2366 priv->video_native_resolution = native_reso;
2367 GST_DEBUG ("Native Resolution : %"G_GUINT64_FORMAT, native_reso);
2373 gst_rtsp_wfd_client_set_audio_codec (GstRTSPWFDClient * client,
2376 GstRTSPResult res = GST_RTSP_OK;
2377 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2379 g_return_val_if_fail (priv != NULL, GST_RTSP_EINVAL);
2381 priv->audio_codec = audio_codec;
2382 GST_DEBUG ("Audio codec : %d", audio_codec);
2388 wfd_ckeck_keep_alive_response (gpointer userdata)
2390 GstRTSPWFDClient *client = (GstRTSPWFDClient *)userdata;
2391 GstRTSPWFDClientPrivate *priv = NULL;
2396 priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2397 g_return_val_if_fail (priv != NULL, GST_RTSP_EINVAL);
2399 if (priv->keep_alive_flag) {
2403 GST_INFO ("%p: source error notification", client);
2405 g_signal_emit (client,
2406 gst_rtsp_client_wfd_signals[SIGNAL_WFD_KEEP_ALIVE_FAIL], 0,
2412 /*Sending keep_alive (M16) message.
2413 Without calling gst_prepare_request function.*/
2414 static GstRTSPResult
2415 handle_M16_message (GstRTSPWFDClient * client)
2417 GstRTSPResult res = GST_RTSP_OK;
2418 GstRTSPMessage request = { 0 };
2419 gchar *url_str = NULL;
2421 url_str = g_strdup("rtsp://localhost/wfd1.0");
2423 res = gst_rtsp_message_init_request (&request, GST_RTSP_GET_PARAMETER, url_str);
2425 GST_ERROR ("init request failed");
2430 gst_send_request (client, NULL, &request);
2435 /*CHecking whether source has got response of any request.
2436 * If yes, keep alive message is sent otherwise error message
2437 * will be displayed.*/
2439 keep_alive_condition(gpointer userdata)
2441 GstRTSPWFDClient *client;
2442 GstRTSPWFDClientPrivate *priv;
2444 client = (GstRTSPWFDClient *)userdata;
2448 priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2450 g_return_val_if_fail (priv != NULL, FALSE);
2452 g_mutex_lock(&priv->keep_alive_lock);
2453 if(!priv->keep_alive_flag) {
2454 g_timeout_add(5000, wfd_ckeck_keep_alive_response, client);
2457 GST_DEBUG_OBJECT (client, "have received last keep alive message response");
2460 GST_DEBUG("sending keep alive message");
2461 res = handle_M16_message(client);
2462 if(res == GST_RTSP_OK) {
2463 priv->keep_alive_flag = FALSE;
2465 GST_ERROR_OBJECT (client, "Failed to send Keep Alive Message");
2466 g_mutex_unlock(&priv->keep_alive_lock);
2470 g_mutex_unlock(&priv->keep_alive_lock);
2475 void wfd_set_keep_alive_condition(GstRTSPWFDClient * client)
2477 g_timeout_add((DEFAULT_WFD_TIMEOUT-5)*1000, keep_alive_condition, client);
2481 gst_rtsp_wfd_client_set_host_address (GstRTSPWFDClient *client, const gchar * address)
2483 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2485 g_return_if_fail (priv != NULL);
2487 if (priv->host_address) {
2488 g_free (priv->host_address);
2491 priv->host_address = g_strdup (address);
2495 gst_rtsp_wfd_client_get_audio_codec(GstRTSPWFDClient *client)
2497 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2498 g_return_val_if_fail (priv != NULL, 0);
2500 return priv->caCodec;
2504 gst_rtsp_wfd_client_get_audio_freq(GstRTSPWFDClient *client)
2506 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2507 g_return_val_if_fail (priv != NULL, 0);
2513 gst_rtsp_wfd_client_get_audio_channels(GstRTSPWFDClient *client)
2515 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2516 g_return_val_if_fail (priv != NULL, 0);
2518 return priv->cChanels;
2522 gst_rtsp_wfd_client_get_audio_bit_width(GstRTSPWFDClient *client)
2524 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2525 g_return_val_if_fail (priv != NULL, 0);
2527 return priv->cBitwidth;
2531 gst_rtsp_wfd_client_get_audio_latency(GstRTSPWFDClient *client)
2533 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2534 g_return_val_if_fail (priv != NULL, 0);
2536 return priv->caLatency;
2540 gst_rtsp_wfd_client_get_video_codec(GstRTSPWFDClient *client)
2542 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2543 g_return_val_if_fail (priv != NULL, 0);
2545 return priv->cvCodec;
2549 gst_rtsp_wfd_client_get_video_native(GstRTSPWFDClient *client)
2551 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2552 g_return_val_if_fail (priv != NULL, 0);
2554 return priv->cNative;
2558 gst_rtsp_wfd_client_get_video_native_resolution(GstRTSPWFDClient *client)
2560 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2561 g_return_val_if_fail (priv != NULL, 0);
2563 return priv->cNativeResolution;
2567 gst_rtsp_wfd_client_get_video_cea_resolution(GstRTSPWFDClient *client)
2569 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2570 g_return_val_if_fail (priv != NULL, 0);
2572 return priv->cCEAResolution;
2576 gst_rtsp_wfd_client_get_video_vesa_resolution(GstRTSPWFDClient *client)
2578 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2579 g_return_val_if_fail (priv != NULL, 0);
2581 return priv->cVESAResolution;
2585 gst_rtsp_wfd_client_get_video_hh_resolution(GstRTSPWFDClient *client)
2587 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2588 g_return_val_if_fail (priv != NULL, 0);
2590 return priv->cHHResolution;
2594 gst_rtsp_wfd_client_get_video_profile(GstRTSPWFDClient *client)
2596 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2597 g_return_val_if_fail (priv != NULL, 0);
2599 return priv->cProfile;
2603 gst_rtsp_wfd_client_get_video_level(GstRTSPWFDClient *client)
2605 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2606 g_return_val_if_fail (priv != NULL, 0);
2608 return priv->cLevel;
2612 gst_rtsp_wfd_client_get_video_latency(GstRTSPWFDClient *client)
2614 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2615 g_return_val_if_fail (priv != NULL, 0);
2617 return priv->cvLatency;
2621 gst_rtsp_wfd_client_get_video_max_height(GstRTSPWFDClient *client)
2623 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2624 g_return_val_if_fail (priv != NULL, 0);
2626 return priv->cMaxHeight;
2630 gst_rtsp_wfd_client_get_video_max_width(GstRTSPWFDClient *client)
2632 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2633 g_return_val_if_fail (priv != NULL, 0);
2635 return priv->cMaxWidth;
2639 gst_rtsp_wfd_client_get_video_framerate(GstRTSPWFDClient *client)
2641 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2642 g_return_val_if_fail (priv != NULL, 0);
2644 return priv->cFramerate;
2648 gst_rtsp_wfd_client_get_video_min_slice_size(GstRTSPWFDClient *client)
2650 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2651 g_return_val_if_fail (priv != NULL, 0);
2653 return priv->cmin_slice_size;
2657 gst_rtsp_wfd_client_get_video_slice_enc_params(GstRTSPWFDClient *client)
2659 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2660 g_return_val_if_fail (priv != NULL, 0);
2662 return priv->cslice_enc_params;
2666 gst_rtsp_wfd_client_get_video_framerate_control(GstRTSPWFDClient *client)
2668 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2669 g_return_val_if_fail (priv != NULL, 0);
2671 return priv->cframe_rate_control;
2675 gst_rtsp_wfd_client_get_rtp_port0(GstRTSPWFDClient *client)
2677 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2678 g_return_val_if_fail (priv != NULL, 0);
2680 return priv->crtp_port0;
2684 gst_rtsp_wfd_client_get_rtp_port1(GstRTSPWFDClient *client)
2686 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2687 g_return_val_if_fail (priv != NULL, 0);
2689 return priv->crtp_port1;
2693 gst_rtsp_wfd_client_get_edid_supported(GstRTSPWFDClient *client)
2695 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2696 g_return_val_if_fail (priv != NULL, 0);
2698 return priv->edid_supported;
2702 gst_rtsp_wfd_client_get_edid_hresolution(GstRTSPWFDClient *client)
2704 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2705 g_return_val_if_fail (priv != NULL, 0);
2707 return priv->edid_hres;
2711 gst_rtsp_wfd_client_get_edid_vresolution(GstRTSPWFDClient *client)
2713 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2714 g_return_val_if_fail (priv != NULL, 0);
2716 return priv->edid_vres;
2720 gst_rtsp_wfd_client_get_protection_enabled(GstRTSPWFDClient *client)
2722 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2723 g_return_val_if_fail (priv != NULL, 0);
2725 return priv->protection_enabled;
2729 gst_rtsp_wfd_client_set_audio_freq(GstRTSPWFDClient *client, guint freq)
2731 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2732 g_return_if_fail (priv != NULL);
2738 gst_rtsp_wfd_client_set_edid_supported(GstRTSPWFDClient *client, gboolean supported)
2740 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2741 g_return_if_fail (priv != NULL);
2743 priv->edid_supported = supported;
2747 gst_rtsp_wfd_client_set_edid_hresolution(GstRTSPWFDClient *client, guint32 reso)
2749 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2750 g_return_if_fail (priv != NULL);
2752 priv->edid_hres = reso;
2756 gst_rtsp_wfd_client_set_edid_vresolution(GstRTSPWFDClient *client, guint32 reso)
2758 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2759 g_return_if_fail (priv != NULL);
2761 priv->edid_vres = reso;
2765 gst_rtsp_wfd_client_set_protection_enabled(GstRTSPWFDClient *client, gboolean enable)
2767 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2768 g_return_if_fail (priv != NULL);
2770 priv->protection_enabled = enable;
2774 gst_rtsp_wfd_client_set_hdcp_version(GstRTSPWFDClient *client, GstWFDHDCPProtection version)
2776 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2777 g_return_if_fail (priv != NULL);
2779 priv->hdcp_version = version;
2783 gst_rtsp_wfd_client_set_hdcp_port(GstRTSPWFDClient *client, guint32 port)
2785 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2786 g_return_if_fail (priv != NULL);
2788 priv->hdcp_tcpport = port;
2791 void gst_rtsp_wfd_client_set_keep_alive_flag(GstRTSPWFDClient *client, gboolean flag)
2793 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2794 g_return_if_fail (priv != NULL);
2796 g_mutex_lock(&priv->keep_alive_lock);
2797 if (priv->keep_alive_flag == !(flag))
2798 priv->keep_alive_flag = flag;
2799 g_mutex_unlock(&priv->keep_alive_lock);
2803 gst_rtsp_wfd_client_set_aud_codec (GstRTSPWFDClient *client, guint acodec)
2805 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2806 g_return_if_fail (priv != NULL);
2808 priv->caCodec = acodec;
2812 gst_rtsp_wfd_client_set_audio_channels(GstRTSPWFDClient *client, guint channels)
2814 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2815 g_return_if_fail (priv != NULL);
2817 priv->cChanels = channels;
2821 gst_rtsp_wfd_client_set_audio_bit_width(GstRTSPWFDClient *client, guint bwidth)
2823 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2824 g_return_if_fail (priv != NULL);
2826 priv->cBitwidth = bwidth;
2830 gst_rtsp_wfd_client_set_audio_latency(GstRTSPWFDClient *client, guint latency)
2832 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2833 g_return_if_fail (priv != NULL);
2835 priv->caLatency = latency;
2839 gst_rtsp_wfd_client_set_video_codec(GstRTSPWFDClient *client, guint vcodec)
2841 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2842 g_return_if_fail (priv != NULL);
2844 priv->cvCodec = vcodec;
2848 gst_rtsp_wfd_client_set_video_native(GstRTSPWFDClient *client, guint native)
2850 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2851 g_return_if_fail (priv != NULL);
2853 priv->cNative = native;
2857 gst_rtsp_wfd_client_set_vid_native_resolution(GstRTSPWFDClient *client, guint64 res)
2859 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2860 g_return_if_fail (priv != NULL);
2862 priv->cNativeResolution = res;
2866 gst_rtsp_wfd_client_set_video_cea_resolution(GstRTSPWFDClient *client, guint64 res)
2868 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2869 g_return_if_fail (priv != NULL);
2871 priv->cCEAResolution = res;
2875 gst_rtsp_wfd_client_set_video_vesa_resolution(GstRTSPWFDClient *client, guint64 res)
2877 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2878 g_return_if_fail (priv != NULL);
2880 priv->cVESAResolution = res;
2884 gst_rtsp_wfd_client_set_video_hh_resolution(GstRTSPWFDClient *client, guint64 res)
2886 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2887 g_return_if_fail (priv != NULL);
2889 priv->cHHResolution = res;
2893 gst_rtsp_wfd_client_set_video_profile(GstRTSPWFDClient *client, guint profile)
2895 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2896 g_return_if_fail (priv != NULL);
2898 priv->cProfile = profile;
2902 gst_rtsp_wfd_client_set_video_level(GstRTSPWFDClient *client, guint level)
2904 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2905 g_return_if_fail (priv != NULL);
2907 priv->cLevel = level;
2911 gst_rtsp_wfd_client_set_video_latency(GstRTSPWFDClient *client, guint latency)
2913 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2914 g_return_if_fail (priv != NULL);
2916 priv->cvLatency = latency;
2920 gst_rtsp_wfd_client_set_video_max_height(GstRTSPWFDClient *client, guint32 height)
2922 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2923 g_return_if_fail (priv != NULL);
2925 priv->cMaxHeight = height;
2929 gst_rtsp_wfd_client_set_video_max_width(GstRTSPWFDClient *client, guint32 width)
2931 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2932 g_return_if_fail (priv != NULL);
2934 priv->cMaxWidth = width;
2938 gst_rtsp_wfd_client_set_video_framerate(GstRTSPWFDClient *client, guint32 framerate)
2940 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2941 g_return_if_fail (priv != NULL);
2943 priv->cFramerate = framerate;
2947 gst_rtsp_wfd_client_set_video_min_slice_size(GstRTSPWFDClient *client, guint32 slice_size)
2949 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2950 g_return_if_fail (priv != NULL);
2952 priv->cmin_slice_size = slice_size;
2956 gst_rtsp_wfd_client_set_video_slice_enc_params(GstRTSPWFDClient *client, guint32 enc_params)
2958 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2959 g_return_if_fail (priv != NULL);
2961 priv->cslice_enc_params = enc_params;
2965 gst_rtsp_wfd_client_set_video_framerate_control(GstRTSPWFDClient *client, guint framerate)
2967 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2968 g_return_if_fail (priv != NULL);
2970 priv->cframe_rate_control = framerate;
2974 gst_rtsp_wfd_client_set_rtp_port0(GstRTSPWFDClient *client, guint32 port)
2976 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2977 g_return_if_fail (priv != NULL);
2979 priv->crtp_port0 = port;
2983 gst_rtsp_wfd_client_set_rtp_port1(GstRTSPWFDClient *client, guint32 port)
2985 GstRTSPWFDClientPrivate *priv = GST_RTSP_WFD_CLIENT_GET_PRIVATE (client);
2986 g_return_if_fail (priv != NULL);
2988 priv->crtp_port1 = port;