diff options
author | Michael Smith <msmith@xiph.org> | 2006-05-03 10:25:46 +0000 |
---|---|---|
committer | Michael Smith <msmith@xiph.org> | 2006-05-03 10:25:46 +0000 |
commit | f910e0f4a58505251af8308fa33f646de8d7e5fe (patch) | |
tree | dac4ecd365df9096b1e73062382e26bfa61ae200 /ext/faad | |
parent | f2ff9c1617fcf25df3deaf67841e4cf58508e0fa (diff) | |
download | gst-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/faad')
-rw-r--r-- | ext/faad/gstfaad.c | 49 |
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; |