[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