]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mpegaudiodec.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / mpegaudiodec.c
index 875d1c8af1fc959e35f3d589e1706c55619771ee..69232ed9b61b19df78d2c352684a775e1e8f317c 100644 (file)
@@ -24,6 +24,8 @@
  * MPEG Audio decoder
  */
 
+#define UNCHECKED_BITSTREAM_READER 1
+
 #include "libavutil/audioconvert.h"
 #include "avcodec.h"
 #include "get_bits.h"
@@ -79,6 +81,7 @@ typedef struct MPADecodeContext {
     int err_recognition;
     AVCodecContext* avctx;
     MPADSPContext mpadsp;
+    AVFrame frame;
 } MPADecodeContext;
 
 #if CONFIG_FLOAT
@@ -269,7 +272,7 @@ static inline int l3_unscale(int value, int exponent)
     return m;
 }
 
-static void decode_init_static(AVCodec *codec)
+static av_cold void decode_init_static(void)
 {
     int i, j, k;
     int offset;
@@ -462,8 +465,14 @@ static void decode_init_static(AVCodec *codec)
 
 static av_cold int decode_init(AVCodecContext * avctx)
 {
+    static int initialized_tables = 0;
     MPADecodeContext *s = avctx->priv_data;
 
+    if (!initialized_tables) {
+        decode_init_static();
+        initialized_tables = 1;
+    }
+
     s->avctx = avctx;
 
     ff_mpadsp_init(&s->mpadsp);
@@ -473,6 +482,10 @@ static av_cold int decode_init(AVCodecContext * avctx)
 
     if (avctx->codec_id == CODEC_ID_MP3ADU)
         s->adu_mode = 1;
+
+    avcodec_get_frame_defaults(&s->frame);
+    avctx->coded_frame = &s->frame;
+
     return 0;
 }
 
@@ -987,7 +1000,7 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
                 s_index -= 4;
                 skip_bits_long(&s->gb, last_pos - pos);
                 av_log(s->avctx, AV_LOG_INFO, "overread, skip %d enddists: %d %d\n", last_pos - pos, end_pos-pos, end_pos2-pos);
-                if(s->err_recognition & AV_EF_BITSTREAM)
+                if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))
                     s_index=0;
                 break;
             }
@@ -1017,10 +1030,10 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
     /* skip extension bits */
     bits_left = end_pos2 - get_bits_count(&s->gb);
 //av_log(NULL, AV_LOG_ERROR, "left:%d buf:%p\n", bits_left, s->in_gb.buffer);
-    if (bits_left < 0 && (s->err_recognition & AV_EF_BITSTREAM)) {
+    if (bits_left < 0 && (s->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))) {
         av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
         s_index=0;
-    } else if (bits_left > 0 && (s->err_recognition & AV_EF_BUFFER)) {
+    } else if (bits_left > 0 && (s->err_recognition & (AV_EF_BITSTREAM|AV_EF_AGGRESSIVE))) {
         av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
         s_index = 0;
     }
@@ -1423,25 +1436,30 @@ static int mp_decode_layer3(MPADecodeContext *s)
         memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES);
         s->in_gb = s->gb;
         init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);
-        skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin));
-    }
-
-    for (gr = 0; gr < nb_granules; gr++) {
-        for (ch = 0; ch < s->nb_channels; ch++) {
-            g = &s->granules[ch][gr];
-            if (get_bits_count(&s->gb) < 0) {
-                av_log(s->avctx, AV_LOG_DEBUG, "mdb:%d, lastbuf:%d skipping granule %d\n",
-                       main_data_begin, s->last_buf_size, gr);
-                skip_bits_long(&s->gb, g->part2_3_length);
+#if !UNCHECKED_BITSTREAM_READER
+        s->gb.size_in_bits_plus8 += EXTRABYTES * 8;
+#endif
+        s->last_buf_size <<= 3;
+        for (gr = 0, ch = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++, ch = 0) {
+            for (; ch < s->nb_channels && (s->last_buf_size >> 3) < main_data_begin; ch++) {
+                g = &s->granules[ch][gr];
+                s->last_buf_size += g->part2_3_length;
                 memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
-                if (get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer) {
-                    skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits);
-                    s->gb           = s->in_gb;
-                    s->in_gb.buffer = NULL;
-                }
-                continue;
             }
+        }
+        skip_bits_long(&s->gb, s->last_buf_size - 8 * main_data_begin);
+        if (get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer) {
+            skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits);
+            s->gb           = s->in_gb;
+            s->in_gb.buffer = NULL;
+        }
+    } else {
+        gr = ch = 0;
+    }
 
+    for (; gr < nb_granules; gr++, ch = 0) {
+        for (; ch < s->nb_channels; ch++) {
+            g = &s->granules[ch][gr];
             bits_pos = get_bits_count(&s->gb);
 
             if (!s->lsf) {
@@ -1575,7 +1593,7 @@ static int mp_decode_layer3(MPADecodeContext *s)
 static int mp_decode_frame(MPADecodeContext *s, OUT_INT *samples,
                            const uint8_t *buf, int buf_size)
 {
-    int i, nb_frames, ch;
+    int i, nb_frames, ch, ret;
     OUT_INT *samples_ptr;
 
     init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8);
@@ -1623,8 +1641,16 @@ static int mp_decode_frame(MPADecodeContext *s, OUT_INT *samples,
         assert(i <= buf_size - HEADER_SIZE && i >= 0);
         memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i);
         s->last_buf_size += i;
+    }
 
-        break;
+    /* get output buffer */
+    if (!samples) {
+        s->frame.nb_samples = s->avctx->frame_size;
+        if ((ret = s->avctx->get_buffer(s->avctx, &s->frame)) < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+            return ret;
+        }
+        samples = (OUT_INT *)s->frame.data[0];
     }
 
     /* apply the synthesis filter */
@@ -1644,7 +1670,7 @@ static int mp_decode_frame(MPADecodeContext *s, OUT_INT *samples,
     return nb_frames * 32 * sizeof(OUT_INT) * s->nb_channels;
 }
 
-static int decode_frame(AVCodecContext * avctx, void *data, int *data_size,
+static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr,
                         AVPacket *avpkt)
 {
     const uint8_t *buf  = avpkt->data;
@@ -1652,7 +1678,6 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size,
     MPADecodeContext *s = avctx->priv_data;
     uint32_t header;
     int out_size;
-    OUT_INT *out_samples = data;
 
     if (buf_size < HEADER_SIZE)
         return AVERROR_INVALIDDATA;
@@ -1675,10 +1700,6 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size,
         avctx->bit_rate = s->bit_rate;
     avctx->sub_id = s->layer;
 
-    if (*data_size < avctx->frame_size * avctx->channels * sizeof(OUT_INT))
-        return AVERROR(EINVAL);
-    *data_size = 0;
-
     if (s->frame_size <= 0 || s->frame_size > buf_size) {
         av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
         return AVERROR_INVALIDDATA;
@@ -1687,9 +1708,10 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size,
         buf_size= s->frame_size;
     }
 
-    out_size = mp_decode_frame(s, out_samples, buf, buf_size);
+    out_size = mp_decode_frame(s, NULL, buf, buf_size);
     if (out_size >= 0) {
-        *data_size         = out_size;
+        *got_frame_ptr   = 1;
+        *(AVFrame *)data = s->frame;
         avctx->sample_rate = s->sample_rate;
         //FIXME maybe move the other codec info stuff from above here too
     } else {
@@ -1698,6 +1720,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size,
            If there is more data in the packet, just consume the bad frame
            instead of returning an error, which would discard the whole
            packet. */
+        *got_frame_ptr = 0;
         if (buf_size == avpkt->size)
             return out_size;
     }
@@ -1713,15 +1736,14 @@ static void flush(AVCodecContext *avctx)
 }
 
 #if CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER
-static int decode_frame_adu(AVCodecContext *avctx, void *data, int *data_size,
-                            AVPacket *avpkt)
+static int decode_frame_adu(AVCodecContext *avctx, void *data,
+                            int *got_frame_ptr, AVPacket *avpkt)
 {
     const uint8_t *buf  = avpkt->data;
     int buf_size        = avpkt->size;
     MPADecodeContext *s = avctx->priv_data;
     uint32_t header;
     int len, out_size;
-    OUT_INT *out_samples = data;
 
     len = buf_size;
 
@@ -1751,9 +1773,6 @@ static int decode_frame_adu(AVCodecContext *avctx, void *data, int *data_size,
         avctx->bit_rate = s->bit_rate;
     avctx->sub_id = s->layer;
 
-    if (*data_size < avctx->frame_size * avctx->channels * sizeof(OUT_INT))
-        return AVERROR(EINVAL);
-
     s->frame_size = len;
 
 #if FF_API_PARSE_FRAME
@@ -1761,9 +1780,11 @@ static int decode_frame_adu(AVCodecContext *avctx, void *data, int *data_size,
         out_size = buf_size;
     else
 #endif
-    out_size = mp_decode_frame(s, out_samples, buf, buf_size);
+    out_size = mp_decode_frame(s, NULL, buf, buf_size);
+
+    *got_frame_ptr   = 1;
+    *(AVFrame *)data = s->frame;
 
-    *data_size = out_size;
     return buf_size;
 }
 #endif /* CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER */
@@ -1774,6 +1795,7 @@ static int decode_frame_adu(AVCodecContext *avctx, void *data, int *data_size,
  * Context for MP3On4 decoder
  */
 typedef struct MP3On4DecodeContext {
+    AVFrame *frame;
     int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
     int syncword;                   ///< syncword patch
     const uint8_t *coff;            ///< channel offsets in output buffer
@@ -1837,7 +1859,8 @@ static int decode_init_mp3on4(AVCodecContext * avctx)
         return AVERROR_INVALIDDATA;
     }
 
-    avpriv_mpeg4audio_get_config(&cfg, avctx->extradata, avctx->extradata_size);
+    avpriv_mpeg4audio_get_config(&cfg, avctx->extradata,
+                                 avctx->extradata_size * 8, 1);
     if (!cfg.chan_config || cfg.chan_config > 7) {
         av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");
         return AVERROR_INVALIDDATA;
@@ -1864,6 +1887,7 @@ static int decode_init_mp3on4(AVCodecContext * avctx)
     // Put decoder context in place to make init_decode() happy
     avctx->priv_data = s->mp3decctx[0];
     decode_init(avctx);
+    s->frame = avctx->coded_frame;
     // Restore mp3on4 context pointer
     avctx->priv_data = s;
     s->mp3decctx[0]->adu_mode = 1; // Set adu mode
@@ -1908,9 +1932,8 @@ static void flush_mp3on4(AVCodecContext *avctx)
 }
 
 
-static int decode_frame_mp3on4(AVCodecContext * avctx,
-                        void *data, int *data_size,
-                        AVPacket *avpkt)
+static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
+                               int *got_frame_ptr, AVPacket *avpkt)
 {
     const uint8_t *buf     = avpkt->data;
     int buf_size           = avpkt->size;
@@ -1918,14 +1941,17 @@ static int decode_frame_mp3on4(AVCodecContext * avctx,
     MPADecodeContext *m;
     int fsize, len = buf_size, out_size = 0;
     uint32_t header;
-    OUT_INT *out_samples = data;
+    OUT_INT *out_samples;
     OUT_INT *outptr, *bp;
-    int fr, j, n, ch;
+    int fr, j, n, ch, ret;
 
-    if (*data_size < MPA_FRAME_SIZE * avctx->channels * sizeof(OUT_INT)) {
-        av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
-        return AVERROR(EINVAL);
+    /* get output buffer */
+    s->frame->nb_samples = MPA_FRAME_SIZE;
+    if ((ret = avctx->get_buffer(avctx, s->frame)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
     }
+    out_samples = (OUT_INT *)s->frame->data[0];
 
     // Discard too short frames
     if (buf_size < HEADER_SIZE)
@@ -1984,7 +2010,10 @@ static int decode_frame_mp3on4(AVCodecContext * avctx,
     /* update codec info */
     avctx->sample_rate = s->mp3decctx[0]->sample_rate;
 
-    *data_size = out_size;
+    s->frame->nb_samples = out_size / (avctx->channels * sizeof(OUT_INT));
+    *got_frame_ptr   = 1;
+    *(AVFrame *)data = *s->frame;
+
     return buf_size;
 }
 #endif /* CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER */
@@ -1996,11 +2025,12 @@ AVCodec ff_mp1_decoder = {
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = CODEC_ID_MP1,
     .priv_data_size = sizeof(MPADecodeContext),
-    .init_static_data = decode_init_static,
     .init           = decode_init,
     .decode         = decode_frame,
 #if FF_API_PARSE_FRAME
-    .capabilities   = CODEC_CAP_PARSE_ONLY,
+    .capabilities   = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+    .capabilities   = CODEC_CAP_DR1,
 #endif
     .flush          = flush,
     .long_name      = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
@@ -2012,11 +2042,12 @@ AVCodec ff_mp2_decoder = {
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = CODEC_ID_MP2,
     .priv_data_size = sizeof(MPADecodeContext),
-    .init_static_data = decode_init_static,
     .init           = decode_init,
     .decode         = decode_frame,
 #if FF_API_PARSE_FRAME
-    .capabilities   = CODEC_CAP_PARSE_ONLY,
+    .capabilities   = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+    .capabilities   = CODEC_CAP_DR1,
 #endif
     .flush          = flush,
     .long_name      = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
@@ -2028,11 +2059,12 @@ AVCodec ff_mp3_decoder = {
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = CODEC_ID_MP3,
     .priv_data_size = sizeof(MPADecodeContext),
-    .init_static_data = decode_init_static,
     .init           = decode_init,
     .decode         = decode_frame,
 #if FF_API_PARSE_FRAME
-    .capabilities   = CODEC_CAP_PARSE_ONLY,
+    .capabilities   = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+    .capabilities   = CODEC_CAP_DR1,
 #endif
     .flush          = flush,
     .long_name      = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
@@ -2044,11 +2076,12 @@ AVCodec ff_mp3adu_decoder = {
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = CODEC_ID_MP3ADU,
     .priv_data_size = sizeof(MPADecodeContext),
-    .init_static_data = decode_init_static,
     .init           = decode_init,
     .decode         = decode_frame_adu,
 #if FF_API_PARSE_FRAME
-    .capabilities   = CODEC_CAP_PARSE_ONLY,
+    .capabilities   = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+    .capabilities   = CODEC_CAP_DR1,
 #endif
     .flush          = flush,
     .long_name      = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
@@ -2060,10 +2093,10 @@ AVCodec ff_mp3on4_decoder = {
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = CODEC_ID_MP3ON4,
     .priv_data_size = sizeof(MP3On4DecodeContext),
-    .init_static_data = decode_init_static,
     .init           = decode_init_mp3on4,
     .close          = decode_close_mp3on4,
     .decode         = decode_frame_mp3on4,
+    .capabilities   = CODEC_CAP_DR1,
     .flush          = flush_mp3on4,
     .long_name      = NULL_IF_CONFIG_SMALL("MP3onMP4"),
 };