Merge commit '23d461fe8714a20ee5e6929f22c61512fdda568e'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 30 Jan 2014 13:55:03 +0000 (14:55 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 30 Jan 2014 13:55:03 +0000 (14:55 +0100)
* commit '23d461fe8714a20ee5e6929f22c61512fdda568e':
  ac3dec: Allow asymmetric application of DRC when drc_scale > 1

Conflicts:
libavcodec/ac3dec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/ac3dec.c

diff --combined libavcodec/ac3dec.c
index 6842e9e20708feedd3228426ae097c2830fd87d7,fcb52e11d01643fdcc41d2c6550c8684ecb3df60..87b7f183f9500f8f23e708be08c30cfe41987bb8
@@@ -7,20 -7,20 +7,20 @@@
   * Copyright (c) 2007-2008 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
   * Copyright (c) 2007 Justin Ruggles <justin.ruggles@gmail.com>
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -472,7 -472,7 +472,7 @@@ static void ac3_decode_transform_coeffs
          case 0:
              /* random noise with approximate range of -0.707 to 0.707 */
              if (dither)
 -                mantissa = (av_lfg_get(&s->dith_state) / 362) - 5932275;
 +                mantissa = (((av_lfg_get(&s->dith_state)>>8)*181)>>8) - 5931008;
              else
                  mantissa = 0;
              break;
              break;
          default: /* 6 to 15 */
              /* Shift mantissa and sign-extend it. */
 +            if (bap > 15) {
 +                av_log(s->avctx, AV_LOG_ERROR, "bap %d is invalid in plain AC-3\n", bap);
 +                bap = 15;
 +            }
              mantissa = get_sbits(gbc, quantization_tab[bap]);
              mantissa <<= 24 - quantization_tab[bap];
              break;
@@@ -782,8 -778,13 +782,13 @@@ static int decode_audio_block(AC3Decode
      i = !s->channel_mode;
      do {
          if (get_bits1(gbc)) {
-             s->dynamic_range[i] = powf(dynamic_range_tab[get_bits(gbc, 8)],
-                                        s->drc_scale);
+             /* Allow asymmetric application of DRC when drc_scale > 1.
+                Amplification of quiet sounds is enhanced */
+             float range = dynamic_range_tab[get_bits(gbc, 8)];
+             if (range > 1.0 || s->drc_scale <= 1.0)
+                 s->dynamic_range[i] = powf(range, s->drc_scale);
+             else
+                 s->dynamic_range[i] = range;
          } else if (blk == 0) {
              s->dynamic_range[i] = 1.0f;
          }
@@@ -1361,7 -1362,7 +1366,7 @@@ static int ac3_decode_frame(AVCodecCont
          if (s->frame_size > buf_size) {
              av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
              err = AAC_AC3_PARSE_ERROR_FRAME_SIZE;
 -        } else if (avctx->err_recognition & AV_EF_CRCCHECK) {
 +        } else if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) {
              /* check for crc mismatch */
              if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2],
                         s->frame_size - 2)) {
              s->output_mode  = AC3_CHMODE_STEREO;
          }
  
 +        s->loro_center_mix_level   = gain_levels[s->  center_mix_level];
 +        s->loro_surround_mix_level = gain_levels[s->surround_mix_level];
 +        s->ltrt_center_mix_level   = LEVEL_MINUS_3DB;
 +        s->ltrt_surround_mix_level = LEVEL_MINUS_3DB;
          /* set downmixing coefficients if needed */
          if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
                  s->fbw_channels == s->out_channels)) {
  
      /* get output buffer */
      frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE;
 -    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
 -        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 +    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
          return ret;
 -    }
  
      /* decode the audio blocks */
      channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];
 +    for (ch = 0; ch < AC3_MAX_CHANNELS; ch++) {
 +        output[ch] = s->output[ch];
 +        s->outptr[ch] = s->output[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)) {
          }
          if (err)
              for (ch = 0; ch < s->out_channels; ch++)
 -                memcpy(s->outptr[channel_map[ch]], output[ch], sizeof(**output) * AC3_BLOCK_SIZE);
 +                memcpy(((float*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], sizeof(**output) * AC3_BLOCK_SIZE);
          for (ch = 0; ch < s->out_channels; ch++)
              output[ch] = s->outptr[channel_map[ch]];
 -        for (ch = 0; ch < s->out_channels; ch++)
 -            s->outptr[ch] += AC3_BLOCK_SIZE;
 +        for (ch = 0; ch < s->out_channels; ch++) {
 +            if (!ch || channel_map[ch])
 +                s->outptr[channel_map[ch]] += AC3_BLOCK_SIZE;
 +        }
      }
  
 +    av_frame_set_decode_error_flags(frame, err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0);
 +
      /* keep last block for error concealment in next frame */
      for (ch = 0; ch < s->out_channels; ch++)
          memcpy(s->output[ch], output[ch], sizeof(**output) * AC3_BLOCK_SIZE);
@@@ -1504,14 -1498,7 +1509,14 @@@ static av_cold int ac3_decode_end(AVCod
  #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, {.dbl = 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, 6.0, PAR },
 +
 +{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 2, 0, "dmix_mode"},
 +{"ltrt_cmixlev",   "Lt/Rt Center Mix Level",   OFFSET(ltrt_center_mix_level),    AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0},
 +{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level),  AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0},
 +{"loro_cmixlev",   "Lo/Ro Center Mix Level",   OFFSET(loro_center_mix_level),    AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0},
 +{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level),  AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0},
 +
      { NULL},
  };