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 | |
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.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | ext/faad/gstfaad.c | 49 |
2 files changed, 52 insertions, 6 deletions
@@ -1,3 +1,12 @@ +2006-05-03 Michael Smith <msmith@fluendo.com> + + * 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. + 2006-05-02 Edgard Lima <edgard.lima@indt.org.br> * sys/v4l2/gstv4l2src.c: (gst_v4l2src_get_caps): 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; |