]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/ac3dec.c
roqvideodec: fix a potential infinite loop in roqvideo_decode_frame().
[ffmpeg] / libavcodec / ac3dec.c
index 83cfa0acc336cc33fbbdde96c3b5f0a12acb55bf..407940d19da6a90ae47ec9179197bd1105ac810e 100644 (file)
@@ -76,18 +76,6 @@ static const float gain_levels[9] = {
     LEVEL_MINUS_9DB
 };
 
-/**
- * Table for center mix levels
- * reference: Section 5.4.2.4 cmixlev
- */
-static const uint8_t center_levels[4] = { 4, 5, 6, 5 };
-
-/**
- * Table for surround mix levels
- * reference: Section 5.4.2.5 surmixlev
- */
-static const uint8_t surround_levels[4] = { 4, 6, 7, 6 };
-
 /**
  * Table for default stereo downmixing coefficients
  * reference: Section 7.8.2 Downmixing Into Two Channels
@@ -172,31 +160,22 @@ static av_cold void ac3_tables_init(void)
 static av_cold int ac3_decode_init(AVCodecContext *avctx)
 {
     AC3DecodeContext *s = avctx->priv_data;
-    s->avctx = avctx;
+    int i;
 
-#if FF_API_DRC_SCALE
-    if (avctx->drc_scale)
-        s->drc_scale = avctx->drc_scale;
-#endif
+    s->avctx = avctx;
 
     ff_ac3_common_init();
     ac3_tables_init();
     ff_mdct_init(&s->imdct_256, 8, 1, 1.0);
     ff_mdct_init(&s->imdct_512, 9, 1, 1.0);
     ff_kbd_window_init(s->window, 5.0, 256);
-    dsputil_init(&s->dsp, avctx);
+    ff_dsputil_init(&s->dsp, avctx);
+    avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
     ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
     ff_fmt_convert_init(&s->fmt_conv, avctx);
     av_lfg_init(&s->dith_state, 0);
 
-    /* set scale value for float to int16 conversion */
-    if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
-        s->mul_bias = 1.0f;
-        avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
-    } else {
-        s->mul_bias = 32767.0f;
-        avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-    }
+    avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
     /* allow downmixing to stereo or mono */
     if (avctx->channels > 0 && avctx->request_channels > 0 &&
@@ -206,8 +185,10 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
     }
     s->downmixed = 1;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
+    for (i = 0; i < AC3_MAX_CHANNELS; i++) {
+        s->xcfptr[i] = s->transform_coeffs[i];
+        s->dlyptr[i] = s->delay[i];
+    }
 
     return 0;
 }
@@ -223,7 +204,7 @@ static int ac3_parse_header(AC3DecodeContext *s)
     int i;
 
     /* read the rest of the bsi. read twice for dual mono mode. */
-    i = !(s->channel_mode);
+    i = !s->channel_mode;
     do {
         skip_bits(gbc, 5); // skip dialog normalization
         if (get_bits1(gbc))
@@ -320,8 +301,8 @@ static int parse_frame_header(AC3DecodeContext *s)
 static void set_downmix_coeffs(AC3DecodeContext *s)
 {
     int i;
-    float cmix = gain_levels[center_levels[s->center_mix_level]];
-    float smix = gain_levels[surround_levels[s->surround_mix_level]];
+    float cmix = gain_levels[s->  center_mix_level];
+    float smix = gain_levels[s->surround_mix_level];
     float norm0, norm1;
 
     for (i = 0; i < s->fbw_channels; i++) {
@@ -458,8 +439,9 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma
         int mantissa;
         switch (bap) {
         case 0:
+            /* random noise with approximate range of -0.707 to 0.707 */
             if (dither)
-                mantissa = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000;
+                mantissa = (av_lfg_get(&s->dith_state) / 362) - 5932275;
             else
                 mantissa = 0;
             break;
@@ -563,7 +545,7 @@ static void decode_transform_coeffs(AC3DecodeContext *s, int blk)
     for (ch = 1; ch <= s->channels; ch++) {
         /* transform coefficients for full-bandwidth channel */
         decode_transform_coeffs_ch(s, blk, ch, &m);
-        /* tranform coefficients for coupling channel come right after the
+        /* transform coefficients for coupling channel come right after the
            coefficients for the first coupled channel*/
         if (s->channel_in_cpl[ch])  {
             if (!got_cplchan) {
@@ -623,48 +605,20 @@ static inline void do_imdct(AC3DecodeContext *s, int channels)
             for (i = 0; i < 128; i++)
                 x[i] = s->transform_coeffs[ch][2 * i];
             s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x);
-            s->dsp.vector_fmul_window(s->output[ch - 1], s->delay[ch - 1],
-                                      s->tmp_output, s->window, 128);
+            s->fdsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
+                                       s->tmp_output, s->window, 128);
             for (i = 0; i < 128; i++)
                 x[i] = s->transform_coeffs[ch][2 * i + 1];
             s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1], x);
         } else {
             s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]);
-            s->dsp.vector_fmul_window(s->output[ch - 1], s->delay[ch - 1],
-                                      s->tmp_output, s->window, 128);
+            s->fdsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
+                                       s->tmp_output, s->window, 128);
             memcpy(s->delay[ch - 1], s->tmp_output + 128, 128 * sizeof(float));
         }
     }
 }
 
-/**
- * Downmix the output to mono or stereo.
- */
-void ff_ac3_downmix_c(float (*samples)[256], float (*matrix)[2],
-                      int out_ch, int in_ch, int len)
-{
-    int i, j;
-    float v0, v1;
-    if (out_ch == 2) {
-        for (i = 0; i < len; i++) {
-            v0 = v1 = 0.0f;
-            for (j = 0; j < in_ch; j++) {
-                v0 += samples[j][i] * matrix[j][0];
-                v1 += samples[j][i] * matrix[j][1];
-            }
-            samples[0][i] = v0;
-            samples[1][i] = v1;
-        }
-    } else if (out_ch == 1) {
-        for (i = 0; i < len; i++) {
-            v0 = 0.0f;
-            for (j = 0; j < in_ch; j++)
-                v0 += samples[j][i] * matrix[j][0];
-            samples[0][i] = v0;
-        }
-    }
-}
-
 /**
  * Upmix delay samples from stereo to original channel layout.
  */
@@ -770,9 +724,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
     int downmix_output;
     int cpl_in_use;
     GetBitContext *gbc = &s->gbc;
-    uint8_t bit_alloc_stages[AC3_MAX_CHANNELS];
-
-    memset(bit_alloc_stages, 0, AC3_MAX_CHANNELS);
+    uint8_t bit_alloc_stages[AC3_MAX_CHANNELS] = { 0 };
 
     /* block switch flags */
     different_transforms = 0;
@@ -792,7 +744,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
     }
 
     /* dynamic range */
-    i = !(s->channel_mode);
+    i = !s->channel_mode;
     do {
         if (get_bits1(gbc)) {
             s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)] - 1.0) *
@@ -923,7 +875,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
             if (s->eac3 && get_bits1(gbc)) {
                 /* TODO: parse enhanced coupling strategy info */
                 av_log_missing_feature(s->avctx, "Enhanced coupling", 1);
-                return -1;
+                return AVERROR_PATCHWELCOME;
             }
 
             /* determine which channels are coupled */
@@ -1253,7 +1205,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
 
     /* apply scaling to coefficients (headroom, dynrng) */
     for (ch = 1; ch <= s->channels; ch++) {
-        float gain = s->mul_bias / 4194304.0f;
+        float gain = 1.0 / 4194304.0f;
         if (s->channel_mode == AC3_CHMODE_DUALMONO) {
             gain *= s->dynamic_range[2 - ch];
         } else {
@@ -1285,19 +1237,19 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
         do_imdct(s, s->channels);
 
         if (downmix_output) {
-            s->dsp.ac3_downmix(s->output, s->downmix_coeffs,
-                               s->out_channels, s->fbw_channels, 256);
+            s->ac3dsp.downmix(s->outptr, s->downmix_coeffs,
+                              s->out_channels, s->fbw_channels, 256);
         }
     } else {
         if (downmix_output) {
-            s->dsp.ac3_downmix(s->transform_coeffs + 1, s->downmix_coeffs,
-                               s->out_channels, s->fbw_channels, 256);
+            s->ac3dsp.downmix(s->xcfptr + 1, s->downmix_coeffs,
+                              s->out_channels, s->fbw_channels, 256);
         }
 
         if (downmix_output && !s->downmixed) {
             s->downmixed = 1;
-            s->dsp.ac3_downmix(s->delay, s->downmix_coeffs, s->out_channels,
-                               s->fbw_channels, 128);
+            s->ac3dsp.downmix(s->dlyptr, s->downmix_coeffs, s->out_channels,
+                              s->fbw_channels, 128);
         }
 
         do_imdct(s, s->out_channels);
@@ -1312,11 +1264,10 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
 static int ac3_decode_frame(AVCodecContext * avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     AC3DecodeContext *s = avctx->priv_data;
-    float   *out_samples_flt;
-    int16_t *out_samples_s16;
     int blk, ch, err, ret;
     const uint8_t *channel_map;
     const float *output[AC3_MAX_CHANNELS];
@@ -1385,8 +1336,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
     if (!err) {
         avctx->sample_rate = s->sample_rate;
         avctx->bit_rate    = s->bit_rate;
+    }
 
-        /* channel config */
+    /* channel config */
+    if (!err || (s->channels && s->out_channels != s->channels)) {
         s->out_channels = s->channels;
         s->output_mode  = s->channel_mode;
         if (s->lfe_on)
@@ -1395,7 +1348,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
                 avctx->request_channels < s->channels) {
             s->out_channels = avctx->request_channels;
             s->output_mode  = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;
-            s->channel_layout = ff_ac3_channel_layout_tab[s->output_mode];
+            s->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode];
         }
         avctx->channels       = s->out_channels;
         avctx->channel_layout = s->channel_layout;
@@ -1405,47 +1358,52 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
                 s->fbw_channels == s->out_channels)) {
             set_downmix_coeffs(s);
         }
-    } else if (!s->out_channels) {
-        s->out_channels = avctx->channels;
-        if (s->out_channels < s->channels)
-            s->output_mode  = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;
+    } else if (!s->channels) {
+        av_log(avctx, AV_LOG_ERROR, "unable to determine channel mode\n");
+        return AVERROR_INVALIDDATA;
     }
+    avctx->channels = s->out_channels;
+
     /* set audio service type based on bitstream mode for AC-3 */
     avctx->audio_service_type = s->bitstream_mode;
     if (s->bitstream_mode == 0x7 && s->channels > 1)
         avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
 
     /* get output buffer */
-    s->frame.nb_samples = s->num_blocks * 256;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->num_blocks * 256;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    out_samples_flt = (float   *)s->frame.data[0];
-    out_samples_s16 = (int16_t *)s->frame.data[0];
 
     /* decode the audio blocks */
     channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];
-    for (ch = 0; ch < s->out_channels; ch++)
-        output[ch] = s->output[channel_map[ch]];
+    for (ch = 0; ch < s->channels; ch++) {
+        if (ch < s->out_channels)
+            s->outptr[channel_map[ch]] = (float *)frame->data[ch];
+        else
+            s->outptr[ch] = s->output[ch];
+        output[ch] = s->output[ch];
+    }
     for (blk = 0; blk < s->num_blocks; blk++) {
         if (!err && decode_audio_block(s, blk)) {
             av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n");
             err = 1;
         }
-        if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
-            s->fmt_conv.float_interleave(out_samples_flt, output, 256,
-                                         s->out_channels);
-            out_samples_flt += 256 * s->out_channels;
-        } else {
-            s->fmt_conv.float_to_int16_interleave(out_samples_s16, output, 256,
-                                                  s->out_channels);
-            out_samples_s16 += 256 * s->out_channels;
+        if (err)
+            for (ch = 0; ch < s->out_channels; ch++)
+                memcpy(s->outptr[channel_map[ch]], output[ch], 1024);
+        for (ch = 0; ch < s->out_channels; ch++) {
+            output[ch] = s->outptr[channel_map[ch]];
+            s->outptr[channel_map[ch]] += AC3_BLOCK_SIZE;
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    /* keep last block for error concealment in next frame */
+    for (ch = 0; ch < s->out_channels; ch++)
+        memcpy(s->output[ch], output[ch], 1024);
+
+    *got_frame_ptr = 1;
 
     return FFMIN(buf_size, s->frame_size);
 }
@@ -1465,7 +1423,7 @@ static av_cold int ac3_decode_end(AVCodecContext *avctx)
 #define OFFSET(x) offsetof(AC3DecodeContext, x)
 #define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM)
 static const AVOption options[] = {
-    { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {1.0}, 0.0, 1.0, PAR },
+    { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 1.0, PAR },
     { NULL},
 };
 
@@ -1479,15 +1437,14 @@ static const AVClass ac3_decoder_class = {
 AVCodec ff_ac3_decoder = {
     .name           = "ac3",
     .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = CODEC_ID_AC3,
+    .id             = AV_CODEC_ID_AC3,
     .priv_data_size = sizeof (AC3DecodeContext),
     .init           = ac3_decode_init,
     .close          = ac3_decode_end,
     .decode         = ac3_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
-                                                      AV_SAMPLE_FMT_S16,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
     .priv_class     = &ac3_decoder_class,
 };
@@ -1503,15 +1460,14 @@ static const AVClass eac3_decoder_class = {
 AVCodec ff_eac3_decoder = {
     .name           = "eac3",
     .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = CODEC_ID_EAC3,
+    .id             = AV_CODEC_ID_EAC3,
     .priv_data_size = sizeof (AC3DecodeContext),
     .init           = ac3_decode_init,
     .close          = ac3_decode_end,
     .decode         = ac3_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
-                                                      AV_SAMPLE_FMT_S16,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
     .priv_class     = &eac3_decoder_class,
 };