mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 07:47:17 +00:00
mssdemux: parse block_align, channels and rate from waveformatex if possible
wma v2 expects block_align, channels and rate fields set to its caps. This isn't present direclty on the manifests, so mssdemux should parse it from the waveformatex structure https://bugzilla.gnome.org/show_bug.cgi?id=699924
This commit is contained in:
parent
f74f9cd3ab
commit
27d726fbfa
1 changed files with 60 additions and 34 deletions
|
@ -563,50 +563,80 @@ _gst_mss_stream_audio_caps_from_qualitylevel_xml (GstMssStreamQuality * q)
|
|||
GstCaps *caps;
|
||||
GstStructure *structure;
|
||||
gchar *fourcc = (gchar *) xmlGetProp (node, (xmlChar *) "FourCC");
|
||||
gchar *channels = (gchar *) xmlGetProp (node, (xmlChar *) "Channels");
|
||||
gchar *rate = (gchar *) xmlGetProp (node, (xmlChar *) "SamplingRate");
|
||||
gchar *codec_data =
|
||||
gchar *channels_str = (gchar *) xmlGetProp (node, (xmlChar *) "Channels");
|
||||
gchar *rate_str = (gchar *) xmlGetProp (node, (xmlChar *) "SamplingRate");
|
||||
gchar *codec_data_str =
|
||||
(gchar *) xmlGetProp (node, (xmlChar *) "CodecPrivateData");
|
||||
GstBuffer *codec_data = NULL;
|
||||
gint block_align = 0;
|
||||
gint rate = 0;
|
||||
gint channels = 0;
|
||||
|
||||
if (!fourcc) /* sometimes the fourcc is omitted, we fallback to the Subtype in the StreamIndex node */
|
||||
fourcc = (gchar *) xmlGetProp (node->parent, (xmlChar *) "Subtype");
|
||||
if (!codec_data)
|
||||
codec_data = (gchar *) xmlGetProp (node, (xmlChar *) "WaveFormatEx");
|
||||
|
||||
caps = _gst_mss_stream_audio_caps_from_fourcc (fourcc);
|
||||
if (!caps)
|
||||
goto end;
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
if (channels) {
|
||||
gst_structure_set (structure, "channels", G_TYPE_INT,
|
||||
(int) g_ascii_strtoull (channels, NULL, 10), NULL);
|
||||
}
|
||||
if (rate) {
|
||||
gst_structure_set (structure, "rate", G_TYPE_INT,
|
||||
(int) g_ascii_strtoull (rate, NULL, 10), NULL);
|
||||
}
|
||||
if (q->bitrate) {
|
||||
gst_structure_set (structure, "bitrate", G_TYPE_INT, q->bitrate, NULL);
|
||||
if (codec_data_str && strlen (codec_data_str)) {
|
||||
codec_data = gst_buffer_from_hex_string ((gchar *) codec_data_str);
|
||||
}
|
||||
|
||||
if (codec_data && strlen (codec_data)) {
|
||||
GstBuffer *buffer = gst_buffer_from_hex_string ((gchar *) codec_data);
|
||||
gst_structure_set (structure, "codec_data", GST_TYPE_BUFFER, buffer, NULL);
|
||||
gst_buffer_unref (buffer);
|
||||
} else if (strcmp (fourcc, "AACL") == 0 && rate && channels) {
|
||||
GstBuffer *buffer =
|
||||
_make_aacl_codec_data (g_ascii_strtoull (rate, NULL, 10),
|
||||
g_ascii_strtoull (channels, NULL, 10));
|
||||
gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL);
|
||||
gst_buffer_unref (buffer);
|
||||
if (rate_str)
|
||||
rate = (gint) g_ascii_strtoull (rate_str, NULL, 10);
|
||||
if (channels_str)
|
||||
channels = (int) g_ascii_strtoull (channels_str, NULL, 10);
|
||||
|
||||
if (!codec_data) {
|
||||
GstMapInfo mapinfo;
|
||||
codec_data_str = (gchar *) xmlGetProp (node, (xmlChar *) "WaveFormatEx");
|
||||
if (codec_data_str && strlen (codec_data_str)) {
|
||||
codec_data = gst_buffer_from_hex_string ((gchar *) codec_data_str);
|
||||
|
||||
/* since this is a waveformatex, try to get the block_align and rate */
|
||||
gst_buffer_map (codec_data, &mapinfo, GST_MAP_READ);
|
||||
if (mapinfo.size >= 14) {
|
||||
if (!channels_str) {
|
||||
channels = GST_READ_UINT16_LE (mapinfo.data + 2);
|
||||
}
|
||||
if (!rate_str) {
|
||||
rate = GST_READ_UINT32_LE (mapinfo.data + 4);
|
||||
}
|
||||
block_align = GST_READ_UINT16_LE (mapinfo.data + 12);
|
||||
}
|
||||
gst_buffer_unmap (codec_data, &mapinfo);
|
||||
}
|
||||
}
|
||||
|
||||
if (!codec_data && strcmp (fourcc, "AACL") == 0 && rate && channels) {
|
||||
codec_data = _make_aacl_codec_data (rate, channels);
|
||||
}
|
||||
|
||||
if (block_align)
|
||||
gst_structure_set (structure, "block_align", G_TYPE_INT, block_align, NULL);
|
||||
|
||||
if (channels)
|
||||
gst_structure_set (structure, "channels", G_TYPE_INT, channels, NULL);
|
||||
|
||||
if (rate)
|
||||
gst_structure_set (structure, "rate", G_TYPE_INT, rate, NULL);
|
||||
|
||||
if (q->bitrate)
|
||||
gst_structure_set (structure, "bitrate", G_TYPE_INT, q->bitrate, NULL);
|
||||
|
||||
if (codec_data)
|
||||
gst_structure_set (structure, "codec_data", GST_TYPE_BUFFER, codec_data,
|
||||
NULL);
|
||||
|
||||
end:
|
||||
if (codec_data)
|
||||
gst_buffer_unref (codec_data);
|
||||
xmlFree (fourcc);
|
||||
xmlFree (channels);
|
||||
xmlFree (rate);
|
||||
xmlFree (codec_data);
|
||||
xmlFree (channels_str);
|
||||
xmlFree (rate_str);
|
||||
xmlFree (codec_data_str);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
@ -700,13 +730,9 @@ gst_mss_stream_get_caps (GstMssStream * stream)
|
|||
GstCaps *caps = NULL;
|
||||
|
||||
if (streamtype == MSS_STREAM_TYPE_VIDEO)
|
||||
caps =
|
||||
_gst_mss_stream_video_caps_from_qualitylevel_xml
|
||||
(qualitylevel);
|
||||
caps = _gst_mss_stream_video_caps_from_qualitylevel_xml (qualitylevel);
|
||||
else if (streamtype == MSS_STREAM_TYPE_AUDIO)
|
||||
caps =
|
||||
_gst_mss_stream_audio_caps_from_qualitylevel_xml
|
||||
(qualitylevel);
|
||||
caps = _gst_mss_stream_audio_caps_from_qualitylevel_xml (qualitylevel);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue