Merge commit '796dca027be09334d7bbf4f2ac1200e06bb054cb'
authorClément Bœsch <u@pkh.me>
Sun, 19 Mar 2017 16:36:17 +0000 (17:36 +0100)
committerClément Bœsch <u@pkh.me>
Sun, 19 Mar 2017 16:36:37 +0000 (17:36 +0100)
* commit '796dca027be09334d7bbf4f2ac1200e06bb054cb':
  alac: do not return success if nothing was decoded

See e11983bda073f8c63f60509ee753da9fba20ed10

Merged-by: Clément Bœsch <u@pkh.me>
1  2 
libavcodec/alac.c

diff --combined libavcodec/alac.c
@@@ -2,20 -2,20 +2,20 @@@
   * ALAC (Apple Lossless Audio Codec) decoder
   * Copyright (c) 2005 David Hammerton
   *
 - * 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
   */
  
@@@ -36,8 -36,8 +36,8 @@@
   *  8 bits  compatible version   (0)
   *  8 bits  sample size
   *  8 bits  history mult         (40)
 - *  8 bits  initial history      (14)
 - *  8 bits  rice param limit     (10)
 + *  8 bits  initial history      (10)
 + *  8 bits  rice param limit     (14)
   *  8 bits  channels
   * 16 bits  maxRun               (255)
   * 32 bits  max coded frame size (0 means unknown)
  #include <inttypes.h>
  
  #include "libavutil/channel_layout.h"
 +#include "libavutil/opt.h"
  #include "avcodec.h"
  #include "get_bits.h"
  #include "bytestream.h"
  #include "internal.h"
 +#include "thread.h"
  #include "unary.h"
  #include "mathops.h"
  #include "alac_data.h"
 +#include "alacdsp.h"
  
  #define ALAC_EXTRADATA_SIZE 36
  
  typedef struct ALACContext {
 +    AVClass *class;
      AVCodecContext *avctx;
      GetBitContext gb;
      int channels;
      uint8_t  rice_history_mult;
      uint8_t  rice_initial_history;
      uint8_t  rice_limit;
 +    int      sample_rate;
  
      int extra_bits;     /**< number of extra bits beyond 16-bit */
      int nb_samples;     /**< number of samples in the current frame */
 +
 +    int direct_output;
 +    int extra_bit_bug;
 +
 +    ALACDSPContext dsp;
  } ALACContext;
  
  static inline unsigned int decode_scalar(GetBitContext *gb, int k, int bps)
      return x;
  }
  
 -static void rice_decompress(ALACContext *alac, int32_t *output_buffer,
 +static int rice_decompress(ALACContext *alac, int32_t *output_buffer,
                              int nb_samples, int bps, int rice_history_mult)
  {
      int i;
          int k;
          unsigned int x;
  
 +        if(get_bits_left(&alac->gb) <= 0)
 +            return -1;
 +
          /* calculate rice param and decode next value */
          k = av_log2((history >> 9) + 3);
          k = FFMIN(k, alac->rice_limit);
              history = 0;
          }
      }
 +    return 0;
  }
  
  static inline int sign_only(int v)
@@@ -200,7 -186,7 +200,7 @@@ static void lpc_prediction(int32_t *err
      }
  
      /* read warm-up samples */
 -    for (i = 1; i <= lpc_order; i++)
 +    for (i = 1; i <= lpc_order && i < nb_samples; i++)
          buffer_out[i] = sign_extend(buffer_out[i - 1] + error_buffer[i], bps);
  
      /* NOTE: 4 and 8 are very common cases that could be optimized. */
      }
  }
  
 -static void decorrelate_stereo(int32_t *buffer[2], int nb_samples,
 -                               int decorr_shift, int decorr_left_weight)
 -{
 -    int i;
 -
 -    for (i = 0; i < nb_samples; i++) {
 -        int32_t a, b;
 -
 -        a = buffer[0][i];
 -        b = buffer[1][i];
 -
 -        a -= (b * decorr_left_weight) >> decorr_shift;
 -        b += a;
 -
 -        buffer[0][i] = b;
 -        buffer[1][i] = a;
 -    }
 -}
 -
 -static void append_extra_bits(int32_t *buffer[2], int32_t *extra_bits_buffer[2],
 -                              int extra_bits, int channels, int nb_samples)
 -{
 -    int i, ch;
 -
 -    for (ch = 0; ch < channels; ch++)
 -        for (i = 0; i < nb_samples; i++)
 -            buffer[ch][i] = (buffer[ch][i] << extra_bits) | extra_bits_buffer[ch][i];
 -}
 -
  static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index,
                            int channels)
  {
  
      alac->extra_bits = get_bits(&alac->gb, 2) << 3;
      bps = alac->sample_size - alac->extra_bits + channels - 1;
 -    if (bps > 32) {
 +    if (bps > 32U) {
          av_log(avctx, AV_LOG_ERROR, "bps is unsupported: %d\n", bps);
          return AVERROR_PATCHWELCOME;
      }
          return AVERROR_INVALIDDATA;
      }
      if (!alac->nb_samples) {
 +        ThreadFrame tframe = { .f = frame };
          /* get output buffer */
          frame->nb_samples = output_samples;
 -        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
 -            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 +        if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
              return ret;
 -        }
      } else if (output_samples != alac->nb_samples) {
          av_log(avctx, AV_LOG_ERROR, "sample count mismatch: %"PRIu32" != %d\n",
                 output_samples, alac->nb_samples);
          return AVERROR_INVALIDDATA;
      }
      alac->nb_samples = output_samples;
 -    if (alac->sample_size > 16) {
 +    if (alac->direct_output) {
          for (ch = 0; ch < channels; ch++)
              alac->output_samples_buffer[ch] = (int32_t *)frame->extended_data[ch_index + ch];
      }
  
          if (alac->extra_bits) {
              for (i = 0; i < alac->nb_samples; i++) {
 +                if(get_bits_left(&alac->gb) <= 0)
 +                    return -1;
                  for (ch = 0; ch < channels; ch++)
                      alac->extra_bits_buffer[ch][i] = get_bits(&alac->gb, alac->extra_bits);
              }
          }
          for (ch = 0; ch < channels; ch++) {
 -            rice_decompress(alac, alac->predict_error_buffer[ch],
 +            int ret=rice_decompress(alac, alac->predict_error_buffer[ch],
                              alac->nb_samples, bps,
                              rice_history_mult[ch] * alac->rice_history_mult / 4);
 +            if(ret<0)
 +                return ret;
  
              /* adaptive FIR filter */
              if (prediction_type[ch] == 15) {
      } else {
          /* not compressed, easy case */
          for (i = 0; i < alac->nb_samples; i++) {
 +            if(get_bits_left(&alac->gb) <= 0)
 +                return -1;
              for (ch = 0; ch < channels; ch++) {
                  alac->output_samples_buffer[ch][i] =
                           get_sbits_long(&alac->gb, alac->sample_size);
          decorr_left_weight = 0;
      }
  
 -    if (channels == 2 && decorr_left_weight) {
 -        decorrelate_stereo(alac->output_samples_buffer, alac->nb_samples,
 -                           decorr_shift, decorr_left_weight);
 -    }
 +    if (channels == 2) {
 +        if (alac->extra_bits && alac->extra_bit_bug) {
 +            alac->dsp.append_extra_bits[1](alac->output_samples_buffer, alac->extra_bits_buffer,
 +                                           alac->extra_bits, channels, alac->nb_samples);
 +        }
 +
 +        if (decorr_left_weight) {
 +            alac->dsp.decorrelate_stereo(alac->output_samples_buffer, alac->nb_samples,
 +                                         decorr_shift, decorr_left_weight);
 +        }
  
 -    if (alac->extra_bits) {
 -        append_extra_bits(alac->output_samples_buffer, alac->extra_bits_buffer,
 -                          alac->extra_bits, channels, alac->nb_samples);
 +        if (alac->extra_bits && !alac->extra_bit_bug) {
 +            alac->dsp.append_extra_bits[1](alac->output_samples_buffer, alac->extra_bits_buffer,
 +                                           alac->extra_bits, channels, alac->nb_samples);
 +        }
 +    } else if (alac->extra_bits) {
 +        alac->dsp.append_extra_bits[0](alac->output_samples_buffer, alac->extra_bits_buffer,
 +                                       alac->extra_bits, channels, alac->nb_samples);
      }
  
      switch(alac->sample_size) {
                  *outbuffer++ = alac->output_samples_buffer[ch][i];
          }}
          break;
 +    case 20: {
 +        for (ch = 0; ch < channels; ch++) {
 +            for (i = 0; i < alac->nb_samples; i++)
 +                alac->output_samples_buffer[ch][i] <<= 12;
 +        }}
 +        break;
      case 24: {
          for (ch = 0; ch < channels; ch++) {
              for (i = 0; i < alac->nb_samples; i++)
@@@ -418,8 -412,7 +418,8 @@@ static int alac_decode_frame(AVCodecCon
      int channels;
      int ch, ret, got_end;
  
 -    init_get_bits(&alac->gb, avpkt->data, avpkt->size * 8);
 +    if ((ret = init_get_bits8(&alac->gb, avpkt->data, avpkt->size)) < 0)
 +        return ret;
  
      got_end = 0;
      alac->nb_samples = 0;
              break;
          }
          if (element > TYPE_CPE && element != TYPE_LFE) {
 -            av_log(avctx, AV_LOG_ERROR, "syntax element unsupported: %d", element);
 +            av_log(avctx, AV_LOG_ERROR, "syntax element unsupported: %d\n", element);
              return AVERROR_PATCHWELCOME;
          }
  
          av_log(avctx, AV_LOG_ERROR, "no end tag found. incomplete packet.\n");
          return AVERROR_INVALIDDATA;
      }
 -    if (!alac->nb_samples) {
 -        av_log(avctx, AV_LOG_ERROR, "No decodable data in the packet\n");
 -        return AVERROR_INVALIDDATA;
 -    }
  
      if (avpkt->size * 8 - get_bits_count(&alac->gb) > 8) {
          av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n",
                 avpkt->size * 8 - get_bits_count(&alac->gb));
      }
  
-     if (alac->channels == ch)
 -    *got_frame_ptr = 1;
++    if (alac->channels == ch && alac->nb_samples)
 +        *got_frame_ptr = 1;
 +    else
 +        av_log(avctx, AV_LOG_WARNING, "Failed to decode all channels\n");
  
      return avpkt->size;
  }
@@@ -475,7 -469,7 +475,7 @@@ static av_cold int alac_decode_close(AV
      int ch;
      for (ch = 0; ch < FFMIN(alac->channels, 2); ch++) {
          av_freep(&alac->predict_error_buffer[ch]);
 -        if (alac->sample_size == 16)
 +        if (!alac->direct_output)
              av_freep(&alac->output_samples_buffer[ch]);
          av_freep(&alac->extra_bits_buffer[ch]);
      }
@@@ -488,24 -482,17 +488,24 @@@ static int allocate_buffers(ALACContex
      int ch;
      int buf_size = alac->max_samples_per_frame * sizeof(int32_t);
  
 +    for (ch = 0; ch < 2; ch++) {
 +        alac->predict_error_buffer[ch]  = NULL;
 +        alac->output_samples_buffer[ch] = NULL;
 +        alac->extra_bits_buffer[ch]     = NULL;
 +    }
 +
      for (ch = 0; ch < FFMIN(alac->channels, 2); ch++) {
          FF_ALLOC_OR_GOTO(alac->avctx, alac->predict_error_buffer[ch],
                           buf_size, buf_alloc_fail);
  
 -        if (alac->sample_size == 16) {
 +        alac->direct_output = alac->sample_size > 16;
 +        if (!alac->direct_output) {
              FF_ALLOC_OR_GOTO(alac->avctx, alac->output_samples_buffer[ch],
 -                             buf_size, buf_alloc_fail);
 +                             buf_size + AV_INPUT_BUFFER_PADDING_SIZE, buf_alloc_fail);
          }
  
          FF_ALLOC_OR_GOTO(alac->avctx, alac->extra_bits_buffer[ch],
 -                         buf_size, buf_alloc_fail);
 +                         buf_size + AV_INPUT_BUFFER_PADDING_SIZE, buf_alloc_fail);
      }
      return 0;
  buf_alloc_fail:
@@@ -539,7 -526,7 +539,7 @@@ static int alac_set_info(ALACContext *a
      bytestream2_get_be16u(&gb); // maxRun
      bytestream2_get_be32u(&gb); // max coded frame size
      bytestream2_get_be32u(&gb); // average bitrate
 -    bytestream2_get_be32u(&gb); // samplerate
 +    alac->sample_rate          = bytestream2_get_be32u(&gb);
  
      return 0;
  }
@@@ -552,18 -539,17 +552,18 @@@ static av_cold int alac_decode_init(AVC
  
      /* initialize from the extradata */
      if (alac->avctx->extradata_size < ALAC_EXTRADATA_SIZE) {
 -        av_log(avctx, AV_LOG_ERROR, "alac: extradata is too small\n");
 +        av_log(avctx, AV_LOG_ERROR, "extradata is too small\n");
          return AVERROR_INVALIDDATA;
      }
      if (alac_set_info(alac)) {
 -        av_log(avctx, AV_LOG_ERROR, "alac: set_info failed\n");
 +        av_log(avctx, AV_LOG_ERROR, "set_info failed\n");
          return -1;
      }
  
      switch (alac->sample_size) {
      case 16: avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
               break;
 +    case 20:
      case 24:
      case 32: avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
               break;
               return AVERROR_PATCHWELCOME;
      }
      avctx->bits_per_raw_sample = alac->sample_size;
 +    avctx->sample_rate         = alac->sample_rate;
  
      if (alac->channels < 1) {
          av_log(avctx, AV_LOG_WARNING, "Invalid channel count\n");
          else
              avctx->channels = alac->channels;
      }
 -    if (avctx->channels > ALAC_MAX_CHANNELS) {
 +    if (avctx->channels > ALAC_MAX_CHANNELS || avctx->channels <= 0 ) {
          av_log(avctx, AV_LOG_ERROR, "Unsupported channel count: %d\n",
                 avctx->channels);
          return AVERROR_PATCHWELCOME;
          return ret;
      }
  
 +    ff_alacdsp_init(&alac->dsp);
 +
      return 0;
  }
  
 +#if HAVE_THREADS
 +static int init_thread_copy(AVCodecContext *avctx)
 +{
 +    ALACContext *alac = avctx->priv_data;
 +    alac->avctx = avctx;
 +    return allocate_buffers(alac);
 +}
 +#endif
 +
 +static const AVOption options[] = {
 +    { "extra_bits_bug", "Force non-standard decoding process",
 +      offsetof(ALACContext, extra_bit_bug), AV_OPT_TYPE_BOOL, { .i64 = 0 },
 +      0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM },
 +    { NULL },
 +};
 +
 +static const AVClass alac_class = {
 +    .class_name = "alac",
 +    .item_name  = av_default_item_name,
 +    .option     = options,
 +    .version    = LIBAVUTIL_VERSION_INT,
 +};
 +
  AVCodec ff_alac_decoder = {
      .name           = "alac",
      .long_name      = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
      .init           = alac_decode_init,
      .close          = alac_decode_close,
      .decode         = alac_decode_frame,
 -    .capabilities   = AV_CODEC_CAP_DR1,
 +    .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
 +    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
 +    .priv_class     = &alac_class
  };