[FFmpeg-soc] [soc]: r5407 - in als: als_data.h alsdec.c

thilo.borgmann subversion at mplayerhq.hu
Tue Oct 13 21:29:01 CEST 2009


Author: thilo.borgmann
Date: Tue Oct 13 21:29:01 2009
New Revision: 5407

Log:
Updated to the current version (rev. 23) still being reviewed on ffmpeg-devel.

Modified:
   als/als_data.h
   als/alsdec.c

Modified: als/als_data.h
==============================================================================
--- als/als_data.h	Sat Oct 10 12:55:16 2009	(r5406)
+++ als/als_data.h	Tue Oct 13 21:29:01 2009	(r5407)
@@ -19,129 +19,77 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#ifndef AVCODEC_ALS_DATA_H
+#define AVCODEC_ALS_DATA_H
+
 /**
  * @file libavcodec/als_data.h
- * MPEG-4 ALS header file for common data
+ * MPEG-4 ALS common data tables
  * @author Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
  */
 
 
-#ifndef AVCODEC_ALS_DATA_H
-#define AVCODEC_ALS_DATA_H
-
-
 #include <stdint.h>
 
 /** Rice parameters and corresponding index offsets for decoding the
  *  indices of scaled PARCOR values. The table choosen is set globally
  *  by the encoder and stored in ALSSpecificConfig.
  */
-int8_t parcor_rice_table[3][20][2] = {
-                        {
-                        {-52, 4},
-                        {-29, 5},
-                        {-31, 4},
-                        { 19, 4},
-                        {-16, 4},
-                        { 12, 3},
-                        { -7, 3},
-                        {  9, 3},
-                        { -5, 3},
-                        {  6, 3},
-                        { -4, 3},
-                        {  3, 3},
-                        { -3, 2},
-                        {  3, 2},
-                        { -2, 2},
-                        {  3, 2},
-                        { -1, 2},
-                        {  2, 2},
-                        { -1, 2},
-                        {  2, 2}
-                        },
-                        {
-                        {-58, 3},
-                        {-42, 4},
-                        {-46, 4},
-                        { 37, 5},
-                        {-36, 4},
-                        { 29, 4},
-                        {-29, 4},
-                        { 25, 4},
-                        {-23, 4},
-                        { 20, 4},
-                        {-17, 4},
-                        { 16, 4},
-                        {-12, 4},
-                        { 12, 3},
-                        {-10, 4},
-                        {  7, 3},
-                        { -4, 4},
-                        {  3, 3},
-                        { -1, 3},
-                        {  1, 3}
-                        },
-                        {
-                        {-59, 3},
-                        {-45, 5},
-                        {-50, 4},
-                        { 38, 4},
-                        {-39, 4},
-                        { 32, 4},
-                        {-30, 4},
-                        { 25, 3},
-                        {-23, 3},
-                        { 20, 3},
-                        {-20, 3},
-                        { 16, 3},
-                        {-13, 3},
-                        { 10, 3},
-                        { -7, 3},
-                        {  3, 3},
-                        {  0, 3},
-                        { -1, 3},
-                        {  2, 3},
-                        { -1, 2}
-                        }
-                        };
+static const int8_t parcor_rice_table[3][20][2] = {
+    { {-52, 4}, {-29, 5}, {-31, 4}, { 19, 4}, {-16, 4},
+      { 12, 3}, { -7, 3}, {  9, 3}, { -5, 3}, {  6, 3},
+      { -4, 3}, {  3, 3}, { -3, 2}, {  3, 2}, { -2, 2},
+      {  3, 2}, { -1, 2}, {  2, 2}, { -1, 2}, {  2, 2} },
+    { {-58, 3}, {-42, 4}, {-46, 4}, { 37, 5}, {-36, 4},
+      { 29, 4}, {-29, 4}, { 25, 4}, {-23, 4}, { 20, 4},
+      {-17, 4}, { 16, 4}, {-12, 4}, { 12, 3}, {-10, 4},
+      {  7, 3}, { -4, 4}, {  3, 3}, { -1, 3}, {  1, 3} },
+    { {-59, 3}, {-45, 5}, {-50, 4}, { 38, 4}, {-39, 4},
+      { 32, 4}, {-30, 4}, { 25, 3}, {-23, 3}, { 20, 3},
+      {-20, 3}, { 16, 3}, {-13, 3}, { 10, 3}, { -7, 3},
+      {  3, 3}, {  0, 3}, { -1, 3}, {  2, 3}, { -1, 2} }
+};
 
 
 /** Scaled PARCOR values used for the first two PARCOR coefficients.
  *  To be indexed by the Rice coded indices.
  *  Generated by: parcor_scaled_values[i] = 32 + ((i * (i+1)) << 7) - (1 << 20)
+ *  Actual values are divided by 32 in order to be stored in 16 bits.
  */
-int32_t parcor_scaled_values[] = {-1048544, -1048288, -1047776, -1047008,
-                                  -1045984, -1044704, -1043168, -1041376,
-                                  -1039328, -1037024, -1034464, -1031648,
-                                  -1028576, -1025248, -1021664, -1017824,
-                                  -1013728, -1009376, -1004768,  -999904,
-                                   -994784,  -989408,  -983776,  -977888,
-                                   -971744,  -965344,  -958688,  -951776,
-                                   -944608,  -937184,  -929504,  -921568,
-                                   -913376,  -904928,  -896224,  -887264,
-                                   -878048,  -868576,  -858848,  -848864,
-                                   -838624,  -828128,  -817376,  -806368,
-                                   -795104,  -783584,  -771808,  -759776,
-                                   -747488,  -734944,  -722144,  -709088,
-                                   -695776,  -682208,  -668384,  -654304,
-                                   -639968,  -625376,  -610528,  -595424,
-                                   -580064,  -564448,  -548576,  -532448,
-                                   -516064,  -499424,  -482528,  -465376,
-                                   -447968,  -430304,  -412384,  -394208,
-                                   -375776,  -357088,  -338144,  -318944,
-                                   -299488,  -279776,  -259808,  -239584,
-                                   -219104,  -198368,  -177376,  -156128,
-                                   -134624,  -112864,   -90848,   -68576,
-                                    -46048,   -23264,     -224,    23072,
-                                     46624,    70432,    94496,   118816,
-                                    143392,   168224,   193312,   218656,
-                                    244256,   270112,   296224,   322592,
-                                    349216,   376096,   403232,   430624,
-                                    458272,   486176,   514336,   542752,
-                                    571424,   600352,   629536,   658976,
-                                    688672,   718624,   748832,   779296,
-                                    810016,   840992,   872224,   903712,
-                                    935456,   967456,   999712,  1032224};
+static const int16_t parcor_scaled_values[] = {
+    -1048544 / 32, -1048288 / 32, -1047776 / 32, -1047008 / 32,
+    -1045984 / 32, -1044704 / 32, -1043168 / 32, -1041376 / 32,
+    -1039328 / 32, -1037024 / 32, -1034464 / 32, -1031648 / 32,
+    -1028576 / 32, -1025248 / 32, -1021664 / 32, -1017824 / 32,
+    -1013728 / 32, -1009376 / 32, -1004768 / 32,  -999904 / 32,
+     -994784 / 32,  -989408 / 32,  -983776 / 32,  -977888 / 32,
+     -971744 / 32,  -965344 / 32,  -958688 / 32,  -951776 / 32,
+     -944608 / 32,  -937184 / 32,  -929504 / 32,  -921568 / 32,
+     -913376 / 32,  -904928 / 32,  -896224 / 32,  -887264 / 32,
+     -878048 / 32,  -868576 / 32,  -858848 / 32,  -848864 / 32,
+     -838624 / 32,  -828128 / 32,  -817376 / 32,  -806368 / 32,
+     -795104 / 32,  -783584 / 32,  -771808 / 32,  -759776 / 32,
+     -747488 / 32,  -734944 / 32,  -722144 / 32,  -709088 / 32,
+     -695776 / 32,  -682208 / 32,  -668384 / 32,  -654304 / 32,
+     -639968 / 32,  -625376 / 32,  -610528 / 32,  -595424 / 32,
+     -580064 / 32,  -564448 / 32,  -548576 / 32,  -532448 / 32,
+     -516064 / 32,  -499424 / 32,  -482528 / 32,  -465376 / 32,
+     -447968 / 32,  -430304 / 32,  -412384 / 32,  -394208 / 32,
+     -375776 / 32,  -357088 / 32,  -338144 / 32,  -318944 / 32,
+     -299488 / 32,  -279776 / 32,  -259808 / 32,  -239584 / 32,
+     -219104 / 32,  -198368 / 32,  -177376 / 32,  -156128 / 32,
+     -134624 / 32,  -112864 / 32,   -90848 / 32,   -68576 / 32,
+      -46048 / 32,   -23264 / 32,     -224 / 32,    23072 / 32,
+       46624 / 32,    70432 / 32,    94496 / 32,   118816 / 32,
+      143392 / 32,   168224 / 32,   193312 / 32,   218656 / 32,
+      244256 / 32,   270112 / 32,   296224 / 32,   322592 / 32,
+      349216 / 32,   376096 / 32,   403232 / 32,   430624 / 32,
+      458272 / 32,   486176 / 32,   514336 / 32,   542752 / 32,
+      571424 / 32,   600352 / 32,   629536 / 32,   658976 / 32,
+      688672 / 32,   718624 / 32,   748832 / 32,   779296 / 32,
+      810016 / 32,   840992 / 32,   872224 / 32,   903712 / 32,
+      935456 / 32,   967456 / 32,   999712 / 32,  1032224 / 32
+};
 
 
 #endif /* AVCODEC_ALS_DATA_H */

Modified: als/alsdec.c
==============================================================================
--- als/alsdec.c	Sat Oct 10 12:55:16 2009	(r5406)
+++ als/alsdec.c	Tue Oct 13 21:29:01 2009	(r5407)
@@ -1,5 +1,5 @@
 /*
- * ALS decoder
+ * MPEG-4 ALS decoder
  * Copyright (c) 2009 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
  *
  * This file is part of FFmpeg.
@@ -33,6 +33,7 @@
 #include "get_bits.h"
 #include "unary.h"
 #include "mpeg4audio.h"
+#include "bytestream.h"
 
 #include "als_data.h"
 
@@ -44,103 +45,86 @@ enum RA_Flag {
 
 
 typedef struct {
-    uint32_t     als_id;                 ///< ALS identifier
-    uint32_t     samp_freq;              ///< sampling frequency in Hz
-    uint32_t     samples;                ///< number of samples (per channel), 0xFFFFFFFF if unknown
-    int          channels;               ///< number of channels
-    int          file_type;              ///< not used, provided for debugging
-    int          resolution;             ///< 000 = 8-bit; 001 = 16-bit; 010 = 24-bit; 011 = 32-bit
-    int          floating;               ///< 1 = IEEE 32-bit floating-point, 0 = integer
-    int          msb_first;              ///< original byte order of the input audio data
-    int          frame_length;           ///< frame Length
-    int          random_access;          ///< distance between RA frames (in frames, 0...255)
-    enum RA_Flag ra_flag;                ///< indicates where the size of ra units is stored
-    int          adapt_order;            ///< adaptive order: 1 = on, 0 = off
-    int          coef_table;             ///< table index of Rice code parameters
-    int          long_term_prediction;   ///< long term prediction (LTP): 1 = on, 0 = off
-    int          max_order;              ///< maximum prediction order (0..1023)
-    int          block_switching;        ///< number of block switching levels
-    int          bgmc_mode;              ///< BGMC Mode: 1 = on, 0 = off (Rice coding only)
-    int          sb_part;                ///< sub-block partition
-    int          joint_stereo;           ///< joint Stereo: 1 = on, 0 = off
-    int          mc_coding;              ///< extended inter-channel coding: 1 = on, 0 = off
-    int          chan_config;            ///< indicates that a chan_config_info field is present
-    int          chan_sort;              ///< channel rearrangement: 1 = on, 0 = off
-    int          crc_enabled;            ///< indicates that the crc field is present
-    int          rlslms;                 ///< use RLS-LMS predictor: 1 = on, 0 = off
-    int          aux_data_enabled;       ///< indicates that auxiliary data is present
-    int          chan_config_info;       ///< mapping of channels to loudspeaker locations
-    int          *chan_pos;              ///< original channel positions
-    uint32_t     header_size;            ///< header size of original audio file in bytes, provided for debugging
-    uint32_t     trailer_size;           ///< Trailer size of original audio file in bytes, provided for debugging
-    uint32_t     crc;                    ///< 32-bit CCITT-32 CRC checksum
+    int resolution;           ///< 000 = 8-bit; 001 = 16-bit; 010 = 24-bit; 011 = 32-bit
+    int floating;             ///< 1 = IEEE 32-bit floating-point, 0 = integer
+    int frame_length;         ///< frame length for each frame (last frame may differ)
+    int ra_distance;          ///< distance between RA frames (in frames, 0...255)
+    enum RA_Flag ra_flag;     ///< indicates where the size of ra units is stored
+    int adapt_order;          ///< adaptive order: 1 = on, 0 = off
+    int coef_table;           ///< table index of Rice code parameters
+    int long_term_prediction; ///< long term prediction (LTP): 1 = on, 0 = off
+    int max_order;            ///< maximum prediction order (0..1023)
+    int block_switching;      ///< number of block switching levels
+    int bgmc;                 ///< "Block Gilbert-Moore Code": 1 = on, 0 = off (Rice coding only)
+    int sb_part;              ///< sub-block partition
+    int joint_stereo;         ///< joint stereo: 1 = on, 0 = off
+    int mc_coding;            ///< extended inter-channel coding (multi channel coding): 1 = on, 0 = off
+    int chan_config;          ///< indicates that a chan_config_info field is present
+    int chan_sort;            ///< channel rearrangement: 1 = on, 0 = off
+    int rlslms;               ///< use "Recursive Least Square-Least Mean Square" predictor: 1 = on, 0 = off
+    int chan_config_info;     ///< mapping of channels to loudspeaker locations. Unused until setting channel configuration is implemented.
+    int *chan_pos;            ///< original channel positions
+    uint32_t header_size;     ///< header size of original audio file in bytes, provided for debugging
+    uint32_t trailer_size;    ///< trailer size of original audio file in bytes, provided for debugging
 } ALSSpecificConfig;
 
 
 typedef struct {
-    AVCodecContext    *avctx;
+    AVCodecContext *avctx;
     ALSSpecificConfig sconf;
-    GetBitContext     gb;                ///< a bit reader context
-    unsigned int      num_frames;        ///< number of frames to decode, 0 if unknown
-    unsigned int      cur_frame_length;  ///< length of the current frame to decode
-    unsigned int      last_frame_length; ///< length of the last frame to decode, 0 if unknown
-    unsigned int      frame_id;          ///< the frame id / number of the current frame
-    unsigned int      js_switch;         ///< if true, joint-stereo decoding is enforced
-    unsigned int      num_blocks;        ///< number of blocks used in the current frame
-    int64_t           *quant_cof;        ///< quantized parcor coefficients
-    int64_t           *lpc_cof;          ///< coefficients of the direct form prediction filter
-    int64_t           *prev_raw_samples; ///< contains unshifted raw samples from the previous block
-    int64_t           **raw_samples;     ///< decoded raw samples for each channel
-    int64_t           *raw_buffer;       ///< contains all decoded raw samples including carryover samples
+    GetBitContext gb;
+    unsigned int num_frames;        ///< number of frames to decode, 0 if unknown
+    unsigned int cur_frame_length;  ///< length of the current frame to decode
+    unsigned int last_frame_length; ///< length of the last frame to decode, 0 if unknown
+    unsigned int frame_id;          ///< the frame ID / number of the current frame
+    unsigned int js_switch;         ///< if true, joint-stereo decoding is enforced
+    unsigned int num_blocks;        ///< number of blocks used in the current frame
+    int32_t *quant_cof;             ///< quantized parcor coefficients
+    int32_t *lpc_cof;               ///< coefficients of the direct form prediction filter
+    int32_t *prev_raw_samples;      ///< contains unshifted raw samples from the previous block
+    int32_t **raw_samples;          ///< decoded raw samples for each channel
+    int32_t *raw_buffer;            ///< contains all decoded raw samples including carryover samples
 } ALSDecContext;
 
 
-#ifdef DEBUG
 static av_cold void dprint_specific_config(ALSDecContext *ctx)
 {
+#ifdef DEBUG
     AVCodecContext *avctx    = ctx->avctx;
     ALSSpecificConfig *sconf = &ctx->sconf;
 
-    dprintf(avctx, "als_id = %x\n",               sconf->als_id);
-    dprintf(avctx, "samp_freq = %i\n",            sconf->samp_freq);
-    dprintf(avctx, "samples = %i\n",              sconf->samples);
-    dprintf(avctx, "channels = %i\n",             sconf->channels);
-    dprintf(avctx, "file_type = %i\n",            sconf->file_type);
     dprintf(avctx, "resolution = %i\n",           sconf->resolution);
     dprintf(avctx, "floating = %i\n",             sconf->floating);
-    dprintf(avctx, "msb_first = %i\n",            sconf->msb_first);
     dprintf(avctx, "frame_length = %i\n",         sconf->frame_length);
-    dprintf(avctx, "random_access = %i\n",        sconf->random_access);
+    dprintf(avctx, "ra_distance = %i\n",          sconf->ra_distance);
     dprintf(avctx, "ra_flag = %i\n",              sconf->ra_flag);
     dprintf(avctx, "adapt_order = %i\n",          sconf->adapt_order);
     dprintf(avctx, "coef_table = %i\n",           sconf->coef_table);
     dprintf(avctx, "long_term_prediction = %i\n", sconf->long_term_prediction);
     dprintf(avctx, "max_order = %i\n",            sconf->max_order);
     dprintf(avctx, "block_switching = %i\n",      sconf->block_switching);
-    dprintf(avctx, "bgmc_mode = %i\n",            sconf->bgmc_mode);
+    dprintf(avctx, "bgmc = %i\n",                 sconf->bgmc);
     dprintf(avctx, "sb_part = %i\n",              sconf->sb_part);
     dprintf(avctx, "joint_stereo = %i\n",         sconf->joint_stereo);
     dprintf(avctx, "mc_coding = %i\n",            sconf->mc_coding);
     dprintf(avctx, "chan_config = %i\n",          sconf->chan_config);
     dprintf(avctx, "chan_sort = %i\n",            sconf->chan_sort);
-    dprintf(avctx, "crc_enabled = %i\n",          sconf->crc_enabled);
     dprintf(avctx, "RLSLMS = %i\n",               sconf->rlslms);
-    dprintf(avctx, "aux_data_enabled = %i\n",     sconf->aux_data_enabled);
     dprintf(avctx, "chan_config_info = %i\n",     sconf->chan_config_info);
     dprintf(avctx, "header_size = %i\n",          sconf->header_size);
     dprintf(avctx, "trailer_size = %i\n",         sconf->trailer_size);
-    dprintf(avctx, "crc_enabled = %i\n",          sconf->crc_enabled);
 
     dprintf(avctx, " num_frames = %i\n",          ctx->num_frames);
     dprintf(avctx, " last_frame_length = %i\n",   ctx->last_frame_length);
-}
 #endif
+}
 
 
-/** Computes ceil(log2(x)) using av_log2.
+/** Returns the bits left for reading.
  */
-static inline int ceil_log2(int x) {
-    return x > 0 ? av_log2((x - 1) << 1) : 0;
+static inline int get_bits_left(GetBitContext *gb)
+{
+    return gb->size_in_bits - get_bits_count(gb);
 }
 
 
@@ -150,123 +134,106 @@ static av_cold int read_specific_config(
 {
     GetBitContext gb;
     uint64_t ht_size;
-    int i, config_offset;
+    int i, config_offset, crc_enabled;
     MPEG4AudioConfig m4ac;
     ALSSpecificConfig *sconf = &ctx->sconf;
-    const uint8_t *buffer    = ctx->avctx->extradata;
-    int buffer_size          = ctx->avctx->extradata_size;
+    AVCodecContext *avctx    = ctx->avctx;
+    uint32_t samples, als_id;
 
-    init_get_bits(&gb, buffer, buffer_size * 8);
+    init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8);
 
-    config_offset = ff_mpeg4audio_get_config(&m4ac, buffer, buffer_size);
+    config_offset = ff_mpeg4audio_get_config(&m4ac, avctx->extradata,
+                                             avctx->extradata_size);
 
     if (config_offset < 0)
         return -1;
 
     skip_bits_long(&gb, config_offset);
-    buffer_size -= config_offset >> 3;
 
-    if (buffer_size < 22)
+    if (get_bits_left(&gb) < (30 << 3))
         return -1;
 
     // read the fixed items
-    sconf->als_id               = get_bits_long(&gb, 32);
-    sconf->samp_freq            = m4ac.sample_rate;
-    skip_bits_long(&gb, 32);
-    sconf->samples              = get_bits_long(&gb, 32);
-    sconf->channels             = m4ac.channels;
-    skip_bits(&gb, 16);
-    sconf->file_type            = get_bits(&gb, 3);
+    als_id                      = get_bits_long(&gb, 32);
+    avctx->sample_rate          = m4ac.sample_rate;
+    skip_bits_long(&gb, 32); // sample rate already known
+    samples                     = get_bits_long(&gb, 32);
+    avctx->channels             = m4ac.channels;
+    skip_bits(&gb, 16);      // number of channels already knwon
+    skip_bits(&gb, 3);       // skip file_type
     sconf->resolution           = get_bits(&gb, 3);
     sconf->floating             = get_bits1(&gb);
-    sconf->msb_first            = get_bits1(&gb);
+    skip_bits1(&gb);         // skip msb_first
     sconf->frame_length         = get_bits(&gb, 16) + 1;
-    sconf->random_access        = get_bits(&gb, 8);
+    sconf->ra_distance          = get_bits(&gb, 8);
     sconf->ra_flag              = get_bits(&gb, 2);
     sconf->adapt_order          = get_bits1(&gb);
     sconf->coef_table           = get_bits(&gb, 2);
     sconf->long_term_prediction = get_bits1(&gb);
     sconf->max_order            = get_bits(&gb, 10);
     sconf->block_switching      = get_bits(&gb, 2);
-    sconf->bgmc_mode            = get_bits1(&gb);
+    sconf->bgmc                 = get_bits1(&gb);
     sconf->sb_part              = get_bits1(&gb);
     sconf->joint_stereo         = get_bits1(&gb);
     sconf->mc_coding            = get_bits1(&gb);
     sconf->chan_config          = get_bits1(&gb);
     sconf->chan_sort            = get_bits1(&gb);
-    sconf->crc_enabled          = get_bits1(&gb);
+    crc_enabled                 = get_bits1(&gb);
     sconf->rlslms               = get_bits1(&gb);
-    skip_bits(&gb, 5);                                      // skip 5 reserved bits
-    sconf->aux_data_enabled     = get_bits1(&gb);
-    buffer_size -= 22;
+    skip_bits(&gb, 5);       // skip 5 reserved bits
+    skip_bits1(&gb);         // skip aux_data_enabled
 
 
     // check for ALSSpecificConfig struct
-    if (sconf->als_id != MKBETAG('A','L','S','\0'))
+    if (als_id != MKBETAG('A','L','S','\0'))
         return -1;
 
     ctx->cur_frame_length = sconf->frame_length;
 
     // allocate quantized parcor coefficient buffer
-    if (!(ctx->quant_cof = av_malloc(sizeof(int64_t) * sconf->max_order))) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-        return AVERROR(ENOMEM);
-    }
-
-    // allocate LPC coefficients
-    if (!(ctx->lpc_cof = av_malloc(sizeof(int64_t) * sconf->max_order))) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
+    if (!(ctx->quant_cof = av_malloc(sizeof(*ctx->quant_cof) * sconf->max_order)) ||
+        !(ctx->lpc_cof   = av_malloc(sizeof(*ctx->lpc_cof)   * sconf->max_order))) {
+        av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
         return AVERROR(ENOMEM);
     }
-
     // calculate total number of frames to decode if possible
-    if (sconf->samples != 0xFFFFFFFF) {
-        ctx->num_frames        = ((sconf->samples - 1) / sconf->frame_length) + 1;
-        ctx->last_frame_length = sconf->samples % ctx->sconf.frame_length;
-        if (!ctx->last_frame_length) {
-            ctx->last_frame_length = sconf->frame_length;
-        }
+    if (samples != 0xFFFFFFFF) {
+        ctx->num_frames        = (samples - 1) / sconf->frame_length + 1;
+        ctx->last_frame_length = (samples - 1) % sconf->frame_length + 1;
     } else {
         ctx->num_frames        = 0;
         ctx->last_frame_length = 0;
     }
 
-
     // read channel config
-    if (sconf->chan_config) {
-        if (buffer_size < 2)
-            return -1;
-
+    if (sconf->chan_config)
         sconf->chan_config_info = get_bits(&gb, 16);
-        buffer_size -= 2;
-        // TODO: use this to set avctx->channel_layout
-    }
+    // TODO: use this to set avctx->channel_layout
 
 
     // read channel sorting
-    if (sconf->chan_sort && sconf->channels > 1) {
-        int chan_pos_bits = ceil_log2(sconf->channels);
-        int bytes_needed  = (sconf->channels * chan_pos_bits + 7) >> 3;
-        if (buffer_size < bytes_needed)
+    if (sconf->chan_sort && avctx->channels > 1) {
+        int chan_pos_bits = av_ceil_log2(avctx->channels);
+        int bits_needed  = avctx->channels * chan_pos_bits + 7;
+        if (get_bits_left(&gb) < bits_needed)
             return -1;
 
-        if(!(sconf->chan_pos = av_malloc(sconf->channels * sizeof(int))))
-            return -1;
+        if (!(sconf->chan_pos = av_malloc(avctx->channels * sizeof(*sconf->chan_pos))))
+            return AVERROR(ENOMEM);
 
-        for (i = 0; i < sconf->channels; i++) {
+        for (i = 0; i < avctx->channels; i++)
             sconf->chan_pos[i] = get_bits(&gb, chan_pos_bits);
-        }
 
         align_get_bits(&gb);
-        buffer_size -= bytes_needed;
         // TODO: use this to actually do channel sorting
     } else {
         sconf->chan_sort = 0;
     }
 
 
-    // read fixed header and trailer sizes, if size = 0xFFFFFFFF then there is no data field!
-    if (buffer_size < 8)
+    // read fixed header and trailer sizes,
+    // if size = 0xFFFFFFFF then there is no data field!
+    if (get_bits_left(&gb) < 64)
         return -1;
 
     sconf->header_size  = get_bits_long(&gb, 32);
@@ -276,39 +243,32 @@ static av_cold int read_specific_config(
     if (sconf->trailer_size == 0xFFFFFFFF)
         sconf->trailer_size = 0;
 
-    ht_size = sconf->header_size + sconf->trailer_size;
-
-    buffer_size -= 8;
+    ht_size = ((int64_t)(sconf->header_size) + (int64_t)(sconf->trailer_size)) << 3;
 
 
     // skip the header and trailer data
-    if (buffer_size < ht_size)
+    if (get_bits_left(&gb) < ht_size)
         return -1;
 
-    ht_size <<= 3;
-
-    while (ht_size > 0) {
-        int len = FFMIN(ht_size, INT32_MAX);
-        skip_bits_long(&gb, len);
-        ht_size -= len;
-    }
+    if (ht_size > INT32_MAX)
+        return -1;
 
-    buffer_size -= ht_size >> 3;
+    skip_bits_long(&gb, ht_size);
 
 
-    // read the crc data
-    if (sconf->crc_enabled) {
-        if (buffer_size < 4)
+    // skip the crc data
+    if (crc_enabled) {
+        if (get_bits_left(&gb) < 32)
             return -1;
 
-        sconf->crc = get_bits_long(&gb, 32);
+        skip_bits_long(&gb, 32);
     }
 
 
     // no need to read the rest of ALSSpecificConfig (ra_unit_size & aux data)
-#ifdef DEBUG
+
     dprint_specific_config(ctx);
-#endif
+
     return 0;
 }
 
@@ -320,45 +280,34 @@ static int check_specific_config(ALSDecC
     ALSSpecificConfig *sconf = &ctx->sconf;
     int error = 0;
 
-    if (sconf->floating) {
-        av_log_missing_feature(ctx->avctx, "Floating point decoding", 0);
-        error = -1;
-    }
-
-    if (sconf->long_term_prediction) {
-        av_log_missing_feature(ctx->avctx, "Long-term prediction", 0);
-        error = -1;
-    }
-
-    if (sconf->bgmc_mode) {
-        av_log_missing_feature(ctx->avctx, "BGMC entropy decoding", 0);
-        error = -1;
-    }
-
-    if (sconf->mc_coding) {
-        av_log_missing_feature(ctx->avctx, "Multi-channel correlation", 0);
-        error = -1;
-    }
-
-    if (sconf->chan_sort) {
-        av_log_missing_feature(ctx->avctx, "Channel sorting", 0);
+    // report unsupported feature and set error value
+    #define MISSING_ERR(cond, str, errval)              \
+    {                                                   \
+        if (cond) {                                     \
+            av_log_missing_feature(ctx->avctx, str, 0); \
+            error = errval;                             \
+        }                                               \
     }
 
-    if (sconf->rlslms) {
-        av_log_missing_feature(ctx->avctx, "Adaptive RLS-LMS prediction", 0);
-        error = -1;
-    }
+    MISSING_ERR(sconf->floating,             "Floating point decoding",     -1);
+    MISSING_ERR(sconf->long_term_prediction, "Long-term prediction",        -1);
+    MISSING_ERR(sconf->bgmc,                 "BGMC entropy decoding",       -1);
+    MISSING_ERR(sconf->mc_coding,            "Multi-channel correlation",   -1);
+    MISSING_ERR(sconf->rlslms,               "Adaptive RLS-LMS prediction", -1);
+    MISSING_ERR(sconf->chan_sort,            "Channel sorting",              0);
 
     return error;
 }
 
 
-/** Parses the bs_info item to extract the block partitioning.
+/** Parses the bs_info field to extract the block partitioning used in
+ *  block switching mode, refer to ISO/IEC 14496-3, section 11.6.2.
  */
-static void parse_bs_info(uint32_t bs_info, unsigned int n, unsigned int div,
-                          unsigned int **div_blocks, unsigned int *num_blocks)
+static void parse_bs_info(const uint32_t bs_info, unsigned int n,
+                          unsigned int div, unsigned int **div_blocks,
+                          unsigned int *num_blocks)
 {
-    if (n < 31 && ((bs_info >> (30 - n)) & 1)) {
+    if (n < 31 && ((bs_info << n) & 0x40000000)) {
         // if the level is valid and the investigated bit n is set
         // then recursively check both children at bits (2n+1) and (2n+2)
         n   *= 2;
@@ -377,45 +326,35 @@ static void parse_bs_info(uint32_t bs_in
 
 /** Reads and decodes a Rice codeword.
  */
-static int64_t decode_rice(GetBitContext *gb, unsigned int k)
+static int32_t decode_rice(GetBitContext *gb, unsigned int k)
 {
-    int64_t value = 0;
-    int64_t q = 0;
-    int     max = gb->size_in_bits - get_bits_count(gb) - k;
-
-    if (!k) {
-        q = get_unary(gb, 0, max);
-        return (q & 1) ? -((q + 1) >> 1) : ((q + 1) >> 1);
-    } else if (k == 1) {
-        q = get_unary(gb, 0, max);
-        return get_bits1(gb) ? q : -(q + 1);
-    } else {
-        unsigned int r, sub_sign;
-
-        q         = get_unary(gb, 0, max);
-        sub_sign  = get_bits1(gb);
-        r         = get_bits_long(gb, k - 1);
-
-        value = (q << (k - 1)) + r;
+    int max = gb->size_in_bits - get_bits_count(gb) - k;
+    int q   = get_unary(gb, 0, max);
+    int r   = k ? get_bits1(gb) : !(q & 1);
 
-        return sub_sign ? value : -(value + 1);
+    if (k > 1) {
+        q <<= (k - 1);
+        q  += get_bits_long(gb, k - 1);
+    } else if (!k) {
+        q >>= 1;
     }
+    return r ? q : ~q;
 }
 
 
 /** Converts PARCOR coefficient k to direct filter coefficient.
  */
-static void parcor_to_lpc(unsigned int k, int64_t *par, int64_t *cof)
+static void parcor_to_lpc(unsigned int k, const int32_t *par, int32_t *cof)
 {
-    int i;
-    int64_t tmp1, tmp2;
+    int i, j;
 
-    for (i = 0; i < (k+1) >> 1; i++) {
-        tmp1 = cof[    i    ] + ((par[k] * cof[k - i - 1] + (1 << 19)) >> 20);
-        tmp2 = cof[k - i - 1] + ((par[k] * cof[    i    ] + (1 << 19)) >> 20);
-        cof[k - i - 1] = tmp2;
-        cof[    i    ] = tmp1;
+    for (i = 0, j = k - 1; i < j; i++, j--) {
+        int tmp1 = ((MUL64(par[k], cof[j]) + (1 << 19)) >> 20);
+        cof[j]  += ((MUL64(par[k], cof[i]) + (1 << 19)) >> 20);
+        cof[i]  += tmp1;
     }
+    if (i == j)
+        cof[i] += ((MUL64(par[k], cof[j]) + (1 << 19)) >> 20);
 
     cof[k] = par[k];
 }
@@ -442,295 +381,401 @@ static void reconstruct_block_sizes(ALSD
     // of 14496-3.
     // The ALS conformance files feature an odd number of samples in the last
     // frame.
+
+    for (b = 0; b < ctx->num_blocks; b++)
+        div_blocks[b] = ctx->sconf.frame_length >> div_blocks[b];
+
     if (ctx->cur_frame_length == ctx->last_frame_length) {
         unsigned int remaining = ctx->cur_frame_length;
 
         for (b = 0; b < ctx->num_blocks; b++) {
-            div_blocks[b] = ctx->sconf.frame_length >> div_blocks[b];
-
             if (remaining < div_blocks[b]) {
                 div_blocks[b] = remaining;
                 ctx->num_blocks = b + 1;
                 break;
-            } else {
-                remaining -= div_blocks[b];
             }
+
+            remaining -= div_blocks[b];
         }
-    } else {
-        for (b = 0; b < ctx->num_blocks; b++)
-            div_blocks[b] = ctx->sconf.frame_length >> div_blocks[b];
     }
 }
 
 
-/** Reads the block data.
+/** Reads block switching field if necessary and sets actual block sizes.
  */
-static int read_block_data(ALSDecContext *ctx, unsigned int ra_block,
-                            int64_t *raw_samples, unsigned int block_length,
-                            unsigned int *js_blocks, int64_t *raw_other)
+static void get_block_sizes(ALSDecContext *ctx, unsigned int *div_blocks,
+                            uint32_t *bs_info)
+{
+    ALSSpecificConfig *sconf     = &ctx->sconf;
+    GetBitContext *gb            = &ctx->gb;
+    unsigned int *ptr_div_blocks = div_blocks;
+
+    if (sconf->block_switching) {
+        unsigned int bs_info_len = 1 << (sconf->block_switching + 2);
+        *bs_info = get_bits_long(gb, bs_info_len);
+        *bs_info <<= (32 - bs_info_len);
+    }
+
+    ctx->num_blocks = 0;
+    parse_bs_info(*bs_info, 0, 0, &ptr_div_blocks, &ctx->num_blocks);
+    reconstruct_block_sizes(ctx, div_blocks);
+}
+
+
+/** Reads the block data for a constant block
+ */
+static void read_const_block(ALSDecContext *ctx, int32_t *raw_samples,
+                             unsigned int block_length, unsigned int *js_blocks)
 {
     ALSSpecificConfig *sconf = &ctx->sconf;
     AVCodecContext *avctx    = ctx->avctx;
     GetBitContext *gb        = &ctx->gb;
-    unsigned int shift_lsbs  = 0;
-    unsigned int block_type;
-    unsigned int k;
+    int32_t const_val        = 0;
+    unsigned int const_block, k;
 
-    block_type = get_bits1(gb);
+    const_block  = get_bits1(gb);    // 1 = constant value, 0 = zero block (silence)
+    *js_blocks   = get_bits1(gb);
 
-    if (block_type == 0) {
-        unsigned int const_block;
-        int32_t      const_val = 0;
+    // skip 5 reserved bits
+    skip_bits(gb, 5);
 
-        const_block  = get_bits1(gb);    // 1 = constant value, 0 = zero block (silence)
-        *js_blocks   = get_bits1(gb);
+    if (const_block) {
+        unsigned int const_val_bits = sconf->floating ? 24 : avctx->bits_per_raw_sample;
+        const_val = get_sbits_long(gb, const_val_bits);
+    }
 
-        // skip 5 reserved bits
-        skip_bits(gb, 5);
+    // write raw samples into buffer
+    for (k = 0; k < block_length; k++)
+        raw_samples[k] = const_val;
+}
 
-        if (const_block) {
-            unsigned int const_val_bits;
 
-            if (sconf->resolution == 2 || sconf->floating)
-                const_val_bits = 24;
-            else
-                const_val_bits = avctx->bits_per_raw_sample;
+/** Reads the block data for a non-constant block
+ */
+static int read_var_block(ALSDecContext *ctx, unsigned int ra_block,
+                          int32_t *raw_samples, unsigned int block_length,
+                          unsigned int *js_blocks, int32_t *raw_other,
+                          unsigned int *shift_lsbs)
+{
+    ALSSpecificConfig *sconf = &ctx->sconf;
+    AVCodecContext *avctx    = ctx->avctx;
+    GetBitContext *gb        = &ctx->gb;
+    unsigned int k;
+    unsigned int s[8];
+    unsigned int sub_blocks, log2_sub_blocks, sb_length;
+    unsigned int opt_order  = 1;
+    int32_t      *quant_cof = ctx->quant_cof;
+    int32_t      *lpc_cof   = ctx->lpc_cof;
+    unsigned int start      = 0;
+    int          smp        = 0;
+    int          sb, store_prev_samples;
+    int64_t      y;
 
-            const_val = get_sbits_long(gb, const_val_bits);
-        }
+    *js_blocks  = get_bits1(gb);
 
-        // write raw samples into buffer
-        for (k = 0; k < block_length; k++)
-            raw_samples[k] = const_val;
+    // determine the number of subblocks for entropy decoding
+    if (!sconf->bgmc && !sconf->sb_part) {
+        log2_sub_blocks = 0;
     } else {
-        unsigned int s[8];
-        unsigned int sub_blocks, sb_length;
-        unsigned int opt_order = 1;
-        int64_t      *quant_cof = ctx->quant_cof;
-        int64_t      *lpc_cof   = ctx->lpc_cof;
-        unsigned int start = 0;
-        int          sb, smp;
-        int64_t      y;
+        if (sconf->bgmc && sconf->sb_part)
+            log2_sub_blocks = get_bits(gb, 2);
+        else
+            log2_sub_blocks = 2 * get_bits1(gb);
+    }
 
-        *js_blocks  = get_bits1(gb);
+    sub_blocks = 1 << log2_sub_blocks;
 
-        // determine the number of sub blocks for entropy decoding
-        if (!sconf->bgmc_mode && !sconf->sb_part)
-            sub_blocks = 1;
-        else if (sconf->bgmc_mode && sconf->sb_part)
-            sub_blocks = 1 << get_bits(gb, 2);
-        else
-            sub_blocks = get_bits1(gb) ? 4 : 1;
+    // do not continue in case of a damaged stream since
+    // block_length must be evenly divisible by sub_blocks
+    if (block_length & (sub_blocks - 1)) {
+        av_log(avctx, AV_LOG_WARNING,
+               "Block length is not evenly divisible by the number of subblocks.\n");
+        return -1;
+    }
 
-        // do not continue in case of a damaged stream since
-        // block_length must be evenly divisible by sub_blocks
-        if (block_length % sub_blocks) {
-            av_log(avctx, AV_LOG_WARNING,
-                   "Block length is not evenly divisible by the number of sub blocks.\n");
-            return -1;
-        }
+    sb_length = block_length >> log2_sub_blocks;
 
-        sb_length = block_length / sub_blocks;
 
+    if (sconf->bgmc) {
+        // TODO: BGMC mode
+    } else {
+        s[0] = get_bits(gb, 4 + (sconf->resolution > 1));
+        for (k = 1; k < sub_blocks; k++)
+            s[k] = s[k - 1] + decode_rice(gb, 0);
+    }
 
-        if (!sconf->bgmc_mode) {
-            s[0] = get_bits(gb, (sconf->resolution > 1) ? 5 : 4);
-            for (k = 1; k < sub_blocks; k++)
-                s[k] = s[k - 1] + decode_rice(gb, 0);
+    if (get_bits1(gb))
+        *shift_lsbs = get_bits(gb, 4) + 1;
+
+    store_prev_samples = (*js_blocks && raw_other) || *shift_lsbs;
+
+
+    if (!sconf->rlslms) {
+        if (sconf->adapt_order) {
+            int opt_order_length = av_ceil_log2(av_clip((block_length >> 3) - 1,
+                                                2, sconf->max_order + 1));
+            opt_order            = get_bits(gb, opt_order_length);
         } else {
-            // TODO: BGMC mode
+            opt_order = sconf->max_order;
         }
 
-        if (get_bits1(gb)) {
-            shift_lsbs = get_bits(gb, 4) + 1;
-        }
+        if (opt_order) {
+            int add_base;
 
+            if (sconf->coef_table == 3) {
+                add_base = 0x7F;
 
-        if (!sconf->rlslms) {
-            int64_t quant_index;
+                // read coefficient 0
+                quant_cof[0]  = parcor_scaled_values[get_bits(gb, 7)];
+                quant_cof[0] *= 32;
 
-            if (sconf->adapt_order) {
-                int opt_order_length =
-                        FFMIN(
-                        ceil_log2(sconf->max_order+1),
-                        FFMAX(ceil_log2((block_length >> 3) - 1), 1)
-                        );
-                opt_order = get_bits(gb, opt_order_length);
+                // read coefficient 1
+                quant_cof[1]  = -parcor_scaled_values[get_bits(gb, 7)];
+                quant_cof[0] *= 32;
+
+                // read coefficients 2 to opt_order
+                for (k = 2; k < opt_order; k++)
+                    quant_cof[k] = get_bits(gb, 7);
             } else {
-                opt_order = sconf->max_order;
+                int k_max;
+                add_base = 1;
+
+                // read coefficient 0 to 19
+                k_max = FFMIN(opt_order, 20);
+                for (k = 0; k < k_max; k++) {
+                    int rice_param = parcor_rice_table[sconf->coef_table][k][1];
+                    int offset     = parcor_rice_table[sconf->coef_table][k][0];
+                    quant_cof[k] = decode_rice(gb, rice_param) + offset;
+                }
+
+                // read coefficients 20 to 126
+                k_max = FFMIN(opt_order, 127);
+                for (; k < k_max; k++)
+                    quant_cof[k] = decode_rice(gb, 2) + (k & 1);
+
+                // read coefficients 127 to opt_order
+                for (; k < opt_order; k++)
+                    quant_cof[k] = decode_rice(gb, 1);
+
+                quant_cof[0]  =  parcor_scaled_values[quant_cof[0] + 64];
+                quant_cof[0] *= 32;
+                quant_cof[1]  = -parcor_scaled_values[quant_cof[1] + 64];
+                quant_cof[1] *= 32;
             }
 
-            if (opt_order) {
-                if (sconf->coef_table == 3) {
-                    // read coefficient 0
-                    quant_index = get_bits(gb, 7) - 64;
-                    quant_cof[0] = parcor_scaled_values[quant_index + 64];
+        for (k = 2; k < opt_order; k++)
+            quant_cof[k] = (quant_cof[k] << 14) + (add_base << 13);
+        }
+    }
 
-                    // read coefficient 1
-                    quant_index = get_bits(gb, 7) - 64;
-                    quant_cof[1] = -parcor_scaled_values[quant_index + 64];
+    // TODO: LTP mode
 
-                    // read coefficients 2 to opt_order
-                    for (k = 2; k < opt_order; k++) {
-                        quant_index = get_bits(gb, 7) - 64;
-                        quant_cof[k] = (quant_index << 14) + (1 << 13);
-                    }
-                } else {
-                    int offset, rice_param, k_max;
+    // read first value and residuals in case of a random access block
+    if (ra_block) {
+        if (opt_order)
+            raw_samples[0] = decode_rice(gb, avctx->bits_per_raw_sample - 4);
+        if (opt_order > 1)
+            raw_samples[1] = decode_rice(gb, s[0] + 3);
+        if (opt_order > 2)
+            raw_samples[2] = decode_rice(gb, s[0] + 1);
 
-                    // read coefficient 0
-                    offset       = parcor_rice_table[sconf->coef_table][0][0];
-                    rice_param   = parcor_rice_table[sconf->coef_table][0][1];
-                    quant_index  = decode_rice(gb, rice_param) + offset;
-                    quant_cof[0] = parcor_scaled_values[quant_index + 64];
+        start = FFMIN(opt_order, 3);
+    }
 
-                    // read coefficient 1
-                    offset       = parcor_rice_table[sconf->coef_table][1][0];
-                    rice_param   = parcor_rice_table[sconf->coef_table][1][1];
-                    quant_index  = decode_rice(gb, rice_param) + offset;
-                    quant_cof[1] = -parcor_scaled_values[quant_index + 64];
+    // read all residuals
+    if (sconf->bgmc) {
+        // TODO: BGMC mode
+    } else {
+        int32_t *current_res = raw_samples + start;
 
-                    // read coefficients 2 to 19
-                    k_max = FFMIN(20, opt_order);
-                    for (k = 2; k < k_max; k++) {
-                        offset       = parcor_rice_table[sconf->coef_table][k][0];
-                        rice_param   = parcor_rice_table[sconf->coef_table][k][1];
-                        quant_index  = decode_rice(gb, rice_param) + offset;
-                        quant_cof[k] = (quant_index << 14) + (1 << 13);
-                    }
+        for (sb = 0; sb < sub_blocks; sb++, start = 0)
+            for (; start < sb_length; start++)
+                *current_res++ = decode_rice(gb, s[sb]);
+     }
 
-                    // read coefficients 20 to 126
-                    k_max = FFMIN(127, opt_order);
-                    for (k = 20; k < k_max; k++) {
-                        offset       = k & 1;
-                        rice_param   = 2;
-                        quant_index  = decode_rice(gb, rice_param) + offset;
-                        quant_cof[k] = (quant_index << 14) + (1 << 13);
-                    }
+    // reconstruct all samples from residuals
+    if (ra_block) {
+        for (smp = 0; smp < opt_order; smp++) {
+            y = 1 << 19;
 
-                    // read coefficients 127 to opt_order
-                    for (k = 127; k < opt_order; k++) {
-                        offset       = 0;
-                        rice_param   = 1;
-                        quant_index  = decode_rice(gb, rice_param) + offset;
-                        quant_cof[k] = (quant_index << 14) + (1 << 13);
-                    }
-                }
-            }
-        }
+            for (sb = 0; sb < smp; sb++)
+                y += MUL64(lpc_cof[sb],raw_samples[smp - (sb + 1)]);
 
-        if (sconf->long_term_prediction) {
-            // TODO: LTP mode
+            raw_samples[smp] -= y >> 20;
+            parcor_to_lpc(smp, quant_cof, lpc_cof);
         }
+    } else {
+        for (k = 0; k < opt_order; k++)
+            parcor_to_lpc(k, quant_cof, lpc_cof);
 
-        start = 0;
+        // store previous samples in case that they have to be altered
+        if (store_prev_samples)
+            memcpy(ctx->prev_raw_samples, raw_samples - sconf->max_order,
+                   sizeof(*ctx->prev_raw_samples) * sconf->max_order);
 
-        // read first value and residuals in case of a random access block
-        if (ra_block) {
-            if (opt_order)
-                raw_samples[0] = decode_rice(gb, avctx->bits_per_raw_sample - 4);
-            if (opt_order > 1)
-                raw_samples[1] = decode_rice(gb, s[0] + 3);
-            if (opt_order > 2)
-                raw_samples[2] = decode_rice(gb, s[0] + 1);
+        // reconstruct difference signal for prediction (joint-stereo)
+        if (*js_blocks && raw_other) {
+            int32_t *left, *right;
 
-            start = FFMIN(opt_order, 3);
-        } else {
-            for (k = 0; k < opt_order; k++)
-                parcor_to_lpc(k, quant_cof, lpc_cof);
+            if (raw_other > raw_samples) {          // D = R - L
+                left  = raw_samples;
+                right = raw_other;
+            } else {                                // D = R - L
+                left  = raw_other;
+                right = raw_samples;
+            }
+
+            for (sb = -1; sb >= -sconf->max_order; sb--)
+                raw_samples[sb] = right[sb] - left[sb];
         }
 
-        // read all residuals
-        // TODO: decode directly into ctx->raw_samples[] instead of storing the residuals
-        if (sconf->bgmc_mode) {
-            // TODO: BGMC mode
-        } else {
-            int64_t *current_res = raw_samples;
+        // reconstruct shifted signal
+        if (*shift_lsbs)
+            for (sb = -1; sb >= -sconf->max_order; sb--)
+                raw_samples[sb] >>= *shift_lsbs;
+    }
 
-            for (sb = 0; sb < sub_blocks; sb++) {
-                for (k = start; k < sb_length; k++) {
-                    current_res[k] = decode_rice(gb, s[sb]);
-                }
-                current_res += sb_length;
-                start = 0;
-            }
-         }
+    // reconstruct raw samples
+    for (; smp < block_length; smp++) {
+        y = 1 << 19;
 
-        // reconstruct all samples from residuals
-        if (ra_block) {
-            unsigned int progressive = FFMIN(block_length, opt_order);
+        for (sb = 0; sb < opt_order; sb++)
+            y += MUL64(lpc_cof[sb],raw_samples[smp - (sb + 1)]);
 
-            for (smp = 0; smp < block_length; smp++) {
-                unsigned int max, dequant;
+        raw_samples[smp] -= y >> 20;
+    }
 
-                dequant = smp < progressive;
-                max     = dequant ? smp : progressive;
+    // restore previous samples in case that they have been altered
+    if (store_prev_samples)
+        memcpy(raw_samples - sconf->max_order, ctx->prev_raw_samples,
+               sizeof(*raw_samples) * sconf->max_order);
 
-                y = 1 << 19;
+    return 0;
+}
 
-                for (sb = 0; sb < max; sb++)
-                    y += lpc_cof[sb] * raw_samples[smp - (sb + 1)];
 
-                raw_samples[smp] -= y >> 20;
-                if (dequant)
-                    parcor_to_lpc(smp, quant_cof, lpc_cof);
-            }
-        } else {
-            int store_prev_samples = (*js_blocks && raw_other) || shift_lsbs;
+/** Reads the block data.
+ */
+static int read_block_data(ALSDecContext *ctx, unsigned int ra_block,
+                           int32_t *raw_samples, unsigned int block_length,
+                           unsigned int *js_blocks, int32_t *raw_other)
+{
+    ALSSpecificConfig *sconf = &ctx->sconf;
+    GetBitContext *gb        = &ctx->gb;
+    unsigned int shift_lsbs  = 0;
+    unsigned int k;
 
-            // store previous smaples in case that they have to be altered
-            if (store_prev_samples)
-                memcpy(ctx->prev_raw_samples, raw_samples - sconf->max_order,
-                       sizeof(int64_t) * sconf->max_order);
+    // read block type flag and read the samples accordingly
+    if (get_bits1(gb)) {
+        if (read_var_block(ctx, ra_block, raw_samples, block_length, js_blocks,
+                           raw_other, &shift_lsbs))
+            return -1;
+    } else {
+        read_const_block(ctx, raw_samples, block_length, js_blocks);
+    }
 
-            // reconstruct difference signal for prediction (joint-stereo)
-            if (*js_blocks && raw_other) {
-                int i;
-                if (raw_other > raw_samples) {          // D = R - L
-                    for (i = -1; i >= -sconf->max_order; i--)
-                        raw_samples[i] = raw_other[i] - raw_samples[i];
-                } else {                                // D = R - L
-                    for (i = -1; i >= -sconf->max_order; i--)
-                        raw_samples[i] = raw_samples[i] - raw_other[i];
-                }
-            }
+    // TODO: read RLSLMS extension data
 
-            // reconstruct shifted signal
-            if (shift_lsbs) {
-                for (smp = -1; smp >= -sconf->max_order; smp--)
-                    raw_samples[smp] >>= shift_lsbs;
-            }
+    if (!sconf->mc_coding || ctx->js_switch)
+        align_get_bits(gb);
 
-            // reconstruct raw samples
-            for (smp = 0; smp < block_length; smp++) {
-                y = 1 << 19;
+    if (shift_lsbs)
+        for (k = 0; k < block_length; k++)
+            raw_samples[k] <<= shift_lsbs;
 
-                for (sb = 0; sb < opt_order; sb++)
-                    y += lpc_cof[sb] * raw_samples[smp - (sb + 1)];
+    return 0;
+}
 
-                raw_samples[smp] -= y >> 20;
-            }
 
-            // restore previous samples in case that they have been altered
-            if (store_prev_samples)
-                memcpy(raw_samples - sconf->max_order, ctx->prev_raw_samples,
-                       sizeof(int64_t) * sconf->max_order);
+/** Computes the number of samples left to decode for the current frame and
+ *  sets these samples to zero.
+ */
+static void zero_remaining(unsigned int b, unsigned int b_max,
+                           const unsigned int *div_blocks, int32_t *buf)
+{
+    unsigned int count = 0;
+
+    while (b < b_max)
+        count += div_blocks[b];
+
+    memset(buf, 0, sizeof(*buf) * count);
+}
+
+
+/** Decodes blocks independently.
+ */
+static int decode_blocks_ind(ALSDecContext *ctx, unsigned int ra_frame,
+                             unsigned int c, const unsigned int *div_blocks,
+                             unsigned int *js_blocks)
+{
+    int32_t *raw_sample;
+    unsigned int b;
+    raw_sample = ctx->raw_samples[c];
+
+    for (b = 0; b < ctx->num_blocks; b++) {
+        if (read_block_data(ctx, ra_frame, raw_sample,
+                            div_blocks[b], &js_blocks[0], NULL)) {
+            // damaged block, write zero for the rest of the frame
+            zero_remaining(b, ctx->num_blocks, div_blocks, raw_sample);
+            return -1;
         }
+        raw_sample += div_blocks[b];
+        ra_frame    = 0;
     }
 
-    if (sconf->rlslms) {
-        // TODO: read RLSLMS extension data
-    }
+    return 0;
+}
 
-    if (!sconf->mc_coding || ctx->js_switch) {
-        align_get_bits(gb);
-    }
 
-    if (shift_lsbs) {
-        for (k = 0; k < block_length; k++)
-            raw_samples[k] <<= shift_lsbs;
+/** Decodes blocks dependently.
+ */
+static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame,
+                         unsigned int c, const unsigned int *div_blocks,
+                         unsigned int *js_blocks)
+{
+    ALSSpecificConfig *sconf = &ctx->sconf;
+    unsigned int offset = 0;
+    int32_t *raw_samples_R;
+    int32_t *raw_samples_L;
+    unsigned int b;
+
+    // decode all blocks
+    for (b = 0; b < ctx->num_blocks; b++) {
+        unsigned int s;
+        raw_samples_L = ctx->raw_samples[c    ] + offset;
+        raw_samples_R = ctx->raw_samples[c + 1] + offset;
+        if (read_block_data(ctx, ra_frame, raw_samples_L, div_blocks[b],
+                            &js_blocks[0], raw_samples_R) ||
+            read_block_data(ctx, ra_frame, raw_samples_R, div_blocks[b],
+                            &js_blocks[1], raw_samples_L)) {
+            // damaged block, write zero for the rest of the frame
+            zero_remaining(b, ctx->num_blocks, div_blocks, raw_samples_L);
+            zero_remaining(b, ctx->num_blocks, div_blocks, raw_samples_R);
+            return -1;
+        }
+
+        // reconstruct joint-stereo blocks
+        if (js_blocks[0]) {
+            if (js_blocks[1])
+                av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel pair!\n");
+
+            for (s = 0; s < div_blocks[b]; s++)
+                raw_samples_L[s] = raw_samples_R[s] - raw_samples_L[s];
+        } else if (js_blocks[1]) {
+            for (s = 0; s < div_blocks[b]; s++)
+                raw_samples_R[s] = raw_samples_R[s] + raw_samples_L[s];
+        }
+
+        offset  += div_blocks[b];
+        ra_frame = 0;
     }
 
+    // store carryover raw samples,
+    // the others channel raw samples are stored by the calling function.
+    memmove(ctx->raw_samples[c] - sconf->max_order,
+            ctx->raw_samples[c] - sconf->max_order + sconf->frame_length,
+            sizeof(*ctx->raw_samples[c]) * sconf->max_order);
+
     return 0;
 }
 
@@ -740,17 +785,15 @@ static int read_block_data(ALSDecContext
 static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame)
 {
     ALSSpecificConfig *sconf = &ctx->sconf;
+    AVCodecContext *avctx    = ctx->avctx;
     GetBitContext *gb = &ctx->gb;
-    unsigned int div_blocks[32];                ///< Block sizes.
-    unsigned int c, b, ra_block;
-    int64_t *raw_samples_L;
-    int64_t *raw_samples_R;
+    unsigned int div_blocks[32];                ///< block sizes.
+    unsigned int c;
     unsigned int js_blocks[2];
 
     uint32_t bs_info = 0;
-    unsigned int *ptr_div_blocks;
 
-    // skip ra_unit_size if present
+    // skip the size of the ra unit if present in the frame
     if (sconf->ra_flag == RA_FLAG_FRAMES && ra_frame)
         skip_bits_long(gb, 32);
 
@@ -762,144 +805,51 @@ static int read_frame_data(ALSDecContext
     if (!sconf->mc_coding || ctx->js_switch) {
         int independent_bs = !sconf->joint_stereo;
 
-        for (c = 0; c < sconf->channels; c++) {
+        for (c = 0; c < avctx->channels; c++) {
             js_blocks[0] = 0;
             js_blocks[1] = 0;
 
-            if (sconf->block_switching) {
-                unsigned int bs_info_len = 1 << (sconf->block_switching + 2);
-                bs_info = get_bits_long(gb, bs_info_len);
-                bs_info <<= (32 - bs_info_len);
-            }
-
-            ctx->num_blocks = 0;
-            ptr_div_blocks = &div_blocks[0];
-            parse_bs_info(bs_info, 0, 0, &ptr_div_blocks, &ctx->num_blocks);
-            reconstruct_block_sizes(ctx, div_blocks);
+            get_block_sizes(ctx, div_blocks, &bs_info);
 
             // if joint_stereo and block_switching is set, independent decoding
             // is signaled via the first bit of bs_info
-            if(sconf->joint_stereo && sconf->block_switching) {
+            if (sconf->joint_stereo && sconf->block_switching)
                 if (bs_info >> 31)
                     independent_bs = 2;
-            }
 
             // if this is the last channel, it has to be decoded independently
-            if (c == sconf->channels - 1)
+            if (c == avctx->channels - 1)
                 independent_bs = 1;
 
             if (independent_bs) {
-                raw_samples_L = ctx->raw_samples[c];
-
-                for (b = 0; b < ctx->num_blocks; b++) {
-                    ra_block = !b && ra_frame;
-                    if (read_block_data(ctx, ra_block, raw_samples_L,
-                                        div_blocks[b], &js_blocks[0], NULL)) {
-                        // damaged block, write zero for the rest of the frame
-                        while (b < ctx->num_blocks) {
-                            memset(raw_samples_L, 0, div_blocks[b]);
-                            raw_samples_L += div_blocks[b];
-                            b++;
-                        }
-                        return -1;
-                    }
-                    raw_samples_L += div_blocks[b];
-                }
-
-                // store carryover raw samples
-                memmove((ctx->raw_samples[c]) - sconf->max_order,
-                        (ctx->raw_samples[c]) - sconf->max_order + sconf->frame_length,
-                        sizeof(int64_t) * sconf->max_order);
+                if (decode_blocks_ind(ctx, ra_frame, c, div_blocks, js_blocks))
+                    return -1;
 
-                if(independent_bs)
+                if (independent_bs)
                     independent_bs--;
             } else {
-                unsigned int offset = 0;
-
-                // decode all blocks
-                for (b = 0; b < ctx->num_blocks; b++) {
-                    unsigned int s;
-                    raw_samples_L = ctx->raw_samples[c    ] + offset;
-                    raw_samples_R = ctx->raw_samples[c + 1] + offset;
-                    ra_block = !b && ra_frame;
-                    if (read_block_data(ctx, ra_block, raw_samples_L, div_blocks[b],
-                                        &js_blocks[0], raw_samples_R) ||
-                        read_block_data(ctx, ra_block, raw_samples_R, div_blocks[b],
-                                        &js_blocks[1], raw_samples_L)) {
-                        // damaged block, write zero for the rest of the frame
-                        while (b < ctx->num_blocks) {
-                            memset(raw_samples_L, 0, div_blocks[b]);
-                            memset(raw_samples_R, 0, div_blocks[b]);
-                            raw_samples_L += div_blocks[b];
-                            raw_samples_R += div_blocks[b];
-                            b++;
-                        }
-                        return -1;
-                    }
-
-                    // reconstruct joint-stereo blocks
-                    if (js_blocks[0]) {
-                        if (js_blocks[1])
-                            av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel pair!\n");
-
-                        for (s = 0; s < div_blocks[b]; s++)
-                            raw_samples_L[s] = raw_samples_R[s] - raw_samples_L[s];
-                    } else if (js_blocks[1]) {
-                        for (s = 0; s < div_blocks[b]; s++)
-                            raw_samples_R[s] = raw_samples_R[s] + raw_samples_L[s];
-                    }
-
-                    offset += div_blocks[b];
-                }
-
-                // store carryover raw samples
-                memmove((ctx->raw_samples[c]) - sconf->max_order,
-                        (ctx->raw_samples[c]) - sconf->max_order + sconf->frame_length,
-                        sizeof(int64_t) * sconf->max_order);
-
-                memmove((ctx->raw_samples[c + 1]) - sconf->max_order,
-                        (ctx->raw_samples[c + 1]) - sconf->max_order + sconf->frame_length,
-                        sizeof(int64_t) * sconf->max_order);
+                if (decode_blocks(ctx, ra_frame, c, div_blocks, js_blocks))
+                    return -1;
 
                 c++;
             }
+
+        // store carryover raw samples
+        memmove(ctx->raw_samples[c] - sconf->max_order,
+                ctx->raw_samples[c] - sconf->max_order + sconf->frame_length,
+                sizeof(*ctx->raw_samples[c]) * sconf->max_order);
         }
     } else { // multi-channel coding
-        if (sconf->block_switching) {
-            unsigned int bs_info_len = 1 << (sconf->block_switching + 2);
-            bs_info = get_bits_long(gb, bs_info_len);
-            bs_info <<= (32 - bs_info_len);
-        }
-
-        ctx->num_blocks = 0;
-        ptr_div_blocks = &div_blocks[0];
-        parse_bs_info(bs_info, 0, 0, &ptr_div_blocks, &ctx->num_blocks);
-        reconstruct_block_sizes(ctx, div_blocks);
+        get_block_sizes(ctx, div_blocks, &bs_info);
 
         // TODO: multi channel coding might use a temporary buffer instead as
         //       the actual channel is not known when read_block-data is called
-        raw_samples_L = ctx->raw_samples[0];
-
-        for (b = 0; b < ctx->num_blocks; b++) {
-            ra_block = !b && ra_frame;
-            if (read_block_data(ctx, ra_block, raw_samples_L,
-                                div_blocks[b], &js_blocks[0], NULL)) {
-                // damaged block, write zero for the rest of the frame
-                while (b < ctx->num_blocks) {
-                    memset(raw_samples_L, 0, div_blocks[b]);
-                    raw_samples_L += div_blocks[b];
-                    b++;
-                }
-                return -1;
-            }
-            raw_samples_L += div_blocks[b];
-            // TODO: read_channel_data
-        }
+        if (decode_blocks_ind(ctx, ra_frame, 0, div_blocks, js_blocks))
+            return -1;
+        // TODO: read_channel_data
     }
 
-    if (sconf->floating) {
-        // TODO: read_diff_float_data
-    }
+    // TODO: read_diff_float_data
 
     return 0;
 }
@@ -915,37 +865,47 @@ static int decode_frame(AVCodecContext *
     ALSSpecificConfig *sconf = &ctx->sconf;
     const uint8_t *buffer    = avpkt->data;
     int buffer_size          = avpkt->size;
-    int invalid_frame        = 0;
+    int invalid_frame, size;
     unsigned int c, sample, ra_frame, bytes_read, shift;
 
     init_get_bits(&ctx->gb, buffer, buffer_size * 8);
-    ra_frame = sconf->random_access && ((!ctx->frame_id) ||
-               !(ctx->frame_id % sconf->random_access));
+
+    // In the case that the distance between random access frames is set to zero
+    // (sconf->ra_distance == 0) no frame is treated as a random access frame.
+    // For the first frame, if prediction is used, all samples used from the
+    // previous frame are assumed to be zero.
+    ra_frame = sconf->ra_distance && !(ctx->frame_id % sconf->ra_distance);
 
     // the last frame to decode might have a different length
-    if (ctx->num_frames && ctx->num_frames - 1 == ctx->frame_id) {
+    if (ctx->num_frames && ctx->num_frames - 1 == ctx->frame_id)
         ctx->cur_frame_length = ctx->last_frame_length;
-    }
 
     // decode the frame data
-    if ((invalid_frame = read_frame_data(ctx, ra_frame))) {
+    if ((invalid_frame = read_frame_data(ctx, ra_frame) < 0))
         av_log(ctx->avctx, AV_LOG_WARNING,
                "Reading frame data failed. Skipping RA unit.\n");
-    }
 
-    // increment the frame counter
     ctx->frame_id++;
 
+    // check for size of decoded data
+    size = ctx->cur_frame_length * avctx->channels *
+           (av_get_bits_per_sample_format(avctx->sample_fmt) >> 3);
+
+    if (size > *data_size) {
+        av_log(avctx, AV_LOG_ERROR, "Decoded data exceeds buffer size.\n");
+        return -1;
+    }
+
+    *data_size = size;
+
     // transform decoded frame into output format
-    #define INTERLEAVE_OUTPUT(bps)                                                 \
-    {                                                                              \
-        int##bps##_t *dest = (int##bps##_t*) data;                                 \
-        shift = bps - ctx->avctx->bits_per_raw_sample;                             \
-        for (sample = 0; sample < ctx->cur_frame_length; sample++) {               \
-            for (c = 0; c < sconf->channels; c++) {                                \
-                *(dest++) = (int##bps##_t) (ctx->raw_samples[c][sample] << shift); \
-            }                                                                      \
-        }                                                                          \
+    #define INTERLEAVE_OUTPUT(bps)                                 \
+    {                                                              \
+        int##bps##_t *dest = (int##bps##_t*) data;                 \
+        shift = bps - ctx->avctx->bits_per_raw_sample;             \
+        for (sample = 0; sample < ctx->cur_frame_length; sample++) \
+            for (c = 0; c < avctx->channels; c++)                  \
+                *dest++ = ctx->raw_samples[c][sample] << shift;    \
     }
 
     if (ctx->avctx->bits_per_raw_sample <= 16) {
@@ -954,9 +914,6 @@ static int decode_frame(AVCodecContext *
         INTERLEAVE_OUTPUT(32)
     }
 
-    *data_size = ctx->cur_frame_length * sconf->channels
-                 * (av_get_bits_per_sample_format(avctx->sample_fmt) >> 3);
-
     bytes_read = invalid_frame ? buffer_size :
                                  (get_bits_count(&ctx->gb) + 7) >> 3;
 
@@ -1008,9 +965,6 @@ static av_cold int decode_init(AVCodecCo
         return -1;
     }
 
-    avctx->sample_rate = sconf->samp_freq;
-    avctx->channels    = sconf->channels;
-
     if (sconf->floating) {
         avctx->sample_fmt          = SAMPLE_FMT_FLT;
         avctx->bits_per_raw_sample = 32;
@@ -1023,38 +977,36 @@ static av_cold int decode_init(AVCodecCo
     avctx->frame_size = sconf->frame_length;
     channel_size      = sconf->frame_length + sconf->max_order;
 
-    // allocate previous raw sample buffer
-    if (!(ctx->prev_raw_samples = av_malloc(sizeof(int64_t) * sconf->max_order))) {
-        av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-        decode_end(avctx);
-        return AVERROR(ENOMEM);
-    }
+    ctx->prev_raw_samples = av_malloc (sizeof(*ctx->prev_raw_samples) * sconf->max_order);
+    ctx->raw_buffer       = av_mallocz(sizeof(*ctx->     raw_buffer)  * avctx->channels * channel_size);
+    ctx->raw_samples      = av_malloc (sizeof(*ctx->     raw_samples) * avctx->channels);
 
-    // allocate raw and carried sample buffer
-    if (!(ctx->raw_buffer = av_mallocz(sizeof(int64_t) *
-                                       avctx->channels * channel_size))) {
+    // allocate previous raw sample buffer
+    if (!ctx->prev_raw_samples || !ctx->raw_buffer|| !ctx->raw_samples) {
         av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
         decode_end(avctx);
         return AVERROR(ENOMEM);
     }
 
-    // allocate raw sample array buffer
-    if (!(ctx->raw_samples = av_malloc(sizeof(int64_t*) * avctx->channels))) {
-        av_log(avctx, AV_LOG_ERROR, "Allocating buffer array failed.\n");
-        decode_end(avctx);
-        return AVERROR(ENOMEM);
-    }
-
-    // allocate raw and carried samples buffers
+    // assign raw samples buffers
     ctx->raw_samples[0] = ctx->raw_buffer + sconf->max_order;
-    for (c = 1; c < avctx->channels; c++) {
+    for (c = 1; c < avctx->channels; c++)
         ctx->raw_samples[c] = ctx->raw_samples[c - 1] + channel_size;
-    }
 
     return 0;
 }
 
 
+/** Flushes (resets) the frame ID after seeking.
+ */
+static av_cold void flush(AVCodecContext *avctx)
+{
+    ALSDecContext *ctx = avctx->priv_data;
+
+    ctx->frame_id = 0;
+}
+
+
 AVCodec als_decoder = {
     "als",
     CODEC_TYPE_AUDIO,
@@ -1064,6 +1016,8 @@ AVCodec als_decoder = {
     NULL,
     decode_end,
     decode_frame,
+    .flush = flush,
+    .capabilities = CODEC_CAP_SUBFRAMES,
     .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"),
 };
 


More information about the FFmpeg-soc mailing list