Resolve memory related and unreachable code issue
[platform/upstream/gst-plugins-tizen.git] / wfdmanager / wfdbase / gstwfdsinkmessage.c
1 /*
2  * wfdrtsp message
3  *
4  * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Taewan Kim<taewan79.kim@samsung.com>, Yejin Cho<cho.yejin@samsung.com>, Sangkyu Park<sk1122.park@samsung.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library (COPYING); if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
31 #ifdef HAVE_SYS_TYPES_H
32 #include <sys/types.h>
33 #endif
34
35 #include <glib.h>               /* for G_OS_WIN32 */
36 #include "gstwfdsinkmessage.h"
37 #include <gio/gio.h>
38
39 /* FIXME, is currently allocated on the stack */
40 #define MAX_LINE_LEN    (1024 * 16)
41
42 #define FREE_STRING(field)              do { g_free(field); (field) = NULL; } while (0)
43 #define REPLACE_STRING(field, val)      do { FREE_STRING(field); (field) = g_strdup(val); } while (0)
44 #define EDID_BLOCK_SIZE 128
45 #define EDID_BLOCK_COUNT_MAX_SIZE 256
46 #define MAX_PORT_SIZE 65535
47
48 enum {
49   GST_WFD_SESSION,
50   GST_WFD_MEDIA,
51 };
52
53 typedef struct {
54   guint state;
55   GstWFDMessage *msg;
56 } WFDContext;
57
58 /**
59 * gst_wfd_message_new:
60 * @msg: pointer to new #GstWFDMessage
61 *
62 * Allocate a new GstWFDMessage and store the result in @msg.
63 *
64 * Returns: a #GstWFDResult.
65 */
66 GstWFDResult
67 gst_wfd_message_new(GstWFDMessage **msg)
68 {
69   GstWFDMessage *newmsg;
70
71   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
72
73   newmsg = g_new0(GstWFDMessage, 1);
74
75   *msg = newmsg;
76
77   return gst_wfd_message_init(newmsg);
78 }
79
80 /**
81 * gst_wfd_message_init:
82 * @msg: a #GstWFDMessage
83 *
84 * Initialize @msg so that its contents are as if it was freshly allocated
85 * with gst_wfd_message_new(). This function is mostly used to initialize a message
86 * allocated on the stack. gst_wfd_message_uninit() undoes this operation.
87 *
88 * When this function is invoked on newly allocated data(with malloc or on the
89 * stack), its contents should be set to 0 before calling this function.
90 *
91 * Returns: a #GstWFDResult.
92 */
93 GstWFDResult
94 gst_wfd_message_init(GstWFDMessage *msg)
95 {
96   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
97
98   return GST_WFD_OK;
99 }
100
101 /**
102 * gst_wfd_message_uninit:
103 * @msg: a #GstWFDMessage
104 *
105 * Free all resources allocated in @msg. @msg should not be used anymore after
106 * this function. This function should be used when @msg was allocated on the
107 * stack and initialized with gst_wfd_message_init().
108 *
109 * Returns: a #GstWFDResult.
110 */
111 GstWFDResult
112 gst_wfd_message_uninit(GstWFDMessage *msg)
113 {
114   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
115
116   if (msg->audio_codecs) {
117     guint i = 0;
118     if (msg->audio_codecs->list) {
119       for (; i < msg->audio_codecs->count; i++) {
120         FREE_STRING(msg->audio_codecs->list[i].audio_format);
121         msg->audio_codecs->list[i].modes = 0;
122         msg->audio_codecs->list[i].latency = 0;
123       }
124       FREE_STRING(msg->audio_codecs->list);
125     }
126     FREE_STRING(msg->audio_codecs);
127   }
128
129   if (msg->video_formats) {
130     FREE_STRING(msg->video_formats->list);
131     FREE_STRING(msg->video_formats);
132   }
133
134   if (msg->wfd2_audio_codecs) {
135     guint i = 0;
136     if (msg->wfd2_audio_codecs->list) {
137       for (; i < msg->wfd2_audio_codecs->count; i++) {
138         FREE_STRING(msg->wfd2_audio_codecs->list[i].audio_format);
139         msg->wfd2_audio_codecs->list[i].modes = 0;
140         msg->wfd2_audio_codecs->list[i].latency = 0;
141       }
142       FREE_STRING(msg->wfd2_audio_codecs->list);
143     }
144     FREE_STRING(msg->wfd2_audio_codecs);
145   }
146
147   if (msg->direct_video_formats) {
148     FREE_STRING(msg->direct_video_formats->list);
149     FREE_STRING(msg->direct_video_formats);
150   }
151
152   if (msg->video_3d_formats) {
153     FREE_STRING(msg->video_3d_formats->list);
154     FREE_STRING(msg->video_3d_formats);
155   }
156
157   if (msg->content_protection) {
158     if (msg->content_protection->hdcp2_spec) {
159       FREE_STRING(msg->content_protection->hdcp2_spec->hdcpversion);
160       FREE_STRING(msg->content_protection->hdcp2_spec->TCPPort);
161       FREE_STRING(msg->content_protection->hdcp2_spec);
162     }
163     FREE_STRING(msg->content_protection);
164   }
165
166   if (msg->display_edid) {
167     if (msg->display_edid->edid_payload)
168       FREE_STRING(msg->display_edid->edid_payload);
169     FREE_STRING(msg->display_edid);
170   }
171
172   if (msg->coupled_sink) {
173     if (msg->coupled_sink->coupled_sink_cap) {
174       FREE_STRING(msg->coupled_sink->coupled_sink_cap->sink_address);
175       FREE_STRING(msg->coupled_sink->coupled_sink_cap);
176     }
177     FREE_STRING(msg->coupled_sink);
178   }
179
180   if (msg->trigger_method) {
181     FREE_STRING(msg->trigger_method->wfd_trigger_method);
182     FREE_STRING(msg->trigger_method);
183   }
184
185   if (msg->presentation_url) {
186     FREE_STRING(msg->presentation_url->wfd_url0);
187     FREE_STRING(msg->presentation_url->wfd_url1);
188     FREE_STRING(msg->presentation_url);
189   }
190
191   if (msg->client_rtp_ports) {
192     FREE_STRING(msg->client_rtp_ports->profile);
193     FREE_STRING(msg->client_rtp_ports->mode);
194     FREE_STRING(msg->client_rtp_ports);
195   }
196
197   if (msg->route) {
198     FREE_STRING(msg->route->destination);
199     FREE_STRING(msg->route);
200   }
201
202   FREE_STRING(msg->I2C);
203   FREE_STRING(msg->av_format_change_timing);
204   FREE_STRING(msg->preferred_display_mode);
205   FREE_STRING(msg->standby_resume_capability);
206   FREE_STRING(msg->standby);
207   FREE_STRING(msg->connector_type);
208   FREE_STRING(msg->idr_request);
209   FREE_STRING(msg->direct_mode);
210
211   if (msg->tcp_ports) {
212     FREE_STRING(msg->tcp_ports->profile);
213     FREE_STRING(msg->tcp_ports->mode);
214     FREE_STRING(msg->tcp_ports);
215   }
216
217   FREE_STRING(msg->buf_len);
218   FREE_STRING(msg->audio_status);
219   FREE_STRING(msg->video_status);
220
221   return GST_WFD_OK;
222 }
223
224 /**
225 * gst_wfd_message_free:
226 * @msg: a #GstWFDMessage
227 *
228 * Free all resources allocated by @msg. @msg should not be used anymore after
229 * this function. This function should be used when @msg was dynamically
230 * allocated with gst_wfd_message_new().
231 *
232 * Returns: a #GstWFDResult.
233 */
234 GstWFDResult
235 gst_wfd_message_free(GstWFDMessage *msg)
236 {
237   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
238
239   gst_wfd_message_uninit(msg);
240   g_free(msg);
241   msg = NULL;
242
243   return GST_WFD_OK;
244 }
245
246 /**
247 * gst_wfd_message_as_text:
248 * @msg: a #GstWFDMessage
249 *
250 * Convert the contents of @msg to a text string.
251 *
252 * Returns: A dynamically allocated string representing the WFD description.
253 */
254 gchar *
255 gst_wfd_message_as_text(const GstWFDMessage *msg)
256 {
257   /* change all vars so they match rfc? */
258   GString *lines;
259   g_return_val_if_fail(msg != NULL, NULL);
260
261   lines = g_string_new("");
262
263   /* list of audio codecs */
264   if (msg->wfd2_audio_codecs) {
265     guint i = 0;
266     g_string_append_printf(lines, GST_STRING_WFD2_AUDIO_CODECS);
267     if (msg->wfd2_audio_codecs->list) {
268       g_string_append_printf(lines, GST_STRING_WFD_COLON);
269       for (; i < msg->wfd2_audio_codecs->count; i++) {
270         g_string_append_printf(lines, " %s", msg->wfd2_audio_codecs->list[i].audio_format);
271         g_string_append_printf(lines, " %08x", msg->wfd2_audio_codecs->list[i].modes);
272         g_string_append_printf(lines, " %02x", msg->wfd2_audio_codecs->list[i].latency);
273         if ((i + 1) < msg->wfd2_audio_codecs->count)
274           g_string_append_printf(lines, GST_STRING_WFD_COMMA);
275       }
276     } else {
277       g_string_append_printf(lines, GST_STRING_WFD_SPACE);
278       g_string_append_printf(lines, GST_STRING_WFD_NONE);
279     }
280     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
281   }
282   else if (msg->audio_codecs) {
283     guint i = 0;
284     g_string_append_printf(lines, GST_STRING_WFD_AUDIO_CODECS);
285     g_string_append_printf(lines, GST_STRING_WFD_COLON);
286     if (msg->audio_codecs->list) {
287       for (; i < msg->audio_codecs->count; i++) {
288         g_string_append_printf(lines, " %s", msg->audio_codecs->list[i].audio_format);
289         g_string_append_printf(lines, " %08x", msg->audio_codecs->list[i].modes);
290         g_string_append_printf(lines, " %02x", msg->audio_codecs->list[i].latency);
291         if ((i + 1) < msg->audio_codecs->count)
292           g_string_append_printf(lines, GST_STRING_WFD_COMMA);
293       }
294     } else {
295       g_string_append_printf(lines, GST_STRING_WFD_SPACE);
296       g_string_append_printf(lines, GST_STRING_WFD_NONE);
297     }
298     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
299   }
300
301   /* list of video codecs */
302   if (msg->video_formats) {
303     g_string_append_printf(lines, GST_STRING_WFD_VIDEO_FORMATS);
304     g_string_append_printf(lines, GST_STRING_WFD_COLON);
305     if (msg->video_formats->list) {
306       g_string_append_printf(lines, " %02x", msg->video_formats->list->native);
307       g_string_append_printf(lines, " %02x", msg->video_formats->list->preferred_display_mode_supported);
308       g_string_append_printf(lines, " %02x", msg->video_formats->list->H264_codec.profile);
309       g_string_append_printf(lines, " %02x", msg->video_formats->list->H264_codec.level);
310       g_string_append_printf(lines, " %08llx", msg->video_formats->list->H264_codec.misc_params.CEA_Support);
311       g_string_append_printf(lines, " %08llx", msg->video_formats->list->H264_codec.misc_params.VESA_Support);
312       g_string_append_printf(lines, " %08llx", msg->video_formats->list->H264_codec.misc_params.HH_Support);
313       g_string_append_printf(lines, " %02x", msg->video_formats->list->H264_codec.misc_params.latency);
314       g_string_append_printf(lines, " %04x", msg->video_formats->list->H264_codec.misc_params.min_slice_size);
315       g_string_append_printf(lines, " %04x", msg->video_formats->list->H264_codec.misc_params.slice_enc_params);
316       g_string_append_printf(lines, " %02x", msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support);
317
318       if (msg->video_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED
319         && msg->video_formats->list->H264_codec.max_hres) {
320         g_string_append_printf(lines, " %04x", msg->video_formats->list->H264_codec.max_hres);
321       } else {
322         g_string_append_printf(lines, GST_STRING_WFD_SPACE);
323         g_string_append_printf(lines, GST_STRING_WFD_NONE);
324       }
325       if (msg->video_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED
326         && msg->video_formats->list->H264_codec.max_vres) {
327         g_string_append_printf(lines, " %04x", msg->video_formats->list->H264_codec.max_vres);
328       } else {
329         g_string_append_printf(lines, GST_STRING_WFD_SPACE);
330         g_string_append_printf(lines, GST_STRING_WFD_NONE);
331       }
332     } else {
333       g_string_append_printf(lines, GST_STRING_WFD_SPACE);
334       g_string_append_printf(lines, GST_STRING_WFD_NONE);
335     }
336     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
337   }
338
339   /* list of video codecs for direct streaming */
340   if (msg->direct_video_formats) {
341     g_string_append_printf(lines, GST_STRING_WFD2_VIDEO_FORMATS);
342     if (msg->direct_video_formats->list) {
343       g_string_append_printf(lines, GST_STRING_WFD_COLON);
344       g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->native);
345       g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->preferred_display_mode_supported);
346       g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->H264_codec.profile);
347       g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->H264_codec.level);
348       g_string_append_printf(lines, " %08llx", msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support);
349       g_string_append_printf(lines, " %08llx", msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support);
350       g_string_append_printf(lines, " %08llx", msg->direct_video_formats->list->H264_codec.misc_params.HH_Support);
351       g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->H264_codec.misc_params.latency);
352       g_string_append_printf(lines, " %04x", msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size);
353       g_string_append_printf(lines, " %04x", msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params);
354       g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support);
355
356       if (msg->direct_video_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED
357         && msg->direct_video_formats->list->H264_codec.max_hres) {
358         g_string_append_printf(lines, " %04x", msg->direct_video_formats->list->H264_codec.max_hres);
359       } else {
360         g_string_append_printf(lines, GST_STRING_WFD_SPACE);
361         g_string_append_printf(lines, GST_STRING_WFD_NONE);
362       }
363       if (msg->direct_video_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED
364         && msg->direct_video_formats->list->H264_codec.max_vres) {
365         g_string_append_printf(lines, " %04x", msg->direct_video_formats->list->H264_codec.max_vres);
366       } else {
367         g_string_append_printf(lines, GST_STRING_WFD_SPACE);
368         g_string_append_printf(lines, GST_STRING_WFD_NONE);
369       }
370     }
371     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
372   }
373
374   /* list of video 3D codecs */
375   if (msg->video_3d_formats) {
376     g_string_append_printf(lines, GST_STRING_WFD_3D_VIDEO_FORMATS);
377     g_string_append_printf(lines, GST_STRING_WFD_COLON);
378     if (msg->video_3d_formats->list) {
379       g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->native);
380       g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->preferred_display_mode_supported);
381       g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->H264_codec.profile);
382       g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->H264_codec.level);
383       g_string_append_printf(lines, " %016llx", msg->video_3d_formats->list->H264_codec.misc_params.video_3d_capability);
384       g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->H264_codec.misc_params.latency);
385       g_string_append_printf(lines, " %04x", msg->video_3d_formats->list->H264_codec.misc_params.min_slice_size);
386       g_string_append_printf(lines, " %04x", msg->video_3d_formats->list->H264_codec.misc_params.slice_enc_params);
387       g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->H264_codec.misc_params.frame_rate_control_support);
388       if (msg->video_3d_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED
389         && msg->video_3d_formats->list->H264_codec.max_hres) {
390         g_string_append_printf(lines, " %04x", msg->video_3d_formats->list->H264_codec.max_hres);
391       } else {
392         g_string_append_printf(lines, GST_STRING_WFD_SPACE);
393         g_string_append_printf(lines, GST_STRING_WFD_NONE);
394       }
395
396       if (msg->video_3d_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED
397         && msg->video_3d_formats->list->H264_codec.max_vres) {
398         g_string_append_printf(lines, " %04x", msg->video_3d_formats->list->H264_codec.max_vres);
399       } else {
400         g_string_append_printf(lines, GST_STRING_WFD_SPACE);
401         g_string_append_printf(lines, GST_STRING_WFD_NONE);
402       }
403     } else {
404       g_string_append_printf(lines, GST_STRING_WFD_SPACE);
405       g_string_append_printf(lines, GST_STRING_WFD_NONE);
406     }
407     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
408   }
409
410   if (msg->content_protection) {
411     g_string_append_printf(lines, GST_STRING_WFD_CONTENT_PROTECTION);
412     g_string_append_printf(lines, GST_STRING_WFD_COLON);
413     if (msg->content_protection->hdcp2_spec) {
414       if (msg->content_protection->hdcp2_spec->hdcpversion) {
415         g_string_append_printf(lines, " %s", msg->content_protection->hdcp2_spec->hdcpversion);
416         g_string_append_printf(lines, " %s", msg->content_protection->hdcp2_spec->TCPPort);
417       } else {
418         g_string_append_printf(lines, GST_STRING_WFD_SPACE);
419         g_string_append_printf(lines, GST_STRING_WFD_NONE);
420       }
421     } else {
422       g_string_append_printf(lines, GST_STRING_WFD_SPACE);
423       g_string_append_printf(lines, GST_STRING_WFD_NONE);
424     }
425     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
426   }
427
428   if (msg->display_edid) {
429     g_string_append_printf(lines, GST_STRING_WFD_DISPLAY_EDID);
430     g_string_append_printf(lines, GST_STRING_WFD_COLON);
431     if (msg->display_edid->edid_supported) {
432       if (msg->display_edid->edid_block_count > 0 &&
433         msg->display_edid->edid_block_count <= EDID_BLOCK_COUNT_MAX_SIZE) {
434         g_string_append_printf(lines, GST_STRING_WFD_SPACE "%04x", msg->display_edid->edid_block_count);
435         g_string_append_printf(lines, GST_STRING_WFD_SPACE "%s", msg->display_edid->edid_payload);
436
437       } else {
438         g_string_append_printf(lines, GST_STRING_WFD_SPACE);
439         g_string_append_printf(lines, GST_STRING_WFD_NONE);
440       }
441     } else {
442       g_string_append_printf(lines, GST_STRING_WFD_SPACE);
443       g_string_append_printf(lines, GST_STRING_WFD_NONE);
444     }
445     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
446   }
447
448   if (msg->coupled_sink) {
449     g_string_append_printf(lines, GST_STRING_WFD_COUPLED_SINK);
450     g_string_append_printf(lines, GST_STRING_WFD_COLON);
451     if (msg->coupled_sink->coupled_sink_cap) {
452       g_string_append_printf(lines, " %02x", msg->coupled_sink->coupled_sink_cap->status);
453       if (msg->coupled_sink->coupled_sink_cap->sink_address) {
454         g_string_append_printf(lines, " %s", msg->coupled_sink->coupled_sink_cap->sink_address);
455       } else {
456         g_string_append_printf(lines, GST_STRING_WFD_SPACE);
457         g_string_append_printf(lines, GST_STRING_WFD_NONE);
458       }
459     } else {
460       g_string_append_printf(lines, GST_STRING_WFD_SPACE);
461       g_string_append_printf(lines, GST_STRING_WFD_NONE);
462     }
463     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
464   }
465
466   if (msg->trigger_method) {
467     g_string_append_printf(lines, GST_STRING_WFD_TRIGGER_METHOD);
468     g_string_append_printf(lines, GST_STRING_WFD_COLON);
469     g_string_append_printf(lines, " %s", msg->trigger_method->wfd_trigger_method);
470     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
471   }
472
473   if (msg->presentation_url) {
474     g_string_append_printf(lines, GST_STRING_WFD_PRESENTATION_URL);
475     g_string_append_printf(lines, GST_STRING_WFD_COLON);
476     if (msg->presentation_url->wfd_url0) {
477       g_string_append_printf(lines, " %s", msg->presentation_url->wfd_url0);
478     } else {
479       g_string_append_printf(lines, GST_STRING_WFD_SPACE);
480       g_string_append_printf(lines, GST_STRING_WFD_NONE);
481     }
482     if (msg->presentation_url->wfd_url1) {
483       g_string_append_printf(lines, " %s", msg->presentation_url->wfd_url1);
484     } else {
485       g_string_append_printf(lines, GST_STRING_WFD_SPACE);
486       g_string_append_printf(lines, GST_STRING_WFD_NONE);
487     }
488     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
489   }
490
491   if (msg->client_rtp_ports) {
492     g_string_append_printf(lines, GST_STRING_WFD_CLIENT_RTP_PORTS);
493     if (msg->client_rtp_ports->profile) {
494       g_string_append_printf(lines, GST_STRING_WFD_COLON);
495       g_string_append_printf(lines, " %s", msg->client_rtp_ports->profile);
496       g_string_append_printf(lines, " %d", msg->client_rtp_ports->rtp_port0);
497       g_string_append_printf(lines, " %d", msg->client_rtp_ports->rtp_port1);
498       g_string_append_printf(lines, " %s", msg->client_rtp_ports->mode);
499     }
500     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
501   }
502
503   if (msg->route) {
504     g_string_append_printf(lines, GST_STRING_WFD_ROUTE);
505     g_string_append_printf(lines, GST_STRING_WFD_COLON);
506     g_string_append_printf(lines, " %s", msg->route->destination);
507     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
508   }
509
510   if (msg->I2C) {
511     g_string_append_printf(lines, GST_STRING_WFD_I2C);
512     g_string_append_printf(lines, GST_STRING_WFD_COLON);
513     g_string_append_printf(lines, GST_STRING_WFD_SPACE);
514     if (msg->I2C->I2CPresent) {
515       g_string_append_printf(lines, "%x", msg->I2C->I2C_port);
516     } else {
517       g_string_append_printf(lines, GST_STRING_WFD_NONE);
518     }
519     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
520   }
521
522   if (msg->av_format_change_timing) {
523     g_string_append_printf(lines, GST_STRING_WFD_AV_FORMAT_CHANGE_TIMING);
524     g_string_append_printf(lines, GST_STRING_WFD_COLON);
525     g_string_append_printf(lines, " %010llx", msg->av_format_change_timing->PTS);
526     g_string_append_printf(lines, " %010llx", msg->av_format_change_timing->DTS);
527     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
528   }
529
530   if (msg->preferred_display_mode) {
531     g_string_append_printf(lines, GST_STRING_WFD_PREFERRED_DISPLAY_MODE);
532     g_string_append_printf(lines, GST_STRING_WFD_COLON);
533     if (msg->preferred_display_mode->displaymodesupported) {
534       g_string_append_printf(lines, " %06llx", msg->preferred_display_mode->p_clock);
535       g_string_append_printf(lines, " %04x", msg->preferred_display_mode->H);
536       g_string_append_printf(lines, " %04x", msg->preferred_display_mode->HB);
537       g_string_append_printf(lines, " %04x", msg->preferred_display_mode->HSPOL_HSOFF);
538       g_string_append_printf(lines, " %04x", msg->preferred_display_mode->HSW);
539       g_string_append_printf(lines, " %04x", msg->preferred_display_mode->V);
540       g_string_append_printf(lines, " %04x", msg->preferred_display_mode->VB);
541       g_string_append_printf(lines, " %04x", msg->preferred_display_mode->VSPOL_VSOFF);
542       g_string_append_printf(lines, " %04x", msg->preferred_display_mode->VSW);
543       g_string_append_printf(lines, " %02x", msg->preferred_display_mode->VBS3D);
544       g_string_append_printf(lines, " %02x", msg->preferred_display_mode->V2d_s3d_modes);
545       g_string_append_printf(lines, " %02x", msg->preferred_display_mode->P_depth);
546     } else {
547       g_string_append_printf(lines, GST_STRING_WFD_SPACE);
548       g_string_append_printf(lines, GST_STRING_WFD_NONE);
549     }
550     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
551   }
552
553   if (msg->standby_resume_capability) {
554     g_string_append_printf(lines, GST_STRING_WFD_STANDBY_RESUME_CAPABILITY);
555     g_string_append_printf(lines, GST_STRING_WFD_COLON);
556     g_string_append_printf(lines, GST_STRING_WFD_SPACE);
557     if (msg->standby_resume_capability->standby_resume_cap)
558       g_string_append_printf(lines, GST_STRING_WFD_SUPPORTED);
559     else
560       g_string_append_printf(lines, GST_STRING_WFD_NONE);
561     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
562   }
563
564   if (msg->standby) {
565     g_string_append_printf(lines, GST_STRING_WFD_STANDBY);
566     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
567   }
568
569   if (msg->connector_type) {
570     g_string_append_printf(lines, GST_STRING_WFD_CONNECTOR_TYPE);
571     g_string_append_printf(lines, GST_STRING_WFD_COLON);
572     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
573   }
574
575   if (msg->idr_request) {
576     g_string_append_printf(lines, GST_STRING_WFD_IDR_REQUEST);
577     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
578   }
579
580   if (msg->direct_mode && msg->direct_mode->direct_mode) {
581     g_string_append_printf(lines, GST_STRING_WFD2_DIRECT_STREAMING_MODE);
582     g_string_append_printf(lines, GST_STRING_WFD_COLON);
583     g_string_append_printf(lines, GST_STRING_WFD_SPACE);
584     g_string_append_printf(lines, GST_STRING_WFD_ACTIVE);
585     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
586   }
587
588   if (msg->tcp_ports) {
589     g_string_append_printf(lines, GST_STRING_WFD2_TRANSPORT_SWITCH);
590     if (msg->tcp_ports->profile) {
591       g_string_append_printf(lines, GST_STRING_WFD_COLON);
592       g_string_append_printf(lines, " %s", msg->tcp_ports->profile);
593       g_string_append_printf(lines, " %d", msg->tcp_ports->rtp_port0);
594       g_string_append_printf(lines, " %d", msg->tcp_ports->rtp_port1);
595       g_string_append_printf(lines, " %s", msg->tcp_ports->mode);
596     }
597     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
598   }
599
600   if (msg->buf_len) {
601     g_string_append_printf(lines, GST_STRING_WFD2_BUFFER_LEN);
602     g_string_append_printf(lines, GST_STRING_WFD_COLON);
603     g_string_append_printf(lines, " %d", msg->buf_len->buf_len);
604     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
605   }
606
607   if (msg->audio_status) {
608     g_string_append_printf(lines, GST_STRING_WFD2_AUDIO_STATUS);
609     g_string_append_printf(lines, GST_STRING_WFD_COLON);
610     g_string_append_printf(lines, " %d", msg->audio_status->aud_bufsize);
611     g_string_append_printf(lines, " %lld", msg->audio_status->aud_pts);
612     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
613   }
614
615   if (msg->video_status) {
616     g_string_append_printf(lines, GST_STRING_WFD2_VIDEO_STATUS);
617     g_string_append_printf(lines, GST_STRING_WFD_COLON);
618     g_string_append_printf(lines, " %d", msg->video_status->vid_bufsize);
619     g_string_append_printf(lines, " %lld", msg->video_status->vid_pts);
620     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
621   }
622
623   /*g_string_append_printf (lines, "\0"); */
624   /*if(g_str_has_suffix (lines, "\r\n\0"))
625   {
626   guint32 length = g_strlen(lines);
627   lines[length-2] = '\0';
628   }*/
629   return g_string_free(lines, FALSE);
630 }
631
632 gchar *gst_wfd_message_param_names_as_text(const GstWFDMessage *msg)
633 {
634   /* change all vars so they match rfc? */
635   GString *lines;
636   g_return_val_if_fail(msg != NULL, NULL);
637
638   lines = g_string_new("");
639
640   /* list of audio codecs */
641   if (msg->audio_codecs) {
642     g_string_append_printf(lines, GST_STRING_WFD_AUDIO_CODECS);
643     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
644   }
645   /* list of video codecs */
646   if (msg->video_formats) {
647     g_string_append_printf(lines, GST_STRING_WFD_VIDEO_FORMATS);
648     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
649   }
650   /* list of audio codecs for R2 */
651   if (msg->wfd2_audio_codecs) {
652     g_string_append_printf(lines, GST_STRING_WFD2_AUDIO_CODECS);
653     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
654   }
655   /* list of video codecs  for direct streaming*/
656   if (msg->direct_video_formats) {
657     g_string_append_printf(lines, GST_STRING_WFD2_VIDEO_FORMATS);
658     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
659   }
660   /* list of video 3D codecs */
661   if (msg->video_3d_formats) {
662     g_string_append_printf(lines, GST_STRING_WFD_3D_VIDEO_FORMATS);
663     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
664   }
665   if (msg->content_protection) {
666     g_string_append_printf(lines, GST_STRING_WFD_CONTENT_PROTECTION);
667     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
668   }
669   if (msg->display_edid) {
670     g_string_append_printf(lines, GST_STRING_WFD_DISPLAY_EDID);
671     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
672   }
673   if (msg->coupled_sink) {
674     g_string_append_printf(lines, GST_STRING_WFD_COUPLED_SINK);
675     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
676   }
677   if (msg->trigger_method) {
678     g_string_append_printf(lines, GST_STRING_WFD_TRIGGER_METHOD);
679     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
680   }
681   if (msg->presentation_url) {
682     g_string_append_printf(lines, GST_STRING_WFD_PRESENTATION_URL);
683     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
684   }
685   if (msg->client_rtp_ports) {
686     g_string_append_printf(lines, GST_STRING_WFD_CLIENT_RTP_PORTS);
687     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
688   }
689   if (msg->route) {
690     g_string_append_printf(lines, GST_STRING_WFD_ROUTE);
691     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
692   }
693   if (msg->I2C) {
694     g_string_append_printf(lines, GST_STRING_WFD_I2C);
695     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
696   }
697   if (msg->av_format_change_timing) {
698     g_string_append_printf(lines, GST_STRING_WFD_AV_FORMAT_CHANGE_TIMING);
699     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
700   }
701   if (msg->preferred_display_mode) {
702     g_string_append_printf(lines, GST_STRING_WFD_PREFERRED_DISPLAY_MODE);
703     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
704   }
705   if (msg->standby_resume_capability) {
706     g_string_append_printf(lines, GST_STRING_WFD_STANDBY_RESUME_CAPABILITY);
707     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
708   }
709   if (msg->standby) {
710     g_string_append_printf(lines, GST_STRING_WFD_STANDBY);
711     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
712   }
713   if (msg->connector_type) {
714     g_string_append_printf(lines, GST_STRING_WFD_CONNECTOR_TYPE);
715     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
716   }
717   if (msg->idr_request) {
718     g_string_append_printf(lines, GST_STRING_WFD_IDR_REQUEST);
719     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
720   }
721   if (msg->direct_mode) {
722     g_string_append_printf(lines, GST_STRING_WFD2_DIRECT_STREAMING_MODE);
723     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
724   }
725   if (msg->tcp_ports) {
726     g_string_append_printf(lines, GST_STRING_WFD2_TRANSPORT_SWITCH);
727     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
728   }
729   if (msg->buf_len) {
730     g_string_append_printf(lines, GST_STRING_WFD2_BUFFER_LEN);
731     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
732   }
733   if (msg->audio_status) {
734     g_string_append_printf(lines, GST_STRING_WFD2_AUDIO_STATUS);
735     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
736   }
737   if (msg->video_status) {
738     g_string_append_printf(lines, GST_STRING_WFD2_VIDEO_STATUS);
739     g_string_append_printf(lines, GST_STRING_WFD_CRLF);
740   }
741   return g_string_free(lines, FALSE);
742 }
743
744 static void
745 read_string_space_ended(gchar *dest, guint size, gchar *src)
746 {
747   guint idx = 0;
748
749   while (!g_ascii_isspace(*src) && *src != '\0') {
750     if (idx < size - 1)
751       dest[idx++] = *src;
752     src++;
753   }
754
755   if (size > 0)
756     dest[idx] = '\0';
757 }
758
759 static void
760 read_string_type_and_value(gchar *type, gchar *value, guint tsize, guint vsize, gchar del, gchar *src)
761 {
762   guint idx;
763
764   idx = 0;
765   while (*src != del && *src != '\0') {
766     if (idx < tsize - 1)
767       type[idx++] = *src;
768     src++;
769   }
770
771   if (tsize > 0)
772     type[idx] = '\0';
773
774   src++;
775   idx = 0;
776   while (*src != '\0') {
777     if (idx < vsize - 1)
778       value[idx++] = *src;
779     src++;
780   }
781   if (vsize > 0)
782     value[idx] = '\0';
783 }
784
785 static gboolean
786 gst_wfd_parse_line(GstWFDMessage *msg, gchar *buffer)
787 {
788   gchar type[8192] = {0};
789   gchar value[8192] = {0};
790   gchar temp[8192] = {0};
791   gchar *p = buffer;
792   gchar *v = value;
793
794 #define GST_WFD_SKIP_SPACE(q) if (*q && g_ascii_isspace(*q)) q++;
795 #define GST_WFD_SKIP_EQUAL(q) if (*q && *q == '=') q++;
796 #define GST_WFD_SKIP_COMMA(q) if (*q && g_ascii_ispunct(*q)) q++;
797 #define GST_WFD_READ_STRING(field) read_string_space_ended(temp, sizeof(temp), v); v += strlen(temp); REPLACE_STRING(field, temp);
798 #define GST_WFD_READ_UINT32(field) read_string_space_ended(temp, sizeof(temp), v); v += strlen(temp); field = strtoul(temp, NULL, 16);
799 #define GST_WFD_READ_UINT32_DIGIT(field) read_string_space_ended(temp, sizeof(temp), v); v += strlen(temp); field = strtoul(temp, NULL, 10);
800
801   /*g_print("gst_wfd_parse_line input: %s\n", buffer); */
802   read_string_type_and_value(type, value, sizeof(type), sizeof(value), ':', p);
803   /*g_print("gst_wfd_parse_line type:%s value:%s\n", type, value); */
804
805   if (!g_strcmp0(type, GST_STRING_WFD_AUDIO_CODECS)) {
806     msg->audio_codecs = g_new0(GstWFDAudioCodeclist, 1);
807     if (strlen(v)) {
808       if (!strcmp(v, GST_STRING_WFD_NONE)) {
809         msg->audio_codecs->list = NULL;
810         msg->audio_codecs->count = 0;
811       } else {
812         guint i = 0;
813         msg->audio_codecs->count = strlen(v) / 16;
814         msg->audio_codecs->list = g_new0(GstWFDAudioCodec, msg->audio_codecs->count);
815         for (; i < msg->audio_codecs->count; i++) {
816           GST_WFD_SKIP_SPACE(v);
817           GST_WFD_READ_STRING(msg->audio_codecs->list[i].audio_format);
818           GST_WFD_SKIP_SPACE(v);
819           GST_WFD_READ_UINT32(msg->audio_codecs->list[i].modes);
820           GST_WFD_SKIP_SPACE(v);
821           GST_WFD_READ_UINT32(msg->audio_codecs->list[i].latency);
822           GST_WFD_SKIP_COMMA(v);
823         }
824       }
825     }
826   } else if (!g_strcmp0(type, GST_STRING_WFD_VIDEO_FORMATS)) {
827     msg->video_formats = g_new0(GstWFDVideoCodeclist, 1);
828     if (strlen(v)) {
829       GST_WFD_SKIP_SPACE(v);
830       if (!strcmp(v, GST_STRING_WFD_NONE)) {
831         msg->video_formats->count = 0 ;
832         msg->video_formats->list = NULL;
833       } else {
834         msg->video_formats->count = 1;
835         msg->video_formats->list = g_new0(GstWFDVideoCodec, 1);
836         GST_WFD_SKIP_SPACE(v);
837         GST_WFD_READ_UINT32(msg->video_formats->list->native);
838         GST_WFD_SKIP_SPACE(v);
839         GST_WFD_READ_UINT32(msg->video_formats->list->preferred_display_mode_supported);
840         GST_WFD_SKIP_SPACE(v);
841         GST_WFD_READ_UINT32(msg->video_formats->list->H264_codec.profile);
842         GST_WFD_SKIP_SPACE(v);
843         GST_WFD_READ_UINT32(msg->video_formats->list->H264_codec.level);
844         GST_WFD_SKIP_SPACE(v);
845         GST_WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.CEA_Support);
846         GST_WFD_SKIP_SPACE(v);
847         GST_WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.VESA_Support);
848         GST_WFD_SKIP_SPACE(v);
849         GST_WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.HH_Support);
850         GST_WFD_SKIP_SPACE(v);
851         GST_WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.latency);
852         GST_WFD_SKIP_SPACE(v);
853         GST_WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.min_slice_size);
854         GST_WFD_SKIP_SPACE(v);
855         GST_WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.slice_enc_params);
856         GST_WFD_SKIP_SPACE(v);
857         GST_WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support);
858         GST_WFD_SKIP_SPACE(v);
859         if (msg->video_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED) {
860           GST_WFD_READ_UINT32(msg->video_formats->list->H264_codec.max_hres);
861           GST_WFD_SKIP_SPACE(v);
862           GST_WFD_READ_UINT32(msg->video_formats->list->H264_codec.max_vres);
863           GST_WFD_SKIP_SPACE(v);
864         }
865       }
866     }
867   } else if (!g_strcmp0(type, GST_STRING_WFD2_AUDIO_CODECS)) {
868     msg->wfd2_audio_codecs = g_new0(GstWFD2AudioCodeclist, 1);
869     if (strlen(v)) {
870       guint i = 0;
871       msg->wfd2_audio_codecs->count = strlen(v) / 16;
872       msg->wfd2_audio_codecs->list = g_new0(GstWFDAudioCodec, msg->wfd2_audio_codecs->count);
873       for (; i < msg->wfd2_audio_codecs->count; i++) {
874         GST_WFD_SKIP_SPACE(v);
875         GST_WFD_READ_STRING(msg->wfd2_audio_codecs->list[i].audio_format);
876         GST_WFD_SKIP_SPACE(v);
877         GST_WFD_READ_UINT32(msg->wfd2_audio_codecs->list[i].modes);
878         GST_WFD_SKIP_SPACE(v);
879         GST_WFD_READ_UINT32(msg->wfd2_audio_codecs->list[i].latency);
880         GST_WFD_SKIP_COMMA(v);
881       }
882     }
883   } else if (!g_strcmp0(type, GST_STRING_WFD2_VIDEO_FORMATS)) {
884     msg->direct_video_formats = g_new0(GstWFD2VideoCodeclist, 1);
885     if (strlen(v)) {
886       msg->direct_video_formats->count = 1;
887       msg->direct_video_formats->list = g_new0(GstWFDVideoCodec, 1);
888       GST_WFD_SKIP_SPACE(v);
889       GST_WFD_READ_UINT32(msg->direct_video_formats->list->native);
890       GST_WFD_SKIP_SPACE(v);
891       GST_WFD_READ_UINT32(msg->direct_video_formats->list->preferred_display_mode_supported);
892       GST_WFD_SKIP_SPACE(v);
893       GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.profile);
894       GST_WFD_SKIP_SPACE(v);
895       GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.level);
896       GST_WFD_SKIP_SPACE(v);
897       GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support);
898       GST_WFD_SKIP_SPACE(v);
899       GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support);
900       GST_WFD_SKIP_SPACE(v);
901       GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.HH_Support);
902       GST_WFD_SKIP_SPACE(v);
903       GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.latency);
904       GST_WFD_SKIP_SPACE(v);
905       GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size);
906       GST_WFD_SKIP_SPACE(v);
907       GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params);
908       GST_WFD_SKIP_SPACE(v);
909       GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support);
910       GST_WFD_SKIP_SPACE(v);
911       if (msg->direct_video_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED) {
912         GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.max_hres);
913         GST_WFD_SKIP_SPACE(v);
914         GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.max_vres);
915         GST_WFD_SKIP_SPACE(v);
916       }
917     }
918   } else if (!g_strcmp0(type, GST_STRING_WFD_3D_VIDEO_FORMATS)) {
919     msg->video_3d_formats = g_new0(GstWFD3DFormats, 1);
920     if (strlen(v)) {
921       msg->video_3d_formats->count = 1;
922       msg->video_3d_formats->list = g_new0(GstWFD3dCapList, 1);
923       GST_WFD_SKIP_SPACE(v);
924       GST_WFD_READ_UINT32(msg->video_3d_formats->list->native);
925       GST_WFD_SKIP_SPACE(v);
926       GST_WFD_READ_UINT32(msg->video_3d_formats->list->preferred_display_mode_supported);
927       GST_WFD_SKIP_SPACE(v);
928       GST_WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.profile);
929       GST_WFD_SKIP_SPACE(v);
930       GST_WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.level);
931       GST_WFD_SKIP_SPACE(v);
932       GST_WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.misc_params.video_3d_capability);
933       GST_WFD_SKIP_SPACE(v);
934       GST_WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.misc_params.latency);
935       GST_WFD_SKIP_SPACE(v);
936       GST_WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.misc_params.min_slice_size);
937       GST_WFD_SKIP_SPACE(v);
938       GST_WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.misc_params.slice_enc_params);
939       GST_WFD_SKIP_SPACE(v);
940       GST_WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.misc_params.frame_rate_control_support);
941       GST_WFD_SKIP_SPACE(v);
942       if (msg->video_3d_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED) {
943         GST_WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.max_hres);
944         GST_WFD_SKIP_SPACE(v);
945         GST_WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.max_vres);
946         GST_WFD_SKIP_SPACE(v);
947       }
948     }
949   } else if (!g_strcmp0(type, GST_STRING_WFD_CONTENT_PROTECTION)) {
950     msg->content_protection = g_new0(GstWFDContentProtection, 1);
951     if (strlen(v)) {
952       GST_WFD_SKIP_SPACE(v);
953       msg->content_protection->hdcp2_spec = g_new0(GstWFDHdcp2Spec, 1);
954       if (strstr(v, GST_STRING_WFD_NONE)) {
955         msg->content_protection->hdcp2_spec->hdcpversion = g_strdup(GST_STRING_WFD_NONE);
956       } else {
957         GST_WFD_READ_STRING(msg->content_protection->hdcp2_spec->hdcpversion);
958         GST_WFD_SKIP_SPACE(v);
959         GST_WFD_READ_STRING(msg->content_protection->hdcp2_spec->TCPPort);
960       }
961     }
962   } else if (!g_strcmp0(type, GST_STRING_WFD_DISPLAY_EDID)) {
963     msg->display_edid = g_new0(GstWFDDisplayEdid, 1);
964     if (strlen(v)) {
965       GST_WFD_SKIP_SPACE(v);
966       if (strstr(v, GST_STRING_WFD_NONE)) {
967         msg->display_edid->edid_supported = 0;
968       } else {
969         msg->display_edid->edid_supported = 1;
970         GST_WFD_READ_UINT32(msg->display_edid->edid_block_count);
971         GST_WFD_SKIP_SPACE(v);
972         if (msg->display_edid->edid_block_count) {
973           gchar *edid_string = v;
974           guint32 i = 0, j = 0, msg_size = 0;
975           guint32 payload_size = EDID_BLOCK_SIZE * msg->display_edid->edid_block_count;
976           msg->display_edid->edid_payload = g_malloc(payload_size);
977           msg_size = payload_size * 2;
978           for (; i < msg_size; j++) {
979             int k = 0, kk = 0;
980             if (edid_string[i] > 0x29 && edid_string[i] < 0x40) k = edid_string[i] - 48;
981             else if (edid_string[i] > 0x60 && edid_string[i] < 0x67) k = edid_string[i] - 87;
982             else if (edid_string[i] > 0x40 && edid_string[i] < 0x47) k = edid_string[i] - 55;
983
984             if (edid_string[i + 1] > 0x29 && edid_string[i + 1] < 0x40) kk = edid_string[i + 1] - 48;
985             else if (edid_string[i + 1] > 0x60 && edid_string[i + 1] < 0x67) kk = edid_string[i + 1] - 87;
986             else if (edid_string[i + 1] > 0x40 && edid_string[i + 1] < 0x47) kk = edid_string[i + 1] - 55;
987
988             msg->display_edid->edid_payload[j] = (k << 4) | kk;
989             i += 2;
990           }
991           /*memcpy(msg->display_edid->edid_payload, v, payload_size); */
992           v += msg_size;
993         } else v += strlen(v);
994       }
995     }
996   } else if (!g_strcmp0(type, GST_STRING_WFD_COUPLED_SINK)) {
997     msg->coupled_sink = g_new0(GstWFDCoupledSink, 1);
998     if (strlen(v)) {
999       msg->coupled_sink->coupled_sink_cap = g_new0(GstWFDCoupledSinkCap, 1);
1000       GST_WFD_SKIP_SPACE(v);
1001       GST_WFD_READ_UINT32(msg->coupled_sink->coupled_sink_cap->status);
1002       GST_WFD_SKIP_SPACE(v);
1003       GST_WFD_READ_STRING(msg->coupled_sink->coupled_sink_cap->sink_address);
1004     }
1005   } else if (!g_strcmp0(type, GST_STRING_WFD_TRIGGER_METHOD)) {
1006     msg->trigger_method = g_new0(GstWFDTriggerMethod, 1);
1007     if (strlen(v)) {
1008       GST_WFD_SKIP_SPACE(v);
1009       GST_WFD_READ_STRING(msg->trigger_method->wfd_trigger_method);
1010     }
1011   } else if (!g_strcmp0(type, GST_STRING_WFD_PRESENTATION_URL)) {
1012     msg->presentation_url = g_new0(GstWFDPresentationUrl, 1);
1013     if (strlen(v)) {
1014       GST_WFD_SKIP_SPACE(v);
1015       GST_WFD_READ_STRING(msg->presentation_url->wfd_url0);
1016       GST_WFD_SKIP_SPACE(v);
1017       GST_WFD_READ_STRING(msg->presentation_url->wfd_url1);
1018     }
1019   } else if (!g_strcmp0(type, GST_STRING_WFD_CLIENT_RTP_PORTS)) {
1020     msg->client_rtp_ports = g_new0(GstWFDClientRtpPorts, 1);
1021     if (strlen(v)) {
1022       GST_WFD_SKIP_SPACE(v);
1023       GST_WFD_READ_STRING(msg->client_rtp_ports->profile);
1024       GST_WFD_SKIP_SPACE(v);
1025       GST_WFD_READ_UINT32_DIGIT(msg->client_rtp_ports->rtp_port0);
1026       GST_WFD_SKIP_SPACE(v);
1027       GST_WFD_READ_UINT32_DIGIT(msg->client_rtp_ports->rtp_port1);
1028       GST_WFD_SKIP_SPACE(v);
1029       GST_WFD_READ_STRING(msg->client_rtp_ports->mode);
1030     }
1031   } else if (!g_strcmp0(type, GST_STRING_WFD_ROUTE)) {
1032     msg->route = g_new0(GstWFDRoute, 1);
1033     if (strlen(v)) {
1034       GST_WFD_SKIP_SPACE(v);
1035       GST_WFD_READ_STRING(msg->route->destination);
1036     }
1037   } else if (!g_strcmp0(type, GST_STRING_WFD_I2C)) {
1038     msg->I2C = g_new0(GstWFDI2C, 1);
1039     if (strlen(v)) {
1040       msg->I2C->I2CPresent = TRUE;
1041       GST_WFD_SKIP_SPACE(v);
1042       GST_WFD_READ_UINT32_DIGIT(msg->I2C->I2C_port);
1043       if (msg->I2C->I2C_port) msg->I2C->I2CPresent = TRUE;
1044     }
1045   } else if (!g_strcmp0(type, GST_STRING_WFD_AV_FORMAT_CHANGE_TIMING)) {
1046     msg->av_format_change_timing = g_new0(GstWFDAVFormatChangeTiming, 1);
1047     if (strlen(v)) {
1048       GST_WFD_SKIP_SPACE(v);
1049       GST_WFD_READ_UINT32(msg->av_format_change_timing->PTS);
1050       GST_WFD_SKIP_SPACE(v);
1051       GST_WFD_READ_UINT32(msg->av_format_change_timing->DTS);
1052     }
1053   } else if (!g_strcmp0(type, GST_STRING_WFD_PREFERRED_DISPLAY_MODE)) {
1054     msg->preferred_display_mode = g_new0(GstWFDPreferredDisplayMode, 1);
1055     if (strlen(v)) {
1056       GST_WFD_SKIP_SPACE(v);
1057       if (!strstr(v, GST_STRING_WFD_NONE)) {
1058         msg->preferred_display_mode->displaymodesupported = FALSE;
1059       } else {
1060         GST_WFD_READ_UINT32(msg->preferred_display_mode->p_clock);
1061         GST_WFD_SKIP_SPACE(v);
1062         GST_WFD_READ_UINT32(msg->preferred_display_mode->H);
1063         GST_WFD_SKIP_SPACE(v);
1064         GST_WFD_READ_UINT32(msg->preferred_display_mode->HB);
1065         GST_WFD_SKIP_SPACE(v);
1066         GST_WFD_READ_UINT32(msg->preferred_display_mode->HSPOL_HSOFF);
1067         GST_WFD_SKIP_SPACE(v);
1068         GST_WFD_READ_UINT32(msg->preferred_display_mode->HSW);
1069         GST_WFD_SKIP_SPACE(v);
1070         GST_WFD_READ_UINT32(msg->preferred_display_mode->V);
1071         GST_WFD_SKIP_SPACE(v);
1072         GST_WFD_READ_UINT32(msg->preferred_display_mode->VB);
1073         GST_WFD_SKIP_SPACE(v);
1074         GST_WFD_READ_UINT32(msg->preferred_display_mode->VSPOL_VSOFF);
1075         GST_WFD_SKIP_SPACE(v);
1076         GST_WFD_READ_UINT32(msg->preferred_display_mode->VSW);
1077         GST_WFD_SKIP_SPACE(v);
1078         GST_WFD_READ_UINT32(msg->preferred_display_mode->VBS3D);
1079         GST_WFD_SKIP_SPACE(v);
1080         GST_WFD_READ_UINT32(msg->preferred_display_mode->V2d_s3d_modes);
1081         GST_WFD_SKIP_SPACE(v);
1082         GST_WFD_READ_UINT32(msg->preferred_display_mode->P_depth);
1083         GST_WFD_SKIP_SPACE(v);
1084         GST_WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.profile);
1085         GST_WFD_SKIP_SPACE(v);
1086         GST_WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.level);
1087         GST_WFD_SKIP_SPACE(v);
1088         GST_WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.CEA_Support);
1089         GST_WFD_SKIP_SPACE(v);
1090         GST_WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.VESA_Support);
1091         GST_WFD_SKIP_SPACE(v);
1092         GST_WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.HH_Support);
1093         GST_WFD_SKIP_SPACE(v);
1094         GST_WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.latency);
1095         GST_WFD_SKIP_SPACE(v);
1096         GST_WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.min_slice_size);
1097         GST_WFD_SKIP_SPACE(v);
1098         GST_WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.slice_enc_params);
1099         GST_WFD_SKIP_SPACE(v);
1100         GST_WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.frame_rate_control_support);
1101         GST_WFD_SKIP_SPACE(v);
1102         GST_WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.max_hres);
1103         GST_WFD_SKIP_SPACE(v);
1104         GST_WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.max_vres);
1105         GST_WFD_SKIP_SPACE(v);
1106       }
1107     }
1108   } else if (!g_strcmp0(type, GST_STRING_WFD_STANDBY_RESUME_CAPABILITY)) {
1109     msg->standby_resume_capability = g_new0(GstWFDStandbyResumeCapability, 1);
1110     if (strlen(v)) {
1111       GST_WFD_SKIP_SPACE(v);
1112       if (!g_strcmp0(v, GST_STRING_WFD_SUPPORTED))
1113         msg->standby_resume_capability->standby_resume_cap = TRUE;
1114       else
1115         msg->standby_resume_capability->standby_resume_cap = FALSE;
1116     }
1117   } else if (!g_strcmp0(type, GST_STRING_WFD_STANDBY)) {
1118     msg->standby = g_new0(GstWFDStandby, 1);
1119     msg->standby->wfd_standby = TRUE;
1120   } else if (!g_strcmp0(type, GST_STRING_WFD_CONNECTOR_TYPE)) {
1121     msg->connector_type = g_new0(GstWFDConnectorType, 1);
1122     if (strlen(v)) {
1123       msg->connector_type->supported = TRUE;
1124       GST_WFD_SKIP_SPACE(v);
1125       GST_WFD_READ_UINT32(msg->connector_type->connector_type);
1126     }
1127   } else if (!g_strcmp0(type, GST_STRING_WFD_IDR_REQUEST)) {
1128     msg->idr_request = g_new0(GstWFDIdrRequest, 1);
1129     msg->idr_request->idr_request = TRUE;
1130   } else if (!g_strcmp0(type, GST_STRING_WFD2_DIRECT_STREAMING_MODE)) {
1131     msg->direct_mode = g_new0(GstWFD2DirectStreamingMode, 1);
1132     if (strlen(v)) {
1133       GST_WFD_SKIP_SPACE(v);
1134       if (!g_strcmp0(v, GST_STRING_WFD_ACTIVE))
1135         msg->direct_mode->direct_mode = TRUE;
1136       else
1137         msg->direct_mode->direct_mode = FALSE;
1138     }
1139   } else if (!g_strcmp0(type, GST_STRING_WFD2_TRANSPORT_SWITCH)) {
1140     msg->tcp_ports = g_new0(GstWFDTCPPorts, 1);
1141     if (strlen(v)) {
1142       GST_WFD_SKIP_SPACE(v);
1143       GST_WFD_READ_STRING(msg->tcp_ports->profile);
1144       GST_WFD_SKIP_SPACE(v);
1145       GST_WFD_READ_UINT32_DIGIT(msg->tcp_ports->rtp_port0);
1146       GST_WFD_SKIP_SPACE(v);
1147       GST_WFD_READ_UINT32_DIGIT(msg->tcp_ports->rtp_port1);
1148       GST_WFD_SKIP_SPACE(v);
1149       GST_WFD_READ_STRING(msg->tcp_ports->mode);
1150     }
1151   } else if (!g_strcmp0(type, GST_STRING_WFD2_BUFFER_LEN)) {
1152     msg->buf_len = g_new0(GstWFDBufferLen, 1);
1153     if (strlen(v)) {
1154       GST_WFD_SKIP_SPACE(v);
1155       GST_WFD_READ_UINT32_DIGIT(msg->buf_len->buf_len);
1156     }
1157   }
1158
1159   return TRUE;
1160 }
1161
1162 /**
1163 * gst_wfd_message_parse_buffer:
1164 * @data: the start of the buffer
1165 * @size: the size of the buffer
1166 * @msg: the result #GstWFDMessage
1167 *
1168 * Parse the contents of @size bytes pointed to by @data and store the result in
1169 * @msg.
1170 *
1171 * Returns: #GST_WFD_OK on success.
1172 */
1173 GstWFDResult
1174 gst_wfd_message_parse_buffer(const guint8 *data, guint size, GstWFDMessage *msg)
1175 {
1176   const gchar *p;
1177   gchar buffer[MAX_LINE_LEN] = {0};
1178   guint idx = 0;
1179
1180   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1181   g_return_val_if_fail(data != NULL, GST_WFD_EINVAL);
1182   g_return_val_if_fail(size != 0, GST_WFD_EINVAL);
1183
1184   p = (const gchar *) data;
1185   while (TRUE) {
1186
1187     if (*p == '\0')
1188       break;
1189
1190     idx = 0;
1191     while (*p != '\n' && *p != '\r' && *p != '\0') {
1192       if (idx < sizeof(buffer) - 1)
1193         buffer[idx++] = *p;
1194       p++;
1195     }
1196     buffer[idx] = '\0';
1197     gst_wfd_parse_line(msg, buffer);
1198
1199     if (*p == '\0')
1200       break;
1201     p += 2;
1202   }
1203
1204   return GST_WFD_OK;
1205 }
1206
1207 /**
1208 * gst_wfd_message_dump:
1209 * @msg: a #GstWFDMessage
1210 *
1211 * Dump the parsed contents of @msg to stdout.
1212 *
1213 * Returns: a #GstWFDResult.
1214 */
1215 GstWFDResult
1216 gst_wfd_message_dump(const GstWFDMessage *msg)
1217 {
1218   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1219   g_print("===========WFD Message dump=========");
1220
1221   if (msg->audio_codecs) {
1222     guint i = 0;
1223     g_print("Audio supported formats : ");
1224     for (; i < msg->audio_codecs->count; i++) {
1225       g_print("Codec: %s", msg->audio_codecs->list[i].audio_format);
1226       if (!strcmp(msg->audio_codecs->list[i].audio_format, GST_STRING_WFD_LPCM)) {
1227         if (msg->audio_codecs->list[i].modes & GST_WFD_FREQ_44100)
1228           g_print("  Freq: %d", 44100);
1229         if (msg->audio_codecs->list[i].modes & GST_WFD_FREQ_48000)
1230           g_print("  Freq: %d", 48000);
1231         g_print("  Channels: %d", 2);
1232       }
1233       if (!strcmp(msg->audio_codecs->list[i].audio_format, GST_STRING_WFD_AAC)) {
1234         g_print("  Freq: %d", 48000);
1235         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_2)
1236           g_print("  Channels: %d", 2);
1237         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_4)
1238           g_print("  Channels: %d", 4);
1239         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_6)
1240           g_print("  Channels: %d", 6);
1241         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_8)
1242           g_print("  Channels: %d", 8);
1243       }
1244       if (!strcmp(msg->audio_codecs->list[i].audio_format, GST_STRING_WFD_AC3)) {
1245         g_print("  Freq: %d", 48000);
1246         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_2)
1247           g_print("  Channels: %d", 2);
1248         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_4)
1249           g_print("  Channels: %d", 4);
1250         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_6)
1251           g_print("  Channels: %d", 6);
1252       }
1253       g_print("  Bitwidth: %d", 16);
1254       g_print("  Latency: %d", msg->audio_codecs->list[i].latency);
1255     }
1256   }
1257
1258
1259   if (msg->video_formats) {
1260     g_print("Video supported formats : ");
1261     if (msg->video_formats->list) {
1262       g_print("Codec: H264");
1263       guint nativeindex = 0;
1264       if ((msg->video_formats->list->native & 0x7) == GST_WFD_VIDEO_CEA_RESOLUTION) {
1265         g_print("  Native type: CEA");
1266       } else if ((msg->video_formats->list->native & 0x7) == GST_WFD_VIDEO_VESA_RESOLUTION) {
1267         g_print("  Native type: VESA");
1268       } else if ((msg->video_formats->list->native & 0x7) == GST_WFD_VIDEO_HH_RESOLUTION) {
1269         g_print("  Native type: HH");
1270       }
1271       nativeindex = msg->video_formats->list->native >> 3;
1272       g_print("  Resolution: %d", (1 << nativeindex));
1273
1274       if (msg->video_formats->list->H264_codec.profile & GST_WFD_H264_BASE_PROFILE) {
1275         g_print("  Profile: BASE");
1276       } else if (msg->video_formats->list->H264_codec.profile & GST_WFD_H264_HIGH_PROFILE) {
1277         g_print("  Profile: HIGH");
1278       }
1279       if (msg->video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_3_1) {
1280         g_print("  Level: 3.1");
1281       } else if (msg->video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_3_2) {
1282         g_print("  Level: 3.2");
1283       } else if (msg->video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_4) {
1284         g_print("  Level: 4");
1285       } else if (msg->video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_4_1) {
1286         g_print("  Level: 4.1");
1287       } else if (msg->video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_4_2) {
1288         g_print("  Level: 4.2");
1289       }
1290       g_print("  Latency: %d", msg->video_formats->list->H264_codec.misc_params.latency);
1291       g_print("  min_slice_size: %x", msg->video_formats->list->H264_codec.misc_params.min_slice_size);
1292       g_print("  slice_enc_params: %x", msg->video_formats->list->H264_codec.misc_params.slice_enc_params);
1293       g_print("  frame_rate_control_support: %x", msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support);
1294       if (msg->video_formats->list->H264_codec.max_hres) {
1295         g_print("  Max Width: %04d", msg->video_formats->list->H264_codec.max_hres);
1296       }
1297       if (msg->video_formats->list->H264_codec.max_vres) {
1298         g_print("  Max Height: %04d", msg->video_formats->list->H264_codec.max_vres);
1299       }
1300     }
1301   }
1302
1303   if (msg->wfd2_audio_codecs) {
1304     guint i = 0;
1305     g_print("Audio supported codec for R2 : ");
1306     for (; i < msg->wfd2_audio_codecs->count; i++) {
1307       g_print("Codec: %s", msg->wfd2_audio_codecs->list[i].audio_format);
1308       if (!strcmp(msg->wfd2_audio_codecs->list[i].audio_format, GST_STRING_WFD_LPCM)) {
1309         if (msg->wfd2_audio_codecs->list[i].modes & GST_WFD_FREQ_44100)
1310           g_print("  Freq: %d", 44100);
1311         if (msg->wfd2_audio_codecs->list[i].modes & GST_WFD_FREQ_48000)
1312           g_print("  Freq: %d", 48000);
1313         g_print("  Channels: %d", 2);
1314       }
1315       if (!strcmp(msg->wfd2_audio_codecs->list[i].audio_format, GST_STRING_WFD_AAC)) {
1316         g_print("  Freq: %d", 48000);
1317         if (msg->wfd2_audio_codecs->list[i].modes & GST_WFD_CHANNEL_2)
1318           g_print("  Channels: %d", 2);
1319         if (msg->wfd2_audio_codecs->list[i].modes & GST_WFD_CHANNEL_4)
1320           g_print("  Channels: %d", 4);
1321         if (msg->wfd2_audio_codecs->list[i].modes & GST_WFD_CHANNEL_6)
1322           g_print("  Channels: %d", 6);
1323         if (msg->wfd2_audio_codecs->list[i].modes & GST_WFD_CHANNEL_8)
1324           g_print("  Channels: %d", 8);
1325       }
1326       if (!strcmp(msg->wfd2_audio_codecs->list[i].audio_format, GST_STRING_WFD_AC3)) {
1327         g_print("  Freq: %d", 48000);
1328         if (msg->wfd2_audio_codecs->list[i].modes & GST_WFD_CHANNEL_2)
1329           g_print("  Channels: %d", 2);
1330         if (msg->wfd2_audio_codecs->list[i].modes & GST_WFD_CHANNEL_4)
1331           g_print("  Channels: %d", 4);
1332         if (msg->wfd2_audio_codecs->list[i].modes & GST_WFD_CHANNEL_6)
1333           g_print("  Channels: %d", 6);
1334       }
1335       g_print("  Bitwidth: %d", 16);
1336       g_print("  Latency: %d", msg->wfd2_audio_codecs->list[i].latency);
1337     }
1338   }
1339
1340
1341   if (msg->direct_video_formats) {
1342     g_print("Video supported formats for direct streaming  : ");
1343     if (msg->direct_video_formats->list) {
1344       g_print("Codec: H264");
1345       guint nativeindex = 0;
1346       if ((msg->direct_video_formats->list->native & GST_CHECK_VIDEO_FORMAT) == GST_WFD_VIDEO_CEA_RESOLUTION) {
1347         g_print("  Native type: CEA");
1348       } else if ((msg->direct_video_formats->list->native & GST_CHECK_VIDEO_FORMAT) == GST_WFD_VIDEO_VESA_RESOLUTION) {
1349         g_print("  Native type: VESA");
1350       } else if ((msg->direct_video_formats->list->native & GST_CHECK_VIDEO_FORMAT) == GST_WFD_VIDEO_HH_RESOLUTION) {
1351         g_print("  Native type: HH");
1352       }
1353       nativeindex = msg->direct_video_formats->list->native >> GST_SHIFT_VIDEO_FORMAT;
1354       g_print("  Resolution: %d", (1 << nativeindex));
1355
1356       if (msg->direct_video_formats->list->H264_codec.profile & GST_WFD_H264_BASE_PROFILE) {
1357         g_print("  Profile: BASE");
1358       } else if (msg->direct_video_formats->list->H264_codec.profile & GST_WFD_H264_HIGH_PROFILE) {
1359         g_print("  Profile: HIGH");
1360       }
1361       if (msg->direct_video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_3_1) {
1362         g_print("  Level: 3.1");
1363       } else if (msg->direct_video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_3_2) {
1364         g_print("  Level: 3.2");
1365       } else if (msg->direct_video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_4) {
1366         g_print("  Level: 4");
1367       } else if (msg->direct_video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_4_1) {
1368         g_print("  Level: 4.1");
1369       } else if (msg->direct_video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_4_2) {
1370         g_print("  Level: 4.2");
1371       }
1372       g_print("  Latency: %d", msg->direct_video_formats->list->H264_codec.misc_params.latency);
1373       g_print("  min_slice_size: %x", msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size);
1374       g_print("  slice_enc_params: %x", msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params);
1375       g_print("  frame_rate_control_support: %x", msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support);
1376       if (msg->direct_video_formats->list->H264_codec.max_hres) {
1377         g_print("  Max Width: %04d", msg->direct_video_formats->list->H264_codec.max_hres);
1378       }
1379       if (msg->direct_video_formats->list->H264_codec.max_vres) {
1380         g_print("  Max Height: %04d", msg->direct_video_formats->list->H264_codec.max_vres);
1381       }
1382     }
1383   }
1384
1385   if (msg->video_3d_formats) {
1386     g_print("wfd_3d_formats");
1387   }
1388
1389   if (msg->content_protection) {
1390     g_print(GST_STRING_WFD_CONTENT_PROTECTION);
1391   }
1392
1393   if (msg->display_edid) {
1394     g_print(GST_STRING_WFD_DISPLAY_EDID);
1395   }
1396
1397   if (msg->coupled_sink) {
1398     g_print(GST_STRING_WFD_COUPLED_SINK);
1399   }
1400
1401   if (msg->trigger_method) {
1402     g_print("  Trigger type: %s", msg->trigger_method->wfd_trigger_method);
1403   }
1404
1405   if (msg->presentation_url) {
1406     g_print(GST_STRING_WFD_PRESENTATION_URL);
1407   }
1408
1409   if (msg->client_rtp_ports) {
1410     g_print(" Client RTP Ports : ");
1411     if (msg->client_rtp_ports->profile) {
1412       g_print("%s", msg->client_rtp_ports->profile);
1413       g_print("  %d", msg->client_rtp_ports->rtp_port0);
1414       g_print("  %d", msg->client_rtp_ports->rtp_port1);
1415       g_print("  %s", msg->client_rtp_ports->mode);
1416     }
1417   }
1418
1419   if (msg->route) {
1420     g_print(GST_STRING_WFD_ROUTE);
1421   }
1422
1423   if (msg->I2C) {
1424     g_print(GST_STRING_WFD_I2C);
1425   }
1426
1427   if (msg->av_format_change_timing) {
1428     g_print(GST_STRING_WFD_AV_FORMAT_CHANGE_TIMING);
1429   }
1430
1431   if (msg->preferred_display_mode) {
1432     g_print(GST_STRING_WFD_PREFERRED_DISPLAY_MODE);
1433   }
1434
1435   if (msg->standby_resume_capability) {
1436     g_print(GST_STRING_WFD_STANDBY_RESUME_CAPABILITY);
1437   }
1438
1439   if (msg->standby) {
1440     g_print(GST_STRING_WFD_STANDBY);
1441   }
1442
1443   if (msg->connector_type) {
1444     g_print(GST_STRING_WFD_CONNECTOR_TYPE);
1445   }
1446
1447   if (msg->idr_request) {
1448     g_print(GST_STRING_WFD_IDR_REQUEST);
1449   }
1450
1451   if (msg->direct_mode) {
1452     g_print(GST_STRING_WFD2_DIRECT_STREAMING_MODE);
1453   }
1454
1455   if (msg->tcp_ports) {
1456     g_print(" Client TCP Ports : ");
1457     if (msg->tcp_ports->profile) {
1458       g_print("%s", msg->tcp_ports->profile);
1459       g_print("  %d", msg->tcp_ports->rtp_port0);
1460       g_print("  %d", msg->tcp_ports->rtp_port1);
1461       g_print("  %s", msg->tcp_ports->mode);
1462     }
1463   }
1464
1465   if (msg->buf_len) {
1466     g_print(" Current buffer length : ");
1467     g_print(" %d", msg->buf_len->buf_len);
1468   }
1469
1470   if (msg->audio_status) {
1471     g_print(" Current audio buffer status : ");
1472     g_print(" bufsize %d", msg->audio_status->aud_bufsize);
1473     g_print(" pts %lld", msg->audio_status->aud_pts);
1474   }
1475
1476   if (msg->video_status) {
1477     g_print(" Current video buffer status : ");
1478     g_print(" bufsize %d", msg->video_status->vid_bufsize);
1479     g_print(" pts %lld", msg->video_status->vid_pts);
1480   }
1481
1482   g_print("===============================================");
1483   return GST_WFD_OK;
1484 }
1485
1486 GstWFDResult gst_wfd_message_set_supported_audio_format(GstWFDMessage *msg, GstWFDAudioFormats aCodec, guint aFreq, guint aChanels,
1487                                                guint aBitwidth, guint32 aLatency)
1488 {
1489   guint i = 0;
1490   guint pcm = 0, aac = 0, ac3 = 0;
1491
1492   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1493
1494   if (!msg->audio_codecs)
1495     msg->audio_codecs = g_new0(GstWFDAudioCodeclist, 1);
1496
1497   if (aCodec != GST_WFD_AUDIO_UNKNOWN) {
1498
1499     if (aCodec & GST_WFD_AUDIO_LPCM)
1500       msg->audio_codecs->count++;
1501     if (aCodec & GST_WFD_AUDIO_AAC)
1502       msg->audio_codecs->count++;
1503     if (aCodec & GST_WFD_AUDIO_AC3)
1504       msg->audio_codecs->count++;
1505
1506     msg->audio_codecs->list = g_new0(GstWFDAudioCodec, msg->audio_codecs->count);
1507     for (; i < msg->audio_codecs->count; i++) {
1508       if ((aCodec & GST_WFD_AUDIO_LPCM) && (!pcm)) {
1509         msg->audio_codecs->list[i].audio_format = g_strdup(GST_STRING_WFD_LPCM);
1510         msg->audio_codecs->list[i].modes = aFreq;
1511         msg->audio_codecs->list[i].latency = aLatency;
1512         pcm = 1;
1513       } else if ((aCodec & GST_WFD_AUDIO_AAC) && (!aac)) {
1514         msg->audio_codecs->list[i].audio_format = g_strdup(GST_STRING_WFD_AAC);
1515         msg->audio_codecs->list[i].modes = aChanels;
1516         msg->audio_codecs->list[i].latency = aLatency;
1517         aac = 1;
1518       } else if ((aCodec & GST_WFD_AUDIO_AC3) && (!ac3)) {
1519         msg->audio_codecs->list[i].audio_format = g_strdup(GST_STRING_WFD_AC3);
1520         msg->audio_codecs->list[i].modes = aChanels;
1521         msg->audio_codecs->list[i].latency = aLatency;
1522         ac3 = 1;
1523       }
1524     }
1525   }
1526   return GST_WFD_OK;
1527 }
1528
1529 GstWFDResult gst_wfd_message_set_preferred_audio_format(GstWFDMessage *msg, GstWFDAudioFormats aCodec, GstWFDAudioFreq aFreq, GstWFDAudioChannels aChanels,
1530                                               guint aBitwidth, guint32 aLatency)
1531 {
1532
1533   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1534
1535   if (!msg->audio_codecs)
1536     msg->audio_codecs = g_new0(GstWFDAudioCodeclist, 1);
1537   if (aCodec != GST_WFD_AUDIO_UNKNOWN) {
1538     msg->audio_codecs->list = g_new0(GstWFDAudioCodec, 1);
1539     msg->audio_codecs->count = 1;
1540     if (aCodec == GST_WFD_AUDIO_LPCM) {
1541       msg->audio_codecs->list->audio_format = g_strdup(GST_STRING_WFD_LPCM);
1542       msg->audio_codecs->list->modes = aFreq;
1543       msg->audio_codecs->list->latency = aLatency;
1544     } else if (aCodec == GST_WFD_AUDIO_AAC) {
1545       msg->audio_codecs->list->audio_format = g_strdup(GST_STRING_WFD_AAC);
1546       msg->audio_codecs->list->modes = aChanels;
1547       msg->audio_codecs->list->latency = aLatency;
1548     } else if (aCodec == GST_WFD_AUDIO_AC3) {
1549       msg->audio_codecs->list->audio_format = g_strdup(GST_STRING_WFD_AC3);
1550       msg->audio_codecs->list->modes = aChanels;
1551       msg->audio_codecs->list->latency = aLatency;
1552     }
1553   } else {
1554     msg->audio_codecs->list = NULL;
1555     msg->audio_codecs->count = 0;
1556   }
1557   return GST_WFD_OK;
1558 }
1559
1560 GstWFDResult gst_wfd_message_get_supported_audio_format(GstWFDMessage *msg, guint *aCodec, guint *aFreq, guint *aChanels,
1561                                                guint *aBitwidth, guint32 *aLatency)
1562 {
1563   guint i = 0;
1564   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1565   g_return_val_if_fail(msg->audio_codecs != NULL, GST_WFD_EINVAL);
1566
1567   for (; i < msg->audio_codecs->count; i++) {
1568     if (!g_strcmp0(msg->audio_codecs->list[i].audio_format, GST_STRING_WFD_LPCM)) {
1569       *aCodec |= GST_WFD_AUDIO_LPCM;
1570       *aFreq |= msg->audio_codecs->list[i].modes;
1571       *aChanels |= GST_WFD_CHANNEL_2;
1572       *aBitwidth = 16;
1573       *aLatency = msg->audio_codecs->list[i].latency;
1574     } else if (!g_strcmp0(msg->audio_codecs->list[i].audio_format, GST_STRING_WFD_AAC)) {
1575       *aCodec |= GST_WFD_AUDIO_AAC;
1576       *aFreq |= GST_WFD_FREQ_48000;
1577       *aChanels |= msg->audio_codecs->list[i].modes;
1578       *aBitwidth = 16;
1579       *aLatency = msg->audio_codecs->list[i].latency;
1580     } else if (!g_strcmp0(msg->audio_codecs->list[i].audio_format, GST_STRING_WFD_AC3)) {
1581       *aCodec |= GST_WFD_AUDIO_AC3;
1582       *aFreq |= GST_WFD_FREQ_48000;
1583       *aChanels |= msg->audio_codecs->list[i].modes;
1584       *aBitwidth = 16;
1585       *aLatency = msg->audio_codecs->list[i].latency;
1586     }
1587   }
1588   return GST_WFD_OK;
1589 }
1590
1591 GstWFDResult gst_wfd_message_get_preferred_audio_format(GstWFDMessage *msg, GstWFDAudioFormats *aCodec, GstWFDAudioFreq *aFreq, GstWFDAudioChannels *aChanels,
1592                                               guint *aBitwidth, guint32 *aLatency)
1593 {
1594   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1595
1596   if (!g_strcmp0(msg->audio_codecs->list->audio_format, GST_STRING_WFD_LPCM)) {
1597     *aCodec = GST_WFD_AUDIO_LPCM;
1598     *aFreq = msg->audio_codecs->list->modes;
1599     *aChanels = GST_WFD_CHANNEL_2;
1600     *aBitwidth = 16;
1601     *aLatency = msg->audio_codecs->list->latency;
1602   } else if (!g_strcmp0(msg->audio_codecs->list->audio_format, GST_STRING_WFD_AAC)) {
1603     *aCodec = GST_WFD_AUDIO_AAC;
1604     *aFreq = GST_WFD_FREQ_48000;
1605     *aChanels = msg->audio_codecs->list->modes;
1606     *aBitwidth = 16;
1607     *aLatency = msg->audio_codecs->list->latency;
1608   } else if (!g_strcmp0(msg->audio_codecs->list->audio_format, GST_STRING_WFD_AC3)) {
1609     *aCodec = GST_WFD_AUDIO_AC3;
1610     *aFreq = GST_WFD_FREQ_48000;
1611     *aChanels = msg->audio_codecs->list->modes;
1612     *aBitwidth = 16;
1613     *aLatency = msg->audio_codecs->list->latency;
1614   }
1615   return GST_WFD_OK;
1616 }
1617
1618 GstWFDResult gst_wfd_message_set_supported_video_format(GstWFDMessage *msg, GstWFDVideoCodecs vCodec,
1619                                                GstWFDVideoNativeResolution vNative, guint64 vNativeResolution,
1620                                                guint64 vCEAResolution, guint64 vVESAResolution, guint64 vHHResolution,
1621                                                guint vProfile, guint vLevel, guint32 vLatency, guint32 vMaxHeight,
1622                                                guint32 vMaxWidth, guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control,
1623                                                guint preferred_display_mode)
1624 {
1625   guint nativeindex = 0;
1626   guint64 temp = vNativeResolution;
1627
1628   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1629
1630   if (!msg->video_formats)
1631     msg->video_formats = g_new0(GstWFDVideoCodeclist, 1);
1632
1633   if (vCodec != GST_WFD_VIDEO_UNKNOWN) {
1634     msg->video_formats->list = g_new0(GstWFDVideoCodec, 1);
1635
1636     temp >>= 1;
1637     while (temp) {
1638       nativeindex++;
1639       temp >>= 1;
1640     }
1641
1642     msg->video_formats->list->native = nativeindex;
1643     msg->video_formats->list->native <<= 3;
1644
1645     if (vNative == GST_WFD_VIDEO_VESA_RESOLUTION)
1646       msg->video_formats->list->native |= 1;
1647     else if (vNative == GST_WFD_VIDEO_HH_RESOLUTION)
1648       msg->video_formats->list->native |= 2;
1649
1650     msg->video_formats->list->preferred_display_mode_supported = preferred_display_mode;
1651     msg->video_formats->list->H264_codec.profile = vProfile;
1652     msg->video_formats->list->H264_codec.level = vLevel;
1653     msg->video_formats->list->H264_codec.max_hres = vMaxWidth;
1654     msg->video_formats->list->H264_codec.max_vres = vMaxHeight;
1655     msg->video_formats->list->H264_codec.misc_params.CEA_Support = vCEAResolution;
1656     msg->video_formats->list->H264_codec.misc_params.VESA_Support = vVESAResolution;
1657     msg->video_formats->list->H264_codec.misc_params.HH_Support = vHHResolution;
1658     msg->video_formats->list->H264_codec.misc_params.latency = vLatency;
1659     msg->video_formats->list->H264_codec.misc_params.min_slice_size = min_slice_size;
1660     msg->video_formats->list->H264_codec.misc_params.slice_enc_params = slice_enc_params;
1661     msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support = frame_rate_control;
1662   }
1663   return GST_WFD_OK;
1664 }
1665
1666 GstWFDResult gst_wfd_message_set_preferred_video_format(GstWFDMessage *msg, GstWFDVideoCodecs vCodec,
1667                                               GstWFDVideoNativeResolution vNative, guint64 vNativeResolution,
1668                                               guint64 vCEAResolution, guint64 vVESAResolution,
1669                                               guint64 vHHResolution,  GstWFDVideoH264Profile vProfile,
1670                                               GstWFDVideoH264Level vLevel, guint32 vLatency, guint32 vMaxHeight,
1671                                               guint32 vMaxWidth, guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control)
1672 {
1673   guint nativeindex = 0;
1674   guint64 temp = vNativeResolution;
1675
1676   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1677
1678   if (!msg->video_formats)
1679     msg->video_formats = g_new0(GstWFDVideoCodeclist, 1);
1680   msg->video_formats->list = g_new0(GstWFDVideoCodec, 1);
1681
1682   while (temp) {
1683     nativeindex++;
1684     temp >>= 1;
1685   }
1686
1687   if (nativeindex) msg->video_formats->list->native = nativeindex - 1;
1688   msg->video_formats->list->native <<= 3;
1689
1690   if (vNative == GST_WFD_VIDEO_VESA_RESOLUTION)
1691     msg->video_formats->list->native |= 1;
1692   else if (vNative == GST_WFD_VIDEO_HH_RESOLUTION)
1693     msg->video_formats->list->native |= 2;
1694
1695   msg->video_formats->list->preferred_display_mode_supported = GST_WFD_PREFERRED_DISPLAY_MODE_NOT_SUPPORTED;
1696   msg->video_formats->list->H264_codec.profile = vProfile;
1697   msg->video_formats->list->H264_codec.level = vLevel;
1698   msg->video_formats->list->H264_codec.max_hres = vMaxWidth;
1699   msg->video_formats->list->H264_codec.max_vres = vMaxHeight;
1700   msg->video_formats->list->H264_codec.misc_params.CEA_Support = vCEAResolution;
1701   msg->video_formats->list->H264_codec.misc_params.VESA_Support = vVESAResolution;
1702   msg->video_formats->list->H264_codec.misc_params.HH_Support = vHHResolution;
1703   msg->video_formats->list->H264_codec.misc_params.latency = vLatency;
1704   msg->video_formats->list->H264_codec.misc_params.min_slice_size = min_slice_size;
1705   msg->video_formats->list->H264_codec.misc_params.slice_enc_params = slice_enc_params;
1706   msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support = frame_rate_control;
1707   return GST_WFD_OK;
1708 }
1709
1710 GstWFDResult gst_wfd_message_get_supported_video_format(GstWFDMessage *msg, GstWFDVideoCodecs *vCodec,
1711                                                GstWFDVideoNativeResolution *vNative, guint64 *vNativeResolution,
1712                                                guint64 *vCEAResolution, guint64 *vVESAResolution, guint64 *vHHResolution,
1713                                                guint *vProfile, guint *vLevel, guint32 *vLatency, guint32 *vMaxHeight,
1714                                                guint32 *vMaxWidth, guint32 *min_slice_size, guint32 *slice_enc_params, guint *frame_rate_control)
1715 {
1716   guint nativeindex = 0;
1717
1718   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1719   g_return_val_if_fail(msg->video_formats != NULL, GST_WFD_EINVAL);
1720   g_return_val_if_fail(msg->video_formats->list != NULL, GST_WFD_EINVAL);
1721
1722   *vCodec = GST_WFD_VIDEO_H264;
1723   *vNative = msg->video_formats->list->native & 0x7;
1724   nativeindex = msg->video_formats->list->native >> 3;
1725   *vNativeResolution = (guint64)1 << nativeindex;
1726   *vProfile = msg->video_formats->list->H264_codec.profile;
1727   *vLevel = msg->video_formats->list->H264_codec.level;
1728   *vMaxWidth = msg->video_formats->list->H264_codec.max_hres;
1729   *vMaxHeight = msg->video_formats->list->H264_codec.max_vres;
1730   *vCEAResolution = msg->video_formats->list->H264_codec.misc_params.CEA_Support;
1731   *vVESAResolution = msg->video_formats->list->H264_codec.misc_params.VESA_Support;
1732   *vHHResolution = msg->video_formats->list->H264_codec.misc_params.HH_Support;
1733   *vLatency = msg->video_formats->list->H264_codec.misc_params.latency;
1734   *min_slice_size = msg->video_formats->list->H264_codec.misc_params.min_slice_size;
1735   *slice_enc_params = msg->video_formats->list->H264_codec.misc_params.slice_enc_params;
1736   *frame_rate_control = msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support;
1737   return GST_WFD_OK;
1738 }
1739
1740 GstWFDResult gst_wfd_message_get_preferred_video_format(GstWFDMessage *msg, GstWFDVideoCodecs *vCodec,
1741                                               GstWFDVideoNativeResolution *vNative, guint64 *vNativeResolution,
1742                                               guint64 *vCEAResolution, guint64 *vVESAResolution,
1743                                               guint64 *vHHResolution,  GstWFDVideoH264Profile *vProfile,
1744                                               GstWFDVideoH264Level *vLevel, guint32 *vLatency, guint32 *vMaxHeight,
1745                                               guint32 *vMaxWidth, guint32 *min_slice_size, guint32 *slice_enc_params, guint *frame_rate_control)
1746 {
1747   guint nativeindex = 0;
1748   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1749   g_return_val_if_fail(msg->video_formats != NULL, GST_WFD_EINVAL);
1750   g_return_val_if_fail(msg->video_formats->list != NULL, GST_WFD_EINVAL);
1751
1752   *vCodec = GST_WFD_VIDEO_H264;
1753   *vNative = msg->video_formats->list->native & 0x7;
1754   nativeindex = msg->video_formats->list->native >> 3;
1755   *vNativeResolution = (guint64)1 << nativeindex;
1756   *vProfile = msg->video_formats->list->H264_codec.profile;
1757   *vLevel = msg->video_formats->list->H264_codec.level;
1758   *vMaxWidth = msg->video_formats->list->H264_codec.max_hres;
1759   *vMaxHeight = msg->video_formats->list->H264_codec.max_vres;
1760   *vCEAResolution = msg->video_formats->list->H264_codec.misc_params.CEA_Support;
1761   *vVESAResolution = msg->video_formats->list->H264_codec.misc_params.VESA_Support;
1762   *vHHResolution = msg->video_formats->list->H264_codec.misc_params.HH_Support;
1763   *vLatency = msg->video_formats->list->H264_codec.misc_params.latency;
1764   *min_slice_size = msg->video_formats->list->H264_codec.misc_params.min_slice_size;
1765   *slice_enc_params = msg->video_formats->list->H264_codec.misc_params.slice_enc_params;
1766   *frame_rate_control = msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support;
1767   return GST_WFD_OK;
1768 }
1769
1770 GstWFDResult gst_wfd_message_set_supported_wfd2_audio_codec(GstWFDMessage *msg, GstWFDAudioFormats aCodec, guint aFreq, guint aChanels,
1771                                                guint aBitwidth, guint32 aLatency)
1772 {
1773   guint temp = aCodec;
1774   guint i = 0;
1775   guint pcm = 0, aac = 0, ac3 = 0, cta = 0, aac_eldv2 = 0;
1776
1777   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1778
1779   if (!msg->wfd2_audio_codecs)
1780     msg->wfd2_audio_codecs = g_new0(GstWFD2AudioCodeclist, 1);
1781
1782   if (aCodec != GST_WFD_AUDIO_UNKNOWN) {
1783     while (temp) {
1784       msg->wfd2_audio_codecs->count++;
1785       temp >>= 1;
1786     }
1787     msg->wfd2_audio_codecs->list = g_new0(GstWFDAudioCodec, msg->wfd2_audio_codecs->count);
1788     for (; i < msg->wfd2_audio_codecs->count; i++) {
1789       if ((aCodec & GST_WFD_AUDIO_LPCM) && (!pcm)) {
1790         msg->wfd2_audio_codecs->list[i].audio_format = g_strdup(GST_STRING_WFD_LPCM);
1791         msg->wfd2_audio_codecs->list[i].modes = aFreq;
1792         msg->wfd2_audio_codecs->list[i].latency = aLatency;
1793         pcm = 1;
1794       } else if ((aCodec & GST_WFD_AUDIO_AAC) && (!aac)) {
1795         msg->wfd2_audio_codecs->list[i].audio_format = g_strdup(GST_STRING_WFD_AAC);
1796         msg->wfd2_audio_codecs->list[i].modes = aChanels;
1797         msg->wfd2_audio_codecs->list[i].latency = aLatency;
1798         aac = 1;
1799       } else if ((aCodec & GST_WFD_AUDIO_AC3) && (!ac3)) {
1800         msg->wfd2_audio_codecs->list[i].audio_format = g_strdup(GST_STRING_WFD_AC3);
1801         msg->wfd2_audio_codecs->list[i].modes = aChanels;
1802         msg->wfd2_audio_codecs->list[i].latency = aLatency;
1803         ac3 = 1;
1804       } else if ((aCodec & GST_WFD_AUDIO_CTA) && (!cta)) {
1805         msg->wfd2_audio_codecs->list[i].audio_format = g_strdup(GST_STRING_WFD_CTA);
1806         msg->wfd2_audio_codecs->list[i].modes = aChanels;
1807         msg->wfd2_audio_codecs->list[i].latency = aLatency;
1808         cta = 1;
1809       } else if ((aCodec & GST_WFD_AUDIO_AAC_ELDV2) && (!aac_eldv2)) {
1810         msg->wfd2_audio_codecs->list[i].audio_format = g_strdup(GST_STRING_WFD_AAC_ELDV2);
1811         msg->wfd2_audio_codecs->list[i].modes = aChanels;
1812         msg->wfd2_audio_codecs->list[i].latency = aLatency;
1813         aac_eldv2 = 1;
1814       }
1815     }
1816   }
1817   return GST_WFD_OK;
1818 }
1819
1820 GstWFDResult gst_wfd_message_set_preferred_wfd2_audio_codec(GstWFDMessage *msg, GstWFDAudioFormats aCodec, GstWFDAudioFreq aFreq, GstWFDAudioChannels aChanels,
1821                                               guint aBitwidth, guint32 aLatency)
1822 {
1823
1824   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1825
1826   if (!msg->wfd2_audio_codecs)
1827     msg->wfd2_audio_codecs = g_new0(GstWFD2AudioCodeclist, 1);
1828
1829   msg->wfd2_audio_codecs->list = g_new0(GstWFDAudioCodec, 1);
1830   msg->wfd2_audio_codecs->count = 1;
1831   if (aCodec == GST_WFD_AUDIO_LPCM) {
1832     msg->wfd2_audio_codecs->list->audio_format = g_strdup(GST_STRING_WFD_LPCM);
1833     msg->wfd2_audio_codecs->list->modes = aFreq;
1834     msg->wfd2_audio_codecs->list->latency = aLatency;
1835   } else if (aCodec == GST_WFD_AUDIO_AAC) {
1836     msg->wfd2_audio_codecs->list->audio_format = g_strdup(GST_STRING_WFD_AAC);
1837     msg->wfd2_audio_codecs->list->modes = aChanels;
1838     msg->wfd2_audio_codecs->list->latency = aLatency;
1839   } else if (aCodec == GST_WFD_AUDIO_AC3) {
1840     msg->wfd2_audio_codecs->list->audio_format = g_strdup(GST_STRING_WFD_AC3);
1841     msg->wfd2_audio_codecs->list->modes = aChanels;
1842     msg->wfd2_audio_codecs->list->latency = aLatency;
1843   } else if (aCodec == GST_WFD_AUDIO_CTA) {
1844     msg->wfd2_audio_codecs->list->audio_format = g_strdup(GST_STRING_WFD_CTA);
1845     msg->wfd2_audio_codecs->list->modes = aChanels;
1846     msg->wfd2_audio_codecs->list->latency = aLatency;
1847   } else if (aCodec == GST_WFD_AUDIO_AAC_ELDV2) {
1848     msg->wfd2_audio_codecs->list->audio_format = g_strdup(GST_STRING_WFD_AAC_ELDV2);
1849     msg->wfd2_audio_codecs->list->modes = aChanels;
1850     msg->wfd2_audio_codecs->list->latency = aLatency;
1851   }
1852   return GST_WFD_OK;
1853 }
1854
1855 GstWFDResult gst_wfd_message_get_supported_wfd2_audio_codec(GstWFDMessage *msg, guint *aCodec, guint *aFreq, guint *aChanels,
1856                                                guint *aBitwidth, guint32 *aLatency)
1857 {
1858   guint i = 0;
1859   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1860   g_return_val_if_fail(msg->wfd2_audio_codecs != NULL, GST_WFD_EINVAL);
1861
1862   for (; i < msg->wfd2_audio_codecs->count; i++) {
1863     if (!g_strcmp0(msg->wfd2_audio_codecs->list[i].audio_format, GST_STRING_WFD_LPCM)) {
1864       *aCodec |= GST_WFD_AUDIO_LPCM;
1865       *aFreq |= msg->wfd2_audio_codecs->list[i].modes;
1866       *aChanels |= GST_WFD_CHANNEL_2;
1867       *aBitwidth = 16;
1868       *aLatency = msg->wfd2_audio_codecs->list[i].latency;
1869     } else if (!g_strcmp0(msg->wfd2_audio_codecs->list[i].audio_format, GST_STRING_WFD_AAC)) {
1870       *aCodec |= GST_WFD_AUDIO_AAC;
1871       *aFreq |= GST_WFD_FREQ_48000;
1872       *aChanels |= msg->wfd2_audio_codecs->list[i].modes;
1873       *aBitwidth = 16;
1874       *aLatency = msg->wfd2_audio_codecs->list[i].latency;
1875     } else if (!g_strcmp0(msg->wfd2_audio_codecs->list[i].audio_format, GST_STRING_WFD_AC3)) {
1876       *aCodec |= GST_WFD_AUDIO_AC3;
1877       *aFreq |= GST_WFD_FREQ_48000;
1878       *aChanels |= msg->wfd2_audio_codecs->list[i].modes;
1879       *aBitwidth = 16;
1880       *aLatency = msg->wfd2_audio_codecs->list[i].latency;
1881     } else if (!g_strcmp0(msg->wfd2_audio_codecs->list[i].audio_format, GST_STRING_WFD_CTA)) {
1882       *aCodec |= GST_WFD_AUDIO_CTA;
1883       *aFreq |= GST_WFD_FREQ_48000;
1884       *aChanels |= msg->wfd2_audio_codecs->list[i].modes;
1885       *aBitwidth = 16;
1886       *aLatency = msg->wfd2_audio_codecs->list[i].latency;
1887     } else if (!g_strcmp0(msg->wfd2_audio_codecs->list[i].audio_format, GST_STRING_WFD_AAC_ELDV2)) {
1888       *aCodec |= GST_WFD_AUDIO_AAC_ELDV2;
1889       *aFreq |= GST_WFD_FREQ_48000;
1890       *aChanels |= msg->wfd2_audio_codecs->list[i].modes;
1891       *aBitwidth = 16;
1892       *aLatency = msg->wfd2_audio_codecs->list[i].latency;
1893     }
1894   }
1895   return GST_WFD_OK;
1896 }
1897
1898 GstWFDResult gst_wfd_message_get_preferred_wfd2_audio_codec(GstWFDMessage *msg, GstWFDAudioFormats *aCodec, GstWFDAudioFreq *aFreq, GstWFDAudioChannels *aChanels,
1899                                               guint *aBitwidth, guint32 *aLatency)
1900 {
1901   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1902
1903   if (!g_strcmp0(msg->wfd2_audio_codecs->list->audio_format, GST_STRING_WFD_LPCM)) {
1904     *aCodec = GST_WFD_AUDIO_LPCM;
1905     *aFreq = msg->wfd2_audio_codecs->list->modes;
1906     *aChanels = GST_WFD_CHANNEL_2;
1907     *aBitwidth = 16;
1908     *aLatency = msg->wfd2_audio_codecs->list->latency;
1909   } else if (!g_strcmp0(msg->wfd2_audio_codecs->list->audio_format, GST_STRING_WFD_AAC)) {
1910     *aCodec = GST_WFD_AUDIO_AAC;
1911     *aFreq = GST_WFD_FREQ_48000;
1912     *aChanels = msg->wfd2_audio_codecs->list->modes;
1913     *aBitwidth = 16;
1914     *aLatency = msg->wfd2_audio_codecs->list->latency;
1915   } else if (!g_strcmp0(msg->wfd2_audio_codecs->list->audio_format, GST_STRING_WFD_AC3)) {
1916     *aCodec = GST_WFD_AUDIO_AC3;
1917     *aFreq = GST_WFD_FREQ_48000;
1918     *aChanels = msg->wfd2_audio_codecs->list->modes;
1919     *aBitwidth = 16;
1920     *aLatency = msg->wfd2_audio_codecs->list->latency;
1921   } else if (!g_strcmp0(msg->wfd2_audio_codecs->list->audio_format, GST_STRING_WFD_CTA)) {
1922     *aCodec = GST_WFD_AUDIO_CTA;
1923     *aFreq = GST_WFD_FREQ_48000;
1924     *aChanels = msg->wfd2_audio_codecs->list->modes;
1925     *aBitwidth = 16;
1926     *aLatency = msg->wfd2_audio_codecs->list->latency;
1927   } else if (!g_strcmp0(msg->wfd2_audio_codecs->list->audio_format, GST_STRING_WFD_AAC_ELDV2)) {
1928     *aCodec = GST_WFD_AUDIO_AAC_ELDV2;
1929     *aFreq = GST_WFD_FREQ_48000;
1930     *aChanels = msg->wfd2_audio_codecs->list->modes;
1931     *aBitwidth = 16;
1932     *aLatency = msg->wfd2_audio_codecs->list->latency;
1933   }
1934   return GST_WFD_OK;
1935 }
1936
1937 GstWFDResult gst_wfd_message_set_supported_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs vCodec,
1938                                                GstWFDVideoNativeResolution vNative, guint64 vNativeResolution,
1939                                                guint64 vCEAResolution, guint64 vVESAResolution, guint64 vHHResolution,
1940                                                guint vProfile, guint vLevel, guint32 vLatency, guint32 vMaxHeight,
1941                                                guint32 vMaxWidth, guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control,
1942                                                guint preferred_display_mode)
1943 {
1944   guint nativeindex = 0;
1945   guint64 temp = vNativeResolution;
1946
1947   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1948
1949   if (!msg->direct_video_formats)
1950     msg->direct_video_formats = g_new0(GstWFD2VideoCodeclist, 1);
1951
1952   if (vCodec != GST_WFD_VIDEO_UNKNOWN) {
1953     msg->direct_video_formats->list = g_new0(GstWFDVideoCodec, 1);
1954
1955     while (temp) {
1956       nativeindex++;
1957       temp >>= 1;
1958     }
1959
1960     if (nativeindex) msg->direct_video_formats->list->native = nativeindex - 1;
1961     msg->direct_video_formats->list->native <<= GST_SHIFT_VIDEO_FORMAT;
1962
1963     if (vNative == GST_WFD_VIDEO_VESA_RESOLUTION)
1964       msg->direct_video_formats->list->native |= 1;
1965     else if (vNative == GST_WFD_VIDEO_HH_RESOLUTION)
1966       msg->direct_video_formats->list->native |= 2;
1967
1968     msg->direct_video_formats->list->preferred_display_mode_supported = preferred_display_mode;
1969     msg->direct_video_formats->list->H264_codec.profile = vProfile;
1970     msg->direct_video_formats->list->H264_codec.level = vLevel;
1971     msg->direct_video_formats->list->H264_codec.max_hres = vMaxWidth;
1972     msg->direct_video_formats->list->H264_codec.max_vres = vMaxHeight;
1973     msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support = vCEAResolution;
1974     msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support = vVESAResolution;
1975     msg->direct_video_formats->list->H264_codec.misc_params.HH_Support = vHHResolution;
1976     msg->direct_video_formats->list->H264_codec.misc_params.latency = vLatency;
1977     msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size = min_slice_size;
1978     msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params = slice_enc_params;
1979     msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support = frame_rate_control;
1980   }
1981   return GST_WFD_OK;
1982 }
1983
1984 GstWFDResult gst_wfd_message_set_preferred_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs vCodec,
1985                                               GstWFDVideoNativeResolution vNative, guint64 vNativeResolution,
1986                                               guint64 vCEAResolution, guint64 vVESAResolution,
1987                                               guint64 vHHResolution,  GstWFDVideoH264Profile vProfile,
1988                                               GstWFDVideoH264Level vLevel, guint32 vLatency, guint32 vMaxHeight,
1989                                               guint32 vMaxWidth, guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control)
1990 {
1991   guint nativeindex = 0;
1992   guint64 temp = vNativeResolution;
1993
1994   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
1995
1996   if (!msg->direct_video_formats)
1997     msg->direct_video_formats = g_new0(GstWFD2VideoCodeclist, 1);
1998   msg->direct_video_formats->list = g_new0(GstWFDVideoCodec, 1);
1999
2000   while (temp) {
2001     nativeindex++;
2002     temp >>= 1;
2003   }
2004
2005   if (nativeindex) msg->direct_video_formats->list->native = nativeindex - 1;
2006   msg->direct_video_formats->list->native <<= GST_SHIFT_VIDEO_FORMAT;
2007
2008   if (vNative == GST_WFD_VIDEO_VESA_RESOLUTION)
2009     msg->direct_video_formats->list->native |= 1;
2010   else if (vNative == GST_WFD_VIDEO_HH_RESOLUTION)
2011     msg->direct_video_formats->list->native |= 2;
2012
2013   msg->direct_video_formats->list->preferred_display_mode_supported = GST_WFD_PREFERRED_DISPLAY_MODE_NOT_SUPPORTED;
2014   msg->direct_video_formats->list->H264_codec.profile = vProfile;
2015   msg->direct_video_formats->list->H264_codec.level = vLevel;
2016   msg->direct_video_formats->list->H264_codec.max_hres = vMaxWidth;
2017   msg->direct_video_formats->list->H264_codec.max_vres = vMaxHeight;
2018   msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support = vCEAResolution;
2019   msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support = vVESAResolution;
2020   msg->direct_video_formats->list->H264_codec.misc_params.HH_Support = vHHResolution;
2021   msg->direct_video_formats->list->H264_codec.misc_params.latency = vLatency;
2022   msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size = min_slice_size;
2023   msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params = slice_enc_params;
2024   msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support = frame_rate_control;
2025   return GST_WFD_OK;
2026 }
2027
2028 GstWFDResult gst_wfd_message_get_supported_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs *vCodec,
2029                                                GstWFDVideoNativeResolution *vNative, guint64 *vNativeResolution,
2030                                                guint64 *vCEAResolution, guint64 *vVESAResolution, guint64 *vHHResolution,
2031                                                guint *vProfile, guint *vLevel, guint32 *vLatency, guint32 *vMaxHeight,
2032                                                guint32 *vMaxWidth, guint32 *min_slice_size, guint32 *slice_enc_params, guint *frame_rate_control)
2033 {
2034   guint nativeindex = 0;
2035
2036   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2037   g_return_val_if_fail(msg->direct_video_formats != NULL, GST_WFD_EINVAL);
2038   g_return_val_if_fail(msg->direct_video_formats->list != NULL, GST_WFD_EINVAL);
2039
2040   *vCodec = GST_WFD_VIDEO_H264;
2041   *vNative = msg->direct_video_formats->list->native & GST_CHECK_VIDEO_FORMAT;
2042   nativeindex = msg->direct_video_formats->list->native >> GST_SHIFT_VIDEO_FORMAT;
2043   *vNativeResolution = (guint64)1 << nativeindex;
2044   *vProfile = msg->direct_video_formats->list->H264_codec.profile;
2045   *vLevel = msg->direct_video_formats->list->H264_codec.level;
2046   *vMaxWidth = msg->direct_video_formats->list->H264_codec.max_hres;
2047   *vMaxHeight = msg->direct_video_formats->list->H264_codec.max_vres;
2048   *vCEAResolution = msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support;
2049   *vVESAResolution = msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support;
2050   *vHHResolution = msg->direct_video_formats->list->H264_codec.misc_params.HH_Support;
2051   *vLatency = msg->direct_video_formats->list->H264_codec.misc_params.latency;
2052   *min_slice_size = msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size;
2053   *slice_enc_params = msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params;
2054   *frame_rate_control = msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support;
2055   return GST_WFD_OK;
2056 }
2057
2058 GstWFDResult gst_wfd_message_get_preferred_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs *vCodec,
2059                                               GstWFDVideoNativeResolution *vNative, guint64 *vNativeResolution,
2060                                               guint64 *vCEAResolution, guint64 *vVESAResolution,
2061                                               guint64 *vHHResolution,  GstWFDVideoH264Profile *vProfile,
2062                                               GstWFDVideoH264Level *vLevel, guint32 *vLatency, guint32 *vMaxHeight,
2063                                               guint32 *vMaxWidth, guint32 *min_slice_size, guint32 *slice_enc_params, guint *frame_rate_control)
2064 {
2065   guint nativeindex = 0;
2066   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2067   g_return_val_if_fail(msg->direct_video_formats != NULL, GST_WFD_EINVAL);
2068   g_return_val_if_fail(msg->direct_video_formats->list != NULL, GST_WFD_EINVAL);
2069
2070   *vCodec = GST_WFD_VIDEO_H264;
2071   *vNative = msg->direct_video_formats->list->native & GST_CHECK_VIDEO_FORMAT;
2072   nativeindex = msg->direct_video_formats->list->native >> GST_SHIFT_VIDEO_FORMAT;
2073   *vNativeResolution = (guint64)1 << nativeindex;
2074   *vProfile = msg->direct_video_formats->list->H264_codec.profile;
2075   *vLevel = msg->direct_video_formats->list->H264_codec.level;
2076   *vMaxWidth = msg->direct_video_formats->list->H264_codec.max_hres;
2077   *vMaxHeight = msg->direct_video_formats->list->H264_codec.max_vres;
2078   *vCEAResolution = msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support;
2079   *vVESAResolution = msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support;
2080   *vHHResolution = msg->direct_video_formats->list->H264_codec.misc_params.HH_Support;
2081   *vLatency = msg->direct_video_formats->list->H264_codec.misc_params.latency;
2082   *min_slice_size = msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size;
2083   *slice_enc_params = msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params;
2084   *frame_rate_control = msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support;
2085   return GST_WFD_OK;
2086 }
2087
2088 GstWFDResult gst_wfd_message_set_contentprotection_type(GstWFDMessage *msg, GstWFDHDCPProtection hdcpversion, guint32 TCPPort)
2089 {
2090   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2091   g_return_val_if_fail(TCPPort <= MAX_PORT_SIZE, GST_WFD_EINVAL);
2092
2093   if (!msg->content_protection) msg->content_protection = g_new0(GstWFDContentProtection, 1);
2094   if (hdcpversion == GST_WFD_HDCP_NONE) return GST_WFD_OK;
2095
2096   msg->content_protection->hdcp2_spec = g_new0(GstWFDHdcp2Spec, 1);
2097   if (hdcpversion == GST_WFD_HDCP_2_0) msg->content_protection->hdcp2_spec->hdcpversion = g_strdup(GST_STRING_WFD_HDCP2_0);
2098   else if (hdcpversion == GST_WFD_HDCP_2_1) msg->content_protection->hdcp2_spec->hdcpversion = g_strdup(GST_STRING_WFD_HDCP2_1);
2099   char str[11] = {0, };
2100   snprintf(str, 11, "port=%d", TCPPort);
2101   msg->content_protection->hdcp2_spec->TCPPort = g_strdup(str);
2102   return GST_WFD_OK;
2103 }
2104
2105 GstWFDResult gst_wfd_message_get_contentprotection_type(GstWFDMessage *msg, GstWFDHDCPProtection *hdcpversion, guint32 *TCPPort)
2106 {
2107   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2108   if (msg->content_protection && msg->content_protection->hdcp2_spec) {
2109     char *result = NULL;
2110     char *ptr = NULL;
2111     if (!g_strcmp0(msg->content_protection->hdcp2_spec->hdcpversion, GST_STRING_WFD_NONE)) {
2112       g_print("HDCP none");
2113       *hdcpversion = GST_WFD_HDCP_NONE;
2114       *TCPPort = 0;
2115       return GST_WFD_OK;
2116     }
2117     if (!g_strcmp0(msg->content_protection->hdcp2_spec->hdcpversion, GST_STRING_WFD_HDCP2_0)) *hdcpversion = GST_WFD_HDCP_2_0;
2118     else if (!g_strcmp0(msg->content_protection->hdcp2_spec->hdcpversion, GST_STRING_WFD_HDCP2_1)) *hdcpversion = GST_WFD_HDCP_2_1;
2119     else {
2120       g_print("Unknown protection type");
2121       *hdcpversion = GST_WFD_HDCP_NONE;
2122       *TCPPort = 0;
2123       return GST_WFD_OK;
2124     }
2125
2126     result = strtok_r(msg->content_protection->hdcp2_spec->TCPPort, GST_STRING_WFD_EQUALS, &ptr);
2127     if (result != NULL) {
2128       result = strtok_r(NULL, GST_STRING_WFD_EQUALS, &ptr);
2129       *TCPPort = atoi(result);
2130     }
2131   } else *hdcpversion = GST_WFD_HDCP_NONE;
2132   return GST_WFD_OK;
2133 }
2134
2135 GstWFDResult gst_wfd_message_set_display_EDID(GstWFDMessage *msg, gboolean edid_supported, guint32 edid_blockcount, gchar *edid_playload)
2136 {
2137   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2138   if (!msg->display_edid) msg->display_edid = g_new0(GstWFDDisplayEdid, 1);
2139   msg->display_edid->edid_supported = edid_supported;
2140   if (!edid_supported) return GST_WFD_OK;
2141   if (edid_blockcount > 0 && edid_blockcount <= EDID_BLOCK_COUNT_MAX_SIZE) {
2142     msg->display_edid->edid_block_count = edid_blockcount;
2143     msg->display_edid->edid_payload = g_malloc(EDID_BLOCK_SIZE * edid_blockcount);
2144     if (msg->display_edid->edid_payload)
2145       memcpy(msg->display_edid->edid_payload, edid_playload, EDID_BLOCK_SIZE * edid_blockcount);
2146     else
2147       msg->display_edid->edid_supported = FALSE;
2148   } else
2149     msg->display_edid->edid_supported = FALSE;
2150
2151   return GST_WFD_OK;
2152 }
2153
2154 GstWFDResult gst_wfd_message_get_display_EDID(GstWFDMessage *msg, gboolean *edid_supported, guint32 *edid_blockcount, gchar **edid_playload)
2155 {
2156   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2157   g_return_val_if_fail(edid_supported != NULL, GST_WFD_EINVAL);
2158   g_return_val_if_fail(edid_blockcount != NULL, GST_WFD_EINVAL);
2159   g_return_val_if_fail(edid_playload != NULL, GST_WFD_EINVAL);
2160
2161   *edid_supported = FALSE;
2162   if (msg->display_edid) {
2163     if (msg->display_edid->edid_supported) {
2164       *edid_blockcount = msg->display_edid->edid_block_count;
2165       if (msg->display_edid->edid_block_count > 0 && msg->display_edid->edid_block_count <= EDID_BLOCK_COUNT_MAX_SIZE) {
2166         char *temp;
2167         temp = g_malloc0(EDID_BLOCK_SIZE * msg->display_edid->edid_block_count);
2168         if (temp) {
2169           memcpy(temp, msg->display_edid->edid_payload, EDID_BLOCK_SIZE * msg->display_edid->edid_block_count);
2170           *edid_playload = temp;
2171           *edid_supported = TRUE;
2172         }
2173       }
2174     }
2175   }
2176   return GST_WFD_OK;
2177 }
2178
2179 GstWFDResult gst_wfd_message_set_coupled_sink(GstWFDMessage *msg, GstWFDCoupledSinkStatus status, const gchar *sink_address)
2180 {
2181   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2182   if (!msg->coupled_sink) msg->coupled_sink = g_new0(GstWFDCoupledSink, 1);
2183   if (status == GST_WFD_SINK_UNKNOWN) return GST_WFD_OK;
2184   msg->coupled_sink->coupled_sink_cap = g_new0(GstWFDCoupledSinkCap, 1);
2185   msg->coupled_sink->coupled_sink_cap->status = status;
2186   msg->coupled_sink->coupled_sink_cap->sink_address = g_strdup(sink_address);
2187   return GST_WFD_OK;
2188 }
2189
2190 GstWFDResult gst_wfd_message_get_coupled_sink(GstWFDMessage *msg, GstWFDCoupledSinkStatus *status, gchar **sink_address)
2191 {
2192   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2193   if (msg->coupled_sink && msg->coupled_sink->coupled_sink_cap) {
2194     *status = msg->coupled_sink->coupled_sink_cap->status;
2195     *sink_address = g_strdup(msg->coupled_sink->coupled_sink_cap->sink_address);
2196   } else *status = GST_WFD_SINK_UNKNOWN;
2197   return GST_WFD_OK;
2198 }
2199
2200 GstWFDResult gst_wfd_message_set_trigger_type(GstWFDMessage *msg, GstWFDTrigger trigger)
2201 {
2202   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2203
2204   if (!msg->trigger_method)
2205     msg->trigger_method = g_new0(GstWFDTriggerMethod, 1);
2206   if (trigger == GST_WFD_TRIGGER_SETUP)
2207     msg->trigger_method->wfd_trigger_method = g_strdup(GST_STRING_WFD_SETUP);
2208   else if (trigger == GST_WFD_TRIGGER_PAUSE)
2209     msg->trigger_method->wfd_trigger_method = g_strdup(GST_STRING_WFD_PAUSE);
2210   else if (trigger == GST_WFD_TRIGGER_TEARDOWN)
2211     msg->trigger_method->wfd_trigger_method = g_strdup(GST_STRING_WFD_TEARDOWN);
2212   else if (trigger == GST_WFD_TRIGGER_TEARDOWN_COUPLING)
2213     msg->trigger_method->wfd_trigger_method = g_strdup(GST_STRING_WFD_TEARDOWN_COUPLING);
2214   else if (trigger == GST_WFD_TRIGGER_PLAY)
2215     msg->trigger_method->wfd_trigger_method = g_strdup(GST_STRING_WFD_PLAY);
2216   else
2217     return GST_WFD_EINVAL;
2218   return GST_WFD_OK;
2219 }
2220
2221 GstWFDResult gst_wfd_message_get_trigger_type(GstWFDMessage *msg, GstWFDTrigger *trigger)
2222 {
2223   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2224   if (!g_strcmp0(msg->trigger_method->wfd_trigger_method, GST_STRING_WFD_SETUP))
2225     *trigger = GST_WFD_TRIGGER_SETUP;
2226   else if (!g_strcmp0(msg->trigger_method->wfd_trigger_method, GST_STRING_WFD_PAUSE))
2227     *trigger = GST_WFD_TRIGGER_PAUSE;
2228   else if (!g_strcmp0(msg->trigger_method->wfd_trigger_method, GST_STRING_WFD_TEARDOWN))
2229     *trigger = GST_WFD_TRIGGER_TEARDOWN;
2230   else if (!g_strcmp0(msg->trigger_method->wfd_trigger_method, GST_STRING_WFD_TEARDOWN_COUPLING))
2231     *trigger = GST_WFD_TRIGGER_TEARDOWN_COUPLING;
2232   else if (!g_strcmp0(msg->trigger_method->wfd_trigger_method, GST_STRING_WFD_PLAY))
2233     *trigger = GST_WFD_TRIGGER_PLAY;
2234   else {
2235     *trigger = GST_WFD_TRIGGER_UNKNOWN;
2236     return GST_WFD_EINVAL;
2237   }
2238   return GST_WFD_OK;
2239 }
2240
2241 GstWFDResult gst_wfd_message_set_presentation_url(GstWFDMessage *msg, gchar *wfd_url0, gchar *wfd_url1)
2242 {
2243   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2244   if (!msg->presentation_url) msg->presentation_url = g_new0(GstWFDPresentationUrl, 1);
2245   if (wfd_url0) msg->presentation_url->wfd_url0 = g_strdup(wfd_url0);
2246   if (wfd_url1) msg->presentation_url->wfd_url1 = g_strdup(wfd_url1);
2247   return GST_WFD_OK;
2248 }
2249
2250 GstWFDResult gst_wfd_message_get_presentation_url(GstWFDMessage *msg, gchar **wfd_url0, gchar **wfd_url1)
2251 {
2252   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2253   if (msg->presentation_url) {
2254     *wfd_url0 = g_strdup(msg->presentation_url->wfd_url0);
2255     *wfd_url1 = g_strdup(msg->presentation_url->wfd_url1);
2256   }
2257   return GST_WFD_OK;
2258 }
2259
2260 GstWFDResult gst_wfd_message_set_preferred_RTP_ports(GstWFDMessage *msg, GstWFDRTSPTransMode trans, GstWFDRTSPProfile profile,
2261                                            GstWFDRTSPLowerTrans lowertrans, guint32 rtp_port0, guint32 rtp_port1)
2262 {
2263   GString *lines;
2264   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2265
2266   if (!msg->client_rtp_ports)
2267     msg->client_rtp_ports = g_new0(GstWFDClientRtpPorts, 1);
2268
2269   if (trans != GST_WFD_RTSP_TRANS_UNKNOWN) {
2270     lines = g_string_new("");
2271     if (trans == GST_WFD_RTSP_TRANS_RTP)  g_string_append_printf(lines, GST_STRING_WFD_RTP);
2272     else if (trans == GST_WFD_RTSP_TRANS_RDT) g_string_append_printf(lines, GST_STRING_WFD_RDT);
2273
2274     if (profile != GST_WFD_RTSP_PROFILE_UNKNOWN) g_string_append_printf(lines, GST_STRING_WFD_SLASH);
2275
2276     if (profile == GST_WFD_RTSP_PROFILE_AVP) g_string_append_printf(lines, GST_STRING_WFD_AVP);
2277     else if (profile == GST_WFD_RTSP_PROFILE_SAVP) g_string_append_printf(lines, GST_STRING_WFD_SAVP);
2278
2279     if (lowertrans != GST_WFD_RTSP_LOWER_TRANS_UNKNOWN) g_string_append_printf(lines, GST_STRING_WFD_SLASH);
2280
2281     if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_UDP) {
2282       g_string_append_printf(lines, GST_STRING_WFD_UDP);
2283       g_string_append_printf(lines, GST_STRING_WFD_SEMI_COLON);
2284       g_string_append_printf(lines, GST_STRING_WFD_UNICAST);
2285     } else if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_UDP_MCAST) {
2286       g_string_append_printf(lines, GST_STRING_WFD_UDP);
2287       g_string_append_printf(lines, GST_STRING_WFD_SEMI_COLON);
2288       g_string_append_printf(lines, GST_STRING_WFD_MULTICAST);
2289     } else if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_TCP) {
2290       g_string_append_printf(lines, GST_STRING_WFD_TCP);
2291       g_string_append_printf(lines, GST_STRING_WFD_SEMI_COLON);
2292       g_string_append_printf(lines, GST_STRING_WFD_UNICAST);
2293     } else if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_HTTP) {
2294       g_string_append_printf(lines, GST_STRING_WFD_TCP_HTTP);
2295     }
2296
2297     msg->client_rtp_ports->profile = g_string_free(lines, FALSE);
2298     msg->client_rtp_ports->rtp_port0 = rtp_port0;
2299     msg->client_rtp_ports->rtp_port1 = rtp_port1;
2300     msg->client_rtp_ports->mode = g_strdup("mode=play");
2301   }
2302   return GST_WFD_OK;
2303 }
2304
2305 GstWFDResult gst_wfd_message_get_preferred_RTP_ports(GstWFDMessage *msg, GstWFDRTSPTransMode *trans, GstWFDRTSPProfile *profile,
2306                                            GstWFDRTSPLowerTrans *lowertrans, guint32 *rtp_port0, guint32 *rtp_port1)
2307 {
2308   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2309   g_return_val_if_fail(msg->client_rtp_ports != NULL, GST_WFD_EINVAL);
2310
2311   if (g_strrstr(msg->client_rtp_ports->profile, GST_STRING_WFD_RTP)) *trans = GST_WFD_RTSP_TRANS_RTP;
2312   if (g_strrstr(msg->client_rtp_ports->profile, GST_STRING_WFD_RDT)) *trans = GST_WFD_RTSP_TRANS_RDT;
2313   if (g_strrstr(msg->client_rtp_ports->profile, GST_STRING_WFD_AVP)) *profile = GST_WFD_RTSP_PROFILE_AVP;
2314   if (g_strrstr(msg->client_rtp_ports->profile, GST_STRING_WFD_SAVP)) *profile = GST_WFD_RTSP_PROFILE_SAVP;
2315   if (g_strrstr(msg->client_rtp_ports->profile, GST_STRING_WFD_UDP) &&
2316     g_strrstr(msg->client_rtp_ports->profile, GST_STRING_WFD_UNICAST)) *lowertrans = GST_WFD_RTSP_LOWER_TRANS_UDP;
2317   if (g_strrstr(msg->client_rtp_ports->profile, GST_STRING_WFD_UDP) &&
2318     g_strrstr(msg->client_rtp_ports->profile, GST_STRING_WFD_MULTICAST)) *lowertrans = GST_WFD_RTSP_LOWER_TRANS_UDP_MCAST;
2319   if (g_strrstr(msg->client_rtp_ports->profile, GST_STRING_WFD_TCP) &&
2320     g_strrstr(msg->client_rtp_ports->profile, GST_STRING_WFD_UNICAST)) *lowertrans = GST_WFD_RTSP_LOWER_TRANS_TCP;
2321   if (g_strrstr(msg->client_rtp_ports->profile, GST_STRING_WFD_TCP_HTTP)) *lowertrans = GST_WFD_RTSP_LOWER_TRANS_HTTP;
2322
2323   *rtp_port0 = msg->client_rtp_ports->rtp_port0;
2324   *rtp_port1 = msg->client_rtp_ports->rtp_port1;
2325
2326   return GST_WFD_OK;
2327 }
2328
2329 GstWFDResult gst_wfd_message_set_audio_sink_type(GstWFDMessage *msg, GstWFDSinkType sinktype)
2330 {
2331   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2332   if (!msg->route) msg->route = g_new0(GstWFDRoute, 1);
2333   if (sinktype == GST_WFD_PRIMARY_SINK) msg->route->destination = g_strdup(GST_STRING_WFD_PRIMARY);
2334   else if (sinktype == GST_WFD_SECONDARY_SINK) msg->route->destination = g_strdup(GST_STRING_WFD_SECONDARY);
2335   return GST_WFD_OK;
2336 }
2337
2338 GstWFDResult gst_wfd_message_get_audio_sink_type(GstWFDMessage *msg, GstWFDSinkType *sinktype)
2339 {
2340   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2341   if (msg->route) {
2342     if (!g_strcmp0(msg->route->destination, GST_STRING_WFD_PRIMARY)) *sinktype = GST_WFD_PRIMARY_SINK;
2343     else if (!g_strcmp0(msg->route->destination, GST_STRING_WFD_SECONDARY)) *sinktype = GST_WFD_SECONDARY_SINK;
2344   }
2345   return GST_WFD_OK;
2346 }
2347
2348 GstWFDResult gst_wfd_message_set_I2C_port(GstWFDMessage *msg, gboolean i2csupport, guint32 i2cport)
2349 {
2350   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2351   if (!msg->I2C) msg->I2C = g_new0(GstWFDI2C, 1);
2352   msg->I2C->I2CPresent = i2csupport;
2353   msg->I2C->I2C_port = i2cport;
2354   return GST_WFD_OK;
2355 }
2356
2357 GstWFDResult gst_wfd_message_get_I2C_port(GstWFDMessage *msg, gboolean *i2csupport, guint32 *i2cport)
2358 {
2359   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2360   if (msg->I2C && msg->I2C->I2CPresent) {
2361     *i2csupport = msg->I2C->I2CPresent;
2362     *i2cport = msg->I2C->I2C_port;
2363   } else *i2csupport = FALSE;
2364   return GST_WFD_OK;
2365 }
2366
2367 GstWFDResult gst_wfd_message_set_av_format_change_timing(GstWFDMessage *msg, guint64 PTS, guint64 DTS)
2368 {
2369   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2370   if (!msg->av_format_change_timing) msg->av_format_change_timing = g_new0(GstWFDAVFormatChangeTiming, 1);
2371   msg->av_format_change_timing->PTS = PTS;
2372   msg->av_format_change_timing->DTS = DTS;
2373   return GST_WFD_OK;
2374 }
2375
2376 GstWFDResult gst_wfd_message_get_av_format_change_timing(GstWFDMessage *msg, guint64 *PTS, guint64 *DTS)
2377 {
2378   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2379   if (msg->av_format_change_timing) {
2380     *PTS = msg->av_format_change_timing->PTS;
2381     *DTS = msg->av_format_change_timing->DTS;
2382   }
2383   return GST_WFD_OK;
2384 }
2385
2386 #ifdef STANDBY_RESUME_CAPABILITY
2387 GstWFDResult gst_wfd_message_set_standby_resume_capability(GstWFDMessage *msg, gboolean supported)
2388 {
2389   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2390   if (!msg->standby_resume_capability) msg->standby_resume_capability = g_new0(GstWFDStandbyResumeCapability, 1);
2391   msg->standby_resume_capability->standby_resume_cap = supported;
2392   return GST_WFD_OK;
2393 }
2394
2395 GstWFDResult gst_wfd_message_get_standby_resume_capability(GstWFDMessage *msg, gboolean *supported)
2396 {
2397   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2398   if (msg->standby_resume_capability) *supported = msg->standby_resume_capability->standby_resume_cap;
2399   return GST_WFD_OK;
2400 }
2401 #endif
2402 GstWFDResult gst_wfd_message_set_standby(GstWFDMessage *msg, gboolean standby_enable)
2403 {
2404   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2405   if (!msg->standby) msg->standby = g_new0(GstWFDStandby, 1);
2406   msg->standby->wfd_standby = standby_enable;
2407   return GST_WFD_OK;
2408 }
2409
2410 GstWFDResult gst_wfd_message_get_standby(GstWFDMessage *msg, gboolean *standby_enable)
2411 {
2412   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2413   if (msg->standby) *standby_enable = msg->standby->wfd_standby;
2414   return GST_WFD_OK;
2415 }
2416
2417 GstWFDResult gst_wfd_message_set_connector_type(GstWFDMessage *msg, GstWFDConnector connector)
2418 {
2419   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2420   if (!msg->connector_type) msg->connector_type = g_new0(GstWFDConnectorType, 1);
2421   msg->connector_type->connector_type = connector;
2422   return GST_WFD_OK;
2423 }
2424
2425 GstWFDResult gst_wfd_message_get_connector_type(GstWFDMessage *msg, GstWFDConnector *connector)
2426 {
2427   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2428   if (msg->connector_type) *connector = msg->connector_type->connector_type;
2429   return GST_WFD_OK;
2430 }
2431
2432 GstWFDResult gst_wfd_message_set_idr_request(GstWFDMessage *msg)
2433 {
2434   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2435   if (!msg->idr_request) msg->idr_request = g_new0(GstWFDIdrRequest, 1);
2436   msg->idr_request->idr_request = TRUE;
2437   return GST_WFD_OK;
2438 }
2439
2440 GstWFDResult gst_wfd_message_get_direct_streaming_mode(GstWFDMessage *msg, gboolean *active)
2441 {
2442   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2443   if (msg->direct_mode) *active = msg->direct_mode->direct_mode;
2444   return GST_WFD_OK;
2445 }
2446
2447 GstWFDResult gst_wfd_message_set_preferred_TCP_ports(GstWFDMessage *msg, GstWFDRTSPTransMode trans, GstWFDRTSPProfile profile,
2448                                            GstWFDRTSPLowerTrans lowertrans, guint32 rtp_port0, guint32 rtp_port1)
2449 {
2450   GString *lines;
2451   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2452
2453   if (!msg->tcp_ports)
2454     msg->tcp_ports = g_new0(GstWFDTCPPorts, 1);
2455
2456   if (trans != GST_WFD_RTSP_TRANS_UNKNOWN) {
2457     lines = g_string_new("");
2458     if (trans == GST_WFD_RTSP_TRANS_RTP)  g_string_append_printf(lines, GST_STRING_WFD_RTP);
2459     else if (trans == GST_WFD_RTSP_TRANS_RDT) g_string_append_printf(lines, GST_STRING_WFD_RDT);
2460
2461     if (profile != GST_WFD_RTSP_PROFILE_UNKNOWN) g_string_append_printf(lines, GST_STRING_WFD_SLASH);
2462
2463     if (profile == GST_WFD_RTSP_PROFILE_AVP) g_string_append_printf(lines, GST_STRING_WFD_AVP);
2464     else if (profile == GST_WFD_RTSP_PROFILE_SAVP) g_string_append_printf(lines, GST_STRING_WFD_SAVP);
2465
2466     if (lowertrans != GST_WFD_RTSP_LOWER_TRANS_UNKNOWN) g_string_append_printf(lines, GST_STRING_WFD_SLASH);
2467
2468     if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_UDP) {
2469       g_string_append_printf(lines, GST_STRING_WFD_UDP);
2470       g_string_append_printf(lines, GST_STRING_WFD_SEMI_COLON);
2471       g_string_append_printf(lines, GST_STRING_WFD_UNICAST);
2472     } else if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_UDP_MCAST) {
2473       g_string_append_printf(lines, GST_STRING_WFD_UDP);
2474       g_string_append_printf(lines, GST_STRING_WFD_SEMI_COLON);
2475       g_string_append_printf(lines, GST_STRING_WFD_MULTICAST);
2476     } else if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_TCP) {
2477       g_string_append_printf(lines, GST_STRING_WFD_TCP);
2478       g_string_append_printf(lines, GST_STRING_WFD_SEMI_COLON);
2479       g_string_append_printf(lines, GST_STRING_WFD_UNICAST);
2480     } else if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_HTTP) {
2481       g_string_append_printf(lines, GST_STRING_WFD_TCP_HTTP);
2482     }
2483
2484     msg->tcp_ports->profile = g_string_free(lines, FALSE);
2485     msg->tcp_ports->rtp_port0 = rtp_port0;
2486     msg->tcp_ports->rtp_port1 = rtp_port1;
2487     msg->tcp_ports->mode = g_strdup("mode=play");
2488   }
2489   return GST_WFD_OK;
2490 }
2491
2492 GstWFDResult gst_wfd_message_get_preferred_TCP_ports(GstWFDMessage *msg, GstWFDRTSPTransMode *trans, GstWFDRTSPProfile *profile,
2493                                            GstWFDRTSPLowerTrans *lowertrans, guint32 *rtp_port0, guint32 *rtp_port1)
2494 {
2495   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2496   g_return_val_if_fail(msg->tcp_ports != NULL, GST_WFD_EINVAL);
2497
2498   if (g_strrstr(msg->tcp_ports->profile, GST_STRING_WFD_RTP)) *trans = GST_WFD_RTSP_TRANS_RTP;
2499   if (g_strrstr(msg->tcp_ports->profile, GST_STRING_WFD_RDT)) *trans = GST_WFD_RTSP_TRANS_RDT;
2500   if (g_strrstr(msg->tcp_ports->profile, GST_STRING_WFD_AVP)) *profile = GST_WFD_RTSP_PROFILE_AVP;
2501   if (g_strrstr(msg->tcp_ports->profile, GST_STRING_WFD_SAVP)) *profile = GST_WFD_RTSP_PROFILE_SAVP;
2502   if (g_strrstr(msg->tcp_ports->profile, GST_STRING_WFD_UDP) &&
2503     g_strrstr(msg->tcp_ports->profile, GST_STRING_WFD_UNICAST)) *lowertrans = GST_WFD_RTSP_LOWER_TRANS_UDP;
2504   if (g_strrstr(msg->tcp_ports->profile, GST_STRING_WFD_UDP) &&
2505     g_strrstr(msg->tcp_ports->profile, GST_STRING_WFD_MULTICAST)) *lowertrans = GST_WFD_RTSP_LOWER_TRANS_UDP_MCAST;
2506   if (g_strrstr(msg->tcp_ports->profile, GST_STRING_WFD_TCP) &&
2507     g_strrstr(msg->tcp_ports->profile, GST_STRING_WFD_UNICAST)) *lowertrans = GST_WFD_RTSP_LOWER_TRANS_TCP;
2508   if (g_strrstr(msg->tcp_ports->profile, GST_STRING_WFD_TCP_HTTP)) *lowertrans = GST_WFD_RTSP_LOWER_TRANS_HTTP;
2509
2510   *rtp_port0 = msg->tcp_ports->rtp_port0;
2511   *rtp_port1 = msg->tcp_ports->rtp_port1;
2512
2513   return GST_WFD_OK;
2514 }
2515
2516 GstWFDResult gst_wfd_message_set_buffer_length(GstWFDMessage *msg, guint buf_len)
2517 {
2518   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2519   if (!msg->buf_len) msg->buf_len = g_new0(GstWFDBufferLen, 1);
2520   msg->buf_len->buf_len = buf_len;
2521   return GST_WFD_OK;
2522 }
2523
2524 GstWFDResult gst_wfd_message_get_buffer_length(GstWFDMessage *msg, guint *buf_len)
2525 {
2526   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2527   if (msg->buf_len) *buf_len = msg->buf_len->buf_len;
2528   return GST_WFD_OK;
2529 }
2530
2531 GstWFDResult gst_wfd_message_set_audio_status(GstWFDMessage *msg, guint aud_bufsize, guint64 aud_pts)
2532 {
2533   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2534   if (!msg->audio_status) msg->audio_status = g_new0(GstWFDAudioStatus, 1);
2535   msg->audio_status->aud_bufsize = aud_bufsize;
2536   msg->audio_status->aud_pts = aud_pts;
2537   return GST_WFD_OK;
2538 }
2539
2540 GstWFDResult gst_wfd_message_set_video_status(GstWFDMessage *msg, guint vid_bufsize, guint64 vid_pts)
2541 {
2542   g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL);
2543   if (!msg->video_status) msg->video_status = g_new0(GstWFDVideoStatus, 1);
2544   msg->video_status->vid_bufsize = vid_bufsize;
2545   msg->video_status->vid_pts = vid_pts;
2546   return GST_WFD_OK;
2547 }