Merge commit 'd7c450436fcb9d3ecf59884a574e7684183e753d'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 24 Feb 2013 15:53:09 +0000 (16:53 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 24 Feb 2013 15:53:09 +0000 (16:53 +0100)
* commit 'd7c450436fcb9d3ecf59884a574e7684183e753d':
  ac3dec: validate channel output mode against channel count

Conflicts:
libavcodec/ac3dec.c

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

diff --combined libavcodec/ac3dec.c
@@@ -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
   */
  
@@@ -441,7 -441,7 +441,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;
@@@ -1322,7 -1322,7 +1322,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)) {
      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)
          avctx->channels       = s->out_channels;
          avctx->channel_layout = s->channel_layout;
  
 +        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)) {
              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;
-     }
-     if (avctx->channels != s->out_channels) {
-         av_log(avctx, AV_LOG_ERROR, "channel number mismatching on damaged frame\n");
+     } 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 */
-     avctx->channels = s->out_channels;
      frame->nb_samples = s->num_blocks * 256;
      if ((ret = ff_get_buffer(avctx, frame)) < 0) {
          av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
  
      /* 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], 1024);
 -        for (ch = 0; ch < s->out_channels; ch++) {
 +                memcpy(((float*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, 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;
 +        for (ch = 0; ch < s->out_channels; ch++) {
 +            if (!ch || channel_map[ch])
 +                s->outptr[channel_map[ch]] += AC3_BLOCK_SIZE;
          }
      }
  
 +    frame->decode_error_flags = 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], 1024);
@@@ -1435,13 -1424,6 +1433,13 @@@ static av_cold int ac3_decode_end(AVCod
  #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 },
 +
 +{"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},
  };