summaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
authorMichael Smith <msmith@xiph.org>2006-05-03 10:25:46 +0000
committerMichael Smith <msmith@xiph.org>2006-05-03 10:25:46 +0000
commitf910e0f4a58505251af8308fa33f646de8d7e5fe (patch)
treedac4ecd365df9096b1e73062382e26bfa61ae200 /ext
parentf2ff9c1617fcf25df3deaf67841e4cf58508e0fa (diff)
downloadgst-plugins-bad-f910e0f4a58505251af8308fa33f646de8d7e5fe.tar.gz
gst-plugins-bad-f910e0f4a58505251af8308fa33f646de8d7e5fe.tar.bz2
gst-plugins-bad-f910e0f4a58505251af8308fa33f646de8d7e5fe.zip
ext/faad/gstfaad.c: Fix #334748: use fake_codec_data if the first bytes of the first buffer we process doesn't look l...
Original commit message from CVS: * ext/faad/gstfaad.c: (gst_faad_setcaps), (looks_like_valid_header), (gst_faad_chain): Fix #334748: use fake_codec_data if the first bytes of the first buffer we process doesn't look like plausible AAC data (e.g. reserved values for rate, or channels). Fixes playback of Apple's movie trailers.
Diffstat (limited to 'ext')
-rw-r--r--ext/faad/gstfaad.c49
1 files changed, 43 insertions, 6 deletions
diff --git a/ext/faad/gstfaad.c b/ext/faad/gstfaad.c
index 85009de8..2c745d0e 100644
--- a/ext/faad/gstfaad.c
+++ b/ext/faad/gstfaad.c
@@ -312,12 +312,14 @@ gst_faad_setcaps (GstPad * pad, GstCaps * caps)
gst_structure_get_int (str, "channels", &channels)) {
gint rate_idx, profile;
- profile = 3; /* 0=MAIN, 1=LC, 2=SSR, 3=? */
+ profile = 3; /* 0=MAIN, 1=LC, 2=SSR, 3=LTP */
rate_idx = aac_rate_idx (rate);
faad->fake_codec_data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
faad->fake_codec_data[1] = ((rate_idx & 0x1) << 7) | (channels << 3);
- GST_LOG_OBJECT (faad, "created fake codec data (%u,%u)", rate, channels);
+ GST_LOG_OBJECT (faad, "created fake codec data (%u,%u): 0x%x 0x%x", rate,
+ channels, (int) faad->fake_codec_data[0],
+ (int) faad->fake_codec_data[1]);
}
}
@@ -1052,6 +1054,28 @@ gst_faad_sync (GstBuffer * buf, guint * off)
return FALSE;
}
+static gboolean
+looks_like_valid_header (guint8 * input_data, guint input_size)
+{
+ guint32 rate;
+ guint32 channels;
+
+ if (input_size < 2)
+ return FALSE;
+
+ rate = ((input_data[0] & 0x7) << 1) | ((input_data[1] & 0x80) >> 7);
+ channels = (input_data[1] & 0x78) >> 3;
+
+ if (rate == 0xd || rate == 0xe) /* Reserved values */
+ return FALSE;
+
+ if (channels == 0) /* Extended specifier: never seen one of these */
+ return FALSE;
+
+ return TRUE;
+}
+
+
static GstFlowReturn
gst_faad_chain (GstPad * pad, GstBuffer * buffer)
{
@@ -1108,10 +1132,23 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
guint8 ch;
GST_DEBUG_OBJECT (faad, "initialising ...");
- if (faacDecInit (faad->handle, input_data, input_size, &rate, &ch) < 0)
- goto init_failed;
-
- GST_DEBUG_OBJECT (faad, "faacDecInit() ok: rate=%u,channels=%u", rate, ch);
+ /* We check if the first data looks like it might plausibly contain
+ * appropriate initialisation info... if not, we use our fake_codec_data
+ */
+ if (looks_like_valid_header (input_data, input_size) || !faad->packetised) {
+ if (faacDecInit (faad->handle, input_data, input_size, &rate, &ch) < 0)
+ goto init_failed;
+
+ GST_DEBUG_OBJECT (faad, "faacDecInit() ok: rate=%u,channels=%u", rate,
+ ch);
+ } else {
+ if ((gint8) faacDecInit2 (faad->handle, faad->fake_codec_data, 2,
+ &rate, &ch) < 0) {
+ goto init2_failed;
+ }
+ GST_DEBUG_OBJECT (faad, "faacDecInit2() ok: rate=%u,channels=%u", rate,
+ ch);
+ }
skip_bytes = 0;
faad->init = TRUE;