diff --git a/gst/qtdemux/Makefile.am b/gst/qtdemux/Makefile.am index 6c31509486..354667de7f 100644 --- a/gst/qtdemux/Makefile.am +++ b/gst/qtdemux/Makefile.am @@ -3,8 +3,12 @@ plugin_LTLIBRARIES = libgstqtdemux.la libgstqtdemux_la_CFLAGS = ${GST_CFLAGS} $(GST_PLUGINS_BASE_CFLAGS) libgstqtdemux_la_LIBADD = \ - $(GST_PLUGINS_BASE_LIBS) -lgstrtp-@GST_MAJORMINOR@ -lgsttag-@GST_MAJORMINOR@ \ - $(GST_BASE_LIBS) $(ZLIB_LIBS) + $(GST_PLUGINS_BASE_LIBS) \ + -lgstriff-@GST_MAJORMINOR@ \ + -lgstaudio-@GST_MAJORMINOR@ \ + -lgstrtp-@GST_MAJORMINOR@ \ + -lgsttag-@GST_MAJORMINOR@ \ + $(GST_BASE_LIBS) $(ZLIB_LIBS) libgstqtdemux_la_LDFLAGS = ${GST_PLUGIN_LDFLAGS} libgstqtdemux_la_SOURCES = quicktime.c gstrtpxqtdepay.c qtdemux.c qtdemux_types.c qtdemux_dump.c libgstqtdemux_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index d474f8c109..65003737b2 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -58,6 +58,9 @@ #include "qtdemux.h" #include "qtpalette.h" +#include "gst/riff/riff-media.h" +#include "gst/riff/riff-read.h" + #include #include #include @@ -5482,7 +5485,58 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) esds = qtdemux_tree_get_child_by_type (mp4a, FOURCC_esds); } - if (esds) { + + /* If the fourcc's bottom 16 bits gives 'sm', then the top + 16 bits is a byte-swapped wave-style codec identifier, + and we can find a WAVE header internally to a 'wave' atom here. + This can more clearly be thought of as 'ms' as the top 16 bits, and a + codec id as the bottom 16 bits - but byte-swapped to store in QT (which + is big-endian). + */ + if ((fourcc & 0xffff) == (('s' << 8) | 'm')) { + if (len < offset + 20) { + GST_WARNING_OBJECT (qtdemux, "No wave atom in MS-style audio"); + } else { + guint32 datalen = QT_UINT32 (stsd_data + offset + 16); + const guint8 *data = stsd_data + offset + 16; + GNode *wavenode; + GNode *waveheadernode; + + wavenode = g_node_new ((guint8 *) data); + if (qtdemux_parse_node (qtdemux, wavenode, data, datalen)) { + const guint8 *waveheader; + guint32 headerlen; + + waveheadernode = qtdemux_tree_get_child_by_type (wavenode, fourcc); + waveheader = (const guint8 *) waveheadernode->data; + headerlen = QT_UINT32 (waveheader); + + if (headerlen > 8) { + gst_riff_strf_auds *header = NULL; + GstBuffer *headerbuf; + GstBuffer *extra; + + waveheader += 8; + headerlen -= 8; + + headerbuf = gst_buffer_new (); + GST_BUFFER_DATA (headerbuf) = (guint8 *) waveheader; + GST_BUFFER_SIZE (headerbuf) = headerlen; + + if (gst_riff_parse_strf_auds (GST_ELEMENT_CAST (qtdemux), + headerbuf, &header, &extra)) { + gst_caps_unref (stream->caps); + stream->caps = gst_riff_create_audio_caps (header->format, NULL, + header, extra, NULL, NULL); + + if (extra) + gst_buffer_unref (extra); + } + } + } + g_node_destroy (wavenode); + } + } else if (esds) { gst_qtdemux_handle_esds (qtdemux, stream, esds, list); } else { switch (fourcc) {