From 2a87a7c0071dd26ad38cca3de4f6fc924567426e Mon Sep 17 00:00:00 2001 From: SeokHoon Lee Date: Wed, 5 Jul 2017 11:08:03 +0900 Subject: [PATCH] direct streaming initial version Signed-off-by: SeokHoon Lee Change-Id: I4a952e862132e345dc5bae1536889c5f7bf99b0b --- packaging/gst-plugins-tizen.spec | 2 +- wfdmanager/wfdbase/gstwfdbasesrc.c | 175 +++++++++- wfdmanager/wfdbase/gstwfdsinkmessage.c | 575 ++++++++++++++++++++++++++++++--- wfdmanager/wfdbase/gstwfdsinkmessage.h | 46 +++ wfdtizenmanager/gstwfdtizenmessage.c | 24 +- 5 files changed, 757 insertions(+), 65 deletions(-) mode change 100755 => 100644 wfdmanager/wfdbase/gstwfdsinkmessage.h mode change 100755 => 100644 wfdtizenmanager/gstwfdtizenmessage.c diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index 2f8c07d..12e4869 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -9,7 +9,7 @@ Name: gst-plugins-tizen Version: 1.0.0 Summary: GStreamer tizen plugins (common) -Release: 42 +Release: 43 Group: Multimedia/Framework Url: http://gstreamer.freedesktop.org/ License: LGPL-2.1+ diff --git a/wfdmanager/wfdbase/gstwfdbasesrc.c b/wfdmanager/wfdbase/gstwfdbasesrc.c index 2c090a6..16cf91f 100644 --- a/wfdmanager/wfdbase/gstwfdbasesrc.c +++ b/wfdmanager/wfdbase/gstwfdbasesrc.c @@ -231,6 +231,9 @@ struct _GstWFDBaseSrcPrivate guint audio_channels; guint audio_bitwidth; guint audio_frequency; + + gboolean direct_streaming_mode; + gint primary_tcpport; guint buf_len; GstRTSPLowerTrans protocol; @@ -1510,6 +1513,114 @@ gst_wfd_base_src_handle_request (GstWFDBaseSrc * src, GstRTSPMessage * request) } } + /* Note : wfd2-audio-codecs : + * The wfd2-audio-codecs parameter specifies the audio formats supported in the WFD session. + * Valid audio codecs are LPCM, AAC, AC3. + * Primary sink should support one of audio codecs. + */ + if(wfd_msg->direct_audio_codecs) { + guint audio_codec = 0; + guint audio_sampling_frequency = 0; + guint audio_channels = 0; + guint audio_latency = 0; + + if(priv->wfd_audio_codecs != NULL) { + GstStructure *wfd_audio_codecs = priv->wfd_audio_codecs; + if (gst_structure_has_field (wfd_audio_codecs, "audio_codec")) + gst_structure_get_uint (wfd_audio_codecs, "audio_codec", &audio_codec); + if (gst_structure_has_field (wfd_audio_codecs, "audio_latency")) + gst_structure_get_uint (wfd_audio_codecs, "audio_latency", &audio_latency); + if (gst_structure_has_field (wfd_audio_codecs, "audio_channels")) + gst_structure_get_uint (wfd_audio_codecs, "audio_channels", &audio_channels); + if (gst_structure_has_field (wfd_audio_codecs, "audio_sampling_frequency")) + gst_structure_get_uint (wfd_audio_codecs, "audio_sampling_frequency", &audio_sampling_frequency); + } + + wfd_res = gst_wfd_message_set_supported_direct_audio_format (wfd_msg, + audio_codec, + audio_sampling_frequency, + audio_channels, + 16, + audio_latency); + if (wfd_res != GST_WFD_OK) { + GST_ERROR ("gst_wfd_message_set_supported_direct_audio_format is failed"); + goto message_config_error; + } + } + + /* Note : wfd2-video-formats : + * The wfd2-video-formats parameter specifies the supported video resolutions, + * H.264 codec profile, level, decoder latency, minimum slice size, slice encoding parameters + * and support for video frame rate control (including explicit frame rate change and implicit video frame skipping. + */ + if(wfd_msg->direct_video_formats) { + guint video_codec = 0; + guint video_native_resolution = 0; + guint64 video_cea_support = 0; + guint64 video_vesa_support = 0; + guint64 video_hh_support = 0; + guint video_profile = 0; + guint video_level = 0; + guint video_latency = 0; + gint video_vertical_resolution = 0; + gint video_horizontal_resolution = 0; + gint video_minimum_slicing = 0; + gint video_slice_enc_param = 0; + gint video_framerate_control_support = 0; + + if (priv->wfd_video_formats != NULL) { + GstStructure *wfd_video_formats = priv->wfd_video_formats; + + if (gst_structure_has_field (wfd_video_formats, "video_codec")) + gst_structure_get_uint (wfd_video_formats, "video_codec", &video_codec); + if (gst_structure_has_field (wfd_video_formats, "video_native_resolution")) + gst_structure_get_uint (wfd_video_formats, "video_native_resolution", &video_native_resolution); + if (gst_structure_has_field (wfd_video_formats, "video_cea_support")) + gst_structure_get_uint64 (wfd_video_formats, "video_cea_support", &video_cea_support); + if (gst_structure_has_field (wfd_video_formats, "video_vesa_support")) + gst_structure_get_uint64 (wfd_video_formats, "video_vesa_support", &video_vesa_support); + if (gst_structure_has_field (wfd_video_formats, "video_hh_support")) + gst_structure_get_uint64 (wfd_video_formats, "video_hh_support", &video_hh_support); + if (gst_structure_has_field (wfd_video_formats, "video_profile")) + gst_structure_get_uint (wfd_video_formats, "video_profile", &video_profile); + if (gst_structure_has_field (wfd_video_formats, "video_level")) + gst_structure_get_uint (wfd_video_formats, "video_level", &video_level); + if (gst_structure_has_field (wfd_video_formats, "video_latency")) + gst_structure_get_uint (wfd_video_formats, "video_latency", &video_latency); + if (gst_structure_has_field (wfd_video_formats, "video_vertical_resolution")) + gst_structure_get_int (wfd_video_formats, "video_vertical_resolution", &video_vertical_resolution); + if (gst_structure_has_field (wfd_video_formats, "video_horizontal_resolution")) + gst_structure_get_int (wfd_video_formats, "video_horizontal_resolution", &video_horizontal_resolution); + if (gst_structure_has_field (wfd_video_formats, "video_minimum_slicing")) + gst_structure_get_int (wfd_video_formats, "video_minimum_slicing", &video_minimum_slicing); + if (gst_structure_has_field (wfd_video_formats, "video_slice_enc_param")) + gst_structure_get_int (wfd_video_formats, "video_slice_enc_param", &video_slice_enc_param); + if (gst_structure_has_field (wfd_video_formats, "video_framerate_control_support")) + gst_structure_get_int (wfd_video_formats, "video_framerate_control_support", &video_framerate_control_support); + } + + wfd_res = gst_wfd_message_set_supported_direct_video_format (wfd_msg, + video_codec, + GST_WFD_VIDEO_CEA_RESOLUTION, + video_native_resolution, + video_cea_support, + video_vesa_support, + video_hh_support, + video_profile, + video_level, + video_latency, + video_vertical_resolution, + video_horizontal_resolution, + video_minimum_slicing, + video_slice_enc_param, + video_framerate_control_support, + GST_WFD_PREFERRED_DISPLAY_MODE_NOT_SUPPORTED); + if (wfd_res != GST_WFD_OK) { + GST_ERROR ("gst_wfd_message_set_supported_direct_video_format is failed"); + goto message_config_error; + } + } + /* Note : wfd-3d-formats : * The wfd-3d-formats parameter specifies the support for stereoscopic video capabilities. */ @@ -1750,6 +1861,8 @@ gst_wfd_base_src_handle_request (GstWFDBaseSrc * src, GstRTSPMessage * request) if (wfd_msg->audio_codecs || wfd_msg->video_formats || wfd_msg->video_3d_formats) { GstStructure *stream_info = gst_structure_new ("WFDStreamInfo", NULL, NULL); + priv->direct_streaming_mode = FALSE; + if (wfd_msg->audio_codecs && wfd_msg->audio_codecs->count > 0) { res = gst_wfd_base_src_get_wfd_audio_codecseter (src, wfd_msg); if (res != GST_RTSP_OK) { @@ -1784,6 +1897,42 @@ gst_wfd_base_src_handle_request (GstWFDBaseSrc * src, GstRTSPMessage * request) g_signal_emit (src, gst_wfd_base_src_signals[SIGNAL_UPDATE_MEDIA_INFO], 0, stream_info); } + if (wfd_msg->direct_audio_codecs && wfd_msg->direct_video_formats && wfd_msg->direct_mode) { + GstStructure *stream_info = gst_structure_new ("WFDStreamInfo", NULL, NULL); + + priv->direct_streaming_mode = TRUE; + + if(wfd_msg->direct_audio_codecs) { + res = gst_wfd_base_src_get_wfd_audio_codecseter(src, wfd_msg); + if(res != GST_RTSP_OK) { + goto message_config_error; + } + + gst_structure_set (stream_info, + "audio_format", G_TYPE_STRING, priv->audio_format, + "audio_channels", G_TYPE_INT, priv->audio_channels, + "audio_rate", G_TYPE_INT, priv->audio_frequency, + "audio_bitwidth", G_TYPE_INT, priv->audio_bitwidth/16, + NULL); + } + + if(wfd_msg->direct_video_formats) { + res = gst_wfd_base_src_get_wfd_video_formatseter(src, wfd_msg); + if(res != GST_RTSP_OK) { + goto message_config_error; + } + + gst_structure_set (stream_info, + "video_format", G_TYPE_STRING, "H264", + "video_width", G_TYPE_INT, priv->video_width, + "video_height", G_TYPE_INT, priv->video_height, + "video_framerate", G_TYPE_INT, priv->video_framerate, + NULL); + } + + g_signal_emit (src, gst_wfd_base_src_signals[SIGNAL_UPDATE_MEDIA_INFO], 0, stream_info); + } + /* Note : wfd-presentation-url : * The wfd-presentation-url parameter describes the Universial Resource Identified (URI) * to be used in the RTSP Setup (RTSP M6) request message in order to setup the WFD session from the WFD sink to the WFD source. @@ -4187,13 +4336,19 @@ gst_wfd_base_src_get_wfd_audio_codecseter(GstWFDBaseSrc * src, GstWFDMessage * m guint32 audio_latency = 0; GstWFDResult wfd_res = GST_WFD_OK; - wfd_res = gst_wfd_message_get_preferred_audio_format (msg, &audio_format, &audio_frequency, &audio_channels, &audio_bitwidth, &audio_latency); + if (priv->direct_streaming_mode) { + wfd_res = gst_wfd_message_get_preferred_direct_audio_format (msg, &audio_format, &audio_frequency, &audio_channels, &audio_bitwidth, &audio_latency); + priv->audio_format = g_strdup(msg->direct_audio_codecs->list->audio_format); + } + else { + wfd_res = gst_wfd_message_get_preferred_audio_format (msg, &audio_format, &audio_frequency, &audio_channels, &audio_bitwidth, &audio_latency); + priv->audio_format = g_strdup(msg->audio_codecs->list->audio_format); + } if(wfd_res != GST_WFD_OK) { GST_ERROR("Failed to get preferred audio format."); return GST_RTSP_ERROR; } - priv->audio_format = g_strdup(msg->audio_codecs->list->audio_format); if(audio_frequency == GST_WFD_FREQ_48000) audio_frequency = 48000; else if(audio_frequency == GST_WFD_FREQ_44100) @@ -4234,10 +4389,18 @@ gst_wfd_base_src_get_wfd_video_formatseter(GstWFDBaseSrc * src, GstWFDMessage * guint cvLatency = 0; GstWFDResult wfd_res = GST_WFD_OK; - wfd_res = gst_wfd_message_get_preferred_video_format (msg, &cvCodec, &cNative, &cNativeResolution, - &cCEAResolution, &cVESAResolution, &cHHResolution, - &cProfile, &cLevel, &cvLatency, &cMaxHeight, - &cMaxWidth, &cmin_slice_size, &cslice_enc_params, &cframe_rate_control); + if (src->priv->direct_streaming_mode) { + wfd_res = gst_wfd_message_get_preferred_direct_video_format (msg, &cvCodec, &cNative, &cNativeResolution, + &cCEAResolution, &cVESAResolution, &cHHResolution, + &cProfile, &cLevel, &cvLatency, &cMaxHeight, + &cMaxWidth, &cmin_slice_size, &cslice_enc_params, &cframe_rate_control); + } + else { + wfd_res = gst_wfd_message_get_preferred_video_format (msg, &cvCodec, &cNative, &cNativeResolution, + &cCEAResolution, &cVESAResolution, &cHHResolution, + &cProfile, &cLevel, &cvLatency, &cMaxHeight, + &cMaxWidth, &cmin_slice_size, &cslice_enc_params, &cframe_rate_control); + } if(wfd_res != GST_WFD_OK) { GST_ERROR("Failed to get preferred video format."); return GST_RTSP_ERROR; diff --git a/wfdmanager/wfdbase/gstwfdsinkmessage.c b/wfdmanager/wfdbase/gstwfdsinkmessage.c index 333eada..2957c29 100644 --- a/wfdmanager/wfdbase/gstwfdsinkmessage.c +++ b/wfdmanager/wfdbase/gstwfdsinkmessage.c @@ -39,7 +39,7 @@ /* FIXME, is currently allocated on the stack */ #define MAX_LINE_LEN (1024 * 16) -#define FREE_STRING(field) if (field != NULL) g_free(field); (field) = NULL; +#define FREE_STRING(field) g_free(field); (field) = NULL; #define REPLACE_STRING(field, val) FREE_STRING(field); (field) = g_strdup(val); #define EDID_BLOCK_SIZE 128 #define EDID_BLOCK_COUNT_MAX_SIZE 256 @@ -131,6 +131,24 @@ gst_wfd_message_uninit(GstWFDMessage *msg) FREE_STRING(msg->video_formats); } + if (msg->direct_audio_codecs) { + guint i = 0; + if (msg->direct_audio_codecs->list) { + for (; i < msg->direct_audio_codecs->count; i++) { + FREE_STRING(msg->direct_audio_codecs->list[i].audio_format); + msg->direct_audio_codecs->list[i].modes = 0; + msg->direct_audio_codecs->list[i].latency = 0; + } + FREE_STRING(msg->direct_audio_codecs->list); + } + FREE_STRING(msg->direct_audio_codecs); + } + + if (msg->direct_video_formats) { + FREE_STRING(msg->direct_video_formats->list); + FREE_STRING(msg->direct_video_formats); + } + if (msg->video_3d_formats) { FREE_STRING(msg->video_3d_formats->list); FREE_STRING(msg->video_3d_formats); @@ -181,33 +199,14 @@ gst_wfd_message_uninit(GstWFDMessage *msg) FREE_STRING(msg->route); } - if (msg->I2C) { - FREE_STRING(msg->I2C); - } - - if (msg->av_format_change_timing) { - FREE_STRING(msg->av_format_change_timing); - } - - if (msg->preferred_display_mode) { - FREE_STRING(msg->preferred_display_mode); - } - - if (msg->standby_resume_capability) { - FREE_STRING(msg->standby_resume_capability); - } - - if (msg->standby) { - FREE_STRING(msg->standby); - } - - if (msg->connector_type) { - FREE_STRING(msg->connector_type); - } - - if (msg->idr_request) { - FREE_STRING(msg->idr_request); - } + FREE_STRING(msg->I2C); + FREE_STRING(msg->av_format_change_timing); + FREE_STRING(msg->preferred_display_mode); + FREE_STRING(msg->standby_resume_capability); + FREE_STRING(msg->standby); + FREE_STRING(msg->connector_type); + FREE_STRING(msg->idr_request); + FREE_STRING(msg->direct_mode); if (msg->tcp_ports) { FREE_STRING(msg->tcp_ports->profile); @@ -215,17 +214,10 @@ gst_wfd_message_uninit(GstWFDMessage *msg) FREE_STRING(msg->tcp_ports); } - if (msg->buf_len) { - FREE_STRING(msg->buf_len); - } - - if (msg->audio_status) { - FREE_STRING(msg->audio_status); - } + FREE_STRING(msg->buf_len); + FREE_STRING(msg->audio_status); + FREE_STRING(msg->video_status); - if (msg->video_status) { - FREE_STRING(msg->video_status); - } return GST_WFD_OK; } @@ -326,6 +318,58 @@ gst_wfd_message_as_text(const GstWFDMessage *msg) g_string_append_printf(lines, GST_STRING_WFD_CRLF); } + /* list of audio codecs for direct streaming */ + if (msg->direct_audio_codecs) { + guint i = 0; + g_string_append_printf(lines, GST_STRING_WFD2_AUDIO_CODECS); + if (msg->direct_audio_codecs->list) { + g_string_append_printf(lines, GST_STRING_WFD_COLON); + for (; i < msg->direct_audio_codecs->count; i++) { + g_string_append_printf(lines, " %s", msg->direct_audio_codecs->list[i].audio_format); + g_string_append_printf(lines, " %08x", msg->direct_audio_codecs->list[i].modes); + g_string_append_printf(lines, " %02x", msg->direct_audio_codecs->list[i].latency); + if ((i + 1) < msg->direct_audio_codecs->count) + g_string_append_printf(lines, GST_STRING_WFD_COMMA); + } + } + g_string_append_printf(lines, GST_STRING_WFD_CRLF); + } + + /* list of video codecs for direct streaming */ + if (msg->direct_video_formats) { + g_string_append_printf(lines, GST_STRING_WFD2_VIDEO_FORMATS); + if (msg->direct_video_formats->list) { + g_string_append_printf(lines, GST_STRING_WFD_COLON); + g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->native); + g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->preferred_display_mode_supported); + g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->H264_codec.profile); + g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->H264_codec.level); + g_string_append_printf(lines, " %08llx", msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support); + g_string_append_printf(lines, " %08llx", msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support); + g_string_append_printf(lines, " %08llx", msg->direct_video_formats->list->H264_codec.misc_params.HH_Support); + g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->H264_codec.misc_params.latency); + g_string_append_printf(lines, " %04x", msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size); + g_string_append_printf(lines, " %04x", msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params); + g_string_append_printf(lines, " %02x", msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support); + + if (msg->direct_video_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED + && msg->direct_video_formats->list->H264_codec.max_hres) { + g_string_append_printf(lines, " %04x", msg->direct_video_formats->list->H264_codec.max_hres); + } else { + g_string_append_printf(lines, GST_STRING_WFD_SPACE); + g_string_append_printf(lines, GST_STRING_WFD_NONE); + } + if (msg->direct_video_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED + && msg->direct_video_formats->list->H264_codec.max_vres) { + g_string_append_printf(lines, " %04x", msg->direct_video_formats->list->H264_codec.max_vres); + } else { + g_string_append_printf(lines, GST_STRING_WFD_SPACE); + g_string_append_printf(lines, GST_STRING_WFD_NONE); + } + } + g_string_append_printf(lines, GST_STRING_WFD_CRLF); + } + /* list of video 3D codecs */ if (msg->video_3d_formats) { g_string_append_printf(lines, GST_STRING_WFD_3D_VIDEO_FORMATS); @@ -532,6 +576,14 @@ gst_wfd_message_as_text(const GstWFDMessage *msg) g_string_append_printf(lines, GST_STRING_WFD_CRLF); } + if (msg->direct_mode && msg->direct_mode->direct_mode) { + g_string_append_printf(lines, GST_STRING_WFD2_DIRECT_STREAMING_MODE); + g_string_append_printf(lines, GST_STRING_WFD_COLON); + g_string_append_printf(lines, GST_STRING_WFD_SPACE); + g_string_append_printf(lines, GST_STRING_WFD_ACTIVE); + g_string_append_printf(lines, GST_STRING_WFD_CRLF); + } + if (msg->tcp_ports) { g_string_append_printf(lines, GST_STRING_WFD2_TCP_PORTS); if (msg->tcp_ports->profile) { @@ -566,6 +618,7 @@ gst_wfd_message_as_text(const GstWFDMessage *msg) g_string_append_printf(lines, " %lld", msg->video_status->vid_pts); g_string_append_printf(lines, GST_STRING_WFD_CRLF); } + /*g_string_append_printf (lines, "\0"); */ /*if(g_str_has_suffix (lines, "\r\n\0")) { @@ -593,6 +646,16 @@ gchar *gst_wfd_message_param_names_as_text(const GstWFDMessage *msg) g_string_append_printf(lines, GST_STRING_WFD_VIDEO_FORMATS); g_string_append_printf(lines, GST_STRING_WFD_CRLF); } + /* list of audio codecs for direct streaming */ + if (msg->direct_audio_codecs) { + g_string_append_printf(lines, GST_STRING_WFD2_AUDIO_CODECS); + g_string_append_printf(lines, GST_STRING_WFD_CRLF); + } + /* list of video codecs for direct streaming*/ + if (msg->direct_video_formats) { + g_string_append_printf(lines, GST_STRING_WFD2_VIDEO_FORMATS); + g_string_append_printf(lines, GST_STRING_WFD_CRLF); + } /* list of video 3D codecs */ if (msg->video_3d_formats) { g_string_append_printf(lines, GST_STRING_WFD_3D_VIDEO_FORMATS); @@ -654,6 +717,10 @@ gchar *gst_wfd_message_param_names_as_text(const GstWFDMessage *msg) g_string_append_printf(lines, GST_STRING_WFD_IDR_REQUEST); g_string_append_printf(lines, GST_STRING_WFD_CRLF); } + if (msg->direct_mode) { + g_string_append_printf(lines, GST_STRING_WFD2_DIRECT_STREAMING_MODE); + g_string_append_printf(lines, GST_STRING_WFD_CRLF); + } if (msg->tcp_ports) { g_string_append_printf(lines, GST_STRING_WFD2_TCP_PORTS); g_string_append_printf(lines, GST_STRING_WFD_CRLF); @@ -795,6 +862,57 @@ gst_wfd_parse_line(GstWFDMessage *msg, gchar *buffer) } } } + } else if (!g_strcmp0(type, GST_STRING_WFD2_AUDIO_CODECS)) { + msg->direct_audio_codecs = g_new0(GstWFD2AudioCodeclist, 1); + if (strlen(v)) { + guint i = 0; + msg->direct_audio_codecs->count = strlen(v) / 16; + msg->direct_audio_codecs->list = g_new0(GstWFDAudioCodec, msg->direct_audio_codecs->count); + for (; i < msg->direct_audio_codecs->count; i++) { + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_STRING(msg->direct_audio_codecs->list[i].audio_format); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_audio_codecs->list[i].modes); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_audio_codecs->list[i].latency); + GST_WFD_SKIP_COMMA(v); + } + } + } else if (!g_strcmp0(type, GST_STRING_WFD2_VIDEO_FORMATS)) { + msg->direct_video_formats = g_new0(GstWFD2VideoCodeclist, 1); + if (strlen(v)) { + msg->direct_video_formats->count = 1; + msg->direct_video_formats->list = g_new0(GstWFDVideoCodec, 1); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->native); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->preferred_display_mode_supported); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.profile); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.level); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.HH_Support); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.latency); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support); + GST_WFD_SKIP_SPACE(v); + if (msg->direct_video_formats->list->preferred_display_mode_supported == GST_WFD_PREFERRED_DISPLAY_MODE_SUPPORTED) { + GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.max_hres); + GST_WFD_SKIP_SPACE(v); + GST_WFD_READ_UINT32(msg->direct_video_formats->list->H264_codec.max_vres); + GST_WFD_SKIP_SPACE(v); + } + } } else if (!g_strcmp0(type, GST_STRING_WFD_3D_VIDEO_FORMATS)) { msg->video_3d_formats = g_new0(GstWFD3DFormats, 1); if (strlen(v)) { @@ -1007,6 +1125,15 @@ gst_wfd_parse_line(GstWFDMessage *msg, gchar *buffer) } else if (!g_strcmp0(type, GST_STRING_WFD_IDR_REQUEST)) { msg->idr_request = g_new0(GstWFDIdrRequest, 1); msg->idr_request->idr_request = TRUE; + } else if (!g_strcmp0(type, GST_STRING_WFD2_DIRECT_STREAMING_MODE)) { + msg->direct_mode = g_new0(GstWFD2DirectStreamingMode, 1); + if (strlen(v)) { + GST_WFD_SKIP_SPACE(v); + if (!g_strcmp0(v, GST_STRING_WFD_ACTIVE)) + msg->direct_mode->direct_mode = TRUE; + else + msg->direct_mode->direct_mode = FALSE; + } } else if (!g_strcmp0(type, GST_STRING_WFD2_TCP_PORTS)) { msg->tcp_ports = g_new0(GstWFDTCPPorts, 1); if (strlen(v)) { @@ -1171,6 +1298,88 @@ gst_wfd_message_dump(const GstWFDMessage *msg) } } + if (msg->direct_audio_codecs) { + guint i = 0; + g_print("Audio supported formats for direct streaming : "); + for (; i < msg->direct_audio_codecs->count; i++) { + g_print("Codec: %s", msg->direct_audio_codecs->list[i].audio_format); + if (!strcmp(msg->direct_audio_codecs->list[i].audio_format, GST_STRING_WFD_LPCM)) { + if (msg->direct_audio_codecs->list[i].modes & GST_WFD_FREQ_44100) + g_print(" Freq: %d", 44100); + if (msg->direct_audio_codecs->list[i].modes & GST_WFD_FREQ_48000) + g_print(" Freq: %d", 48000); + g_print(" Channels: %d", 2); + } + if (!strcmp(msg->direct_audio_codecs->list[i].audio_format, GST_STRING_WFD_AAC)) { + g_print(" Freq: %d", 48000); + if (msg->direct_audio_codecs->list[i].modes & GST_WFD_CHANNEL_2) + g_print(" Channels: %d", 2); + if (msg->direct_audio_codecs->list[i].modes & GST_WFD_CHANNEL_4) + g_print(" Channels: %d", 4); + if (msg->direct_audio_codecs->list[i].modes & GST_WFD_CHANNEL_6) + g_print(" Channels: %d", 6); + if (msg->direct_audio_codecs->list[i].modes & GST_WFD_CHANNEL_8) + g_print(" Channels: %d", 8); + } + if (!strcmp(msg->direct_audio_codecs->list[i].audio_format, GST_STRING_WFD_AC3)) { + g_print(" Freq: %d", 48000); + if (msg->direct_audio_codecs->list[i].modes & GST_WFD_CHANNEL_2) + g_print(" Channels: %d", 2); + if (msg->direct_audio_codecs->list[i].modes & GST_WFD_CHANNEL_4) + g_print(" Channels: %d", 4); + if (msg->direct_audio_codecs->list[i].modes & GST_WFD_CHANNEL_6) + g_print(" Channels: %d", 6); + } + g_print(" Bitwidth: %d", 16); + g_print(" Latency: %d", msg->direct_audio_codecs->list[i].latency); + } + } + + + if (msg->direct_video_formats) { + g_print("Video supported formats for direct streaming : "); + if (msg->direct_video_formats->list) { + g_print("Codec: H264"); + guint nativeindex = 0; + if ((msg->direct_video_formats->list->native & GST_CHECK_VIDEO_FORMAT) == GST_WFD_VIDEO_CEA_RESOLUTION) { + g_print(" Native type: CEA"); + } else if ((msg->direct_video_formats->list->native & GST_CHECK_VIDEO_FORMAT) == GST_WFD_VIDEO_VESA_RESOLUTION) { + g_print(" Native type: VESA"); + } else if ((msg->direct_video_formats->list->native & GST_CHECK_VIDEO_FORMAT) == GST_WFD_VIDEO_HH_RESOLUTION) { + g_print(" Native type: HH"); + } + nativeindex = msg->direct_video_formats->list->native >> GST_SHIFT_VIDEO_FORMAT; + g_print(" Resolution: %d", (1 << nativeindex)); + + if (msg->direct_video_formats->list->H264_codec.profile & GST_WFD_H264_BASE_PROFILE) { + g_print(" Profile: BASE"); + } else if (msg->direct_video_formats->list->H264_codec.profile & GST_WFD_H264_HIGH_PROFILE) { + g_print(" Profile: HIGH"); + } + if (msg->direct_video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_3_1) { + g_print(" Level: 3.1"); + } else if (msg->direct_video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_3_2) { + g_print(" Level: 3.2"); + } else if (msg->direct_video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_4) { + g_print(" Level: 4"); + } else if (msg->direct_video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_4_1) { + g_print(" Level: 4.1"); + } else if (msg->direct_video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_4_2) { + g_print(" Level: 4.2"); + } + g_print(" Latency: %d", msg->direct_video_formats->list->H264_codec.misc_params.latency); + g_print(" min_slice_size: %x", msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size); + g_print(" slice_enc_params: %x", msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params); + g_print(" frame_rate_control_support: %x", msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support); + if (msg->direct_video_formats->list->H264_codec.max_hres) { + g_print(" Max Width: %04d", msg->direct_video_formats->list->H264_codec.max_hres); + } + if (msg->direct_video_formats->list->H264_codec.max_vres) { + g_print(" Max Height: %04d", msg->direct_video_formats->list->H264_codec.max_vres); + } + } + } + if (msg->video_3d_formats) { g_print("wfd_3d_formats"); } @@ -1237,6 +1446,10 @@ gst_wfd_message_dump(const GstWFDMessage *msg) g_print(GST_STRING_WFD_IDR_REQUEST); } + if (msg->direct_mode) { + g_print(GST_STRING_WFD2_DIRECT_STREAMING_MODE); + } + if (msg->tcp_ports) { g_print(" Client TCP Ports : "); if (msg->tcp_ports->profile) { @@ -1263,6 +1476,7 @@ gst_wfd_message_dump(const GstWFDMessage *msg) g_print(" bufsize %d", msg->video_status->vid_bufsize); g_print(" pts %lld", msg->video_status->vid_pts); } + g_print("==============================================="); return GST_WFD_OK; } @@ -1347,6 +1561,7 @@ GstWFDResult gst_wfd_message_get_supported_audio_format(GstWFDMessage *msg, guin guint i = 0; g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); g_return_val_if_fail(msg->audio_codecs != NULL, GST_WFD_EINVAL); + for (; i < msg->audio_codecs->count; i++) { if (!g_strcmp0(msg->audio_codecs->list[i].audio_format, GST_STRING_WFD_LPCM)) { *aCodec |= GST_WFD_AUDIO_LPCM; @@ -1375,6 +1590,7 @@ GstWFDResult gst_wfd_message_get_preferred_audio_format(GstWFDMessage *msg, GstW guint *aBitwidth, guint32 *aLatency) { g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); + if (!g_strcmp0(msg->audio_codecs->list->audio_format, GST_STRING_WFD_LPCM)) { *aCodec = GST_WFD_AUDIO_LPCM; *aFreq = msg->audio_codecs->list->modes; @@ -1549,6 +1765,282 @@ GstWFDResult gst_wfd_message_get_preferred_video_format(GstWFDMessage *msg, GstW return GST_WFD_OK; } +GstWFDResult gst_wfd_message_set_supported_direct_audio_format(GstWFDMessage *msg, GstWFDAudioFormats aCodec, guint aFreq, guint aChanels, + guint aBitwidth, guint32 aLatency) +{ + guint temp = aCodec; + guint i = 0; + guint pcm = 0, aac = 0, ac3 = 0; + + g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); + + if (!msg->direct_audio_codecs) + msg->direct_audio_codecs = g_new0(GstWFD2AudioCodeclist, 1); + + if (aCodec != GST_WFD_AUDIO_UNKNOWN) { + while (temp) { + msg->direct_audio_codecs->count++; + temp >>= 1; + } + msg->direct_audio_codecs->list = g_new0(GstWFDAudioCodec, msg->direct_audio_codecs->count); + for (; i < msg->direct_audio_codecs->count; i++) { + if ((aCodec & GST_WFD_AUDIO_LPCM) && (!pcm)) { + msg->direct_audio_codecs->list[i].audio_format = g_strdup(GST_STRING_WFD_LPCM); + msg->direct_audio_codecs->list[i].modes = aFreq; + msg->direct_audio_codecs->list[i].latency = aLatency; + pcm = 1; + } else if ((aCodec & GST_WFD_AUDIO_AAC) && (!aac)) { + msg->direct_audio_codecs->list[i].audio_format = g_strdup(GST_STRING_WFD_AAC); + msg->direct_audio_codecs->list[i].modes = aChanels; + msg->direct_audio_codecs->list[i].latency = aLatency; + aac = 1; + } else if ((aCodec & GST_WFD_AUDIO_AC3) && (!ac3)) { + msg->direct_audio_codecs->list[i].audio_format = g_strdup(GST_STRING_WFD_AC3); + msg->direct_audio_codecs->list[i].modes = aChanels; + msg->direct_audio_codecs->list[i].latency = aLatency; + ac3 = 1; + } + } + } + return GST_WFD_OK; +} + +GstWFDResult gst_wfd_message_set_preferred_direct_audio_format(GstWFDMessage *msg, GstWFDAudioFormats aCodec, GstWFDAudioFreq aFreq, GstWFDAudioChannels aChanels, + guint aBitwidth, guint32 aLatency) +{ + + g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); + + if (!msg->direct_audio_codecs) + msg->direct_audio_codecs = g_new0(GstWFD2AudioCodeclist, 1); + + msg->direct_audio_codecs->list = g_new0(GstWFDAudioCodec, 1); + msg->direct_audio_codecs->count = 1; + if (aCodec == GST_WFD_AUDIO_LPCM) { + msg->direct_audio_codecs->list->audio_format = g_strdup(GST_STRING_WFD_LPCM); + msg->direct_audio_codecs->list->modes = aFreq; + msg->direct_audio_codecs->list->latency = aLatency; + } else if (aCodec == GST_WFD_AUDIO_AAC) { + msg->direct_audio_codecs->list->audio_format = g_strdup(GST_STRING_WFD_AAC); + msg->direct_audio_codecs->list->modes = aChanels; + msg->direct_audio_codecs->list->latency = aLatency; + } else if (aCodec == GST_WFD_AUDIO_AC3) { + msg->direct_audio_codecs->list->audio_format = g_strdup(GST_STRING_WFD_AC3); + msg->direct_audio_codecs->list->modes = aChanels; + msg->direct_audio_codecs->list->latency = aLatency; + } + return GST_WFD_OK; +} + +GstWFDResult gst_wfd_message_get_supported_direct_audio_format(GstWFDMessage *msg, guint *aCodec, guint *aFreq, guint *aChanels, + guint *aBitwidth, guint32 *aLatency) +{ + guint i = 0; + g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); + g_return_val_if_fail(msg->direct_audio_codecs != NULL, GST_WFD_EINVAL); + + for (; i < msg->direct_audio_codecs->count; i++) { + if (!g_strcmp0(msg->direct_audio_codecs->list[i].audio_format, GST_STRING_WFD_LPCM)) { + *aCodec |= GST_WFD_AUDIO_LPCM; + *aFreq |= msg->direct_audio_codecs->list[i].modes; + *aChanels |= GST_WFD_CHANNEL_2; + *aBitwidth = 16; + *aLatency = msg->direct_audio_codecs->list[i].latency; + } else if (!g_strcmp0(msg->direct_audio_codecs->list[i].audio_format, GST_STRING_WFD_AAC)) { + *aCodec |= GST_WFD_AUDIO_AAC; + *aFreq |= GST_WFD_FREQ_48000; + *aChanels |= msg->direct_audio_codecs->list[i].modes; + *aBitwidth = 16; + *aLatency = msg->direct_audio_codecs->list[i].latency; + } else if (!g_strcmp0(msg->direct_audio_codecs->list[i].audio_format, GST_STRING_WFD_AC3)) { + *aCodec |= GST_WFD_AUDIO_AC3; + *aFreq |= GST_WFD_FREQ_48000; + *aChanels |= msg->direct_audio_codecs->list[i].modes; + *aBitwidth = 16; + *aLatency = msg->direct_audio_codecs->list[i].latency; + } + } + return GST_WFD_OK; +} + +GstWFDResult gst_wfd_message_get_preferred_direct_audio_format(GstWFDMessage *msg, GstWFDAudioFormats *aCodec, GstWFDAudioFreq *aFreq, GstWFDAudioChannels *aChanels, + guint *aBitwidth, guint32 *aLatency) +{ + g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); + + if (!g_strcmp0(msg->direct_audio_codecs->list->audio_format, GST_STRING_WFD_LPCM)) { + *aCodec = GST_WFD_AUDIO_LPCM; + *aFreq = msg->direct_audio_codecs->list->modes; + *aChanels = GST_WFD_CHANNEL_2; + *aBitwidth = 16; + *aLatency = msg->direct_audio_codecs->list->latency; + } else if (!g_strcmp0(msg->direct_audio_codecs->list->audio_format, GST_STRING_WFD_AAC)) { + *aCodec = GST_WFD_AUDIO_AAC; + *aFreq = GST_WFD_FREQ_48000; + *aChanels = msg->direct_audio_codecs->list->modes; + *aBitwidth = 16; + *aLatency = msg->direct_audio_codecs->list->latency; + } else if (!g_strcmp0(msg->direct_audio_codecs->list->audio_format, GST_STRING_WFD_AC3)) { + *aCodec = GST_WFD_AUDIO_AC3; + *aFreq = GST_WFD_FREQ_48000; + *aChanels = msg->direct_audio_codecs->list->modes; + *aBitwidth = 16; + *aLatency = msg->direct_audio_codecs->list->latency; + } + return GST_WFD_OK; +} + +GstWFDResult gst_wfd_message_set_supported_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs vCodec, + GstWFDVideoNativeResolution vNative, guint64 vNativeResolution, + guint64 vCEAResolution, guint64 vVESAResolution, guint64 vHHResolution, + guint vProfile, guint vLevel, guint32 vLatency, guint32 vMaxHeight, + guint32 vMaxWidth, guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control, + guint preferred_display_mode) +{ + guint nativeindex = 0; + guint64 temp = vNativeResolution; + + g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); + + if (!msg->direct_video_formats) + msg->direct_video_formats = g_new0(GstWFD2VideoCodeclist, 1); + + if (vCodec != GST_WFD_VIDEO_UNKNOWN) { + msg->direct_video_formats->list = g_new0(GstWFDVideoCodec, 1); + + while (temp) { + nativeindex++; + temp >>= 1; + } + + if (nativeindex) msg->direct_video_formats->list->native = nativeindex - 1; + msg->direct_video_formats->list->native <<= GST_SHIFT_VIDEO_FORMAT; + + if (vNative == GST_WFD_VIDEO_VESA_RESOLUTION) + msg->direct_video_formats->list->native |= 1; + else if (vNative == GST_WFD_VIDEO_HH_RESOLUTION) + msg->direct_video_formats->list->native |= 2; + + msg->direct_video_formats->list->preferred_display_mode_supported = preferred_display_mode; + msg->direct_video_formats->list->H264_codec.profile = vProfile; + msg->direct_video_formats->list->H264_codec.level = vLevel; + msg->direct_video_formats->list->H264_codec.max_hres = vMaxWidth; + msg->direct_video_formats->list->H264_codec.max_vres = vMaxHeight; + msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support = vCEAResolution; + msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support = vVESAResolution; + msg->direct_video_formats->list->H264_codec.misc_params.HH_Support = vHHResolution; + msg->direct_video_formats->list->H264_codec.misc_params.latency = vLatency; + msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size = min_slice_size; + msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params = slice_enc_params; + msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support = frame_rate_control; + } + return GST_WFD_OK; +} + +GstWFDResult gst_wfd_message_set_preferred_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs vCodec, + GstWFDVideoNativeResolution vNative, guint64 vNativeResolution, + guint64 vCEAResolution, guint64 vVESAResolution, + guint64 vHHResolution, GstWFDVideoH264Profile vProfile, + GstWFDVideoH264Level vLevel, guint32 vLatency, guint32 vMaxHeight, + guint32 vMaxWidth, guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control) +{ + guint nativeindex = 0; + guint64 temp = vNativeResolution; + + g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); + + if (!msg->direct_video_formats) + msg->direct_video_formats = g_new0(GstWFD2VideoCodeclist, 1); + msg->direct_video_formats->list = g_new0(GstWFDVideoCodec, 1); + + while (temp) { + nativeindex++; + temp >>= 1; + } + + if (nativeindex) msg->direct_video_formats->list->native = nativeindex - 1; + msg->direct_video_formats->list->native <<= GST_SHIFT_VIDEO_FORMAT; + + if (vNative == GST_WFD_VIDEO_VESA_RESOLUTION) + msg->direct_video_formats->list->native |= 1; + else if (vNative == GST_WFD_VIDEO_HH_RESOLUTION) + msg->direct_video_formats->list->native |= 2; + + msg->direct_video_formats->list->preferred_display_mode_supported = GST_WFD_PREFERRED_DISPLAY_MODE_NOT_SUPPORTED; + msg->direct_video_formats->list->H264_codec.profile = vProfile; + msg->direct_video_formats->list->H264_codec.level = vLevel; + msg->direct_video_formats->list->H264_codec.max_hres = vMaxWidth; + msg->direct_video_formats->list->H264_codec.max_vres = vMaxHeight; + msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support = vCEAResolution; + msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support = vVESAResolution; + msg->direct_video_formats->list->H264_codec.misc_params.HH_Support = vHHResolution; + msg->direct_video_formats->list->H264_codec.misc_params.latency = vLatency; + msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size = min_slice_size; + msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params = slice_enc_params; + msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support = frame_rate_control; + return GST_WFD_OK; +} + +GstWFDResult gst_wfd_message_get_supported_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs *vCodec, + GstWFDVideoNativeResolution *vNative, guint64 *vNativeResolution, + guint64 *vCEAResolution, guint64 *vVESAResolution, guint64 *vHHResolution, + guint *vProfile, guint *vLevel, guint32 *vLatency, guint32 *vMaxHeight, + guint32 *vMaxWidth, guint32 *min_slice_size, guint32 *slice_enc_params, guint *frame_rate_control) +{ + guint nativeindex = 0; + + g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); + g_return_val_if_fail(msg->direct_video_formats != NULL, GST_WFD_EINVAL); + g_return_val_if_fail(msg->direct_video_formats->list != NULL, GST_WFD_EINVAL); + + *vCodec = GST_WFD_VIDEO_H264; + *vNative = msg->direct_video_formats->list->native & GST_CHECK_VIDEO_FORMAT; + nativeindex = msg->direct_video_formats->list->native >> GST_SHIFT_VIDEO_FORMAT; + *vNativeResolution = (guint64)1 << nativeindex; + *vProfile = msg->direct_video_formats->list->H264_codec.profile; + *vLevel = msg->direct_video_formats->list->H264_codec.level; + *vMaxWidth = msg->direct_video_formats->list->H264_codec.max_hres; + *vMaxHeight = msg->direct_video_formats->list->H264_codec.max_vres; + *vCEAResolution = msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support; + *vVESAResolution = msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support; + *vHHResolution = msg->direct_video_formats->list->H264_codec.misc_params.HH_Support; + *vLatency = msg->direct_video_formats->list->H264_codec.misc_params.latency; + *min_slice_size = msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size; + *slice_enc_params = msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params; + *frame_rate_control = msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support; + return GST_WFD_OK; +} + +GstWFDResult gst_wfd_message_get_preferred_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs *vCodec, + GstWFDVideoNativeResolution *vNative, guint64 *vNativeResolution, + guint64 *vCEAResolution, guint64 *vVESAResolution, + guint64 *vHHResolution, GstWFDVideoH264Profile *vProfile, + GstWFDVideoH264Level *vLevel, guint32 *vLatency, guint32 *vMaxHeight, + guint32 *vMaxWidth, guint32 *min_slice_size, guint32 *slice_enc_params, guint *frame_rate_control) +{ + guint nativeindex = 0; + g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); + g_return_val_if_fail(msg->direct_video_formats != NULL, GST_WFD_EINVAL); + g_return_val_if_fail(msg->direct_video_formats->list != NULL, GST_WFD_EINVAL); + + *vCodec = GST_WFD_VIDEO_H264; + *vNative = msg->direct_video_formats->list->native & GST_CHECK_VIDEO_FORMAT; + nativeindex = msg->direct_video_formats->list->native >> GST_SHIFT_VIDEO_FORMAT; + *vNativeResolution = (guint64)1 << nativeindex; + *vProfile = msg->direct_video_formats->list->H264_codec.profile; + *vLevel = msg->direct_video_formats->list->H264_codec.level; + *vMaxWidth = msg->direct_video_formats->list->H264_codec.max_hres; + *vMaxHeight = msg->direct_video_formats->list->H264_codec.max_vres; + *vCEAResolution = msg->direct_video_formats->list->H264_codec.misc_params.CEA_Support; + *vVESAResolution = msg->direct_video_formats->list->H264_codec.misc_params.VESA_Support; + *vHHResolution = msg->direct_video_formats->list->H264_codec.misc_params.HH_Support; + *vLatency = msg->direct_video_formats->list->H264_codec.misc_params.latency; + *min_slice_size = msg->direct_video_formats->list->H264_codec.misc_params.min_slice_size; + *slice_enc_params = msg->direct_video_formats->list->H264_codec.misc_params.slice_enc_params; + *frame_rate_control = msg->direct_video_formats->list->H264_codec.misc_params.frame_rate_control_support; + return GST_WFD_OK; +} + GstWFDResult gst_wfd_message_set_contentprotection_type(GstWFDMessage *msg, GstWFDHDCPProtection hdcpversion, guint32 TCPPort) { g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); @@ -1898,6 +2390,13 @@ GstWFDResult gst_wfd_message_set_idr_request(GstWFDMessage *msg) return GST_WFD_OK; } +GstWFDResult gst_wfd_message_get_direct_streaming_mode(GstWFDMessage *msg, gboolean *active) +{ + g_return_val_if_fail(msg != NULL, GST_WFD_EINVAL); + if (msg->direct_mode) *active = msg->direct_mode->direct_mode; + return GST_WFD_OK; +} + GstWFDResult gst_wfd_message_set_preferred_TCP_ports(GstWFDMessage *msg, GstWFDRTSPTransMode trans, GstWFDRTSPProfile profile, GstWFDRTSPLowerTrans lowertrans, guint32 rtp_port0, guint32 rtp_port1) { diff --git a/wfdmanager/wfdbase/gstwfdsinkmessage.h b/wfdmanager/wfdbase/gstwfdsinkmessage.h old mode 100755 new mode 100644 index a2b92aa..7e42af8 --- a/wfdmanager/wfdbase/gstwfdsinkmessage.h +++ b/wfdmanager/wfdbase/gstwfdsinkmessage.h @@ -489,6 +489,10 @@ typedef struct { } GstWFDIdrRequest; typedef struct { + gboolean direct_mode; +} GstWFD2DirectStreamingMode; + +typedef struct { gchar *profile; guint32 rtp_port0; guint32 rtp_port1; @@ -508,12 +512,15 @@ typedef struct { guint vid_bufsize; guint64 vid_pts; } GstWFDVideoStatus; + /***********************************************************/ typedef struct { GstWFDAudioCodeclist *audio_codecs; GstWFDVideoCodeclist *video_formats; + GstWFD2AudioCodeclist *direct_audio_codecs; + GstWFD2VideoCodeclist *direct_video_formats; GstWFD3DFormats *video_3d_formats; GstWFDContentProtection *content_protection; GstWFDDisplayEdid *display_edid; @@ -529,6 +536,7 @@ typedef struct { GstWFDStandby *standby; GstWFDConnectorType *connector_type; GstWFDIdrRequest *idr_request; + GstWFD2DirectStreamingMode *direct_mode; GstWFDTCPPorts *tcp_ports; GstWFDBufferLen *buf_len; GstWFDAudioStatus *audio_status; @@ -583,6 +591,42 @@ GstWFDResult gst_wfd_message_get_preferred_video_format(GstWFDMessage *msg, GstW GstWFDVideoH264Level *vLevel, guint32 *vLatency, guint32 *vMaxHeight, guint32 *vMaxWidth, guint32 *min_slice_size, guint32 *slice_enc_params, guint *frame_rate_control); +GstWFDResult gst_wfd_message_set_supported_direct_audio_format(GstWFDMessage *msg, + guint aCodec, guint aFreq, guint aChanels, + guint aBitwidth, guint32 aLatency); +GstWFDResult gst_wfd_message_set_preferred_direct_audio_format(GstWFDMessage *msg, + GstWFDAudioFormats aCodec, GstWFDAudioFreq aFreq, GstWFDAudioChannels aChanels, + guint aBitwidth, guint32 aLatency); +GstWFDResult gst_wfd_message_get_supported_direct_audio_format(GstWFDMessage *msg, + guint *aCodec, guint *aFreq, guint *aChanels, + guint *aBitwidth, guint32 *aLatency); +GstWFDResult gst_wfd_message_get_preferred_direct_audio_format(GstWFDMessage *msg, + GstWFDAudioFormats *aCodec, GstWFDAudioFreq *aFreq, GstWFDAudioChannels *aChanels, + guint *aBitwidth, guint32 *aLatency); + +GstWFDResult gst_wfd_message_set_supported_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs vCodec, + GstWFDVideoNativeResolution vNative, guint64 vNativeResolution, + guint64 vCEAResolution, guint64 vVESAResolution, guint64 vHHResolution, + guint vProfile, guint vLevel, guint32 vLatency, guint32 vMaxHeight, + guint32 vMaxWidth, guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control, + guint preferred_display_mode); +GstWFDResult gst_wfd_message_set_preferred_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs vCodec, + GstWFDVideoNativeResolution vNative, guint64 vNativeResolution, + guint64 vCEAResolution, guint64 vVESAResolution, + guint64 vHHResolution, GstWFDVideoH264Profile vProfile, + GstWFDVideoH264Level vLevel, guint32 vLatency, guint32 vMaxHeight, + guint32 vMaxWidth, guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control); +GstWFDResult gst_wfd_message_get_supported_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs *vCodec, + GstWFDVideoNativeResolution *vNative, guint64 *vNativeResolution, + guint64 *vCEAResolution, guint64 *vVESAResolution, guint64 *vHHResolution, + guint *vProfile, guint *vLevel, guint32 *vLatency, guint32 *vMaxHeight, + guint32 *vMaxWidth, guint32 *min_slice_size, guint32 *slice_enc_params, guint *frame_rate_control); +GstWFDResult gst_wfd_message_get_preferred_direct_video_format(GstWFDMessage *msg, GstWFDVideoCodecs *vCodec, + GstWFDVideoNativeResolution *vNative, guint64 *vNativeResolution, + guint64 *vCEAResolution, guint64 *vVESAResolution, + guint64 *vHHResolution, GstWFDVideoH264Profile *vProfile, + GstWFDVideoH264Level *vLevel, guint32 *vLatency, guint32 *vMaxHeight, + guint32 *vMaxWidth, guint32 *min_slice_size, guint32 *slice_enc_params, guint *frame_rate_control); /* Todo wfd-3d-formats */ GstWFDResult gst_wfd_message_set_contentprotection_type(GstWFDMessage *msg, GstWFDHDCPProtection hdcpversion, guint32 TCPPort); @@ -628,6 +672,8 @@ GstWFDResult gst_wfd_message_get_connector_type(GstWFDMessage *msg, GstWFDConnec GstWFDResult gst_wfd_message_set_idr_request(GstWFDMessage *msg); +GstWFDResult gst_wfd_message_get_direct_streaming_mode(GstWFDMessage *msg, gboolean *enabled); + GstWFDResult gst_wfd_message_set_preferred_TCP_ports(GstWFDMessage *msg, GstWFDRTSPTransMode trans, GstWFDRTSPProfile profile, GstWFDRTSPLowerTrans lowertrans, guint32 rtp_port0, guint32 rtp_port1); GstWFDResult gst_wfd_message_get_preferred_TCP_ports(GstWFDMessage *msg, GstWFDRTSPTransMode *trans, GstWFDRTSPProfile *profile, diff --git a/wfdtizenmanager/gstwfdtizenmessage.c b/wfdtizenmanager/gstwfdtizenmessage.c old mode 100755 new mode 100644 index 77a021f..2d8ef96 --- a/wfdtizenmanager/gstwfdtizenmessage.c +++ b/wfdtizenmanager/gstwfdtizenmessage.c @@ -33,11 +33,7 @@ #include /* for G_OS_WIN32 */ #include "gstwfdtizenmessage.h" -/* FIXME, is currently allocated on the stack */ -#define MAX_LINE_LEN (1024 * 16) - -#define FREE_STRING(field) if (field != NULL) g_free(field); (field) = NULL; -#define REPLACE_STRING(field, val) FREE_STRING(field); (field) = g_strdup(val); +#define FREE_STRING(field) g_free(field); (field) = NULL; static GstWFDTizenMessage *gst_wfd_tizen_message_boxed_copy (GstWFDTizenMessage * orig); @@ -121,17 +117,9 @@ gst_wfd_tizen_message_uninit (GstWFDTizenMessage * msg) { g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL); - if (msg->tizen_retransmission) { - FREE_STRING (msg->tizen_retransmission); - } - - if (msg->tizen_fec) { - FREE_STRING (msg->tizen_fec); - } - - if (msg->tizen_latency_mode) { - FREE_STRING (msg->tizen_latency_mode); - } + FREE_STRING (msg->tizen_retransmission); + FREE_STRING (msg->tizen_fec); + FREE_STRING (msg->tizen_latency_mode); return GST_WFD_OK; } @@ -216,10 +204,6 @@ gst_wfd_tizen_parse_attribute (gchar * buffer, GstWFDTizenMessage * msg) #define WFD_SKIP_SPACE(q) if (*q && g_ascii_isspace (*q)) q++ #define WFD_SKIP_EQUAL(q) if (*q && *q == '=') q++ #define WFD_SKIP_COMMA(q) if (*q && g_ascii_ispunct (*q)) q++ -#define WFD_READ_STRING(field) _read_string_space_ended (temp, sizeof (temp), v); v+=strlen(temp); REPLACE_STRING (field, temp) -#if 0 -#define WFD_READ_CHAR_END_STRING(field, del) _read_string_char_ended (temp, sizeof (temp), del, v); v+=strlen(temp); REPLACE_STRING (field, temp) -#endif #define WFD_READ_UINT32(field) _read_string_space_ended (temp, sizeof (temp), v); v+=strlen(temp); field = strtoul (temp, NULL, 16) #define WFD_READ_UINT32_DIGIT(field) _read_string_space_ended (temp, sizeof (temp), v); v+=strlen(temp); field = strtoul (temp, NULL, 10) -- 2.7.4