summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Smith <msmith@songbirdnest.com>2010-01-04 15:44:28 -0800
committerMichael Smith <msmith@songbirdnest.com>2010-01-05 12:11:31 -0800
commit7f442ab1c1bfb35f15b0df3c42e51eeba58cbe9b (patch)
treef4fc468087d12a44d5f7a693bfe9501533138bdd
parente8dcea17fcdd27dd9184d46ad43e071ba202cbbf (diff)
qtdemux: Add support for wave-style audio in qt.
Uses gstriff to parse the wave headers appropriately. Tested with MS-ADPCM content.
-rw-r--r--gst/qtdemux/Makefile.am8
-rw-r--r--gst/qtdemux/qtdemux.c56
2 files changed, 61 insertions, 3 deletions
diff --git a/gst/qtdemux/Makefile.am b/gst/qtdemux/Makefile.am
index 6c3150948..354667de7 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 d474f8c10..65003737b 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -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) {