2009-11-11 22:36:17 +00:00
/*
* MPEG-4 ALS decoder
2013-08-13 10:04:05 +02:00
* Copyright (c) 2009 Thilo Borgmann <thilo.borgmann _at_ mail.de>
2009-11-11 22:36:17 +00:00
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
2010-04-20 14:45:34 +00:00
* @file
2009-11-11 22:36:17 +00:00
* MPEG-4 ALS decoder
2013-08-13 10:04:05 +02:00
* @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
2009-11-11 22:36:17 +00:00
*/
2014-03-13 12:13:33 +01:00
#include <inttypes.h>
2009-11-11 22:36:17 +00:00
#include "avcodec.h"
#include "get_bits.h"
#include "unary.h"
#include "mpeg4audio.h"
2010-02-13 18:24:13 +00:00
#include "bgmc.h"
2014-02-13 17:57:05 +01:00
#include "bswapdsp.h"
2022-03-16 18:18:28 +01:00
#include "codec_internal.h"
2022-08-24 21:28:16 +02:00
#include "decode.h"
2012-11-10 13:22:56 +01:00
#include "internal.h"
2016-08-12 17:51:41 +05:30
#include "mlz.h"
2024-03-25 01:30:37 +01:00
#include "libavutil/mem.h"
2025-07-22 02:56:27 +02:00
#include "libavutil/opt.h"
2011-02-07 14:37:08 +01:00
#include "libavutil/samplefmt.h"
2010-06-29 16:56:28 +00:00
#include "libavutil/crc.h"
2016-08-12 17:51:41 +05:30
#include "libavutil/softfloat_ieee754.h"
#include "libavutil/intreadwrite.h"
2009-11-11 22:36:17 +00:00
2009-11-14 11:49:48 +00:00
#include <stdint.h>
/** Rice parameters and corresponding index offsets for decoding the
2010-08-07 14:11:43 +00:00
* indices of scaled PARCOR values. The table chosen is set globally
2009-11-14 11:49:48 +00:00
* by the encoder and stored in ALSSpecificConfig.
*/
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.
*/
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
};
/** Gain values of p(0) for long-term prediction.
* To be indexed by the Rice coded indices.
*/
static const uint8_t ltp_gain_values [ 4 ][ 4 ] = {
{ 0 , 8 , 16 , 24 },
{ 32 , 40 , 48 , 56 },
{ 64 , 70 , 76 , 82 },
{ 88 , 92 , 96 , 100 }
};
2009-11-11 22:36:17 +00:00
2010-01-07 22:48:58 +00:00
/** Inter-channel weighting factors for multi-channel correlation.
* To be indexed by the Rice coded indices.
*/
static const int16_t mcc_weightings [] = {
204 , 192 , 179 , 166 , 153 , 140 , 128 , 115 ,
102 , 89 , 76 , 64 , 51 , 38 , 25 , 12 ,
0 , - 12 , - 25 , - 38 , - 51 , - 64 , - 76 , - 89 ,
- 102 , - 115 , - 128 , - 140 , - 153 , - 166 , - 179 , - 192
};
2010-02-13 18:24:13 +00:00
/** Tail codes used in arithmetic coding using block Gilbert-Moore codes.
*/
static const uint8_t tail_code [ 16 ][ 6 ] = {
{ 74 , 44 , 25 , 13 , 7 , 3 },
{ 68 , 42 , 24 , 13 , 7 , 3 },
{ 58 , 39 , 23 , 13 , 7 , 3 },
{ 126 , 70 , 37 , 19 , 10 , 5 },
{ 132 , 70 , 37 , 20 , 10 , 5 },
{ 124 , 70 , 38 , 20 , 10 , 5 },
{ 120 , 69 , 37 , 20 , 11 , 5 },
{ 116 , 67 , 37 , 20 , 11 , 5 },
{ 108 , 66 , 36 , 20 , 10 , 5 },
{ 102 , 62 , 36 , 20 , 10 , 5 },
{ 88 , 58 , 34 , 19 , 10 , 5 },
{ 162 , 89 , 49 , 25 , 13 , 7 },
{ 156 , 87 , 49 , 26 , 14 , 7 },
{ 150 , 86 , 47 , 26 , 14 , 7 },
{ 142 , 84 , 47 , 26 , 14 , 7 },
{ 131 , 79 , 46 , 26 , 14 , 7 }
};
2009-11-11 22:36:17 +00:00
enum RA_Flag {
RA_FLAG_NONE ,
RA_FLAG_FRAMES ,
RA_FLAG_HEADER
};
2014-09-22 11:01:31 +02:00
typedef struct ALSSpecificConfig {
2009-11-11 22:36:17 +00:00
uint32_t samples ; ///< number of samples, 0xFFFFFFFF if unknown
int resolution ; ///< 000 = 8-bit; 001 = 16-bit; 010 = 24-bit; 011 = 32-bit
int floating ; ///< 1 = IEEE 32-bit floating-point, 0 = integer
2010-06-29 16:56:28 +00:00
int msb_first ; ///< 1 = original CRC calculated on big-endian system, 0 = little-endian
2009-11-11 22:36:17 +00:00
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
2010-06-29 16:56:28 +00:00
int crc_enabled ; ///< enable Cyclic Redundancy Checksum
2009-11-11 22:36:17 +00:00
} ALSSpecificConfig ;
2014-09-22 11:01:31 +02:00
typedef struct ALSChannelData {
2010-01-07 22:48:58 +00:00
int stop_flag ;
int master_channel ;
int time_diff_flag ;
int time_diff_sign ;
int time_diff_index ;
int weighting [ 6 ];
} ALSChannelData ;
2014-09-22 11:01:31 +02:00
typedef struct ALSDecContext {
2025-07-22 02:56:27 +02:00
AVClass * av_class ;
2009-11-11 22:36:17 +00:00
AVCodecContext * avctx ;
ALSSpecificConfig sconf ;
GetBitContext gb ;
2014-02-13 17:57:05 +01:00
BswapDSPContext bdsp ;
2010-06-29 16:56:28 +00:00
const AVCRC * crc_table ;
uint32_t crc_org ; ///< CRC value of the original input data
uint32_t crc ; ///< CRC value calculated from decoded data
2009-11-11 22:36:17 +00:00
unsigned int cur_frame_length ; ///< length of the current frame to decode
unsigned int frame_id ; ///< the frame ID / number of the current frame
unsigned int js_switch ; ///< if true, joint-stereo decoding is enforced
2013-01-05 15:29:13 +01:00
unsigned int cs_switch ; ///< if true, channel rearrangement is done
2009-11-11 22:36:17 +00:00
unsigned int num_blocks ; ///< number of blocks used in the current frame
2010-02-16 14:48:01 +00:00
unsigned int s_max ; ///< maximum Rice parameter allowed in entropy coding
2010-02-13 18:24:13 +00:00
uint8_t * bgmc_lut ; ///< pointer at lookup tables used for BGMC
2010-11-08 15:24:11 +00:00
int * bgmc_lut_status ; ///< pointer at lookup table status flags used for BGMC
2009-11-14 06:29:19 +00:00
int ltp_lag_length ; ///< number of bits used for ltp lag value
2010-12-06 15:18:50 +00:00
int * const_block ; ///< contains const_block flags for all channels
unsigned int * shift_lsbs ; ///< contains shift_lsbs flags for all channels
unsigned int * opt_order ; ///< contains opt_order flags for all channels
int * store_prev_samples ; ///< contains store_prev_samples flags for all channels
2009-12-13 15:40:26 +00:00
int * use_ltp ; ///< contains use_ltp flags for all channels
int * ltp_lag ; ///< contains ltp lag values for all channels
int ** ltp_gain ; ///< gain values for ltp 5-tap filter for a channel
int * ltp_gain_buffer ; ///< contains all gain values for ltp 5-tap filter
2010-01-07 22:48:58 +00:00
int32_t ** quant_cof ; ///< quantized parcor coefficients for a channel
int32_t * quant_cof_buffer ; ///< contains all quantized parcor coefficients
int32_t ** lpc_cof ; ///< coefficients of the direct form prediction filter for a channel
int32_t * lpc_cof_buffer ; ///< contains all coefficients of the direct form prediction filter
2025-08-01 22:43:23 +02:00
int32_t * lpc_cof_reversed_buffer ; ///< temporary buffer to set up a reversed version of lpc_cof_buffer
2010-01-07 22:48:58 +00:00
ALSChannelData ** chan_data ; ///< channel data for multi-channel correlation
ALSChannelData * chan_data_buffer ; ///< contains channel data for all channels
int * reverted_channels ; ///< stores a flag for each reverted channel
2009-11-11 22:36:17 +00:00
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
2010-06-29 16:56:28 +00:00
uint8_t * crc_buffer ; ///< buffer of byte order corrected samples used for CRC check
2016-08-12 17:51:41 +05:30
MLZ * mlz ; ///< masked lz decompression structure
SoftFloat_IEEE754 * acf ; ///< contains common multiplier for all channels
int * last_acf_mantissa ; ///< contains the last acf mantissa data of common multiplier for all channels
int * shift_value ; ///< value by which the binary point is to be shifted for all channels
int * last_shift_value ; ///< contains last shift value for all channels
int ** raw_mantissa ; ///< decoded mantissa bits of the difference signal
unsigned char * larray ; ///< buffer to store the output of masked lz decompression
int * nbits ; ///< contains the number of bits to read for masked lz decompression for all samples
2019-11-09 22:02:50 +01:00
int highest_decoded_channel ;
2025-07-22 02:56:27 +02:00
int user_max_order ; ///< user specified maximum prediction order
2009-11-11 22:36:17 +00:00
} ALSDecContext ;
2014-09-22 11:01:31 +02:00
typedef struct ALSBlockData {
2009-12-13 15:40:26 +00:00
unsigned int block_length ; ///< number of samples within the block
unsigned int ra_block ; ///< if true, this is a random access block
2010-12-06 15:18:50 +00:00
int * const_block ; ///< if true, this is a constant value block
2009-12-13 15:40:26 +00:00
int js_blocks ; ///< true if this block contains a difference signal
2010-12-06 15:18:50 +00:00
unsigned int * shift_lsbs ; ///< shift of values for this block
unsigned int * opt_order ; ///< prediction order of this block
int * store_prev_samples ; ///< if true, carryover samples have to be stored
2009-12-13 15:40:26 +00:00
int * use_ltp ; ///< if true, long-term prediction is used
int * ltp_lag ; ///< lag value for long-term prediction
int * ltp_gain ; ///< gain values for ltp 5-tap filter
int32_t * quant_cof ; ///< quantized parcor coefficients
int32_t * lpc_cof ; ///< coefficients of the direct form prediction
int32_t * raw_samples ; ///< decoded raw samples / residuals for this block
int32_t * prev_raw_samples ; ///< contains unshifted raw samples from the previous block
int32_t * raw_other ; ///< decoded raw samples of the other channel of a channel pair
} ALSBlockData ;
2009-11-11 22:36:17 +00:00
static av_cold void dprint_specific_config ( ALSDecContext * ctx )
{
#ifdef DEBUG
AVCodecContext * avctx = ctx -> avctx ;
ALSSpecificConfig * sconf = & ctx -> sconf ;
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , "resolution = %i \n " , sconf -> resolution );
ff_dlog ( avctx , "floating = %i \n " , sconf -> floating );
ff_dlog ( avctx , "frame_length = %i \n " , sconf -> frame_length );
ff_dlog ( avctx , "ra_distance = %i \n " , sconf -> ra_distance );
ff_dlog ( avctx , "ra_flag = %i \n " , sconf -> ra_flag );
ff_dlog ( avctx , "adapt_order = %i \n " , sconf -> adapt_order );
ff_dlog ( avctx , "coef_table = %i \n " , sconf -> coef_table );
ff_dlog ( avctx , "long_term_prediction = %i \n " , sconf -> long_term_prediction );
ff_dlog ( avctx , "max_order = %i \n " , sconf -> max_order );
ff_dlog ( avctx , "block_switching = %i \n " , sconf -> block_switching );
ff_dlog ( avctx , "bgmc = %i \n " , sconf -> bgmc );
ff_dlog ( avctx , "sb_part = %i \n " , sconf -> sb_part );
ff_dlog ( avctx , "joint_stereo = %i \n " , sconf -> joint_stereo );
ff_dlog ( avctx , "mc_coding = %i \n " , sconf -> mc_coding );
ff_dlog ( avctx , "chan_config = %i \n " , sconf -> chan_config );
ff_dlog ( avctx , "chan_sort = %i \n " , sconf -> chan_sort );
ff_dlog ( avctx , "RLSLMS = %i \n " , sconf -> rlslms );
ff_dlog ( avctx , "chan_config_info = %i \n " , sconf -> chan_config_info );
2009-11-11 22:36:17 +00:00
#endif
}
2010-06-30 15:38:06 +00:00
/** Read an ALSSpecificConfig from a buffer into the output struct.
2009-11-11 22:36:17 +00:00
*/
static av_cold int read_specific_config ( ALSDecContext * ctx )
{
GetBitContext gb ;
uint64_t ht_size ;
2010-06-29 16:56:28 +00:00
int i , config_offset ;
2014-06-08 14:30:30 +02:00
MPEG4AudioConfig m4ac = { 0 };
2009-11-11 22:36:17 +00:00
ALSSpecificConfig * sconf = & ctx -> sconf ;
AVCodecContext * avctx = ctx -> avctx ;
2010-02-01 09:53:37 +00:00
uint32_t als_id , header_size , trailer_size ;
2013-01-27 22:36:37 +01:00
int ret ;
2009-11-11 22:36:17 +00:00
2013-01-27 22:36:37 +01:00
if (( ret = init_get_bits8 ( & gb , avctx -> extradata , avctx -> extradata_size )) < 0 )
return ret ;
2009-11-11 22:36:17 +00:00
2019-09-21 20:04:33 -03:00
config_offset = avpriv_mpeg4audio_get_config2 ( & m4ac , avctx -> extradata ,
avctx -> extradata_size , 1 , avctx );
2009-11-11 22:36:17 +00:00
if ( config_offset < 0 )
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2009-11-11 22:36:17 +00:00
skip_bits_long ( & gb , config_offset );
if ( get_bits_left ( & gb ) < ( 30 << 3 ))
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2009-11-11 22:36:17 +00:00
// read the fixed items
als_id = get_bits_long ( & gb , 32 );
avctx -> sample_rate = m4ac . sample_rate ;
skip_bits_long ( & gb , 32 ); // sample rate already known
sconf -> samples = get_bits_long ( & gb , 32 );
2017-04-04 16:29:55 +02:00
if ( avctx -> ch_layout . nb_channels != m4ac . channels ) {
av_channel_layout_uninit ( & avctx -> ch_layout );
avctx -> ch_layout . order = AV_CHANNEL_ORDER_UNSPEC ;
avctx -> ch_layout . nb_channels = m4ac . channels ;
}
2013-01-04 19:12:08 +00:00
skip_bits ( & gb , 16 ); // number of channels already known
2009-11-11 22:36:17 +00:00
skip_bits ( & gb , 3 ); // skip file_type
sconf -> resolution = get_bits ( & gb , 3 );
sconf -> floating = get_bits1 ( & gb );
2010-06-29 16:56:28 +00:00
sconf -> msb_first = get_bits1 ( & gb );
2009-11-11 22:36:17 +00:00
sconf -> frame_length = get_bits ( & gb , 16 ) + 1 ;
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 = 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 );
2010-06-29 16:56:28 +00:00
sconf -> crc_enabled = get_bits1 ( & gb );
2009-11-11 22:36:17 +00:00
sconf -> rlslms = get_bits1 ( & gb );
skip_bits ( & gb , 5 ); // skip 5 reserved bits
skip_bits1 ( & gb ); // skip aux_data_enabled
2025-07-22 02:56:27 +02:00
if ( sconf -> max_order > ctx -> user_max_order ) {
av_log ( avctx , AV_LOG_ERROR , "order %d exceeds specified max %d \n " , sconf -> max_order , ctx -> user_max_order );
return AVERROR_INVALIDDATA ;
}
2009-11-11 22:36:17 +00:00
// check for ALSSpecificConfig struct
if ( als_id != MKBETAG ( 'A' , 'L' , 'S' , '\0' ))
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2009-11-11 22:36:17 +00:00
2017-04-04 16:29:55 +02:00
if ( avctx -> ch_layout . nb_channels > FF_SANE_NB_CHANNELS ) {
2020-10-11 19:59:24 +02:00
avpriv_request_sample ( avctx , "Huge number of channels" );
2019-08-20 16:52:07 +02:00
return AVERROR_PATCHWELCOME ;
}
2022-07-02 14:22:48 +02:00
if ( avctx -> ch_layout . nb_channels == 0 )
return AVERROR_INVALIDDATA ;
2009-11-11 22:36:17 +00:00
ctx -> cur_frame_length = sconf -> frame_length ;
// read channel config
if ( sconf -> chan_config )
sconf -> chan_config_info = get_bits ( & gb , 16 );
// TODO: use this to set avctx->channel_layout
// read channel sorting
2017-04-04 16:29:55 +02:00
if ( sconf -> chan_sort && avctx -> ch_layout . nb_channels > 1 ) {
int chan_pos_bits = av_ceil_log2 ( avctx -> ch_layout . nb_channels );
int bits_needed = avctx -> ch_layout . nb_channels * chan_pos_bits + 7 ;
2009-11-11 22:36:17 +00:00
if ( get_bits_left ( & gb ) < bits_needed )
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2009-11-11 22:36:17 +00:00
2017-04-04 16:29:55 +02:00
if ( ! ( sconf -> chan_pos = av_malloc_array ( avctx -> ch_layout . nb_channels , sizeof ( * sconf -> chan_pos ))))
2009-11-11 22:36:17 +00:00
return AVERROR ( ENOMEM );
2013-01-05 15:29:13 +01:00
ctx -> cs_switch = 1 ;
2017-04-04 16:29:55 +02:00
for ( i = 0 ; i < avctx -> ch_layout . nb_channels ; i ++ ) {
2015-04-18 18:31:36 +02:00
sconf -> chan_pos [ i ] = - 1 ;
}
2017-04-04 16:29:55 +02:00
for ( i = 0 ; i < avctx -> ch_layout . nb_channels ; i ++ ) {
2013-01-03 18:37:32 +00:00
int idx ;
idx = get_bits ( & gb , chan_pos_bits );
2017-04-04 16:29:55 +02:00
if ( idx >= avctx -> ch_layout . nb_channels || sconf -> chan_pos [ idx ] != - 1 ) {
2012-12-22 12:01:57 +00:00
av_log ( avctx , AV_LOG_WARNING , "Invalid channel reordering. \n " );
2013-01-05 15:29:13 +01:00
ctx -> cs_switch = 0 ;
2012-12-21 12:51:08 +00:00
break ;
}
2013-01-03 18:37:32 +00:00
sconf -> chan_pos [ idx ] = i ;
2012-12-21 12:51:08 +00:00
}
2009-11-11 22:36:17 +00:00
align_get_bits ( & gb );
}
// read fixed header and trailer sizes,
// if size = 0xFFFFFFFF then there is no data field!
if ( get_bits_left ( & gb ) < 64 )
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2009-11-11 22:36:17 +00:00
2010-02-01 09:53:37 +00:00
header_size = get_bits_long ( & gb , 32 );
trailer_size = get_bits_long ( & gb , 32 );
if ( header_size == 0xFFFFFFFF )
header_size = 0 ;
if ( trailer_size == 0xFFFFFFFF )
trailer_size = 0 ;
2009-11-11 22:36:17 +00:00
2010-02-01 09:53:37 +00:00
ht_size = (( int64_t )( header_size ) + ( int64_t )( trailer_size )) << 3 ;
2009-11-11 22:36:17 +00:00
// skip the header and trailer data
if ( get_bits_left ( & gb ) < ht_size )
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2009-11-11 22:36:17 +00:00
if ( ht_size > INT32_MAX )
2013-07-12 23:38:02 +02:00
return AVERROR_PATCHWELCOME ;
2009-11-11 22:36:17 +00:00
skip_bits_long ( & gb , ht_size );
2010-06-29 16:56:28 +00:00
// initialize CRC calculation
if ( sconf -> crc_enabled ) {
2009-11-11 22:36:17 +00:00
if ( get_bits_left ( & gb ) < 32 )
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2009-11-11 22:36:17 +00:00
2011-11-19 20:41:30 +01:00
if ( avctx -> err_recognition & ( AV_EF_CRCCHECK | AV_EF_CAREFUL )) {
2010-06-29 16:56:28 +00:00
ctx -> crc_table = av_crc_get_table ( AV_CRC_32_IEEE_LE );
ctx -> crc = 0xFFFFFFFF ;
ctx -> crc_org = ~ get_bits_long ( & gb , 32 );
} else
skip_bits_long ( & gb , 32 );
2009-11-11 22:36:17 +00:00
}
// no need to read the rest of ALSSpecificConfig (ra_unit_size & aux data)
dprint_specific_config ( ctx );
return 0 ;
}
2010-06-30 15:38:06 +00:00
/** Check the ALSSpecificConfig for unsupported features.
2009-11-11 22:36:17 +00:00
*/
static int check_specific_config ( ALSDecContext * ctx )
{
ALSSpecificConfig * sconf = & ctx -> sconf ;
int error = 0 ;
// report unsupported feature and set error value
#define MISSING_ERR(cond, str, errval) \
{ \
if (cond) { \
2013-02-25 23:53:52 +01:00
avpriv_report_missing_feature(ctx->avctx, \
str); \
2009-11-11 22:36:17 +00:00
error = errval; \
} \
}
2012-10-09 00:41:34 +02:00
MISSING_ERR ( sconf -> rlslms , "Adaptive RLS-LMS prediction" , AVERROR_PATCHWELCOME );
2009-11-11 22:36:17 +00:00
return error ;
}
2010-06-30 15:38:06 +00:00
/** Parse the bs_info field to extract the block partitioning used in
2009-11-11 22:36:17 +00:00
* block switching mode, refer to ISO/IEC 14496-3, section 11.6.2.
*/
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 << 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 ;
div += 1 ;
parse_bs_info ( bs_info , n + 1 , div , div_blocks , num_blocks );
parse_bs_info ( bs_info , n + 2 , div , div_blocks , num_blocks );
} else {
// else the bit is not set or the last level has been reached
// (bit implicitly not set)
** div_blocks = div ;
( * div_blocks ) ++ ;
( * num_blocks ) ++ ;
}
}
2010-07-02 00:03:48 +00:00
/** Read and decode a Rice codeword.
2009-11-11 22:36:17 +00:00
*/
static int32_t decode_rice ( GetBitContext * gb , unsigned int k )
{
2009-11-16 17:42:43 +00:00
int max = get_bits_left ( gb ) - k ;
2019-06-19 23:17:31 +02:00
unsigned q = get_unary ( gb , 0 , max );
2009-11-11 22:36:17 +00:00
int r = k ? get_bits1 ( gb ) : ! ( q & 1 );
if ( k > 1 ) {
q <<= ( k - 1 );
q += get_bits_long ( gb , k - 1 );
} else if ( ! k ) {
q >>= 1 ;
}
return r ? q : ~ q ;
}
2010-06-30 15:38:06 +00:00
/** Convert PARCOR coefficient k to direct filter coefficient.
2009-11-11 22:36:17 +00:00
*/
static void parcor_to_lpc ( unsigned int k , const int32_t * par , int32_t * cof )
{
int i , j ;
for ( i = 0 , j = k - 1 ; i < j ; i ++ , j -- ) {
2019-07-06 23:20:30 +02:00
unsigned tmp1 = (( MUL64 ( par [ k ], cof [ j ]) + ( 1 << 19 )) >> 20 );
2009-11-11 22:36:17 +00:00
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 ];
}
2010-07-02 00:03:48 +00:00
/** Read block switching field if necessary and set actual block sizes.
* Also assure that the block sizes of the last frame correspond to the
2009-11-11 22:36:17 +00:00
* actual number of samples.
*/
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 ;
unsigned int b ;
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 );
// The last frame may have an overdetermined block structure given in
// the bitstream. In that case the defined block structure would need
// more samples than available to be consistent.
// The block structure is actually used but the block sizes are adapted
// to fit the actual number of available samples.
// Example: 5 samples, 2nd level block sizes: 2 2 2 2.
// This results in the actual block sizes: 2 2 1 0.
// This is not specified in 14496-3 but actually done by the reference
// codec RM22 revision 2.
// This appears to happen in case of an odd number of samples in the last
// frame which is actually not allowed by the block length switching part
// 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 -> sconf . frame_length ) {
unsigned int remaining = ctx -> cur_frame_length ;
for ( b = 0 ; b < ctx -> num_blocks ; b ++ ) {
2010-03-06 17:13:31 +00:00
if ( remaining <= div_blocks [ b ]) {
2009-11-11 22:36:17 +00:00
div_blocks [ b ] = remaining ;
ctx -> num_blocks = b + 1 ;
break ;
}
remaining -= div_blocks [ b ];
}
}
}
2010-06-30 15:38:06 +00:00
/** Read the block data for a constant block
2009-11-11 22:36:17 +00:00
*/
2012-12-12 12:28:45 +01:00
static int read_const_block_data ( ALSDecContext * ctx , ALSBlockData * bd )
2009-11-11 22:36:17 +00:00
{
ALSSpecificConfig * sconf = & ctx -> sconf ;
AVCodecContext * avctx = ctx -> avctx ;
GetBitContext * gb = & ctx -> gb ;
2012-12-12 12:28:45 +01:00
if ( bd -> block_length <= 0 )
2012-12-13 03:03:56 +01:00
return AVERROR_INVALIDDATA ;
2012-12-12 12:28:45 +01:00
2010-12-06 15:18:50 +00:00
* bd -> raw_samples = 0 ;
* bd -> const_block = get_bits1 ( gb ); // 1 = constant value, 0 = zero block (silence)
2009-12-13 15:40:26 +00:00
bd -> js_blocks = get_bits1 ( gb );
2009-11-11 22:36:17 +00:00
// skip 5 reserved bits
skip_bits ( gb , 5 );
2010-12-06 15:18:50 +00:00
if ( * bd -> const_block ) {
2009-11-11 22:36:17 +00:00
unsigned int const_val_bits = sconf -> floating ? 24 : avctx -> bits_per_raw_sample ;
2010-12-06 15:18:50 +00:00
* bd -> raw_samples = get_sbits_long ( gb , const_val_bits );
2009-11-11 22:36:17 +00:00
}
2009-12-13 15:40:26 +00:00
// ensure constant block decoding by reusing this field
2010-12-06 15:18:50 +00:00
* bd -> const_block = 1 ;
2012-12-12 12:28:45 +01:00
return 0 ;
2009-12-13 15:40:26 +00:00
}
2010-06-30 15:38:06 +00:00
/** Decode the block data for a constant block
2009-12-13 15:40:26 +00:00
*/
static void decode_const_block_data ( ALSDecContext * ctx , ALSBlockData * bd )
{
2010-12-06 15:18:50 +00:00
int smp = bd -> block_length - 1 ;
int32_t val = * bd -> raw_samples ;
int32_t * dst = bd -> raw_samples + 1 ;
2009-12-13 15:40:26 +00:00
2009-11-11 22:36:17 +00:00
// write raw samples into buffer
2009-12-13 15:40:26 +00:00
for (; smp ; smp -- )
* dst ++ = val ;
2009-11-11 22:36:17 +00:00
}
2010-06-30 15:38:06 +00:00
/** Read the block data for a non-constant block
2009-11-11 22:36:17 +00:00
*/
2009-12-13 15:40:26 +00:00
static int read_var_block_data ( ALSDecContext * ctx , ALSBlockData * bd )
2009-11-11 22:36:17 +00:00
{
ALSSpecificConfig * sconf = & ctx -> sconf ;
AVCodecContext * avctx = ctx -> avctx ;
GetBitContext * gb = & ctx -> gb ;
unsigned int k ;
unsigned int s [ 8 ];
2010-02-13 18:24:13 +00:00
unsigned int sx [ 8 ];
2009-11-11 22:36:17 +00:00
unsigned int sub_blocks , log2_sub_blocks , sb_length ;
unsigned int start = 0 ;
2009-12-13 15:40:26 +00:00
unsigned int opt_order ;
int sb ;
int32_t * quant_cof = bd -> quant_cof ;
2010-02-13 18:24:13 +00:00
int32_t * current_res ;
2009-11-11 22:36:17 +00:00
2009-12-13 15:40:26 +00:00
// ensure variable block decoding by reusing this field
2010-12-06 15:18:50 +00:00
* bd -> const_block = 0 ;
2009-12-13 15:40:26 +00:00
2010-12-06 15:18:50 +00:00
* bd -> opt_order = 1 ;
2009-12-13 15:40:26 +00:00
bd -> js_blocks = get_bits1 ( gb );
2010-12-06 15:18:50 +00:00
opt_order = * bd -> opt_order ;
2009-11-11 22:36:17 +00:00
// determine the number of subblocks for entropy decoding
if ( ! sconf -> bgmc && ! sconf -> sb_part ) {
log2_sub_blocks = 0 ;
} else {
if ( sconf -> bgmc && sconf -> sb_part )
log2_sub_blocks = get_bits ( gb , 2 );
else
log2_sub_blocks = 2 * get_bits1 ( gb );
}
sub_blocks = 1 << log2_sub_blocks ;
// do not continue in case of a damaged stream since
// block_length must be evenly divisible by sub_blocks
2019-07-26 15:26:08 +02:00
if ( bd -> block_length & ( sub_blocks - 1 ) || bd -> block_length <= 0 ) {
2009-11-11 22:36:17 +00:00
av_log ( avctx , AV_LOG_WARNING ,
"Block length is not evenly divisible by the number of subblocks. \n " );
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2009-11-11 22:36:17 +00:00
}
2009-12-13 15:40:26 +00:00
sb_length = bd -> block_length >> log2_sub_blocks ;
2009-11-11 22:36:17 +00:00
if ( sconf -> bgmc ) {
2010-02-13 18:24:13 +00:00
s [ 0 ] = get_bits ( gb , 8 + ( sconf -> resolution > 1 ));
for ( k = 1 ; k < sub_blocks ; k ++ )
s [ k ] = s [ k - 1 ] + decode_rice ( gb , 2 );
for ( k = 0 ; k < sub_blocks ; k ++ ) {
sx [ k ] = s [ k ] & 0x0F ;
s [ k ] >>= 4 ;
}
2009-11-11 22:36:17 +00:00
} 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 );
}
2012-04-07 17:25:47 +02:00
for ( k = 1 ; k < sub_blocks ; k ++ )
2012-05-05 13:14:36 +02:00
if ( s [ k ] > 32 ) {
2012-04-07 17:25:47 +02:00
av_log ( avctx , AV_LOG_ERROR , "k invalid for rice code. \n " );
2012-04-07 17:25:47 +02:00
return AVERROR_INVALIDDATA ;
2012-04-07 17:25:47 +02:00
}
2009-11-11 22:36:17 +00:00
if ( get_bits1 ( gb ))
2010-12-06 15:18:50 +00:00
* bd -> shift_lsbs = get_bits ( gb , 4 ) + 1 ;
2009-11-11 22:36:17 +00:00
2010-12-06 15:18:50 +00:00
* bd -> store_prev_samples = ( bd -> js_blocks && bd -> raw_other ) || * bd -> shift_lsbs ;
2009-11-11 22:36:17 +00:00
if ( ! sconf -> rlslms ) {
2015-04-22 16:03:41 +02:00
if ( sconf -> adapt_order && sconf -> max_order ) {
2009-12-13 15:40:26 +00:00
int opt_order_length = av_ceil_log2 ( av_clip (( bd -> block_length >> 3 ) - 1 ,
2009-11-11 22:36:17 +00:00
2 , sconf -> max_order + 1 ));
2010-12-06 15:18:50 +00:00
* bd -> opt_order = get_bits ( gb , opt_order_length );
2012-03-24 01:39:13 +01:00
if ( * bd -> opt_order > sconf -> max_order ) {
2012-03-27 13:49:58 +02:00
* bd -> opt_order = sconf -> max_order ;
2013-01-06 12:14:53 +01:00
av_log ( avctx , AV_LOG_ERROR , "Predictor order too large. \n " );
2012-03-24 01:39:13 +01:00
return AVERROR_INVALIDDATA ;
2012-03-24 01:39:13 +01:00
}
2009-11-11 22:36:17 +00:00
} else {
2010-12-06 15:18:50 +00:00
* bd -> opt_order = sconf -> max_order ;
2009-11-11 22:36:17 +00:00
}
2010-12-06 15:18:50 +00:00
opt_order = * bd -> opt_order ;
2009-12-13 15:40:26 +00:00
2009-11-11 22:36:17 +00:00
if ( opt_order ) {
int add_base ;
if ( sconf -> coef_table == 3 ) {
add_base = 0x7F ;
// read coefficient 0
quant_cof [ 0 ] = 32 * parcor_scaled_values [ get_bits ( gb , 7 )];
// read coefficient 1
if ( opt_order > 1 )
quant_cof [ 1 ] = - 32 * parcor_scaled_values [ get_bits ( gb , 7 )];
// read coefficients 2 to opt_order
for ( k = 2 ; k < opt_order ; k ++ )
quant_cof [ k ] = get_bits ( gb , 7 );
} else {
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 ;
2012-02-29 06:10:17 +01:00
if ( quant_cof [ k ] < - 64 || quant_cof [ k ] > 63 ) {
2014-03-13 12:13:33 +01:00
av_log ( avctx , AV_LOG_ERROR ,
2016-03-06 03:06:18 +05:30
"quant_cof %" PRId32 " is out of range. \n " ,
2014-03-13 12:13:33 +01:00
quant_cof [ k ]);
2012-02-29 06:10:17 +01:00
return AVERROR_INVALIDDATA ;
}
2009-11-11 22:36:17 +00:00
}
// 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 ] = 32 * parcor_scaled_values [ quant_cof [ 0 ] + 64 ];
if ( opt_order > 1 )
quant_cof [ 1 ] = - 32 * parcor_scaled_values [ quant_cof [ 1 ] + 64 ];
}
for ( k = 2 ; k < opt_order ; k ++ )
2020-12-26 18:55:08 +01:00
quant_cof [ k ] = ( quant_cof [ k ] * ( 1U << 14 )) + ( add_base << 13 );
2009-11-11 22:36:17 +00:00
}
}
2009-11-14 06:29:19 +00:00
// read LTP gain and lag values
if ( sconf -> long_term_prediction ) {
2009-12-13 15:40:26 +00:00
* bd -> use_ltp = get_bits1 ( gb );
2009-11-14 06:29:19 +00:00
2009-12-13 15:40:26 +00:00
if ( * bd -> use_ltp ) {
2010-02-19 08:07:02 +00:00
int r , c ;
2019-06-19 21:53:43 +02:00
bd -> ltp_gain [ 0 ] = decode_rice ( gb , 1 ) * 8 ;
bd -> ltp_gain [ 1 ] = decode_rice ( gb , 2 ) * 8 ;
2009-11-14 06:29:19 +00:00
2016-03-12 02:34:30 +05:30
r = get_unary ( gb , 0 , 4 );
2010-02-19 08:07:02 +00:00
c = get_bits ( gb , 2 );
2016-06-07 20:50:38 +02:00
if ( r >= 4 ) {
av_log ( avctx , AV_LOG_ERROR , "r overflow \n " );
return AVERROR_INVALIDDATA ;
}
2010-02-19 08:07:02 +00:00
bd -> ltp_gain [ 2 ] = ltp_gain_values [ r ][ c ];
2009-11-14 06:29:19 +00:00
2019-06-19 21:53:43 +02:00
bd -> ltp_gain [ 3 ] = decode_rice ( gb , 2 ) * 8 ;
bd -> ltp_gain [ 4 ] = decode_rice ( gb , 1 ) * 8 ;
2009-11-14 06:29:19 +00:00
2009-12-13 15:40:26 +00:00
* bd -> ltp_lag = get_bits ( gb , ctx -> ltp_lag_length );
* bd -> ltp_lag += FFMAX ( 4 , opt_order + 1 );
2009-11-14 06:29:19 +00:00
}
}
2009-11-11 22:36:17 +00:00
// read first value and residuals in case of a random access block
2009-12-13 15:40:26 +00:00
if ( bd -> ra_block ) {
2019-06-21 00:47:15 +02:00
start = FFMIN ( opt_order , 3 );
av_assert0 ( sb_length <= sconf -> frame_length );
if ( sb_length <= start ) {
// opt_order or sb_length may be corrupted, either way this is unsupported and not well defined in the specification
av_log ( avctx , AV_LOG_ERROR , "Sub block length smaller or equal start \n " );
return AVERROR_PATCHWELCOME ;
}
2009-11-11 22:36:17 +00:00
if ( opt_order )
2009-12-13 15:40:26 +00:00
bd -> raw_samples [ 0 ] = decode_rice ( gb , avctx -> bits_per_raw_sample - 4 );
2009-11-11 22:36:17 +00:00
if ( opt_order > 1 )
2010-02-16 14:48:01 +00:00
bd -> raw_samples [ 1 ] = decode_rice ( gb , FFMIN ( s [ 0 ] + 3 , ctx -> s_max ));
2009-11-11 22:36:17 +00:00
if ( opt_order > 2 )
2010-02-16 14:48:01 +00:00
bd -> raw_samples [ 2 ] = decode_rice ( gb , FFMIN ( s [ 0 ] + 1 , ctx -> s_max ));
2009-11-11 22:36:17 +00:00
}
// read all residuals
if ( sconf -> bgmc ) {
2010-11-08 15:24:11 +00:00
int delta [ 8 ];
2010-06-26 14:34:18 +00:00
unsigned int k [ 8 ];
2010-02-13 18:24:13 +00:00
unsigned int b = av_clip (( av_ceil_log2 ( bd -> block_length ) - 3 ) >> 1 , 0 , 5 );
// read most significant bits
unsigned int high ;
unsigned int low ;
unsigned int value ;
2019-09-01 22:31:45 +02:00
int ret = ff_bgmc_decode_init ( gb , & high , & low , & value );
if ( ret < 0 )
return ret ;
2010-02-13 18:24:13 +00:00
current_res = bd -> raw_samples + start ;
2012-07-01 13:36:30 +01:00
for ( sb = 0 ; sb < sub_blocks ; sb ++ ) {
2012-04-15 18:07:12 +02:00
unsigned int sb_len = sb_length - ( sb ? 0 : start );
2010-02-13 18:24:13 +00:00
k [ sb ] = s [ sb ] > b ? s [ sb ] - b : 0 ;
delta [ sb ] = 5 - s [ sb ] + k [ sb ];
2019-08-25 18:22:50 +02:00
if ( k [ sb ] >= 32 )
return AVERROR_INVALIDDATA ;
2012-04-15 18:07:12 +02:00
ff_bgmc_decode ( gb , sb_len , current_res ,
2010-02-13 18:24:13 +00:00
delta [ sb ], sx [ sb ], & high , & low , & value , ctx -> bgmc_lut , ctx -> bgmc_lut_status );
2012-04-15 18:07:12 +02:00
current_res += sb_len ;
2010-02-13 18:24:13 +00:00
}
ff_bgmc_decode_end ( gb );
// read least significant bits and tails
current_res = bd -> raw_samples + start ;
2012-04-15 18:07:12 +02:00
for ( sb = 0 ; sb < sub_blocks ; sb ++ , start = 0 ) {
2010-02-13 18:24:13 +00:00
unsigned int cur_tail_code = tail_code [ sx [ sb ]][ delta [ sb ]];
unsigned int cur_k = k [ sb ];
unsigned int cur_s = s [ sb ];
2012-04-15 18:07:12 +02:00
for (; start < sb_length ; start ++ ) {
2010-02-13 18:24:13 +00:00
int32_t res = * current_res ;
if ( res == cur_tail_code ) {
unsigned int max_msb = ( 2 + ( sx [ sb ] > 2 ) + ( sx [ sb ] > 10 ))
<< ( 5 - delta [ sb ]);
res = decode_rice ( gb , cur_s );
if ( res >= 0 ) {
res += ( max_msb ) << cur_k ;
} else {
res -= ( max_msb - 1 ) << cur_k ;
}
} else {
if ( res > cur_tail_code )
res -- ;
if ( res & 1 )
res = - res ;
res >>= 1 ;
if ( cur_k ) {
2019-06-21 00:47:16 +02:00
res *= 1U << cur_k ;
2010-02-13 18:24:13 +00:00
res |= get_bits_long ( gb , cur_k );
}
}
2010-02-13 19:59:53 +00:00
* current_res ++ = res ;
2010-02-13 18:24:13 +00:00
}
}
2009-11-11 22:36:17 +00:00
} else {
2010-02-13 18:24:13 +00:00
current_res = bd -> raw_samples + start ;
2009-11-11 22:36:17 +00:00
for ( sb = 0 ; sb < sub_blocks ; sb ++ , start = 0 )
for (; start < sb_length ; start ++ )
* current_res ++ = decode_rice ( gb , s [ sb ]);
}
2009-12-13 15:40:26 +00:00
return 0 ;
}
2010-06-30 15:38:06 +00:00
/** Decode the block data for a non-constant block
2009-12-13 15:40:26 +00:00
*/
static int decode_var_block_data ( ALSDecContext * ctx , ALSBlockData * bd )
{
ALSSpecificConfig * sconf = & ctx -> sconf ;
unsigned int block_length = bd -> block_length ;
unsigned int smp = 0 ;
unsigned int k ;
2010-12-06 15:18:50 +00:00
int opt_order = * bd -> opt_order ;
2009-12-13 15:40:26 +00:00
int sb ;
int64_t y ;
int32_t * quant_cof = bd -> quant_cof ;
int32_t * lpc_cof = bd -> lpc_cof ;
int32_t * raw_samples = bd -> raw_samples ;
2010-01-07 22:23:28 +00:00
int32_t * raw_samples_end = bd -> raw_samples + bd -> block_length ;
2010-01-12 20:35:22 +00:00
int32_t * lpc_cof_reversed = ctx -> lpc_cof_reversed_buffer ;
2009-12-13 15:40:26 +00:00
2009-11-14 06:29:19 +00:00
// reverse long-term prediction
2009-12-13 15:40:26 +00:00
if ( * bd -> use_ltp ) {
2009-11-14 06:29:19 +00:00
int ltp_smp ;
2009-12-13 15:40:26 +00:00
for ( ltp_smp = FFMAX ( * bd -> ltp_lag - 2 , 0 ); ltp_smp < block_length ; ltp_smp ++ ) {
int center = ltp_smp - * bd -> ltp_lag ;
2009-11-14 06:29:19 +00:00
int begin = FFMAX ( 0 , center - 2 );
int end = center + 3 ;
int tab = 5 - ( end - begin );
int base ;
y = 1 << 6 ;
for ( base = begin ; base < end ; base ++ , tab ++ )
2019-07-26 15:37:30 +02:00
y += ( uint64_t ) MUL64 ( bd -> ltp_gain [ tab ], raw_samples [ base ]);
2009-11-14 06:29:19 +00:00
raw_samples [ ltp_smp ] += y >> 7 ;
}
}
2009-11-11 22:36:17 +00:00
// reconstruct all samples from residuals
2009-12-13 15:40:26 +00:00
if ( bd -> ra_block ) {
2017-11-13 11:07:42 +05:30
for ( smp = 0 ; smp < FFMIN ( opt_order , block_length ); smp ++ ) {
2009-11-11 22:36:17 +00:00
y = 1 << 19 ;
for ( sb = 0 ; sb < smp ; sb ++ )
2019-07-26 15:37:30 +02:00
y += ( uint64_t ) MUL64 ( lpc_cof [ sb ], raw_samples [ - ( sb + 1 )]);
2009-11-11 22:36:17 +00:00
2010-01-07 22:23:28 +00:00
* raw_samples ++ -= y >> 20 ;
2009-11-11 22:36:17 +00:00
parcor_to_lpc ( smp , quant_cof , lpc_cof );
}
} else {
for ( k = 0 ; k < opt_order ; k ++ )
parcor_to_lpc ( k , quant_cof , lpc_cof );
// store previous samples in case that they have to be altered
2010-12-06 15:18:50 +00:00
if ( * bd -> store_prev_samples )
2009-12-13 15:40:26 +00:00
memcpy ( bd -> prev_raw_samples , raw_samples - sconf -> max_order ,
sizeof ( * bd -> prev_raw_samples ) * sconf -> max_order );
2009-11-11 22:36:17 +00:00
// reconstruct difference signal for prediction (joint-stereo)
2009-12-13 15:40:26 +00:00
if ( bd -> js_blocks && bd -> raw_other ) {
2019-08-19 01:30:53 +02:00
uint32_t * left , * right ;
2009-11-11 22:36:17 +00:00
2009-12-13 15:40:26 +00:00
if ( bd -> raw_other > raw_samples ) { // D = R - L
2009-11-11 22:36:17 +00:00
left = raw_samples ;
2009-12-13 15:40:26 +00:00
right = bd -> raw_other ;
2009-11-11 22:36:17 +00:00
} else { // D = R - L
2009-12-13 15:40:26 +00:00
left = bd -> raw_other ;
2009-11-11 22:36:17 +00:00
right = raw_samples ;
}
for ( sb = - 1 ; sb >= - sconf -> max_order ; sb -- )
raw_samples [ sb ] = right [ sb ] - left [ sb ];
}
// reconstruct shifted signal
2010-12-06 15:18:50 +00:00
if ( * bd -> shift_lsbs )
2009-11-11 22:36:17 +00:00
for ( sb = - 1 ; sb >= - sconf -> max_order ; sb -- )
2010-12-06 15:18:50 +00:00
raw_samples [ sb ] >>= * bd -> shift_lsbs ;
2009-11-11 22:36:17 +00:00
}
2010-01-07 22:23:28 +00:00
// reverse linear prediction coefficients for efficiency
lpc_cof = lpc_cof + opt_order ;
for ( sb = 0 ; sb < opt_order ; sb ++ )
lpc_cof_reversed [ sb ] = lpc_cof [ - ( sb + 1 )];
2009-11-11 22:36:17 +00:00
// reconstruct raw samples
2010-01-07 22:23:28 +00:00
raw_samples = bd -> raw_samples + smp ;
lpc_cof = lpc_cof_reversed + opt_order ;
for (; raw_samples < raw_samples_end ; raw_samples ++ ) {
2009-11-11 22:36:17 +00:00
y = 1 << 19 ;
2010-01-07 22:23:28 +00:00
for ( sb = - opt_order ; sb < 0 ; sb ++ )
2019-07-06 23:20:30 +02:00
y += ( uint64_t ) MUL64 ( lpc_cof [ sb ], raw_samples [ sb ]);
2009-11-11 22:36:17 +00:00
2010-01-07 22:23:28 +00:00
* raw_samples -= y >> 20 ;
2009-11-11 22:36:17 +00:00
}
2010-01-07 22:23:28 +00:00
raw_samples = bd -> raw_samples ;
2009-11-11 22:36:17 +00:00
// restore previous samples in case that they have been altered
2010-12-06 15:18:50 +00:00
if ( * bd -> store_prev_samples )
2009-12-13 15:40:26 +00:00
memcpy ( raw_samples - sconf -> max_order , bd -> prev_raw_samples ,
2009-11-11 22:36:17 +00:00
sizeof ( * raw_samples ) * sconf -> max_order );
return 0 ;
}
2010-06-30 15:38:06 +00:00
/** Read the block data.
2009-11-11 22:36:17 +00:00
*/
2009-12-13 15:40:26 +00:00
static int read_block ( ALSDecContext * ctx , ALSBlockData * bd )
2009-11-11 22:36:17 +00:00
{
2012-12-13 03:07:33 +01:00
int ret ;
2009-11-11 22:36:17 +00:00
GetBitContext * gb = & ctx -> gb ;
2016-04-27 09:04:18 +05:30
ALSSpecificConfig * sconf = & ctx -> sconf ;
2009-11-11 22:36:17 +00:00
2010-12-06 15:18:50 +00:00
* bd -> shift_lsbs = 0 ;
2021-03-01 23:24:37 +01:00
2022-10-29 18:41:24 +02:00
if ( get_bits_left ( gb ) < 7 )
2021-03-01 23:24:37 +01:00
return AVERROR_INVALIDDATA ;
2009-11-11 22:36:17 +00:00
// read block type flag and read the samples accordingly
if ( get_bits1 ( gb )) {
2013-07-12 23:38:02 +02:00
ret = read_var_block_data ( ctx , bd );
2009-11-11 22:36:17 +00:00
} else {
2013-07-24 12:36:52 +02:00
ret = read_const_block_data ( ctx , bd );
2009-11-11 22:36:17 +00:00
}
2016-04-27 09:04:18 +05:30
if ( ! sconf -> mc_coding || ctx -> js_switch )
align_get_bits ( gb );
2013-07-12 23:38:02 +02:00
return ret ;
2009-12-13 15:40:26 +00:00
}
2010-06-30 15:38:06 +00:00
/** Decode the block data.
2009-12-13 15:40:26 +00:00
*/
static int decode_block ( ALSDecContext * ctx , ALSBlockData * bd )
{
unsigned int smp ;
2013-07-12 23:38:02 +02:00
int ret = 0 ;
2009-12-13 15:40:26 +00:00
// read block type flag and read the samples accordingly
2010-12-06 15:18:50 +00:00
if ( * bd -> const_block )
2009-12-13 15:40:26 +00:00
decode_const_block_data ( ctx , bd );
2013-07-12 23:38:02 +02:00
else
ret = decode_var_block_data ( ctx , bd ); // always return 0
if ( ret < 0 )
return ret ;
2009-12-13 15:40:26 +00:00
2009-11-11 22:36:17 +00:00
// TODO: read RLSLMS extension data
2010-12-06 15:18:50 +00:00
if ( * bd -> shift_lsbs )
2009-12-13 15:40:26 +00:00
for ( smp = 0 ; smp < bd -> block_length ; smp ++ )
2019-06-19 23:27:21 +02:00
bd -> raw_samples [ smp ] = ( unsigned ) bd -> raw_samples [ smp ] << * bd -> shift_lsbs ;
2009-11-11 22:36:17 +00:00
return 0 ;
}
2010-07-02 00:03:48 +00:00
/** Read and decode block data successively.
2009-12-13 15:40:26 +00:00
*/
static int read_decode_block ( ALSDecContext * ctx , ALSBlockData * bd )
{
int ret ;
2013-07-12 23:38:02 +02:00
if (( ret = read_block ( ctx , bd )) < 0 )
2009-12-13 15:40:26 +00:00
return ret ;
2013-07-12 23:38:02 +02:00
return decode_block ( ctx , bd );
2009-12-13 15:40:26 +00:00
}
2010-06-30 15:38:06 +00:00
/** Compute the number of samples left to decode for the current frame and
2009-11-11 22:36:17 +00:00
* 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 )
2012-01-04 21:00:06 +01:00
count += div_blocks [ b ++ ];
2009-11-11 22:36:17 +00:00
2009-11-12 01:44:38 +00:00
if ( count )
2009-11-12 01:45:04 +00:00
memset ( buf , 0 , sizeof ( * buf ) * count );
2009-11-11 22:36:17 +00:00
}
2010-06-30 15:38:06 +00:00
/** Decode blocks independently.
2009-11-11 22:36:17 +00:00
*/
static int decode_blocks_ind ( ALSDecContext * ctx , unsigned int ra_frame ,
unsigned int c , const unsigned int * div_blocks ,
unsigned int * js_blocks )
{
2013-07-12 23:38:02 +02:00
int ret ;
2009-11-11 22:36:17 +00:00
unsigned int b ;
2011-06-06 14:13:02 +02:00
ALSBlockData bd = { 0 };
2009-12-13 15:40:26 +00:00
bd . ra_block = ra_frame ;
2010-12-06 15:18:50 +00:00
bd . const_block = ctx -> const_block ;
bd . shift_lsbs = ctx -> shift_lsbs ;
bd . opt_order = ctx -> opt_order ;
bd . store_prev_samples = ctx -> store_prev_samples ;
2009-12-13 15:40:26 +00:00
bd . use_ltp = ctx -> use_ltp ;
bd . ltp_lag = ctx -> ltp_lag ;
bd . ltp_gain = ctx -> ltp_gain [ 0 ];
2010-01-07 22:48:58 +00:00
bd . quant_cof = ctx -> quant_cof [ 0 ];
bd . lpc_cof = ctx -> lpc_cof [ 0 ];
2009-12-13 15:40:26 +00:00
bd . prev_raw_samples = ctx -> prev_raw_samples ;
bd . raw_samples = ctx -> raw_samples [ c ];
2009-11-11 22:36:17 +00:00
for ( b = 0 ; b < ctx -> num_blocks ; b ++ ) {
2009-12-13 15:40:26 +00:00
bd . block_length = div_blocks [ b ];
2013-07-12 23:38:02 +02:00
if (( ret = read_decode_block ( ctx , & bd )) < 0 ) {
2009-11-11 22:36:17 +00:00
// damaged block, write zero for the rest of the frame
2009-12-13 15:40:26 +00:00
zero_remaining ( b , ctx -> num_blocks , div_blocks , bd . raw_samples );
2013-07-12 23:38:02 +02:00
return ret ;
2009-11-11 22:36:17 +00:00
}
2009-12-13 15:40:26 +00:00
bd . raw_samples += div_blocks [ b ];
bd . ra_block = 0 ;
2009-11-11 22:36:17 +00:00
}
return 0 ;
}
2010-06-30 15:38:06 +00:00
/** Decode blocks dependently.
2009-11-11 22:36:17 +00:00
*/
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 ;
unsigned int b ;
2013-07-12 23:38:02 +02:00
int ret ;
2011-06-06 14:13:02 +02:00
ALSBlockData bd [ 2 ] = { { 0 } };
2009-12-13 15:40:26 +00:00
bd [ 0 ]. ra_block = ra_frame ;
2010-12-06 15:18:50 +00:00
bd [ 0 ]. const_block = ctx -> const_block ;
bd [ 0 ]. shift_lsbs = ctx -> shift_lsbs ;
bd [ 0 ]. opt_order = ctx -> opt_order ;
bd [ 0 ]. store_prev_samples = ctx -> store_prev_samples ;
2009-12-13 15:40:26 +00:00
bd [ 0 ]. use_ltp = ctx -> use_ltp ;
bd [ 0 ]. ltp_lag = ctx -> ltp_lag ;
bd [ 0 ]. ltp_gain = ctx -> ltp_gain [ 0 ];
2010-01-07 22:48:58 +00:00
bd [ 0 ]. quant_cof = ctx -> quant_cof [ 0 ];
bd [ 0 ]. lpc_cof = ctx -> lpc_cof [ 0 ];
2009-12-13 15:40:26 +00:00
bd [ 0 ]. prev_raw_samples = ctx -> prev_raw_samples ;
bd [ 0 ]. js_blocks = * js_blocks ;
bd [ 1 ]. ra_block = ra_frame ;
2010-12-06 15:18:50 +00:00
bd [ 1 ]. const_block = ctx -> const_block ;
bd [ 1 ]. shift_lsbs = ctx -> shift_lsbs ;
bd [ 1 ]. opt_order = ctx -> opt_order ;
bd [ 1 ]. store_prev_samples = ctx -> store_prev_samples ;
2009-12-13 15:40:26 +00:00
bd [ 1 ]. use_ltp = ctx -> use_ltp ;
bd [ 1 ]. ltp_lag = ctx -> ltp_lag ;
bd [ 1 ]. ltp_gain = ctx -> ltp_gain [ 0 ];
2010-01-07 22:48:58 +00:00
bd [ 1 ]. quant_cof = ctx -> quant_cof [ 0 ];
bd [ 1 ]. lpc_cof = ctx -> lpc_cof [ 0 ];
2009-12-13 15:40:26 +00:00
bd [ 1 ]. prev_raw_samples = ctx -> prev_raw_samples ;
bd [ 1 ]. js_blocks = * ( js_blocks + 1 );
2009-11-11 22:36:17 +00:00
// decode all blocks
for ( b = 0 ; b < ctx -> num_blocks ; b ++ ) {
unsigned int s ;
2009-12-13 15:40:26 +00:00
bd [ 0 ]. block_length = div_blocks [ b ];
bd [ 1 ]. block_length = div_blocks [ b ];
bd [ 0 ]. raw_samples = ctx -> raw_samples [ c ] + offset ;
bd [ 1 ]. raw_samples = ctx -> raw_samples [ c + 1 ] + offset ;
bd [ 0 ]. raw_other = bd [ 1 ]. raw_samples ;
bd [ 1 ]. raw_other = bd [ 0 ]. raw_samples ;
2013-07-12 23:38:02 +02:00
if (( ret = read_decode_block ( ctx , & bd [ 0 ])) < 0 ||
( ret = read_decode_block ( ctx , & bd [ 1 ])) < 0 )
goto fail ;
2009-11-11 22:36:17 +00:00
// reconstruct joint-stereo blocks
2009-12-13 15:40:26 +00:00
if ( bd [ 0 ]. js_blocks ) {
if ( bd [ 1 ]. js_blocks )
2012-03-26 15:24:45 +02:00
av_log ( ctx -> avctx , AV_LOG_WARNING , "Invalid channel pair. \n " );
2009-11-11 22:36:17 +00:00
for ( s = 0 ; s < div_blocks [ b ]; s ++ )
2019-07-26 14:33:14 +02:00
bd [ 0 ]. raw_samples [ s ] = bd [ 1 ]. raw_samples [ s ] - ( unsigned ) bd [ 0 ]. raw_samples [ s ];
2009-12-13 15:40:26 +00:00
} else if ( bd [ 1 ]. js_blocks ) {
2009-11-11 22:36:17 +00:00
for ( s = 0 ; s < div_blocks [ b ]; s ++ )
2019-07-26 14:33:14 +02:00
bd [ 1 ]. raw_samples [ s ] = bd [ 1 ]. raw_samples [ s ] + ( unsigned ) bd [ 0 ]. raw_samples [ s ];
2009-11-11 22:36:17 +00:00
}
offset += div_blocks [ b ];
2009-12-13 15:40:26 +00:00
bd [ 0 ]. ra_block = 0 ;
bd [ 1 ]. ra_block = 0 ;
2009-11-11 22:36:17 +00:00
}
// 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 ;
2013-07-12 23:38:02 +02:00
fail :
// damaged block, write zero for the rest of the frame
zero_remaining ( b , ctx -> num_blocks , div_blocks , bd [ 0 ]. raw_samples );
zero_remaining ( b , ctx -> num_blocks , div_blocks , bd [ 1 ]. raw_samples );
return ret ;
2009-11-11 22:36:17 +00:00
}
2013-07-12 23:02:25 +02:00
static inline int als_weighting ( GetBitContext * gb , int k , int off )
{
int idx = av_clip ( decode_rice ( gb , k ) + off ,
0 , FF_ARRAY_ELEMS ( mcc_weightings ) - 1 );
return mcc_weightings [ idx ];
}
2009-11-11 22:36:17 +00:00
2010-06-30 15:38:06 +00:00
/** Read the channel data.
2010-01-07 22:48:58 +00:00
*/
static int read_channel_data ( ALSDecContext * ctx , ALSChannelData * cd , int c )
{
GetBitContext * gb = & ctx -> gb ;
ALSChannelData * current = cd ;
2017-04-04 16:29:55 +02:00
unsigned int channels = ctx -> avctx -> ch_layout . nb_channels ;
2010-01-07 22:48:58 +00:00
int entries = 0 ;
while ( entries < channels && ! ( current -> stop_flag = get_bits1 ( gb ))) {
current -> master_channel = get_bits_long ( gb , av_ceil_log2 ( channels ));
if ( current -> master_channel >= channels ) {
2013-01-06 12:14:53 +01:00
av_log ( ctx -> avctx , AV_LOG_ERROR , "Invalid master channel. \n " );
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2010-01-07 22:48:58 +00:00
}
if ( current -> master_channel != c ) {
current -> time_diff_flag = get_bits1 ( gb );
2013-07-12 23:02:25 +02:00
current -> weighting [ 0 ] = als_weighting ( gb , 1 , 16 );
current -> weighting [ 1 ] = als_weighting ( gb , 2 , 14 );
current -> weighting [ 2 ] = als_weighting ( gb , 1 , 16 );
2010-01-07 22:48:58 +00:00
if ( current -> time_diff_flag ) {
2013-07-12 23:02:25 +02:00
current -> weighting [ 3 ] = als_weighting ( gb , 1 , 16 );
current -> weighting [ 4 ] = als_weighting ( gb , 1 , 16 );
current -> weighting [ 5 ] = als_weighting ( gb , 1 , 16 );
2010-01-07 22:48:58 +00:00
current -> time_diff_sign = get_bits1 ( gb );
current -> time_diff_index = get_bits ( gb , ctx -> ltp_lag_length - 3 ) + 3 ;
}
}
current ++ ;
entries ++ ;
}
if ( entries == channels ) {
2013-01-06 12:14:53 +01:00
av_log ( ctx -> avctx , AV_LOG_ERROR , "Damaged channel data. \n " );
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2010-01-07 22:48:58 +00:00
}
align_get_bits ( gb );
return 0 ;
}
/** Recursively reverts the inter-channel correlation for a block.
*/
static int revert_channel_correlation ( ALSDecContext * ctx , ALSBlockData * bd ,
ALSChannelData ** cd , int * reverted ,
unsigned int offset , int c )
{
ALSChannelData * ch = cd [ c ];
unsigned int dep = 0 ;
2017-04-04 16:29:55 +02:00
unsigned int channels = ctx -> avctx -> ch_layout . nb_channels ;
2015-04-21 19:25:50 +02:00
unsigned int channel_size = ctx -> sconf . frame_length + ctx -> sconf . max_order ;
2010-01-07 22:48:58 +00:00
if ( reverted [ c ])
return 0 ;
reverted [ c ] = 1 ;
while ( dep < channels && ! ch [ dep ]. stop_flag ) {
revert_channel_correlation ( ctx , bd , cd , reverted , offset ,
ch [ dep ]. master_channel );
dep ++ ;
}
if ( dep == channels ) {
2012-03-26 15:24:45 +02:00
av_log ( ctx -> avctx , AV_LOG_WARNING , "Invalid channel correlation. \n " );
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2010-01-07 22:48:58 +00:00
}
2010-12-06 15:18:50 +00:00
bd -> const_block = ctx -> const_block + c ;
bd -> shift_lsbs = ctx -> shift_lsbs + c ;
bd -> opt_order = ctx -> opt_order + c ;
bd -> store_prev_samples = ctx -> store_prev_samples + c ;
2010-01-07 22:48:58 +00:00
bd -> use_ltp = ctx -> use_ltp + c ;
bd -> ltp_lag = ctx -> ltp_lag + c ;
bd -> ltp_gain = ctx -> ltp_gain [ c ];
bd -> lpc_cof = ctx -> lpc_cof [ c ];
bd -> quant_cof = ctx -> quant_cof [ c ];
bd -> raw_samples = ctx -> raw_samples [ c ] + offset ;
2013-12-28 23:53:24 +01:00
for ( dep = 0 ; ! ch [ dep ]. stop_flag ; dep ++ ) {
2015-04-21 19:25:50 +02:00
ptrdiff_t smp ;
ptrdiff_t begin = 1 ;
ptrdiff_t end = bd -> block_length - 1 ;
2010-01-07 22:48:58 +00:00
int64_t y ;
int32_t * master = ctx -> raw_samples [ ch [ dep ]. master_channel ] + offset ;
2013-12-28 23:53:24 +01:00
if ( ch [ dep ]. master_channel == c )
continue ;
2010-01-07 22:48:58 +00:00
if ( ch [ dep ]. time_diff_flag ) {
int t = ch [ dep ]. time_diff_index ;
if ( ch [ dep ]. time_diff_sign ) {
t = - t ;
2015-04-21 19:25:50 +02:00
if ( begin < t ) {
2025-12-03 00:41:00 +01:00
av_log ( ctx -> avctx , AV_LOG_ERROR , "begin %td smaller than time diff index %d. \n " , begin , t );
2015-04-18 20:09:28 +02:00
return AVERROR_INVALIDDATA ;
}
2010-01-07 22:48:58 +00:00
begin -= t ;
} else {
2015-04-21 19:25:50 +02:00
if ( end < t ) {
2025-12-03 00:41:00 +01:00
av_log ( ctx -> avctx , AV_LOG_ERROR , "end %td smaller than time diff index %d. \n " , end , t );
2015-04-18 20:09:28 +02:00
return AVERROR_INVALIDDATA ;
}
2010-01-07 22:48:58 +00:00
end -= t ;
}
2015-04-21 19:25:50 +02:00
if ( FFMIN ( begin - 1 , begin - 1 + t ) < ctx -> raw_buffer - master ||
FFMAX ( end + 1 , end + 1 + t ) > ctx -> raw_buffer + channels * channel_size - master ) {
av_log ( ctx -> avctx , AV_LOG_ERROR ,
"sample pointer range [%p, %p] not contained in raw_buffer [%p, %p]. \n " ,
master + FFMIN ( begin - 1 , begin - 1 + t ), master + FFMAX ( end + 1 , end + 1 + t ),
ctx -> raw_buffer , ctx -> raw_buffer + channels * channel_size );
return AVERROR_INVALIDDATA ;
}
2010-01-07 22:48:58 +00:00
for ( smp = begin ; smp < end ; smp ++ ) {
y = ( 1 << 6 ) +
MUL64 ( ch [ dep ]. weighting [ 0 ], master [ smp - 1 ]) +
MUL64 ( ch [ dep ]. weighting [ 1 ], master [ smp ]) +
MUL64 ( ch [ dep ]. weighting [ 2 ], master [ smp + 1 ]) +
MUL64 ( ch [ dep ]. weighting [ 3 ], master [ smp - 1 + t ]) +
MUL64 ( ch [ dep ]. weighting [ 4 ], master [ smp + t ]) +
MUL64 ( ch [ dep ]. weighting [ 5 ], master [ smp + 1 + t ]);
bd -> raw_samples [ smp ] += y >> 7 ;
}
} else {
2015-04-21 19:25:50 +02:00
if ( begin - 1 < ctx -> raw_buffer - master ||
end + 1 > ctx -> raw_buffer + channels * channel_size - master ) {
av_log ( ctx -> avctx , AV_LOG_ERROR ,
"sample pointer range [%p, %p] not contained in raw_buffer [%p, %p]. \n " ,
master + begin - 1 , master + end + 1 ,
ctx -> raw_buffer , ctx -> raw_buffer + channels * channel_size );
return AVERROR_INVALIDDATA ;
}
2010-01-07 22:48:58 +00:00
for ( smp = begin ; smp < end ; smp ++ ) {
y = ( 1 << 6 ) +
MUL64 ( ch [ dep ]. weighting [ 0 ], master [ smp - 1 ]) +
MUL64 ( ch [ dep ]. weighting [ 1 ], master [ smp ]) +
MUL64 ( ch [ dep ]. weighting [ 2 ], master [ smp + 1 ]);
bd -> raw_samples [ smp ] += y >> 7 ;
}
}
}
return 0 ;
}
2016-08-12 17:51:41 +05:30
/** multiply two softfloats and handle the rounding off
*/
static SoftFloat_IEEE754 multiply ( SoftFloat_IEEE754 a , SoftFloat_IEEE754 b ) {
uint64_t mantissa_temp ;
uint64_t mask_64 ;
int cutoff_bit_count ;
unsigned char last_2_bits ;
unsigned int mantissa ;
int32_t sign ;
uint32_t return_val = 0 ;
int bit_count = 48 ;
sign = a . sign ^ b . sign ;
// Multiply mantissa bits in a 64-bit register
mantissa_temp = ( uint64_t ) a . mant * ( uint64_t ) b . mant ;
mask_64 = ( uint64_t ) 0x1 << 47 ;
2019-06-20 19:09:11 +02:00
if ( ! mantissa_temp )
return FLOAT_0 ;
2016-08-12 17:51:41 +05:30
// Count the valid bit count
while ( ! ( mantissa_temp & mask_64 ) && mask_64 ) {
bit_count -- ;
mask_64 >>= 1 ;
}
// Round off
cutoff_bit_count = bit_count - 24 ;
if ( cutoff_bit_count > 0 ) {
last_2_bits = ( unsigned char )((( unsigned int ) mantissa_temp >> ( cutoff_bit_count - 1 )) & 0x3 );
if (( last_2_bits == 0x3 ) || (( last_2_bits == 0x1 ) && (( unsigned int ) mantissa_temp & (( 0x1UL << ( cutoff_bit_count - 1 )) - 1 )))) {
// Need to round up
mantissa_temp += ( uint64_t ) 0x1 << cutoff_bit_count ;
}
}
2019-07-26 17:07:01 +02:00
if ( cutoff_bit_count >= 0 ) {
mantissa = ( unsigned int )( mantissa_temp >> cutoff_bit_count );
} else {
mantissa = ( unsigned int )( mantissa_temp <<- cutoff_bit_count );
}
2016-08-12 17:51:41 +05:30
// Need one more shift?
if ( mantissa & 0x01000000ul ) {
bit_count ++ ;
mantissa >>= 1 ;
}
if ( ! sign ) {
return_val = 0x80000000U ;
}
2019-07-07 00:03:51 +02:00
return_val |= (( unsigned ) av_clip ( a . exp + b . exp + bit_count - 47 , - 126 , 127 ) << 23 ) & 0x7F800000 ;
2016-08-12 17:51:41 +05:30
return_val |= mantissa ;
return av_bits2sf_ieee754 ( return_val );
}
/** Read and decode the floating point sample data
*/
static int read_diff_float_data ( ALSDecContext * ctx , unsigned int ra_frame ) {
AVCodecContext * avctx = ctx -> avctx ;
GetBitContext * gb = & ctx -> gb ;
SoftFloat_IEEE754 * acf = ctx -> acf ;
int * shift_value = ctx -> shift_value ;
int * last_shift_value = ctx -> last_shift_value ;
int * last_acf_mantissa = ctx -> last_acf_mantissa ;
int ** raw_mantissa = ctx -> raw_mantissa ;
int * nbits = ctx -> nbits ;
unsigned char * larray = ctx -> larray ;
int frame_length = ctx -> cur_frame_length ;
SoftFloat_IEEE754 scale = av_int2sf_ieee754 ( 0x1u , 23 );
unsigned int partA_flag ;
unsigned int highest_byte ;
unsigned int shift_amp ;
uint32_t tmp_32 ;
int use_acf ;
int nchars ;
int i ;
int c ;
long k ;
long nbits_aligned ;
unsigned long acc ;
unsigned long j ;
uint32_t sign ;
uint32_t e ;
uint32_t mantissa ;
skip_bits_long ( gb , 32 ); //num_bytes_diff_float
use_acf = get_bits1 ( gb );
if ( ra_frame ) {
2017-04-04 16:29:55 +02:00
memset ( last_acf_mantissa , 0 , avctx -> ch_layout . nb_channels * sizeof ( * last_acf_mantissa ));
memset ( last_shift_value , 0 , avctx -> ch_layout . nb_channels * sizeof ( * last_shift_value ) );
2016-08-12 17:51:41 +05:30
ff_mlz_flush_dict ( ctx -> mlz );
}
2017-04-04 16:29:55 +02:00
if ( avctx -> ch_layout . nb_channels * 8 > get_bits_left ( gb ))
2019-10-04 19:35:15 +02:00
return AVERROR_INVALIDDATA ;
2017-04-04 16:29:55 +02:00
for ( c = 0 ; c < avctx -> ch_layout . nb_channels ; ++ c ) {
2016-08-12 17:51:41 +05:30
if ( use_acf ) {
//acf_flag
if ( get_bits1 ( gb )) {
tmp_32 = get_bits ( gb , 23 );
last_acf_mantissa [ c ] = tmp_32 ;
} else {
tmp_32 = last_acf_mantissa [ c ];
}
acf [ c ] = av_bits2sf_ieee754 ( tmp_32 );
} else {
acf [ c ] = FLOAT_1 ;
}
highest_byte = get_bits ( gb , 2 );
partA_flag = get_bits1 ( gb );
shift_amp = get_bits1 ( gb );
if ( shift_amp ) {
shift_value [ c ] = get_bits ( gb , 8 );
last_shift_value [ c ] = shift_value [ c ];
} else {
shift_value [ c ] = last_shift_value [ c ];
}
if ( partA_flag ) {
if ( ! get_bits1 ( gb )) { //uncompressed
for ( i = 0 ; i < frame_length ; ++ i ) {
if ( ctx -> raw_samples [ c ][ i ] == 0 ) {
ctx -> raw_mantissa [ c ][ i ] = get_bits_long ( gb , 32 );
}
}
} else { //compressed
nchars = 0 ;
for ( i = 0 ; i < frame_length ; ++ i ) {
if ( ctx -> raw_samples [ c ][ i ] == 0 ) {
nchars += 4 ;
}
}
tmp_32 = ff_mlz_decompression ( ctx -> mlz , gb , nchars , larray );
if ( tmp_32 != nchars ) {
2017-03-27 21:31:46 +02:00
av_log ( ctx -> avctx , AV_LOG_ERROR , "Error in MLZ decompression (%" PRId32 ", %d). \n " , tmp_32 , nchars );
2016-08-12 17:51:41 +05:30
return AVERROR_INVALIDDATA ;
}
2026-03-26 17:59:15 +05:30
j = 0 ;
2016-08-12 17:51:41 +05:30
for ( i = 0 ; i < frame_length ; ++ i ) {
2026-03-26 17:59:15 +05:30
if ( ctx -> raw_samples [ c ][ i ] == 0 ) {
ctx -> raw_mantissa [ c ][ i ] = AV_RB32 ( larray + j );
j += 4 ;
}
2016-08-12 17:51:41 +05:30
}
}
}
//decode part B
if ( highest_byte ) {
for ( i = 0 ; i < frame_length ; ++ i ) {
if ( ctx -> raw_samples [ c ][ i ] != 0 ) {
2025-08-01 22:43:23 +02:00
//The following logic is taken from Table 14.45 and 14.46 from the ISO spec
2016-08-12 17:51:41 +05:30
if ( av_cmp_sf_ieee754 ( acf [ c ], FLOAT_1 )) {
2026-03-25 01:25:40 +01:00
int nbit = av_log2 ( FFABSU ( ctx -> raw_samples [ c ][ i ]));
if ( nbit > 23 )
return AVERROR_INVALIDDATA ;
nbits [ i ] = 23 - nbit ;
2016-08-12 17:51:41 +05:30
} else {
nbits [ i ] = 23 ;
}
nbits [ i ] = FFMIN ( nbits [ i ], highest_byte * 8 );
}
}
if ( ! get_bits1 ( gb )) { //uncompressed
for ( i = 0 ; i < frame_length ; ++ i ) {
if ( ctx -> raw_samples [ c ][ i ] != 0 ) {
2016-09-09 12:29:23 +02:00
raw_mantissa [ c ][ i ] = get_bitsz ( gb , nbits [ i ]);
2016-08-12 17:51:41 +05:30
}
}
} else { //compressed
nchars = 0 ;
for ( i = 0 ; i < frame_length ; ++ i ) {
if ( ctx -> raw_samples [ c ][ i ]) {
nchars += ( int ) nbits [ i ] / 8 ;
if ( nbits [ i ] & 7 ) {
++ nchars ;
}
}
}
tmp_32 = ff_mlz_decompression ( ctx -> mlz , gb , nchars , larray );
if ( tmp_32 != nchars ) {
2017-03-27 21:31:46 +02:00
av_log ( ctx -> avctx , AV_LOG_ERROR , "Error in MLZ decompression (%" PRId32 ", %d). \n " , tmp_32 , nchars );
2016-08-12 17:51:41 +05:30
return AVERROR_INVALIDDATA ;
}
j = 0 ;
for ( i = 0 ; i < frame_length ; ++ i ) {
if ( ctx -> raw_samples [ c ][ i ]) {
if ( nbits [ i ] & 7 ) {
nbits_aligned = 8 * (( unsigned int )( nbits [ i ] / 8 ) + 1 );
} else {
nbits_aligned = nbits [ i ];
}
acc = 0 ;
for ( k = 0 ; k < nbits_aligned / 8 ; ++ k ) {
acc = ( acc << 8 ) + larray [ j ++ ];
}
acc >>= ( nbits_aligned - nbits [ i ]);
raw_mantissa [ c ][ i ] = acc ;
}
}
}
}
for ( i = 0 ; i < frame_length ; ++ i ) {
SoftFloat_IEEE754 pcm_sf = av_int2sf_ieee754 ( ctx -> raw_samples [ c ][ i ], 0 );
pcm_sf = av_div_sf_ieee754 ( pcm_sf , scale );
if ( ctx -> raw_samples [ c ][ i ] != 0 ) {
if ( ! av_cmp_sf_ieee754 ( acf [ c ], FLOAT_1 )) {
pcm_sf = multiply ( acf [ c ], pcm_sf );
}
sign = pcm_sf . sign ;
e = pcm_sf . exp ;
mantissa = ( pcm_sf . mant | 0x800000 ) + raw_mantissa [ c ][ i ];
while ( mantissa >= 0x1000000 ) {
e ++ ;
mantissa >>= 1 ;
}
if ( mantissa ) e += ( shift_value [ c ] - 127 );
mantissa &= 0x007fffffUL ;
tmp_32 = ( sign << 31 ) | (( e + EXP_BIAS ) << 23 ) | ( mantissa );
ctx -> raw_samples [ c ][ i ] = tmp_32 ;
} else {
2026-03-27 14:22:45 +05:30
ctx -> raw_samples [ c ][ i ] = raw_mantissa [ c ][ i ];
2016-08-12 17:51:41 +05:30
}
}
align_get_bits ( gb );
}
return 0 ;
}
2010-06-30 15:38:06 +00:00
/** Read the frame data.
2009-11-11 22:36:17 +00:00
*/
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.
2021-05-07 10:02:01 +09:00
int c ;
2009-11-11 22:36:17 +00:00
unsigned int js_blocks [ 2 ];
2017-04-04 16:29:55 +02:00
int channels = avctx -> ch_layout . nb_channels ;
2009-11-11 22:36:17 +00:00
uint32_t bs_info = 0 ;
2013-07-12 23:38:02 +02:00
int ret ;
2009-11-11 22:36:17 +00:00
// 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 );
if ( sconf -> mc_coding && sconf -> joint_stereo ) {
ctx -> js_switch = get_bits1 ( gb );
align_get_bits ( gb );
}
if ( ! sconf -> mc_coding || ctx -> js_switch ) {
int independent_bs = ! sconf -> joint_stereo ;
2022-10-29 18:47:34 +02:00
if ( get_bits_left ( gb ) < 7 * channels * ctx -> num_blocks )
return AVERROR_INVALIDDATA ;
2017-04-04 16:29:55 +02:00
for ( c = 0 ; c < channels ; c ++ ) {
2009-11-11 22:36:17 +00:00
js_blocks [ 0 ] = 0 ;
js_blocks [ 1 ] = 0 ;
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 ( bs_info >> 31 )
independent_bs = 2 ;
// if this is the last channel, it has to be decoded independently
2017-04-04 16:29:55 +02:00
if ( c == channels - 1 || ( c & 1 ))
2009-11-11 22:36:17 +00:00
independent_bs = 1 ;
if ( independent_bs ) {
2013-07-12 23:38:02 +02:00
ret = decode_blocks_ind ( ctx , ra_frame , c ,
div_blocks , js_blocks );
if ( ret < 0 )
return ret ;
2009-11-11 22:36:17 +00:00
independent_bs -- ;
} else {
2013-07-12 23:38:02 +02:00
ret = decode_blocks ( ctx , ra_frame , c , div_blocks , js_blocks );
if ( ret < 0 )
return ret ;
2009-11-11 22:36:17 +00:00
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 );
2019-11-09 22:02:50 +01:00
ctx -> highest_decoded_channel = c ;
2009-11-11 22:36:17 +00:00
}
} else { // multi-channel coding
2011-06-06 14:13:02 +02:00
ALSBlockData bd = { 0 };
2012-03-27 18:06:54 +02:00
int b , ret ;
2010-01-07 22:48:58 +00:00
int * reverted_channels = ctx -> reverted_channels ;
unsigned int offset = 0 ;
2017-04-04 16:29:55 +02:00
for ( c = 0 ; c < channels ; c ++ )
2010-01-07 22:48:58 +00:00
if ( ctx -> chan_data [ c ] < ctx -> chan_data_buffer ) {
2013-01-06 12:14:53 +01:00
av_log ( ctx -> avctx , AV_LOG_ERROR , "Invalid channel data. \n " );
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2010-01-07 22:48:58 +00:00
}
2017-04-04 16:29:55 +02:00
memset ( reverted_channels , 0 , sizeof ( * reverted_channels ) * channels );
2010-01-07 22:48:58 +00:00
bd . ra_block = ra_frame ;
bd . prev_raw_samples = ctx -> prev_raw_samples ;
2009-11-11 22:36:17 +00:00
get_block_sizes ( ctx , div_blocks , & bs_info );
2010-01-07 22:48:58 +00:00
for ( b = 0 ; b < ctx -> num_blocks ; b ++ ) {
bd . block_length = div_blocks [ b ];
2013-12-08 13:24:26 -05:00
if ( bd . block_length <= 0 ) {
av_log ( ctx -> avctx , AV_LOG_WARNING ,
2014-03-13 12:13:33 +01:00
"Invalid block length %u in channel data! \n " ,
bd . block_length );
2013-12-08 13:24:26 -05:00
continue ;
}
2010-01-07 22:48:58 +00:00
2017-04-04 16:29:55 +02:00
for ( c = 0 ; c < channels ; c ++ ) {
2010-12-06 15:18:50 +00:00
bd . const_block = ctx -> const_block + c ;
bd . shift_lsbs = ctx -> shift_lsbs + c ;
bd . opt_order = ctx -> opt_order + c ;
bd . store_prev_samples = ctx -> store_prev_samples + c ;
2010-01-07 22:48:58 +00:00
bd . use_ltp = ctx -> use_ltp + c ;
bd . ltp_lag = ctx -> ltp_lag + c ;
bd . ltp_gain = ctx -> ltp_gain [ c ];
bd . lpc_cof = ctx -> lpc_cof [ c ];
bd . quant_cof = ctx -> quant_cof [ c ];
bd . raw_samples = ctx -> raw_samples [ c ] + offset ;
bd . raw_other = NULL ;
2012-03-27 18:06:54 +02:00
if (( ret = read_block ( ctx , & bd )) < 0 )
return ret ;
if (( ret = read_channel_data ( ctx , ctx -> chan_data [ c ], c )) < 0 )
return ret ;
2010-01-07 22:48:58 +00:00
}
2017-04-04 16:29:55 +02:00
for ( c = 0 ; c < channels ; c ++ ) {
2013-07-12 23:38:02 +02:00
ret = revert_channel_correlation ( ctx , & bd , ctx -> chan_data ,
reverted_channels , offset , c );
if ( ret < 0 )
return ret ;
}
2017-04-04 16:29:55 +02:00
for ( c = 0 ; c < channels ; c ++ ) {
2010-12-06 15:18:50 +00:00
bd . const_block = ctx -> const_block + c ;
bd . shift_lsbs = ctx -> shift_lsbs + c ;
bd . opt_order = ctx -> opt_order + c ;
bd . store_prev_samples = ctx -> store_prev_samples + c ;
2010-01-07 22:48:58 +00:00
bd . use_ltp = ctx -> use_ltp + c ;
bd . ltp_lag = ctx -> ltp_lag + c ;
bd . ltp_gain = ctx -> ltp_gain [ c ];
bd . lpc_cof = ctx -> lpc_cof [ c ];
bd . quant_cof = ctx -> quant_cof [ c ];
bd . raw_samples = ctx -> raw_samples [ c ] + offset ;
2012-09-18 15:06:43 +02:00
2012-03-27 18:06:54 +02:00
if (( ret = decode_block ( ctx , & bd )) < 0 )
return ret ;
2019-11-09 22:02:50 +01:00
ctx -> highest_decoded_channel = FFMAX ( ctx -> highest_decoded_channel , c );
2010-01-07 22:48:58 +00:00
}
2017-04-04 16:29:55 +02:00
memset ( reverted_channels , 0 , channels * sizeof ( * reverted_channels ));
2010-01-07 22:48:58 +00:00
offset += div_blocks [ b ];
bd . ra_block = 0 ;
}
// store carryover raw samples
2017-04-04 16:29:55 +02:00
for ( c = 0 ; c < channels ; c ++ )
2010-01-07 22:48:58 +00:00
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 );
2009-11-11 22:36:17 +00:00
}
2016-08-12 17:51:41 +05:30
if ( sconf -> floating ) {
2026-03-25 13:36:07 +05:30
ret = read_diff_float_data ( ctx , ra_frame );
if ( ret < 0 )
return ret ;
2016-08-12 17:51:41 +05:30
}
2009-11-11 22:36:17 +00:00
2015-06-04 22:59:34 +02:00
if ( get_bits_left ( gb ) < 0 ) {
av_log ( ctx -> avctx , AV_LOG_ERROR , "Overread %d \n " , - get_bits_left ( gb ));
return AVERROR_INVALIDDATA ;
}
2009-11-11 22:36:17 +00:00
return 0 ;
}
2010-06-30 15:38:06 +00:00
/** Decode an ALS frame.
2009-11-11 22:36:17 +00:00
*/
2022-03-30 21:33:24 +02:00
static int decode_frame ( AVCodecContext * avctx , AVFrame * frame ,
int * got_frame_ptr , AVPacket * avpkt )
2009-11-11 22:36:17 +00:00
{
ALSDecContext * ctx = avctx -> priv_data ;
ALSSpecificConfig * sconf = & ctx -> sconf ;
const uint8_t * buffer = avpkt -> data ;
int buffer_size = avpkt -> size ;
2011-09-06 12:17:45 -04:00
int invalid_frame , ret ;
2017-04-04 16:29:55 +02:00
int channels = avctx -> ch_layout . nb_channels ;
2009-11-11 22:36:17 +00:00
unsigned int c , sample , ra_frame , bytes_read , shift ;
2015-02-04 13:44:22 +00:00
if (( ret = init_get_bits8 ( & ctx -> gb , buffer , buffer_size )) < 0 )
return ret ;
2009-11-11 22:36:17 +00:00
// 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 ( sconf -> samples != 0xFFFFFFFF )
ctx -> cur_frame_length = FFMIN ( sconf -> samples - ctx -> frame_id * ( uint64_t ) sconf -> frame_length ,
sconf -> frame_length );
else
ctx -> cur_frame_length = sconf -> frame_length ;
2021-05-07 10:02:01 +09:00
ctx -> highest_decoded_channel = - 1 ;
2009-11-11 22:36:17 +00:00
// decode the frame data
2011-11-21 07:50:03 +01:00
if (( invalid_frame = read_frame_data ( ctx , ra_frame )) < 0 )
2009-11-11 22:36:17 +00:00
av_log ( ctx -> avctx , AV_LOG_WARNING ,
"Reading frame data failed. Skipping RA unit. \n " );
2021-05-07 10:02:01 +09:00
if ( ctx -> highest_decoded_channel == - 1 ) {
av_log ( ctx -> avctx , AV_LOG_WARNING ,
"No channel data decoded. \n " );
2019-11-09 22:02:50 +01:00
return AVERROR_INVALIDDATA ;
2021-05-07 10:02:01 +09:00
}
2019-11-09 22:02:50 +01:00
2009-11-11 22:36:17 +00:00
ctx -> frame_id ++ ;
2011-09-06 12:17:45 -04:00
/* get output buffer */
2012-12-23 16:59:43 -05:00
frame -> nb_samples = ctx -> cur_frame_length ;
2013-03-12 08:41:53 +01:00
if (( ret = ff_get_buffer ( avctx , frame , 0 )) < 0 )
2011-09-06 12:17:45 -04:00
return ret ;
2009-11-11 22:36:17 +00:00
// transform decoded frame into output format
2012-12-21 14:14:57 +00:00
#define INTERLEAVE_OUTPUT(bps) \
{ \
2013-02-13 11:36:28 +01:00
int##bps##_t *dest = (int##bps##_t*)frame->data[0]; \
2019-11-09 21:52:26 +01:00
int32_t *raw_samples = ctx->raw_samples[0]; \
int raw_step = channels > 1 ? ctx->raw_samples[1] - raw_samples : 1; \
2012-12-21 14:14:57 +00:00
shift = bps - ctx->avctx->bits_per_raw_sample; \
2013-01-05 15:29:13 +01:00
if (!ctx->cs_switch) { \
2012-12-21 14:14:57 +00:00
for (sample = 0; sample < ctx->cur_frame_length; sample++) \
2019-09-25 20:31:50 +02:00
for (c = 0; c < channels; c++) \
2019-11-09 21:52:26 +01:00
*dest++ = raw_samples[c*raw_step + sample] * (1U << shift); \
2012-12-21 12:51:08 +00:00
} else { \
for (sample = 0; sample < ctx->cur_frame_length; sample++) \
2019-09-25 20:31:50 +02:00
for (c = 0; c < channels; c++) \
2019-11-09 21:52:26 +01:00
*dest++ = raw_samples[sconf->chan_pos[c]*raw_step + sample] * (1U << shift);\
2012-12-21 12:51:08 +00:00
} \
2009-11-11 22:36:17 +00:00
}
if ( ctx -> avctx -> bits_per_raw_sample <= 16 ) {
INTERLEAVE_OUTPUT ( 16 )
} else {
INTERLEAVE_OUTPUT ( 32 )
}
2010-06-29 16:56:28 +00:00
// update CRC
2011-11-19 20:41:30 +01:00
if ( sconf -> crc_enabled && ( avctx -> err_recognition & ( AV_EF_CRCCHECK | AV_EF_CAREFUL ))) {
2010-06-29 16:56:28 +00:00
int swap = HAVE_BIGENDIAN != sconf -> msb_first ;
if ( ctx -> avctx -> bits_per_raw_sample == 24 ) {
2012-12-23 16:59:43 -05:00
int32_t * src = ( int32_t * ) frame -> data [ 0 ];
2010-06-29 16:56:28 +00:00
for ( sample = 0 ;
2017-04-04 16:29:55 +02:00
sample < ctx -> cur_frame_length * channels ;
2010-06-29 16:56:28 +00:00
sample ++ ) {
int32_t v ;
if ( swap )
2010-07-10 22:12:30 +00:00
v = av_bswap32 ( src [ sample ]);
2010-06-29 16:56:28 +00:00
else
v = src [ sample ];
if ( ! HAVE_BIGENDIAN )
v >>= 8 ;
ctx -> crc = av_crc ( ctx -> crc_table , ctx -> crc , ( uint8_t * )( & v ), 3 );
}
} else {
uint8_t * crc_source ;
if ( swap ) {
if ( ctx -> avctx -> bits_per_raw_sample <= 16 ) {
2012-12-23 16:59:43 -05:00
int16_t * src = ( int16_t * ) frame -> data [ 0 ];
2010-06-29 16:56:28 +00:00
int16_t * dest = ( int16_t * ) ctx -> crc_buffer ;
for ( sample = 0 ;
2017-04-04 16:29:55 +02:00
sample < ctx -> cur_frame_length * channels ;
2010-06-29 16:56:28 +00:00
sample ++ )
2010-07-10 22:12:30 +00:00
* dest ++ = av_bswap16 ( src [ sample ]);
2010-06-29 16:56:28 +00:00
} else {
2014-02-13 17:57:05 +01:00
ctx -> bdsp . bswap_buf (( uint32_t * ) ctx -> crc_buffer ,
( uint32_t * ) frame -> data [ 0 ],
2017-04-04 16:29:55 +02:00
ctx -> cur_frame_length * channels );
2010-06-29 16:56:28 +00:00
}
crc_source = ctx -> crc_buffer ;
} else {
2012-12-23 16:59:43 -05:00
crc_source = frame -> data [ 0 ];
2010-06-29 16:56:28 +00:00
}
2011-09-06 12:17:45 -04:00
ctx -> crc = av_crc ( ctx -> crc_table , ctx -> crc , crc_source ,
2017-04-04 16:29:55 +02:00
ctx -> cur_frame_length * channels *
2011-09-06 12:17:45 -04:00
av_get_bytes_per_sample ( avctx -> sample_fmt ));
2010-06-29 16:56:28 +00:00
}
// check CRC sums if this is the last frame
if ( ctx -> cur_frame_length != sconf -> frame_length &&
ctx -> crc_org != ctx -> crc ) {
2013-01-06 12:14:53 +01:00
av_log ( avctx , AV_LOG_ERROR , "CRC error. \n " );
2013-10-26 22:46:48 +02:00
if ( avctx -> err_recognition & AV_EF_EXPLODE )
return AVERROR_INVALIDDATA ;
2010-06-29 16:56:28 +00:00
}
}
2012-12-23 16:59:43 -05:00
* got_frame_ptr = 1 ;
2010-06-29 16:56:28 +00:00
2009-11-11 22:36:17 +00:00
bytes_read = invalid_frame ? buffer_size :
( get_bits_count ( & ctx -> gb ) + 7 ) >> 3 ;
return bytes_read ;
}
2010-06-30 15:38:06 +00:00
/** Uninitialize the ALS decoder.
2009-11-11 22:36:17 +00:00
*/
static av_cold int decode_end ( AVCodecContext * avctx )
{
ALSDecContext * ctx = avctx -> priv_data ;
2016-09-08 18:11:30 +02:00
int i ;
2009-11-11 22:36:17 +00:00
av_freep ( & ctx -> sconf . chan_pos );
2010-02-13 18:24:13 +00:00
ff_bgmc_end ( & ctx -> bgmc_lut , & ctx -> bgmc_lut_status );
2010-12-06 15:18:50 +00:00
av_freep ( & ctx -> const_block );
av_freep ( & ctx -> shift_lsbs );
av_freep ( & ctx -> opt_order );
av_freep ( & ctx -> store_prev_samples );
2009-12-13 15:40:26 +00:00
av_freep ( & ctx -> use_ltp );
av_freep ( & ctx -> ltp_lag );
av_freep ( & ctx -> ltp_gain );
av_freep ( & ctx -> ltp_gain_buffer );
2009-11-11 22:36:17 +00:00
av_freep ( & ctx -> quant_cof );
av_freep ( & ctx -> lpc_cof );
2010-01-07 22:48:58 +00:00
av_freep ( & ctx -> quant_cof_buffer );
av_freep ( & ctx -> lpc_cof_buffer );
2010-01-12 20:35:22 +00:00
av_freep ( & ctx -> lpc_cof_reversed_buffer );
2009-11-11 22:36:17 +00:00
av_freep ( & ctx -> prev_raw_samples );
av_freep ( & ctx -> raw_samples );
av_freep ( & ctx -> raw_buffer );
2010-01-07 22:48:58 +00:00
av_freep ( & ctx -> chan_data );
av_freep ( & ctx -> chan_data_buffer );
av_freep ( & ctx -> reverted_channels );
2011-01-29 15:39:09 +01:00
av_freep ( & ctx -> crc_buffer );
2016-09-08 18:04:13 +02:00
if ( ctx -> mlz ) {
av_freep ( & ctx -> mlz -> dict );
av_freep ( & ctx -> mlz );
}
2016-08-12 17:51:41 +05:30
av_freep ( & ctx -> acf );
av_freep ( & ctx -> last_acf_mantissa );
av_freep ( & ctx -> shift_value );
av_freep ( & ctx -> last_shift_value );
2016-09-08 18:11:30 +02:00
if ( ctx -> raw_mantissa ) {
2017-04-04 16:29:55 +02:00
for ( i = 0 ; i < avctx -> ch_layout . nb_channels ; i ++ ) {
2016-09-08 18:11:30 +02:00
av_freep ( & ctx -> raw_mantissa [ i ]);
}
av_freep ( & ctx -> raw_mantissa );
}
2016-08-12 17:51:41 +05:30
av_freep ( & ctx -> larray );
av_freep ( & ctx -> nbits );
2009-11-11 22:36:17 +00:00
return 0 ;
}
2010-06-30 15:38:06 +00:00
/** Initialize the ALS decoder.
2009-11-11 22:36:17 +00:00
*/
static av_cold int decode_init ( AVCodecContext * avctx )
{
unsigned int c ;
unsigned int channel_size ;
2013-07-12 23:38:02 +02:00
int num_buffers , ret ;
2022-03-18 00:11:28 +01:00
int channels ;
2009-11-11 22:36:17 +00:00
ALSDecContext * ctx = avctx -> priv_data ;
ALSSpecificConfig * sconf = & ctx -> sconf ;
ctx -> avctx = avctx ;
if ( ! avctx -> extradata ) {
2013-01-06 12:14:53 +01:00
av_log ( avctx , AV_LOG_ERROR , "Missing required ALS extradata. \n " );
2013-07-12 23:38:02 +02:00
return AVERROR_INVALIDDATA ;
2009-11-11 22:36:17 +00:00
}
2013-07-12 23:38:02 +02:00
if (( ret = read_specific_config ( ctx )) < 0 ) {
2013-01-06 12:14:53 +01:00
av_log ( avctx , AV_LOG_ERROR , "Reading ALSSpecificConfig failed. \n " );
2022-02-11 15:17:30 +01:00
return ret ;
2009-11-11 22:36:17 +00:00
}
2022-03-18 00:11:28 +01:00
channels = avctx -> ch_layout . nb_channels ;
2009-11-11 22:36:17 +00:00
2013-07-12 23:38:02 +02:00
if (( ret = check_specific_config ( ctx )) < 0 ) {
2022-02-11 15:17:30 +01:00
return ret ;
2009-11-11 22:36:17 +00:00
}
2013-07-12 23:38:02 +02:00
if ( sconf -> bgmc ) {
ret = ff_bgmc_init ( avctx , & ctx -> bgmc_lut , & ctx -> bgmc_lut_status );
if ( ret < 0 )
2022-02-11 15:17:30 +01:00
return ret ;
2013-07-12 23:38:02 +02:00
}
2009-11-11 22:36:17 +00:00
if ( sconf -> floating ) {
2010-11-12 11:04:40 +00:00
avctx -> sample_fmt = AV_SAMPLE_FMT_FLT ;
2009-11-11 22:36:17 +00:00
avctx -> bits_per_raw_sample = 32 ;
} else {
avctx -> sample_fmt = sconf -> resolution > 1
2010-11-12 11:04:40 +00:00
? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S16 ;
2009-11-11 22:36:17 +00:00
avctx -> bits_per_raw_sample = ( sconf -> resolution + 1 ) * 8 ;
2015-04-18 20:29:13 +02:00
if ( avctx -> bits_per_raw_sample > 32 ) {
av_log ( avctx , AV_LOG_ERROR , "Bits per raw sample %d larger than 32. \n " ,
avctx -> bits_per_raw_sample );
2022-02-11 15:17:30 +01:00
return AVERROR_INVALIDDATA ;
2015-04-18 20:29:13 +02:00
}
2009-11-11 22:36:17 +00:00
}
2010-02-16 14:48:01 +00:00
// set maximum Rice parameter for progressive decoding based on resolution
// This is not specified in 14496-3 but actually done by the reference
// codec RM22 revision 2.
ctx -> s_max = sconf -> resolution > 1 ? 31 : 15 ;
2009-11-14 06:29:19 +00:00
// set lag value for long-term prediction
ctx -> ltp_lag_length = 8 + ( avctx -> sample_rate >= 96000 ) +
( avctx -> sample_rate >= 192000 );
2009-12-13 15:40:26 +00:00
// allocate quantized parcor coefficient buffer
2017-04-04 16:29:55 +02:00
num_buffers = sconf -> mc_coding ? channels : 1 ;
2019-06-21 00:47:17 +02:00
if ( num_buffers * ( uint64_t ) num_buffers > INT_MAX ) // protect chan_data_buffer allocation
return AVERROR_INVALIDDATA ;
2009-12-13 15:40:26 +00:00
2015-04-13 18:44:49 +00:00
ctx -> quant_cof = av_malloc_array ( num_buffers , sizeof ( * ctx -> quant_cof ));
ctx -> lpc_cof = av_malloc_array ( num_buffers , sizeof ( * ctx -> lpc_cof ));
ctx -> quant_cof_buffer = av_malloc_array ( num_buffers * sconf -> max_order ,
sizeof ( * ctx -> quant_cof_buffer ));
ctx -> lpc_cof_buffer = av_malloc_array ( num_buffers * sconf -> max_order ,
sizeof ( * ctx -> lpc_cof_buffer ));
ctx -> lpc_cof_reversed_buffer = av_malloc_array ( sconf -> max_order ,
sizeof ( * ctx -> lpc_cof_buffer ));
2010-01-07 22:48:58 +00:00
2010-01-12 20:37:56 +00:00
if ( ! ctx -> quant_cof || ! ctx -> lpc_cof ||
! ctx -> quant_cof_buffer || ! ctx -> lpc_cof_buffer ||
2010-01-12 20:35:22 +00:00
! ctx -> lpc_cof_reversed_buffer ) {
2013-01-06 12:14:53 +01:00
av_log ( avctx , AV_LOG_ERROR , "Allocating buffer memory failed. \n " );
2022-02-11 15:17:30 +01:00
return AVERROR ( ENOMEM );
2010-01-07 22:48:58 +00:00
}
// assign quantized parcor coefficient buffers
for ( c = 0 ; c < num_buffers ; c ++ ) {
ctx -> quant_cof [ c ] = ctx -> quant_cof_buffer + c * sconf -> max_order ;
ctx -> lpc_cof [ c ] = ctx -> lpc_cof_buffer + c * sconf -> max_order ;
}
2009-12-13 15:40:26 +00:00
// allocate and assign lag and gain data buffer for ltp mode
2015-04-13 18:44:49 +00:00
ctx -> const_block = av_malloc_array ( num_buffers , sizeof ( * ctx -> const_block ));
ctx -> shift_lsbs = av_malloc_array ( num_buffers , sizeof ( * ctx -> shift_lsbs ));
ctx -> opt_order = av_malloc_array ( num_buffers , sizeof ( * ctx -> opt_order ));
ctx -> store_prev_samples = av_malloc_array ( num_buffers , sizeof ( * ctx -> store_prev_samples ));
2021-09-14 21:31:53 +02:00
ctx -> use_ltp = av_calloc ( num_buffers , sizeof ( * ctx -> use_ltp ));
2015-04-13 18:44:49 +00:00
ctx -> ltp_lag = av_malloc_array ( num_buffers , sizeof ( * ctx -> ltp_lag ));
ctx -> ltp_gain = av_malloc_array ( num_buffers , sizeof ( * ctx -> ltp_gain ));
ctx -> ltp_gain_buffer = av_malloc_array ( num_buffers * 5 , sizeof ( * ctx -> ltp_gain_buffer ));
2009-12-13 15:40:26 +00:00
2010-12-06 15:18:50 +00:00
if ( ! ctx -> const_block || ! ctx -> shift_lsbs ||
! ctx -> opt_order || ! ctx -> store_prev_samples ||
! ctx -> use_ltp || ! ctx -> ltp_lag ||
2009-12-13 15:40:26 +00:00
! ctx -> ltp_gain || ! ctx -> ltp_gain_buffer ) {
2013-01-06 12:14:53 +01:00
av_log ( avctx , AV_LOG_ERROR , "Allocating buffer memory failed. \n " );
2022-02-11 15:17:30 +01:00
return AVERROR ( ENOMEM );
2009-12-13 15:40:26 +00:00
}
for ( c = 0 ; c < num_buffers ; c ++ )
ctx -> ltp_gain [ c ] = ctx -> ltp_gain_buffer + c * 5 ;
2010-01-07 22:48:58 +00:00
// allocate and assign channel data buffer for mcc mode
if ( sconf -> mc_coding ) {
2021-09-14 21:31:53 +02:00
ctx -> chan_data_buffer = av_calloc ( num_buffers * num_buffers ,
sizeof ( * ctx -> chan_data_buffer ));
ctx -> chan_data = av_calloc ( num_buffers , sizeof ( * ctx -> chan_data ));
2015-04-13 18:44:49 +00:00
ctx -> reverted_channels = av_malloc_array ( num_buffers ,
sizeof ( * ctx -> reverted_channels ));
2010-01-07 22:48:58 +00:00
if ( ! ctx -> chan_data_buffer || ! ctx -> chan_data || ! ctx -> reverted_channels ) {
2013-01-06 12:14:53 +01:00
av_log ( avctx , AV_LOG_ERROR , "Allocating buffer memory failed. \n " );
2022-02-11 15:17:30 +01:00
return AVERROR ( ENOMEM );
2010-01-07 22:48:58 +00:00
}
for ( c = 0 ; c < num_buffers ; c ++ )
2010-02-17 22:53:25 +00:00
ctx -> chan_data [ c ] = ctx -> chan_data_buffer + c * num_buffers ;
2010-01-07 22:48:58 +00:00
} else {
ctx -> chan_data = NULL ;
ctx -> chan_data_buffer = NULL ;
ctx -> reverted_channels = NULL ;
}
2016-08-12 17:51:41 +05:30
if ( sconf -> floating ) {
2017-04-04 16:29:55 +02:00
ctx -> acf = av_malloc_array ( channels , sizeof ( * ctx -> acf ));
2024-07-19 17:08:22 +02:00
ctx -> shift_value = av_calloc ( channels , sizeof ( * ctx -> shift_value ));
ctx -> last_shift_value = av_calloc ( channels , sizeof ( * ctx -> last_shift_value ));
2024-08-04 22:32:31 +02:00
ctx -> last_acf_mantissa = av_calloc ( channels , sizeof ( * ctx -> last_acf_mantissa ));
2017-04-04 16:29:55 +02:00
ctx -> raw_mantissa = av_calloc ( channels , sizeof ( * ctx -> raw_mantissa ));
2016-08-12 17:51:41 +05:30
ctx -> larray = av_malloc_array ( ctx -> cur_frame_length * 4 , sizeof ( * ctx -> larray ));
ctx -> nbits = av_malloc_array ( ctx -> cur_frame_length , sizeof ( * ctx -> nbits ));
2016-09-08 18:04:13 +02:00
ctx -> mlz = av_mallocz ( sizeof ( * ctx -> mlz ));
2016-08-12 17:51:41 +05:30
2025-07-10 16:26:39 +00:00
if ( ! ctx -> larray || ! ctx -> nbits || ! ctx -> mlz || ! ctx -> acf || ! ctx -> shift_value
|| ! ctx -> last_shift_value || ! ctx -> last_acf_mantissa || ! ctx -> raw_mantissa ) {
2016-08-12 17:51:41 +05:30
av_log ( avctx , AV_LOG_ERROR , "Allocating buffer memory failed. \n " );
2022-02-11 15:17:30 +01:00
return AVERROR ( ENOMEM );
2016-08-12 17:51:41 +05:30
}
2022-02-11 16:22:16 +01:00
ret = ff_mlz_init_dict ( avctx , ctx -> mlz );
if ( ret < 0 )
return ret ;
2016-08-12 17:51:41 +05:30
ff_mlz_flush_dict ( ctx -> mlz );
2017-04-04 16:29:55 +02:00
for ( c = 0 ; c < channels ; ++ c ) {
2021-09-14 21:31:53 +02:00
ctx -> raw_mantissa [ c ] = av_calloc ( ctx -> cur_frame_length , sizeof ( ** ctx -> raw_mantissa ));
2025-07-10 16:26:39 +00:00
if ( ! ctx -> raw_mantissa [ c ]) {
av_log ( avctx , AV_LOG_ERROR , "Allocating buffer memory failed. \n " );
return AVERROR ( ENOMEM );
}
2016-08-12 17:51:41 +05:30
}
}
2022-02-11 15:22:48 +01:00
channel_size = sconf -> frame_length + sconf -> max_order ;
2009-11-11 22:36:17 +00:00
// allocate previous raw sample buffer
2022-02-11 15:22:48 +01:00
ctx -> prev_raw_samples = av_malloc_array ( sconf -> max_order , sizeof ( * ctx -> prev_raw_samples ));
2017-04-04 16:29:55 +02:00
ctx -> raw_buffer = av_calloc ( channels * channel_size , sizeof ( * ctx -> raw_buffer ));
ctx -> raw_samples = av_malloc_array ( channels , sizeof ( * ctx -> raw_samples ));
2009-11-11 22:36:17 +00:00
if ( ! ctx -> prev_raw_samples || ! ctx -> raw_buffer || ! ctx -> raw_samples ) {
2013-01-06 12:14:53 +01:00
av_log ( avctx , AV_LOG_ERROR , "Allocating buffer memory failed. \n " );
2022-02-11 15:17:30 +01:00
return AVERROR ( ENOMEM );
2009-11-11 22:36:17 +00:00
}
// assign raw samples buffers
ctx -> raw_samples [ 0 ] = ctx -> raw_buffer + sconf -> max_order ;
2017-04-04 16:29:55 +02:00
for ( c = 1 ; c < channels ; c ++ )
2009-11-11 22:36:17 +00:00
ctx -> raw_samples [ c ] = ctx -> raw_samples [ c - 1 ] + channel_size ;
2010-06-29 16:56:28 +00:00
// allocate crc buffer
if ( HAVE_BIGENDIAN != sconf -> msb_first && sconf -> crc_enabled &&
2011-11-19 20:41:30 +01:00
( avctx -> err_recognition & ( AV_EF_CRCCHECK | AV_EF_CAREFUL ))) {
2015-04-13 18:44:49 +00:00
ctx -> crc_buffer = av_malloc_array ( ctx -> cur_frame_length *
2017-04-04 16:29:55 +02:00
channels *
2015-04-13 18:44:49 +00:00
av_get_bytes_per_sample ( avctx -> sample_fmt ),
sizeof ( * ctx -> crc_buffer ));
2010-06-29 16:56:28 +00:00
if ( ! ctx -> crc_buffer ) {
2013-01-06 12:14:53 +01:00
av_log ( avctx , AV_LOG_ERROR , "Allocating buffer memory failed. \n " );
2022-02-11 15:17:30 +01:00
return AVERROR ( ENOMEM );
2010-06-29 16:56:28 +00:00
}
}
2014-02-13 17:57:05 +01:00
ff_bswapdsp_init ( & ctx -> bdsp );
2010-06-29 16:56:28 +00:00
2009-11-11 22:36:17 +00:00
return 0 ;
}
2010-06-30 15:38:06 +00:00
/** Flush (reset) the frame ID after seeking.
2009-11-11 22:36:17 +00:00
*/
static av_cold void flush ( AVCodecContext * avctx )
{
ALSDecContext * ctx = avctx -> priv_data ;
ctx -> frame_id = 0 ;
}
2025-07-22 02:56:27 +02:00
static const AVOption options [] = {
{ "max_order" , "Sets the maximum order (ALS simple profile allows max 15)" , offsetof ( ALSDecContext , user_max_order ), AV_OPT_TYPE_INT , { . i64 = 1023 }, 0 , 1023 , AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM },
{ NULL }
};
static const AVClass als_class = {
. class_name = "als" ,
. item_name = av_default_item_name ,
. option = options ,
. version = LIBAVUTIL_VERSION_INT ,
};
2009-11-11 22:36:17 +00:00
2022-03-16 21:09:54 +01:00
const FFCodec ff_als_decoder = {
. p . name = "als" ,
2022-08-29 13:38:02 +02:00
CODEC_LONG_NAME ( "MPEG-4 Audio Lossless Coding (ALS)" ),
2022-03-16 21:09:54 +01:00
. p . type = AVMEDIA_TYPE_AUDIO ,
. p . id = AV_CODEC_ID_MP4ALS ,
2011-07-17 12:54:31 +02:00
. priv_data_size = sizeof ( ALSDecContext ),
. init = decode_init ,
. close = decode_end ,
2022-03-30 23:28:24 +02:00
FF_CODEC_DECODE_CB ( decode_frame ),
2025-07-22 02:56:27 +02:00
. p . priv_class = & als_class ,
2012-04-06 19:19:39 +03:00
. flush = flush ,
2025-02-19 12:16:20 -03:00
. p . capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF ,
2022-07-10 00:05:45 +02:00
. caps_internal = FF_CODEC_CAP_INIT_CLEANUP ,
2009-11-11 22:36:17 +00:00
};