| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |  * Windows Media Audio Lossless decoder | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |  * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion | 
					
						
							|  |  |  |  * Copyright (c) 2008 - 2011 Sascha Sommer, Benjamin Larsson | 
					
						
							|  |  |  |  * Copyright (c) 2011 Andreas Öman | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |  * Copyright (c) 2011 - 2012 Mashiat Sarker Shakkhar | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01: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 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-13 12:13:33 +01:00
										 |  |  | #include <inttypes.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-19 14:48:16 +02:00
										 |  |  | #include "libavutil/attributes.h"
 | 
					
						
							| 
									
										
										
										
											2012-09-29 08:40:42 +02:00
										 |  |  | #include "libavutil/avassert.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | #include "avcodec.h"
 | 
					
						
							|  |  |  | #include "internal.h"
 | 
					
						
							|  |  |  | #include "get_bits.h"
 | 
					
						
							|  |  |  | #include "put_bits.h"
 | 
					
						
							| 
									
										
										
										
											2012-11-24 15:55:49 +01:00
										 |  |  | #include "lossless_audiodsp.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | #include "wma.h"
 | 
					
						
							| 
									
										
										
										
											2012-03-06 19:07:10 +01:00
										 |  |  | #include "wma_common.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** current decoder limitations */ | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  | #define WMALL_MAX_CHANNELS      8                       ///< max number of handled channels
 | 
					
						
							|  |  |  | #define MAX_SUBFRAMES          32                       ///< max number of subframes per channel
 | 
					
						
							|  |  |  | #define MAX_BANDS              29                       ///< max number of scale factor bands
 | 
					
						
							|  |  |  | #define MAX_FRAMESIZE       32768                       ///< maximum compressed frame size
 | 
					
						
							| 
									
										
										
										
											2012-03-21 12:40:59 -07:00
										 |  |  | #define MAX_ORDER             256
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define WMALL_BLOCK_MIN_BITS    6                       ///< log2 of min block size
 | 
					
						
							| 
									
										
										
										
											2012-09-29 08:37:08 +02:00
										 |  |  | #define WMALL_BLOCK_MAX_BITS   14                       ///< log2 of max block size
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  | #define WMALL_BLOCK_MAX_SIZE (1 << WMALL_BLOCK_MAX_BITS)    ///< maximum block size
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | #define WMALL_BLOCK_SIZES    (WMALL_BLOCK_MAX_BITS - WMALL_BLOCK_MIN_BITS + 1) ///< possible block sizes
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-24 15:55:49 +01:00
										 |  |  | #define WMALL_COEFF_PAD_SIZE   16                       ///< pad coef buffers with 0 for use with SIMD
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |  * @brief frame-specific decoder context for a single channel | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-09-22 11:01:31 +02:00
										 |  |  | typedef struct WmallChannelCtx { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int16_t     prev_block_len;                         ///< length of the previous block
 | 
					
						
							|  |  |  |     uint8_t     transmit_coefs; | 
					
						
							|  |  |  |     uint8_t     num_subframes; | 
					
						
							|  |  |  |     uint16_t    subframe_len[MAX_SUBFRAMES];            ///< subframe length in samples
 | 
					
						
							|  |  |  |     uint16_t    subframe_offsets[MAX_SUBFRAMES];        ///< subframe positions in the current frame
 | 
					
						
							|  |  |  |     uint8_t     cur_subframe;                           ///< current subframe number
 | 
					
						
							|  |  |  |     uint16_t    decoded_samples;                        ///< number of already processed samples
 | 
					
						
							|  |  |  |     int         quant_step;                             ///< quantization step for the current subframe
 | 
					
						
							|  |  |  |     int         transient_counter;                      ///< number of transient samples from the beginning of the transient zone
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | } WmallChannelCtx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @brief main decoder context | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | typedef struct WmallDecodeCtx { | 
					
						
							|  |  |  |     /* generic decoder variables */ | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     AVCodecContext  *avctx; | 
					
						
							| 
									
										
										
										
											2013-08-08 18:48:43 +02:00
										 |  |  |     AVFrame         *frame; | 
					
						
							| 
									
										
										
										
											2012-11-24 15:55:49 +01:00
										 |  |  |     LLAudDSPContext dsp;                           ///< accelerated DSP functions
 | 
					
						
							| 
									
										
										
										
											2016-04-13 20:21:07 +02:00
										 |  |  |     uint8_t         *frame_data;                    ///< compressed frame data
 | 
					
						
							|  |  |  |     int             max_frame_size;                 ///< max bitstream size
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     PutBitContext   pb;                             ///< context for filling the frame_data buffer
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* frame size dependent frame information (set during initialization) */ | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     uint32_t        decode_flags;                   ///< used compression features
 | 
					
						
							|  |  |  |     int             len_prefix;                     ///< frame is prefixed with its length
 | 
					
						
							|  |  |  |     int             dynamic_range_compression;      ///< frame contains DRC data
 | 
					
						
							|  |  |  |     uint8_t         bits_per_sample;                ///< integer audio sample size for the unscaled IMDCT output (used to scale to [-1.0, 1.0])
 | 
					
						
							|  |  |  |     uint16_t        samples_per_frame;              ///< number of samples to output
 | 
					
						
							|  |  |  |     uint16_t        log2_frame_size; | 
					
						
							|  |  |  |     int8_t          num_channels;                   ///< number of channels in the stream (same as AVCodecContext.num_channels)
 | 
					
						
							|  |  |  |     int8_t          lfe_channel;                    ///< lfe channel index
 | 
					
						
							|  |  |  |     uint8_t         max_num_subframes; | 
					
						
							|  |  |  |     uint8_t         subframe_len_bits;              ///< number of bits used for the subframe length
 | 
					
						
							|  |  |  |     uint8_t         max_subframe_len_bit;           ///< flag indicating that the subframe is of maximum size when the first subframe length bit is 1
 | 
					
						
							|  |  |  |     uint16_t        min_samples_per_subframe; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* packet decode state */ | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     GetBitContext   pgb;                            ///< bitstream reader context for the packet
 | 
					
						
							|  |  |  |     int             next_packet_start;              ///< start offset of the next WMA packet in the demuxer packet
 | 
					
						
							|  |  |  |     uint8_t         packet_offset;                  ///< offset to the frame in the packet
 | 
					
						
							|  |  |  |     uint8_t         packet_sequence_number;         ///< current packet number
 | 
					
						
							|  |  |  |     int             num_saved_bits;                 ///< saved number of bits
 | 
					
						
							|  |  |  |     int             frame_offset;                   ///< frame offset in the bit reservoir
 | 
					
						
							|  |  |  |     int             subframe_offset;                ///< subframe offset in the bit reservoir
 | 
					
						
							|  |  |  |     uint8_t         packet_loss;                    ///< set in case of bitstream error
 | 
					
						
							|  |  |  |     uint8_t         packet_done;                    ///< set when a packet is fully decoded
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* frame decode state */ | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     uint32_t        frame_num;                      ///< current frame number (not used for decoding)
 | 
					
						
							|  |  |  |     GetBitContext   gb;                             ///< bitstream reader context
 | 
					
						
							|  |  |  |     int             buf_bit_size;                   ///< buffer size in bits
 | 
					
						
							| 
									
										
										
										
											2016-04-27 13:45:23 -04:00
										 |  |  |     int16_t         *samples_16[WMALL_MAX_CHANNELS]; ///< current sample buffer pointer (16-bit)
 | 
					
						
							|  |  |  |     int32_t         *samples_32[WMALL_MAX_CHANNELS]; ///< current sample buffer pointer (24-bit)
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     uint8_t         drc_gain;                       ///< gain for the DRC tool
 | 
					
						
							|  |  |  |     int8_t          skip_frame;                     ///< skip output step
 | 
					
						
							|  |  |  |     int8_t          parsed_all_subframes;           ///< all subframes decoded?
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* subframe/block decode state */ | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int16_t         subframe_len;                   ///< current subframe length
 | 
					
						
							|  |  |  |     int8_t          channels_for_cur_subframe;      ///< number of channels that contain the subframe
 | 
					
						
							|  |  |  |     int8_t          channel_indexes_for_cur_subframe[WMALL_MAX_CHANNELS]; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-04 02:50:54 +06:00
										 |  |  |     WmallChannelCtx channel[WMALL_MAX_CHANNELS];    ///< per channel data
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     // WMA Lossless-specific
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     uint8_t do_arith_coding; | 
					
						
							|  |  |  |     uint8_t do_ac_filter; | 
					
						
							|  |  |  |     uint8_t do_inter_ch_decorr; | 
					
						
							|  |  |  |     uint8_t do_mclms; | 
					
						
							|  |  |  |     uint8_t do_lpc; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int8_t  acfilter_order; | 
					
						
							|  |  |  |     int8_t  acfilter_scaling; | 
					
						
							| 
									
										
										
										
											2015-02-14 00:49:49 +08:00
										 |  |  |     int16_t acfilter_coeffs[16]; | 
					
						
							| 
									
										
										
										
											2013-01-10 04:50:33 +01:00
										 |  |  |     int     acfilter_prevvalues[WMALL_MAX_CHANNELS][16]; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int8_t  mclms_order; | 
					
						
							|  |  |  |     int8_t  mclms_scaling; | 
					
						
							| 
									
										
										
										
											2014-02-07 15:07:23 +01:00
										 |  |  |     int16_t mclms_coeffs[WMALL_MAX_CHANNELS * WMALL_MAX_CHANNELS * 32]; | 
					
						
							|  |  |  |     int16_t mclms_coeffs_cur[WMALL_MAX_CHANNELS * WMALL_MAX_CHANNELS]; | 
					
						
							| 
									
										
										
										
											2016-04-13 20:36:26 +02:00
										 |  |  |     int32_t mclms_prevvalues[WMALL_MAX_CHANNELS * 2 * 32]; | 
					
						
							|  |  |  |     int32_t mclms_updates[WMALL_MAX_CHANNELS * 2 * 32]; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int     mclms_recent; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int     movave_scaling; | 
					
						
							|  |  |  |     int     quant_stepsize; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     struct { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         int order; | 
					
						
							|  |  |  |         int scaling; | 
					
						
							|  |  |  |         int coefsend; | 
					
						
							|  |  |  |         int bitsend; | 
					
						
							| 
									
										
										
										
											2016-05-01 10:46:20 +02:00
										 |  |  |         DECLARE_ALIGNED(16, int16_t, coefs)[MAX_ORDER + WMALL_COEFF_PAD_SIZE/sizeof(int16_t)]; | 
					
						
							| 
									
										
										
										
											2016-04-13 20:36:26 +02:00
										 |  |  |         DECLARE_ALIGNED(16, int32_t, lms_prevvalues)[MAX_ORDER * 2 + WMALL_COEFF_PAD_SIZE/sizeof(int16_t)]; | 
					
						
							| 
									
										
										
										
											2016-05-01 10:46:20 +02:00
										 |  |  |         DECLARE_ALIGNED(16, int16_t, lms_updates)[MAX_ORDER * 2 + WMALL_COEFF_PAD_SIZE/sizeof(int16_t)]; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         int recent; | 
					
						
							| 
									
										
										
										
											2013-01-10 04:50:33 +01:00
										 |  |  |     } cdlms[WMALL_MAX_CHANNELS][9]; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 04:50:33 +01:00
										 |  |  |     int cdlms_ttl[WMALL_MAX_CHANNELS]; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     int bV3RTM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 04:50:33 +01:00
										 |  |  |     int is_channel_coded[WMALL_MAX_CHANNELS]; | 
					
						
							|  |  |  |     int update_speed[WMALL_MAX_CHANNELS]; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 04:50:33 +01:00
										 |  |  |     int transient[WMALL_MAX_CHANNELS]; | 
					
						
							|  |  |  |     int transient_pos[WMALL_MAX_CHANNELS]; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     int seekable_tile; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 18:09:24 +01:00
										 |  |  |     unsigned ave_sum[WMALL_MAX_CHANNELS]; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 04:50:33 +01:00
										 |  |  |     int channel_residues[WMALL_MAX_CHANNELS][WMALL_BLOCK_MAX_SIZE]; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 04:50:33 +01:00
										 |  |  |     int lpc_coefs[WMALL_MAX_CHANNELS][40]; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     int lpc_order; | 
					
						
							|  |  |  |     int lpc_scaling; | 
					
						
							|  |  |  |     int lpc_intbits; | 
					
						
							|  |  |  | } WmallDecodeCtx; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 00:51:27 +08:00
										 |  |  | /** Get sign of integer (1 for positive, -1 for negative and 0 for zero) */ | 
					
						
							| 
									
										
										
										
											2015-02-18 01:34:50 +01:00
										 |  |  | #define WMASIGN(x) (((x) > 0) - ((x) < 0))
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static av_cold int decode_init(AVCodecContext *avctx) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     WmallDecodeCtx *s  = avctx->priv_data; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     uint8_t *edata_ptr = avctx->extradata; | 
					
						
							|  |  |  |     unsigned int channel_mask; | 
					
						
							| 
									
										
										
										
											2012-10-08 03:12:44 +02:00
										 |  |  |     int i, log2_max_num_subframes; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-19 19:18:18 +02:00
										 |  |  |     if (avctx->block_align <= 0) { | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "block_align is not set or invalid\n"); | 
					
						
							| 
									
										
										
										
											2013-10-02 01:16:11 +02:00
										 |  |  |         return AVERROR(EINVAL); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-15 00:46:53 +01:00
										 |  |  |     av_assert0(avctx->channels >= 0); | 
					
						
							|  |  |  |     if (avctx->channels > WMALL_MAX_CHANNELS) { | 
					
						
							| 
									
										
										
										
											2020-01-15 00:32:55 +01:00
										 |  |  |         avpriv_request_sample(avctx, | 
					
						
							| 
									
										
										
										
											2020-01-15 13:12:28 +01:00
										 |  |  |                               "More than " AV_STRINGIFY(WMALL_MAX_CHANNELS) " channels"); | 
					
						
							| 
									
										
										
										
											2020-01-15 00:32:55 +01:00
										 |  |  |         return AVERROR_PATCHWELCOME; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 20:21:07 +02:00
										 |  |  |     s->max_frame_size = MAX_FRAMESIZE * avctx->channels; | 
					
						
							|  |  |  |     s->frame_data = av_mallocz(s->max_frame_size + AV_INPUT_BUFFER_PADDING_SIZE); | 
					
						
							|  |  |  |     if (!s->frame_data) | 
					
						
							|  |  |  |         return AVERROR(ENOMEM); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     s->avctx = avctx; | 
					
						
							| 
									
										
										
										
											2012-11-24 15:55:49 +01:00
										 |  |  |     ff_llauddsp_init(&s->dsp); | 
					
						
							| 
									
										
										
										
											2016-04-13 20:21:07 +02:00
										 |  |  |     init_put_bits(&s->pb, s->frame_data, s->max_frame_size); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (avctx->extradata_size >= 18) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         s->decode_flags    = AV_RL16(edata_ptr + 14); | 
					
						
							|  |  |  |         channel_mask       = AV_RL32(edata_ptr +  2); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         s->bits_per_sample = AV_RL16(edata_ptr); | 
					
						
							| 
									
										
										
										
											2012-01-03 01:49:00 +06:00
										 |  |  |         if (s->bits_per_sample == 16) | 
					
						
							| 
									
										
										
										
											2012-08-25 19:09:40 -04:00
										 |  |  |             avctx->sample_fmt = AV_SAMPLE_FMT_S16P; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         else if (s->bits_per_sample == 24) { | 
					
						
							| 
									
										
										
										
											2012-08-25 19:09:40 -04:00
										 |  |  |             avctx->sample_fmt = AV_SAMPLE_FMT_S32P; | 
					
						
							| 
									
										
										
										
											2014-11-22 20:49:40 +01:00
										 |  |  |             avctx->bits_per_raw_sample = 24; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2014-03-13 12:13:33 +01:00
										 |  |  |             av_log(avctx, AV_LOG_ERROR, "Unknown bit-depth: %"PRIu8"\n", | 
					
						
							| 
									
										
										
										
											2012-01-03 01:49:00 +06:00
										 |  |  |                    s->bits_per_sample); | 
					
						
							|  |  |  |             return AVERROR_INVALIDDATA; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* dump the extradata */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         for (i = 0; i < avctx->extradata_size; i++) | 
					
						
							| 
									
										
										
										
											2015-03-16 08:57:36 +00:00
										 |  |  |             ff_dlog(avctx, "[%x] ", avctx->extradata[i]); | 
					
						
							|  |  |  |         ff_dlog(avctx, "\n"); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2013-03-13 21:17:05 +01:00
										 |  |  |         avpriv_request_sample(avctx, "Unsupported extradata size"); | 
					
						
							| 
									
										
										
										
											2012-12-23 18:10:05 +01:00
										 |  |  |         return AVERROR_PATCHWELCOME; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* generic init */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     s->log2_frame_size = av_log2(avctx->block_align) + 4; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* frame info */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     s->skip_frame  = 1; /* skip first frame */ | 
					
						
							|  |  |  |     s->packet_loss = 1; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     s->len_prefix  = s->decode_flags & 0x40; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* get frame len */ | 
					
						
							|  |  |  |     s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate, | 
					
						
							|  |  |  |                                                           3, s->decode_flags); | 
					
						
							| 
									
										
										
										
											2012-09-29 08:40:42 +02:00
										 |  |  |     av_assert0(s->samples_per_frame <= WMALL_BLOCK_MAX_SIZE); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* init previous block len */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     for (i = 0; i < avctx->channels; i++) | 
					
						
							|  |  |  |         s->channel[i].prev_block_len = s->samples_per_frame; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* subframe info */ | 
					
						
							|  |  |  |     log2_max_num_subframes  = (s->decode_flags & 0x38) >> 3; | 
					
						
							| 
									
										
										
										
											2011-11-04 02:50:54 +06:00
										 |  |  |     s->max_num_subframes    = 1 << log2_max_num_subframes; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     s->max_subframe_len_bit = 0; | 
					
						
							| 
									
										
										
										
											2011-11-04 02:50:54 +06:00
										 |  |  |     s->subframe_len_bits    = av_log2(log2_max_num_subframes) + 1; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s->min_samples_per_subframe  = s->samples_per_frame / s->max_num_subframes; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     s->dynamic_range_compression = s->decode_flags & 0x80; | 
					
						
							|  |  |  |     s->bV3RTM                    = s->decode_flags & 0x100; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (s->max_num_subframes > MAX_SUBFRAMES) { | 
					
						
							| 
									
										
										
										
											2014-03-13 12:13:33 +01:00
										 |  |  |         av_log(avctx, AV_LOG_ERROR, "invalid number of subframes %"PRIu8"\n", | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |                s->max_num_subframes); | 
					
						
							|  |  |  |         return AVERROR_INVALIDDATA; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->num_channels = avctx->channels; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* extract lfe channel position */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     s->lfe_channel = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (channel_mask & 8) { | 
					
						
							|  |  |  |         unsigned int mask; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         for (mask = 1; mask < 16; mask <<= 1) | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |             if (channel_mask & mask) | 
					
						
							|  |  |  |                 ++s->lfe_channel; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-08 18:48:43 +02:00
										 |  |  |     s->frame = av_frame_alloc(); | 
					
						
							|  |  |  |     if (!s->frame) | 
					
						
							|  |  |  |         return AVERROR(ENOMEM); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     avctx->channel_layout = channel_mask; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |  * @brief Decode the subframe length. | 
					
						
							|  |  |  |  * @param s      context | 
					
						
							|  |  |  |  * @param offset sample offset in the frame | 
					
						
							|  |  |  |  * @return decoded subframe length on success, < 0 in case of an error | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | static int decode_subframe_length(WmallDecodeCtx *s, int offset) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int frame_len_ratio, subframe_len, len; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* no need to read from the bitstream when only one length is possible */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     if (offset == s->samples_per_frame - s->min_samples_per_subframe) | 
					
						
							|  |  |  |         return s->min_samples_per_subframe; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     len             = av_log2(s->max_num_subframes - 1) + 1; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     frame_len_ratio = get_bits(&s->gb, len); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     subframe_len    = s->min_samples_per_subframe * (frame_len_ratio + 1); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* sanity check the length */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     if (subframe_len < s->min_samples_per_subframe || | 
					
						
							|  |  |  |         subframe_len > s->samples_per_frame) { | 
					
						
							|  |  |  |         av_log(s->avctx, AV_LOG_ERROR, "broken frame: subframe_len %i\n", | 
					
						
							|  |  |  |                subframe_len); | 
					
						
							|  |  |  |         return AVERROR_INVALIDDATA; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return subframe_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |  * @brief Decode how the data in the frame is split into subframes. | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |  *       Every WMA frame contains the encoded data for a fixed number of | 
					
						
							|  |  |  |  *       samples per channel. The data for every channel might be split | 
					
						
							|  |  |  |  *       into several subframes. This function will reconstruct the list of | 
					
						
							|  |  |  |  *       subframes for every channel. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *       If the subframes are not evenly split, the algorithm estimates the | 
					
						
							|  |  |  |  *       channels with the lowest number of total samples. | 
					
						
							|  |  |  |  *       Afterwards, for each of these channels a bit is read from the | 
					
						
							|  |  |  |  *       bitstream that indicates if the channel contains a subframe with the | 
					
						
							|  |  |  |  *       next subframe size that is going to be read from the bitstream or not. | 
					
						
							|  |  |  |  *       If a channel contains such a subframe, the subframe size gets added to | 
					
						
							|  |  |  |  *       the channel's subframe list. | 
					
						
							|  |  |  |  *       The algorithm repeats these steps until the frame is properly divided | 
					
						
							|  |  |  |  *       between the individual channels. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |  * @param s context | 
					
						
							|  |  |  |  * @return 0 on success, < 0 in case of an error | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | static int decode_tilehdr(WmallDecodeCtx *s) | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     uint16_t num_samples[WMALL_MAX_CHANNELS] = { 0 }; /* sum of samples for all currently known subframes of a channel */ | 
					
						
							|  |  |  |     uint8_t  contains_subframe[WMALL_MAX_CHANNELS];   /* flag indicating if a channel contains the current subframe */ | 
					
						
							|  |  |  |     int channels_for_cur_subframe = s->num_channels;  /* number of channels that contain the current subframe */ | 
					
						
							|  |  |  |     int fixed_channel_layout = 0;                     /* flag indicating that all channels use the same subfra2me offsets and sizes */ | 
					
						
							|  |  |  |     int min_channel_len = 0;                          /* smallest sum of samples (channels with this length will be processed first) */ | 
					
						
							|  |  |  |     int c, tile_aligned; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* reset tiling information */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     for (c = 0; c < s->num_channels; c++) | 
					
						
							|  |  |  |         s->channel[c].num_subframes = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     tile_aligned = get_bits1(&s->gb); | 
					
						
							|  |  |  |     if (s->max_num_subframes == 1 || tile_aligned) | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         fixed_channel_layout = 1; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* loop until the frame data is split between the subframes */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     do { | 
					
						
							| 
									
										
										
										
											2012-03-21 15:43:03 -07:00
										 |  |  |         int subframe_len, in_use = 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* check which channels contain the subframe */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         for (c = 0; c < s->num_channels; c++) { | 
					
						
							|  |  |  |             if (num_samples[c] == min_channel_len) { | 
					
						
							|  |  |  |                 if (fixed_channel_layout || channels_for_cur_subframe == 1 || | 
					
						
							| 
									
										
										
										
											2012-01-20 01:52:14 +06:00
										 |  |  |                    (min_channel_len == s->samples_per_frame - s->min_samples_per_subframe)) { | 
					
						
							| 
									
										
										
										
											2013-12-16 12:48:56 +01:00
										 |  |  |                     contains_subframe[c] = 1; | 
					
						
							| 
									
										
										
										
											2012-01-20 01:52:14 +06:00
										 |  |  |                 } else { | 
					
						
							| 
									
										
										
										
											2013-12-16 12:48:56 +01:00
										 |  |  |                     contains_subframe[c] = get_bits1(&s->gb); | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2013-12-16 12:48:56 +01:00
										 |  |  |                 in_use |= contains_subframe[c]; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |             } else | 
					
						
							|  |  |  |                 contains_subframe[c] = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 15:43:03 -07:00
										 |  |  |         if (!in_use) { | 
					
						
							|  |  |  |             av_log(s->avctx, AV_LOG_ERROR, | 
					
						
							|  |  |  |                    "Found empty subframe\n"); | 
					
						
							|  |  |  |             return AVERROR_INVALIDDATA; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* get subframe length, subframe_len == 0 is not allowed */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         if ((subframe_len = decode_subframe_length(s, min_channel_len)) <= 0) | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |             return AVERROR_INVALIDDATA; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* add subframes to the individual channels and find new min_channel_len */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         min_channel_len += subframe_len; | 
					
						
							|  |  |  |         for (c = 0; c < s->num_channels; c++) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             WmallChannelCtx *chan = &s->channel[c]; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (contains_subframe[c]) { | 
					
						
							|  |  |  |                 if (chan->num_subframes >= MAX_SUBFRAMES) { | 
					
						
							|  |  |  |                     av_log(s->avctx, AV_LOG_ERROR, | 
					
						
							|  |  |  |                            "broken frame: num subframes > 31\n"); | 
					
						
							|  |  |  |                     return AVERROR_INVALIDDATA; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 chan->subframe_len[chan->num_subframes] = subframe_len; | 
					
						
							|  |  |  |                 num_samples[c] += subframe_len; | 
					
						
							|  |  |  |                 ++chan->num_subframes; | 
					
						
							|  |  |  |                 if (num_samples[c] > s->samples_per_frame) { | 
					
						
							|  |  |  |                     av_log(s->avctx, AV_LOG_ERROR, "broken frame: " | 
					
						
							| 
									
										
										
										
											2014-03-13 12:13:33 +01:00
										 |  |  |                            "channel len(%"PRIu16") > samples_per_frame(%"PRIu16")\n", | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |                            num_samples[c], s->samples_per_frame); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |                     return AVERROR_INVALIDDATA; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } else if (num_samples[c] <= min_channel_len) { | 
					
						
							|  |  |  |                 if (num_samples[c] < min_channel_len) { | 
					
						
							|  |  |  |                     channels_for_cur_subframe = 0; | 
					
						
							|  |  |  |                     min_channel_len = num_samples[c]; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 ++channels_for_cur_subframe; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } while (min_channel_len < s->samples_per_frame); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (c = 0; c < s->num_channels; c++) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         int i, offset = 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         for (i = 0; i < s->channel[c].num_subframes; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             s->channel[c].subframe_offsets[i] = offset; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |             offset += s->channel[c].subframe_len[i]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void decode_ac_filter(WmallDecodeCtx *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int i; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     s->acfilter_order   = get_bits(&s->gb, 4) + 1; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     s->acfilter_scaling = get_bits(&s->gb, 4); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     for (i = 0; i < s->acfilter_order; i++) | 
					
						
							| 
									
										
										
										
											2016-01-03 01:19:23 +01:00
										 |  |  |         s->acfilter_coeffs[i] = get_bitsz(&s->gb, s->acfilter_scaling) + 1; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void decode_mclms(WmallDecodeCtx *s) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     s->mclms_order   = (get_bits(&s->gb, 4) + 1) * 2; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     s->mclms_scaling = get_bits(&s->gb, 4); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     if (get_bits1(&s->gb)) { | 
					
						
							|  |  |  |         int i, send_coef_bits; | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         int cbits = av_log2(s->mclms_scaling + 1); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         if (1 << cbits < s->mclms_scaling + 1) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             cbits++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 01:19:23 +01:00
										 |  |  |         send_coef_bits = get_bitsz(&s->gb, cbits) + 2; | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         for (i = 0; i < s->mclms_order * s->num_channels * s->num_channels; i++) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             s->mclms_coeffs[i] = get_bits(&s->gb, send_coef_bits); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         for (i = 0; i < s->num_channels; i++) { | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             int c; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             for (c = 0; c < i; c++) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |                 s->mclms_coeffs_cur[i * s->num_channels + c] = get_bits(&s->gb, send_coef_bits); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 12:40:59 -07:00
										 |  |  | static int decode_cdlms(WmallDecodeCtx *s) | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     int c, i; | 
					
						
							|  |  |  |     int cdlms_send_coef = get_bits1(&s->gb); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     for (c = 0; c < s->num_channels; c++) { | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         s->cdlms_ttl[c] = get_bits(&s->gb, 3) + 1; | 
					
						
							| 
									
										
										
										
											2012-03-21 12:40:59 -07:00
										 |  |  |         for (i = 0; i < s->cdlms_ttl[c]; i++) { | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             s->cdlms[c][i].order = (get_bits(&s->gb, 7) + 1) * 8; | 
					
						
							| 
									
										
										
										
											2012-03-21 12:40:59 -07:00
										 |  |  |             if (s->cdlms[c][i].order > MAX_ORDER) { | 
					
						
							|  |  |  |                 av_log(s->avctx, AV_LOG_ERROR, | 
					
						
							|  |  |  |                        "Order[%d][%d] %d > max (%d), not supported\n", | 
					
						
							|  |  |  |                        c, i, s->cdlms[c][i].order, MAX_ORDER); | 
					
						
							|  |  |  |                 s->cdlms[0][0].order = 0; | 
					
						
							|  |  |  |                 return AVERROR_INVALIDDATA; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2016-05-01 11:18:09 +02:00
										 |  |  |             if(s->cdlms[c][i].order & 8 && s->bits_per_sample == 16) { | 
					
						
							| 
									
										
										
										
											2012-11-24 15:55:49 +01:00
										 |  |  |                 static int warned; | 
					
						
							|  |  |  |                 if(!warned) | 
					
						
							|  |  |  |                     avpriv_request_sample(s->avctx, "CDLMS of order %d", | 
					
						
							|  |  |  |                                           s->cdlms[c][i].order); | 
					
						
							|  |  |  |                 warned = 1; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-03-21 12:40:59 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         for (i = 0; i < s->cdlms_ttl[c]; i++) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             s->cdlms[c][i].scaling = get_bits(&s->gb, 4); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         if (cdlms_send_coef) { | 
					
						
							|  |  |  |             for (i = 0; i < s->cdlms_ttl[c]; i++) { | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |                 int cbits, shift_l, shift_r, j; | 
					
						
							|  |  |  |                 cbits = av_log2(s->cdlms[c][i].order); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |                 if ((1 << cbits) < s->cdlms[c][i].order) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |                     cbits++; | 
					
						
							|  |  |  |                 s->cdlms[c][i].coefsend = get_bits(&s->gb, cbits) + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 cbits = av_log2(s->cdlms[c][i].scaling + 1); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |                 if ((1 << cbits) < s->cdlms[c][i].scaling + 1) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |                     cbits++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 01:19:23 +01:00
										 |  |  |                 s->cdlms[c][i].bitsend = get_bitsz(&s->gb, cbits) + 2; | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |                 shift_l = 32 - s->cdlms[c][i].bitsend; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |                 shift_r = 32 - s->cdlms[c][i].scaling - 2; | 
					
						
							|  |  |  |                 for (j = 0; j < s->cdlms[c][i].coefsend; j++) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |                     s->cdlms[c][i].coefs[j] = | 
					
						
							|  |  |  |                         (get_bits(&s->gb, s->cdlms[c][i].bitsend) << shift_l) >> shift_r; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-11-24 15:55:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (i = 0; i < s->cdlms_ttl[c]; i++) | 
					
						
							|  |  |  |             memset(s->cdlms[c][i].coefs + s->cdlms[c][i].order, | 
					
						
							|  |  |  |                    0, WMALL_COEFF_PAD_SIZE); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-03-21 12:40:59 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int decode_channel_residues(WmallDecodeCtx *s, int ch, int tile_size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int i = 0; | 
					
						
							|  |  |  |     unsigned int ave_mean; | 
					
						
							|  |  |  |     s->transient[ch] = get_bits1(&s->gb); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     if (s->transient[ch]) { | 
					
						
							|  |  |  |         s->transient_pos[ch] = get_bits(&s->gb, av_log2(tile_size)); | 
					
						
							| 
									
										
										
										
											2011-11-12 16:03:54 +06:00
										 |  |  |         if (s->transient_pos[ch]) | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             s->transient[ch] = 0; | 
					
						
							|  |  |  |         s->channel[ch].transient_counter = | 
					
						
							|  |  |  |             FFMAX(s->channel[ch].transient_counter, s->samples_per_frame / 2); | 
					
						
							|  |  |  |     } else if (s->channel[ch].transient_counter) | 
					
						
							|  |  |  |         s->transient[ch] = 1; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     if (s->seekable_tile) { | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         ave_mean = get_bits(&s->gb, s->bits_per_sample); | 
					
						
							|  |  |  |         s->ave_sum[ch] = ave_mean << (s->movave_scaling + 1); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     if (s->seekable_tile) { | 
					
						
							|  |  |  |         if (s->do_inter_ch_decorr) | 
					
						
							| 
									
										
										
										
											2012-04-07 19:33:49 +02:00
										 |  |  |             s->channel_residues[ch][0] = get_sbits_long(&s->gb, s->bits_per_sample + 1); | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2012-04-07 19:33:49 +02:00
										 |  |  |             s->channel_residues[ch][0] = get_sbits_long(&s->gb, s->bits_per_sample); | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         i++; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     for (; i < tile_size; i++) { | 
					
						
							| 
									
										
										
										
											2020-01-09 02:06:36 +01:00
										 |  |  |         int rem, rem_bits; | 
					
						
							|  |  |  |         unsigned quo = 0, residue; | 
					
						
							| 
									
										
										
										
											2012-02-19 21:50:18 +01:00
										 |  |  |         while(get_bits1(&s->gb)) { | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             quo++; | 
					
						
							| 
									
										
										
										
											2012-02-19 21:50:18 +01:00
										 |  |  |             if (get_bits_left(&s->gb) <= 0) | 
					
						
							|  |  |  |                 return -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         if (quo >= 32) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             quo += get_bits_long(&s->gb, get_bits(&s->gb, 5) + 1); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         ave_mean = (s->ave_sum[ch] + (1 << s->movave_scaling)) >> (s->movave_scaling + 1); | 
					
						
							|  |  |  |         if (ave_mean <= 1) | 
					
						
							|  |  |  |             residue = quo; | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             rem_bits = av_ceil_log2(ave_mean); | 
					
						
							| 
									
										
										
										
											2012-04-14 14:51:24 +02:00
										 |  |  |             rem      = get_bits_long(&s->gb, rem_bits); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             residue  = (quo << rem_bits) + rem; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         s->ave_sum[ch] = residue + s->ave_sum[ch] - | 
					
						
							|  |  |  |                          (s->ave_sum[ch] >> s->movave_scaling); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 00:53:12 +08:00
										 |  |  |         residue = (residue >> 1) ^ -(residue & 1); | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         s->channel_residues[ch][i] = residue; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  | static void decode_lpc(WmallDecodeCtx *s) | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     int ch, i, cbits; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     s->lpc_order   = get_bits(&s->gb, 5) + 1; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     s->lpc_scaling = get_bits(&s->gb, 4); | 
					
						
							|  |  |  |     s->lpc_intbits = get_bits(&s->gb, 3) + 1; | 
					
						
							|  |  |  |     cbits = s->lpc_scaling + s->lpc_intbits; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     for (ch = 0; ch < s->num_channels; ch++) | 
					
						
							|  |  |  |         for (i = 0; i < s->lpc_order; i++) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             s->lpc_coefs[ch][i] = get_sbits(&s->gb, cbits); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-05 02:19:35 +06:00
										 |  |  | static void clear_codec_buffers(WmallDecodeCtx *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int ich, ilms; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     memset(s->acfilter_coeffs,     0, sizeof(s->acfilter_coeffs)); | 
					
						
							|  |  |  |     memset(s->acfilter_prevvalues, 0, sizeof(s->acfilter_prevvalues)); | 
					
						
							|  |  |  |     memset(s->lpc_coefs,           0, sizeof(s->lpc_coefs)); | 
					
						
							| 
									
										
										
										
											2011-11-05 02:19:35 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     memset(s->mclms_coeffs,     0, sizeof(s->mclms_coeffs)); | 
					
						
							|  |  |  |     memset(s->mclms_coeffs_cur, 0, sizeof(s->mclms_coeffs_cur)); | 
					
						
							|  |  |  |     memset(s->mclms_prevvalues, 0, sizeof(s->mclms_prevvalues)); | 
					
						
							|  |  |  |     memset(s->mclms_updates,    0, sizeof(s->mclms_updates)); | 
					
						
							| 
									
										
										
										
											2011-11-05 02:19:35 +06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (ich = 0; ich < s->num_channels; ich++) { | 
					
						
							|  |  |  |         for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             memset(s->cdlms[ich][ilms].coefs, 0, | 
					
						
							|  |  |  |                    sizeof(s->cdlms[ich][ilms].coefs)); | 
					
						
							|  |  |  |             memset(s->cdlms[ich][ilms].lms_prevvalues, 0, | 
					
						
							|  |  |  |                    sizeof(s->cdlms[ich][ilms].lms_prevvalues)); | 
					
						
							|  |  |  |             memset(s->cdlms[ich][ilms].lms_updates, 0, | 
					
						
							|  |  |  |                    sizeof(s->cdlms[ich][ilms].lms_updates)); | 
					
						
							| 
									
										
										
										
											2011-11-05 02:19:35 +06:00
										 |  |  |         } | 
					
						
							|  |  |  |         s->ave_sum[ich] = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-12 16:04:35 +06:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |  * @brief Reset filter parameters and transient area at new seekable tile. | 
					
						
							| 
									
										
										
										
											2011-11-12 16:04:35 +06:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-11-06 03:00:49 +06:00
										 |  |  | static void reset_codec(WmallDecodeCtx *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int ich, ilms; | 
					
						
							|  |  |  |     s->mclms_recent = s->mclms_order * s->num_channels; | 
					
						
							| 
									
										
										
										
											2011-11-12 16:03:54 +06:00
										 |  |  |     for (ich = 0; ich < s->num_channels; ich++) { | 
					
						
							| 
									
										
										
										
											2011-11-06 03:00:49 +06:00
										 |  |  |         for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++) | 
					
						
							| 
									
										
										
										
											2011-12-08 03:57:21 +06:00
										 |  |  |             s->cdlms[ich][ilms].recent = s->cdlms[ich][ilms].order; | 
					
						
							| 
									
										
										
										
											2011-11-12 16:03:54 +06:00
										 |  |  |         /* first sample of a seekable subframe is considered as the starting of
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             a transient area which is samples_per_frame samples long */ | 
					
						
							| 
									
										
										
										
											2011-11-12 16:03:54 +06:00
										 |  |  |         s->channel[ich].transient_counter = s->samples_per_frame; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         s->transient[ich]     = 1; | 
					
						
							| 
									
										
										
										
											2011-12-08 03:57:21 +06:00
										 |  |  |         s->transient_pos[ich] = 0; | 
					
						
							| 
									
										
										
										
											2011-11-12 16:03:54 +06:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-11-06 03:00:49 +06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-22 23:48:02 +06:00
										 |  |  | static void mclms_update(WmallDecodeCtx *s, int icoef, int *pred) | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int i, j, ich, pred_error; | 
					
						
							|  |  |  |     int order        = s->mclms_order; | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |     int num_channels = s->num_channels; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int range        = 1 << (s->bits_per_sample - 1); | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (ich = 0; ich < num_channels; ich++) { | 
					
						
							| 
									
										
										
										
											2019-11-20 22:05:40 +01:00
										 |  |  |         pred_error = s->channel_residues[ich][icoef] - (unsigned)pred[ich]; | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |         if (pred_error > 0) { | 
					
						
							|  |  |  |             for (i = 0; i < order * num_channels; i++) | 
					
						
							|  |  |  |                 s->mclms_coeffs[i + ich * order * num_channels] += | 
					
						
							|  |  |  |                     s->mclms_updates[s->mclms_recent + i]; | 
					
						
							| 
									
										
										
										
											2015-02-14 00:51:27 +08:00
										 |  |  |             for (j = 0; j < ich; j++) | 
					
						
							|  |  |  |                 s->mclms_coeffs_cur[ich * num_channels + j] += WMASIGN(s->channel_residues[j][icoef]); | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |         } else if (pred_error < 0) { | 
					
						
							|  |  |  |             for (i = 0; i < order * num_channels; i++) | 
					
						
							|  |  |  |                 s->mclms_coeffs[i + ich * order * num_channels] -= | 
					
						
							|  |  |  |                     s->mclms_updates[s->mclms_recent + i]; | 
					
						
							| 
									
										
										
										
											2015-02-14 00:51:27 +08:00
										 |  |  |             for (j = 0; j < ich; j++) | 
					
						
							|  |  |  |                 s->mclms_coeffs_cur[ich * num_channels + j] -= WMASIGN(s->channel_residues[j][icoef]); | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (ich = num_channels - 1; ich >= 0; ich--) { | 
					
						
							|  |  |  |         s->mclms_recent--; | 
					
						
							| 
									
										
										
										
											2015-02-14 00:53:12 +08:00
										 |  |  |         s->mclms_prevvalues[s->mclms_recent] = av_clip(s->channel_residues[ich][icoef], | 
					
						
							|  |  |  |             -range, range - 1); | 
					
						
							| 
									
										
										
										
											2015-02-14 00:51:27 +08:00
										 |  |  |         s->mclms_updates[s->mclms_recent] = WMASIGN(s->channel_residues[ich][icoef]); | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s->mclms_recent == 0) { | 
					
						
							| 
									
										
										
										
											2011-12-08 22:52:16 +06:00
										 |  |  |         memcpy(&s->mclms_prevvalues[order * num_channels], | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |                s->mclms_prevvalues, | 
					
						
							| 
									
										
										
										
											2016-04-13 20:36:26 +02:00
										 |  |  |                sizeof(int32_t) * order * num_channels); | 
					
						
							| 
									
										
										
										
											2011-12-08 22:52:16 +06:00
										 |  |  |         memcpy(&s->mclms_updates[order * num_channels], | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |                s->mclms_updates, | 
					
						
							| 
									
										
										
										
											2016-04-13 20:36:26 +02:00
										 |  |  |                sizeof(int32_t) * order * num_channels); | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |         s->mclms_recent = num_channels * order; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-12-22 23:48:02 +06:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void mclms_predict(WmallDecodeCtx *s, int icoef, int *pred) | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  | { | 
					
						
							|  |  |  |     int ich, i; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int order        = s->mclms_order; | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |     int num_channels = s->num_channels; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (ich = 0; ich < num_channels; ich++) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         pred[ich] = 0; | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |         if (!s->is_channel_coded[ich]) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         for (i = 0; i < order * num_channels; i++) | 
					
						
							| 
									
										
										
										
											2016-05-16 13:14:31 +02:00
										 |  |  |             pred[ich] += (uint32_t)s->mclms_prevvalues[i + s->mclms_recent] * | 
					
						
							| 
									
										
										
										
											2011-12-22 23:48:02 +06:00
										 |  |  |                          s->mclms_coeffs[i + order * num_channels * ich]; | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |         for (i = 0; i < ich; i++) | 
					
						
							| 
									
										
										
										
											2016-05-16 13:14:31 +02:00
										 |  |  |             pred[ich] += (uint32_t)s->channel_residues[i][icoef] * | 
					
						
							| 
									
										
										
										
											2011-12-22 23:48:02 +06:00
										 |  |  |                          s->mclms_coeffs_cur[i + num_channels * ich]; | 
					
						
							| 
									
										
										
										
											2020-05-23 22:02:56 +02:00
										 |  |  |         pred[ich] += (1U << s->mclms_scaling) >> 1; | 
					
						
							| 
									
										
										
										
											2011-12-22 23:48:02 +06:00
										 |  |  |         pred[ich] >>= s->mclms_scaling; | 
					
						
							| 
									
										
										
										
											2019-11-20 22:05:40 +01:00
										 |  |  |         s->channel_residues[ich][icoef] += (unsigned)pred[ich]; | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void revert_mclms(WmallDecodeCtx *s, int tile_size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int icoef, pred[WMALL_MAX_CHANNELS] = { 0 }; | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |     for (icoef = 0; icoef < tile_size; icoef++) { | 
					
						
							| 
									
										
										
										
											2011-12-22 23:48:02 +06:00
										 |  |  |         mclms_predict(s, icoef, pred); | 
					
						
							|  |  |  |         mclms_update(s, icoef, pred); | 
					
						
							| 
									
										
										
										
											2011-11-30 22:41:12 +06:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-10 13:42:10 +06:00
										 |  |  | static void use_high_update_speed(WmallDecodeCtx *s, int ich) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int ilms, recent, icoef; | 
					
						
							| 
									
										
										
										
											2011-11-22 01:01:30 +06:00
										 |  |  |     for (ilms = s->cdlms_ttl[ich] - 1; ilms >= 0; ilms--) { | 
					
						
							| 
									
										
										
										
											2011-11-10 13:42:10 +06:00
										 |  |  |         recent = s->cdlms[ich][ilms].recent; | 
					
						
							| 
									
										
										
										
											2011-12-09 01:43:34 +06:00
										 |  |  |         if (s->update_speed[ich] == 16) | 
					
						
							|  |  |  |             continue; | 
					
						
							| 
									
										
										
										
											2011-11-10 13:42:10 +06:00
										 |  |  |         if (s->bV3RTM) { | 
					
						
							|  |  |  |             for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) | 
					
						
							|  |  |  |                 s->cdlms[ich][ilms].lms_updates[icoef + recent] *= 2; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) | 
					
						
							|  |  |  |                 s->cdlms[ich][ilms].lms_updates[icoef] *= 2; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-12-09 01:43:34 +06:00
										 |  |  |     s->update_speed[ich] = 16; | 
					
						
							| 
									
										
										
										
											2011-11-10 13:42:10 +06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void use_normal_update_speed(WmallDecodeCtx *s, int ich) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int ilms, recent, icoef; | 
					
						
							| 
									
										
										
										
											2011-11-22 01:01:30 +06:00
										 |  |  |     for (ilms = s->cdlms_ttl[ich] - 1; ilms >= 0; ilms--) { | 
					
						
							| 
									
										
										
										
											2011-11-10 13:42:10 +06:00
										 |  |  |         recent = s->cdlms[ich][ilms].recent; | 
					
						
							| 
									
										
										
										
											2011-12-09 01:43:34 +06:00
										 |  |  |         if (s->update_speed[ich] == 8) | 
					
						
							|  |  |  |             continue; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         if (s->bV3RTM) | 
					
						
							| 
									
										
										
										
											2011-11-10 13:42:10 +06:00
										 |  |  |             for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) | 
					
						
							|  |  |  |                 s->cdlms[ich][ilms].lms_updates[icoef + recent] /= 2; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2011-11-10 13:42:10 +06:00
										 |  |  |             for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) | 
					
						
							|  |  |  |                 s->cdlms[ich][ilms].lms_updates[icoef] /= 2; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-12-09 01:43:34 +06:00
										 |  |  |     s->update_speed[ich] = 8; | 
					
						
							| 
									
										
										
										
											2011-11-10 13:42:10 +06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-01 12:34:29 +02:00
										 |  |  | #define CD_LMS(bits, ROUND) \
 | 
					
						
							|  |  |  | static void lms_update ## bits (WmallDecodeCtx *s, int ich, int ilms, int input) \ | 
					
						
							|  |  |  | { \ | 
					
						
							|  |  |  |     int recent = s->cdlms[ich][ilms].recent; \ | 
					
						
							|  |  |  |     int range  = 1 << s->bits_per_sample - 1; \ | 
					
						
							|  |  |  |     int order  = s->cdlms[ich][ilms].order; \ | 
					
						
							|  |  |  |     int ##bits##_t *prev = (int##bits##_t *)s->cdlms[ich][ilms].lms_prevvalues; \ | 
					
						
							|  |  |  |  \ | 
					
						
							|  |  |  |     if (recent) \ | 
					
						
							|  |  |  |         recent--; \ | 
					
						
							|  |  |  |     else { \ | 
					
						
							|  |  |  |         memcpy(prev + order, prev, (bits/8) * order); \ | 
					
						
							|  |  |  |         memcpy(s->cdlms[ich][ilms].lms_updates + order, \ | 
					
						
							|  |  |  |                s->cdlms[ich][ilms].lms_updates, \ | 
					
						
							|  |  |  |                sizeof(*s->cdlms[ich][ilms].lms_updates) * order); \ | 
					
						
							|  |  |  |         recent = order - 1; \ | 
					
						
							|  |  |  |     } \ | 
					
						
							|  |  |  |  \ | 
					
						
							|  |  |  |     prev[recent] = av_clip(input, -range, range - 1); \ | 
					
						
							|  |  |  |     s->cdlms[ich][ilms].lms_updates[recent] = WMASIGN(input) * s->update_speed[ich]; \ | 
					
						
							|  |  |  |  \ | 
					
						
							|  |  |  |     s->cdlms[ich][ilms].lms_updates[recent + (order >> 4)] >>= 2; \ | 
					
						
							|  |  |  |     s->cdlms[ich][ilms].lms_updates[recent + (order >> 3)] >>= 1; \ | 
					
						
							|  |  |  |     s->cdlms[ich][ilms].recent = recent; \ | 
					
						
							|  |  |  |     memset(s->cdlms[ich][ilms].lms_updates + recent + order, 0, \ | 
					
						
							|  |  |  |            sizeof(s->cdlms[ich][ilms].lms_updates) - \ | 
					
						
							|  |  |  |            sizeof(*s->cdlms[ich][ilms].lms_updates)*(recent+order)); \ | 
					
						
							|  |  |  | } \ | 
					
						
							|  |  |  |  \ | 
					
						
							|  |  |  | static void revert_cdlms ## bits (WmallDecodeCtx *s, int ch, \ | 
					
						
							|  |  |  |                                   int coef_begin, int coef_end) \ | 
					
						
							|  |  |  | { \ | 
					
						
							|  |  |  |     int icoef, pred, ilms, num_lms, residue, input; \ | 
					
						
							|  |  |  |  \ | 
					
						
							|  |  |  |     num_lms = s->cdlms_ttl[ch]; \ | 
					
						
							|  |  |  |     for (ilms = num_lms - 1; ilms >= 0; ilms--) { \ | 
					
						
							|  |  |  |         for (icoef = coef_begin; icoef < coef_end; icoef++) { \ | 
					
						
							|  |  |  |             int##bits##_t *prevvalues = (int##bits##_t *)s->cdlms[ch][ilms].lms_prevvalues; \ | 
					
						
							| 
									
										
										
										
											2019-10-28 00:12:59 +01:00
										 |  |  |             pred = (1 << s->cdlms[ch][ilms].scaling) >> 1; \ | 
					
						
							| 
									
										
										
										
											2016-05-01 12:34:29 +02:00
										 |  |  |             residue = s->channel_residues[ch][icoef]; \ | 
					
						
							|  |  |  |             pred += s->dsp.scalarproduct_and_madd_int## bits (s->cdlms[ch][ilms].coefs, \ | 
					
						
							|  |  |  |                                                         prevvalues + s->cdlms[ch][ilms].recent, \ | 
					
						
							|  |  |  |                                                         s->cdlms[ch][ilms].lms_updates + \ | 
					
						
							|  |  |  |                                                         s->cdlms[ch][ilms].recent, \ | 
					
						
							|  |  |  |                                                         FFALIGN(s->cdlms[ch][ilms].order, ROUND), \ | 
					
						
							|  |  |  |                                                         WMASIGN(residue)); \ | 
					
						
							| 
									
										
										
										
											2020-01-09 02:06:36 +01:00
										 |  |  |             input = residue + (unsigned)(pred >> s->cdlms[ch][ilms].scaling); \ | 
					
						
							| 
									
										
										
										
											2016-05-01 12:34:29 +02:00
										 |  |  |             lms_update ## bits(s, ch, ilms, input); \ | 
					
						
							|  |  |  |             s->channel_residues[ch][icoef] = input; \ | 
					
						
							|  |  |  |         } \ | 
					
						
							|  |  |  |     } \ | 
					
						
							|  |  |  |     if (bits <= 16) emms_c(); \ | 
					
						
							| 
									
										
										
										
											2011-11-12 16:07:12 +06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-01 12:34:29 +02:00
										 |  |  | CD_LMS(16, WMALL_COEFF_PAD_SIZE) | 
					
						
							|  |  |  | CD_LMS(32, 8) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-23 13:17:28 +06:00
										 |  |  | static void revert_inter_ch_decorr(WmallDecodeCtx *s, int tile_size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (s->num_channels != 2) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2012-05-01 16:09:51 +02:00
										 |  |  |     else if (s->is_channel_coded[0] || s->is_channel_coded[1]) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         int icoef; | 
					
						
							| 
									
										
										
										
											2011-12-23 13:17:28 +06:00
										 |  |  |         for (icoef = 0; icoef < tile_size; icoef++) { | 
					
						
							| 
									
										
										
										
											2020-04-26 21:19:13 +02:00
										 |  |  |             s->channel_residues[0][icoef] -= (unsigned)(s->channel_residues[1][icoef] >> 1); | 
					
						
							|  |  |  |             s->channel_residues[1][icoef] += (unsigned) s->channel_residues[0][icoef]; | 
					
						
							| 
									
										
										
										
											2011-12-23 13:17:28 +06:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-11-12 16:07:12 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-23 13:17:28 +06:00
										 |  |  | static void revert_acfilter(WmallDecodeCtx *s, int tile_size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int ich, pred, i, j; | 
					
						
							| 
									
										
										
										
											2015-02-14 00:49:49 +08:00
										 |  |  |     int16_t *filter_coeffs = s->acfilter_coeffs; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int scaling            = s->acfilter_scaling; | 
					
						
							|  |  |  |     int order              = s->acfilter_order; | 
					
						
							| 
									
										
										
										
											2011-11-12 16:07:12 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-23 13:17:28 +06:00
										 |  |  |     for (ich = 0; ich < s->num_channels; ich++) { | 
					
						
							| 
									
										
										
										
											2011-12-31 23:47:43 +06:00
										 |  |  |         int *prevvalues = s->acfilter_prevvalues[ich]; | 
					
						
							|  |  |  |         for (i = 0; i < order; i++) { | 
					
						
							|  |  |  |             pred = 0; | 
					
						
							|  |  |  |             for (j = 0; j < order; j++) { | 
					
						
							|  |  |  |                 if (i <= j) | 
					
						
							| 
									
										
										
										
											2019-11-18 14:22:57 +01:00
										 |  |  |                     pred += (uint32_t)filter_coeffs[j] * prevvalues[j - i]; | 
					
						
							| 
									
										
										
										
											2011-12-31 23:47:43 +06:00
										 |  |  |                 else | 
					
						
							| 
									
										
										
										
											2019-11-18 14:22:57 +01:00
										 |  |  |                     pred += (uint32_t)s->channel_residues[ich][i - j - 1] * filter_coeffs[j]; | 
					
						
							| 
									
										
										
										
											2011-12-31 23:47:43 +06:00
										 |  |  |             } | 
					
						
							|  |  |  |             pred >>= scaling; | 
					
						
							| 
									
										
										
										
											2019-11-18 14:22:57 +01:00
										 |  |  |             s->channel_residues[ich][i] += (unsigned)pred; | 
					
						
							| 
									
										
										
										
											2011-12-31 23:47:43 +06:00
										 |  |  |         } | 
					
						
							|  |  |  |         for (i = order; i < tile_size; i++) { | 
					
						
							|  |  |  |             pred = 0; | 
					
						
							|  |  |  |             for (j = 0; j < order; j++) | 
					
						
							| 
									
										
										
										
											2016-05-16 13:14:31 +02:00
										 |  |  |                 pred += (uint32_t)s->channel_residues[ich][i - j - 1] * filter_coeffs[j]; | 
					
						
							| 
									
										
										
										
											2011-12-23 13:17:28 +06:00
										 |  |  |             pred >>= scaling; | 
					
						
							| 
									
										
										
										
											2019-11-18 14:22:57 +01:00
										 |  |  |             s->channel_residues[ich][i] += (unsigned)pred; | 
					
						
							| 
									
										
										
										
											2011-12-23 13:17:28 +06:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-01-18 19:28:36 +01:00
										 |  |  |         for (j = order - 1; j >= 0; j--) | 
					
						
							|  |  |  |             if (tile_size <= j) { | 
					
						
							|  |  |  |                 prevvalues[j] = prevvalues[j - tile_size]; | 
					
						
							|  |  |  |             }else | 
					
						
							|  |  |  |                 prevvalues[j] = s->channel_residues[ich][tile_size - j - 1]; | 
					
						
							| 
									
										
										
										
											2011-12-23 13:17:28 +06:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-11-12 16:07:12 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | static int decode_subframe(WmallDecodeCtx *s) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int offset        = s->samples_per_frame; | 
					
						
							|  |  |  |     int subframe_len  = s->samples_per_frame; | 
					
						
							|  |  |  |     int total_samples = s->samples_per_frame * s->num_channels; | 
					
						
							| 
									
										
										
										
											2012-03-21 12:40:59 -07:00
										 |  |  |     int i, j, rawpcm_tile, padding_zeroes, res; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s->subframe_offset = get_bits_count(&s->gb); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* reset channel context and find the next block offset and size
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         == the next block of the channel with the smallest number of | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         decoded samples */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     for (i = 0; i < s->num_channels; i++) { | 
					
						
							|  |  |  |         if (offset > s->channel[i].decoded_samples) { | 
					
						
							|  |  |  |             offset = s->channel[i].decoded_samples; | 
					
						
							|  |  |  |             subframe_len = | 
					
						
							|  |  |  |                 s->channel[i].subframe_len[s->channel[i].cur_subframe]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* get a list of all channels that contain the estimated block */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     s->channels_for_cur_subframe = 0; | 
					
						
							|  |  |  |     for (i = 0; i < s->num_channels; i++) { | 
					
						
							|  |  |  |         const int cur_subframe = s->channel[i].cur_subframe; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* subtract already processed samples */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         total_samples -= s->channel[i].decoded_samples; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* and count if there are multiple subframes that match our profile */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         if (offset == s->channel[i].decoded_samples && | 
					
						
							|  |  |  |             subframe_len == s->channel[i].subframe_len[cur_subframe]) { | 
					
						
							|  |  |  |             total_samples -= s->channel[i].subframe_len[cur_subframe]; | 
					
						
							|  |  |  |             s->channel[i].decoded_samples += | 
					
						
							|  |  |  |                 s->channel[i].subframe_len[cur_subframe]; | 
					
						
							|  |  |  |             s->channel_indexes_for_cur_subframe[s->channels_for_cur_subframe] = i; | 
					
						
							|  |  |  |             ++s->channels_for_cur_subframe; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* check if the frame will be complete after processing the
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         estimated block */ | 
					
						
							|  |  |  |     if (!total_samples) | 
					
						
							|  |  |  |         s->parsed_all_subframes = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->seekable_tile = get_bits1(&s->gb); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     if (s->seekable_tile) { | 
					
						
							| 
									
										
										
										
											2011-11-06 03:04:12 +06:00
										 |  |  |         clear_codec_buffers(s); | 
					
						
							| 
									
										
										
										
											2011-11-05 01:24:29 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         s->do_arith_coding    = get_bits1(&s->gb); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         if (s->do_arith_coding) { | 
					
						
							| 
									
										
										
										
											2013-03-13 21:18:34 +01:00
										 |  |  |             avpriv_request_sample(s->avctx, "Arithmetic coding"); | 
					
						
							| 
									
										
										
										
											2012-03-21 12:40:59 -07:00
										 |  |  |             return AVERROR_PATCHWELCOME; | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         s->do_ac_filter       = get_bits1(&s->gb); | 
					
						
							|  |  |  |         s->do_inter_ch_decorr = get_bits1(&s->gb); | 
					
						
							|  |  |  |         s->do_mclms           = get_bits1(&s->gb); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         if (s->do_ac_filter) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             decode_ac_filter(s); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         if (s->do_mclms) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             decode_mclms(s); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 12:40:59 -07:00
										 |  |  |         if ((res = decode_cdlms(s)) < 0) | 
					
						
							|  |  |  |             return res; | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         s->movave_scaling = get_bits(&s->gb, 3); | 
					
						
							|  |  |  |         s->quant_stepsize = get_bits(&s->gb, 8) + 1; | 
					
						
							| 
									
										
										
										
											2011-11-05 01:24:29 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         reset_codec(s); | 
					
						
							| 
									
										
										
										
											2016-04-30 19:48:57 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rawpcm_tile = get_bits1(&s->gb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!rawpcm_tile && !s->cdlms[0][0].order) { | 
					
						
							| 
									
										
										
										
											2012-03-21 12:40:59 -07:00
										 |  |  |         av_log(s->avctx, AV_LOG_DEBUG, | 
					
						
							|  |  |  |                "Waiting for seekable tile\n"); | 
					
						
							| 
									
										
										
										
											2013-08-08 18:48:43 +02:00
										 |  |  |         av_frame_unref(s->frame); | 
					
						
							| 
									
										
										
										
											2012-03-21 12:40:59 -07:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     for (i = 0; i < s->num_channels; i++) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         s->is_channel_coded[i] = 1; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     if (!rawpcm_tile) { | 
					
						
							|  |  |  |         for (i = 0; i < s->num_channels; i++) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             s->is_channel_coded[i] = get_bits1(&s->gb); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         if (s->bV3RTM) { | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             // LPC
 | 
					
						
							|  |  |  |             s->do_lpc = get_bits1(&s->gb); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             if (s->do_lpc) { | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |                 decode_lpc(s); | 
					
						
							| 
									
										
										
										
											2013-03-13 21:17:05 +01:00
										 |  |  |                 avpriv_request_sample(s->avctx, "Expect wrong output since " | 
					
						
							|  |  |  |                                       "inverse LPC filter"); | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         } else | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |             s->do_lpc = 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     if (get_bits1(&s->gb)) | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         padding_zeroes = get_bits(&s->gb, 5); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         padding_zeroes = 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     if (rawpcm_tile) { | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         int bits = s->bits_per_sample - padding_zeroes; | 
					
						
							| 
									
										
										
										
											2012-04-13 07:40:53 -07:00
										 |  |  |         if (bits <= 0) { | 
					
						
							|  |  |  |             av_log(s->avctx, AV_LOG_ERROR, | 
					
						
							|  |  |  |                    "Invalid number of padding bits in raw PCM tile\n"); | 
					
						
							|  |  |  |             return AVERROR_INVALIDDATA; | 
					
						
							| 
									
										
										
										
											2012-04-07 19:34:32 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-03-16 08:57:36 +00:00
										 |  |  |         ff_dlog(s->avctx, "RAWPCM %d bits per sample. " | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |                 "total %d bits, remain=%d\n", bits, | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |                 bits * s->num_channels * subframe_len, get_bits_count(&s->gb)); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         for (i = 0; i < s->num_channels; i++) | 
					
						
							|  |  |  |             for (j = 0; j < subframe_len; j++) | 
					
						
							| 
									
										
										
										
											2016-04-30 19:48:57 +02:00
										 |  |  |                 s->channel_residues[i][j] = get_sbits_long(&s->gb, bits); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2019-11-18 12:49:25 +01:00
										 |  |  |         if (s->bits_per_sample < padding_zeroes) | 
					
						
							|  |  |  |             return AVERROR_INVALIDDATA; | 
					
						
							| 
									
										
										
										
											2016-04-30 19:48:57 +02:00
										 |  |  |         for (i = 0; i < s->num_channels; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             if (s->is_channel_coded[i]) { | 
					
						
							|  |  |  |                 decode_channel_residues(s, i, subframe_len); | 
					
						
							|  |  |  |                 if (s->seekable_tile) | 
					
						
							|  |  |  |                     use_high_update_speed(s, i); | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     use_normal_update_speed(s, i); | 
					
						
							| 
									
										
										
										
											2016-05-01 12:34:29 +02:00
										 |  |  |                 if (s->bits_per_sample > 16) | 
					
						
							|  |  |  |                     revert_cdlms32(s, i, 0, subframe_len); | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     revert_cdlms16(s, i, 0, subframe_len); | 
					
						
							| 
									
										
										
										
											2012-05-01 16:09:51 +02:00
										 |  |  |             } else { | 
					
						
							|  |  |  |                 memset(s->channel_residues[i], 0, sizeof(**s->channel_residues) * subframe_len); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2016-04-30 19:48:57 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (s->do_mclms) | 
					
						
							|  |  |  |             revert_mclms(s, subframe_len); | 
					
						
							|  |  |  |         if (s->do_inter_ch_decorr) | 
					
						
							|  |  |  |             revert_inter_ch_decorr(s, subframe_len); | 
					
						
							|  |  |  |         if (s->do_ac_filter) | 
					
						
							|  |  |  |             revert_acfilter(s, subframe_len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Dequantize */ | 
					
						
							|  |  |  |         if (s->quant_stepsize != 1) | 
					
						
							|  |  |  |             for (i = 0; i < s->num_channels; i++) | 
					
						
							|  |  |  |                 for (j = 0; j < subframe_len; j++) | 
					
						
							| 
									
										
										
										
											2019-11-29 22:45:07 +01:00
										 |  |  |                     s->channel_residues[i][j] *= (unsigned)s->quant_stepsize; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-12-23 13:21:33 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* Write to proper output buffer depending on bit-depth */ | 
					
						
							| 
									
										
										
										
											2012-03-21 15:02:19 -07:00
										 |  |  |     for (i = 0; i < s->channels_for_cur_subframe; i++) { | 
					
						
							|  |  |  |         int c = s->channel_indexes_for_cur_subframe[i]; | 
					
						
							|  |  |  |         int subframe_len = s->channel[c].subframe_len[s->channel[c].cur_subframe]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (j = 0; j < subframe_len; j++) { | 
					
						
							|  |  |  |             if (s->bits_per_sample == 16) { | 
					
						
							| 
									
										
										
										
											2019-10-28 00:12:59 +01:00
										 |  |  |                 *s->samples_16[c]++ = (int16_t) s->channel_residues[c][j] * (1 << padding_zeroes); | 
					
						
							| 
									
										
										
										
											2012-03-21 15:02:19 -07:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2020-01-18 19:55:23 +01:00
										 |  |  |                 *s->samples_32[c]++ = s->channel_residues[c][j] * (256U << padding_zeroes); | 
					
						
							| 
									
										
										
										
											2012-03-21 15:02:19 -07:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2012-01-03 01:49:00 +06:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-03-21 15:02:19 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* handled one subframe */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     for (i = 0; i < s->channels_for_cur_subframe; i++) { | 
					
						
							|  |  |  |         int c = s->channel_indexes_for_cur_subframe[i]; | 
					
						
							|  |  |  |         if (s->channel[c].cur_subframe >= s->channel[c].num_subframes) { | 
					
						
							|  |  |  |             av_log(s->avctx, AV_LOG_ERROR, "broken subframe\n"); | 
					
						
							|  |  |  |             return AVERROR_INVALIDDATA; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         ++s->channel[c].cur_subframe; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |  * @brief Decode one WMA frame. | 
					
						
							|  |  |  |  * @param s codec context | 
					
						
							|  |  |  |  * @return 0 if the trailer bit indicates that this is the last frame, | 
					
						
							|  |  |  |  *         1 if there are additional frames | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | static int decode_frame(WmallDecodeCtx *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     GetBitContext* gb = &s->gb; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     int more_frames = 0, len = 0, i, ret; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-08 18:48:43 +02:00
										 |  |  |     s->frame->nb_samples = s->samples_per_frame; | 
					
						
							|  |  |  |     if ((ret = ff_get_buffer(s->avctx, s->frame, 0)) < 0) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* return an error if no frame could be decoded at all */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         s->packet_loss = 1; | 
					
						
							| 
									
										
										
										
											2015-07-03 00:02:44 +02:00
										 |  |  |         s->frame->nb_samples = 0; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-03-21 15:02:19 -07:00
										 |  |  |     for (i = 0; i < s->num_channels; i++) { | 
					
						
							| 
									
										
										
										
											2013-08-08 18:48:43 +02:00
										 |  |  |         s->samples_16[i] = (int16_t *)s->frame->extended_data[i]; | 
					
						
							|  |  |  |         s->samples_32[i] = (int32_t *)s->frame->extended_data[i]; | 
					
						
							| 
									
										
										
										
											2012-03-21 15:02:19 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* get frame length */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     if (s->len_prefix) | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         len = get_bits(gb, s->log2_frame_size); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* decode tile information */ | 
					
						
							| 
									
										
										
										
											2014-01-11 01:58:36 +01:00
										 |  |  |     if ((ret = decode_tilehdr(s))) { | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         s->packet_loss = 1; | 
					
						
							| 
									
										
										
										
											2014-01-11 01:59:20 +01:00
										 |  |  |         av_frame_unref(s->frame); | 
					
						
							| 
									
										
										
										
											2014-01-11 01:58:36 +01:00
										 |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* read drc info */ | 
					
						
							|  |  |  |     if (s->dynamic_range_compression) | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         s->drc_gain = get_bits(gb, 8); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* no idea what these are for, might be the number of samples
 | 
					
						
							|  |  |  |        that need to be skipped at the beginning or end of a stream */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     if (get_bits1(gb)) { | 
					
						
							| 
									
										
										
										
											2012-04-19 14:48:16 +02:00
										 |  |  |         int av_unused skip; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* usually true for the first frame */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         if (get_bits1(gb)) { | 
					
						
							|  |  |  |             skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); | 
					
						
							| 
									
										
										
										
											2015-03-16 08:57:36 +00:00
										 |  |  |             ff_dlog(s->avctx, "start skip: %i\n", skip); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* sometimes true for the last frame */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         if (get_bits1(gb)) { | 
					
						
							|  |  |  |             skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); | 
					
						
							| 
									
										
										
										
											2015-03-16 08:57:36 +00:00
										 |  |  |             ff_dlog(s->avctx, "end skip: %i\n", skip); | 
					
						
							| 
									
										
										
										
											2016-04-10 21:33:56 +02:00
										 |  |  |             s->frame->nb_samples -= skip; | 
					
						
							|  |  |  |             if (s->frame->nb_samples <= 0) | 
					
						
							|  |  |  |                 return AVERROR_INVALIDDATA; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* reset subframe states */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     s->parsed_all_subframes = 0; | 
					
						
							|  |  |  |     for (i = 0; i < s->num_channels; i++) { | 
					
						
							|  |  |  |         s->channel[i].decoded_samples = 0; | 
					
						
							|  |  |  |         s->channel[i].cur_subframe    = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* decode all subframes */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     while (!s->parsed_all_subframes) { | 
					
						
							| 
									
										
										
										
											2014-01-11 02:04:01 +01:00
										 |  |  |         int decoded_samples = s->channel[0].decoded_samples; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         if (decode_subframe(s) < 0) { | 
					
						
							|  |  |  |             s->packet_loss = 1; | 
					
						
							| 
									
										
										
										
											2014-01-11 02:04:01 +01:00
										 |  |  |             if (s->frame->nb_samples) | 
					
						
							|  |  |  |                 s->frame->nb_samples = decoded_samples; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 08:57:36 +00:00
										 |  |  |     ff_dlog(s->avctx, "Frame done\n"); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 00:53:12 +08:00
										 |  |  |     s->skip_frame = 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (s->len_prefix) { | 
					
						
							|  |  |  |         if (len != (get_bits_count(gb) - s->frame_offset) + 2) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             /* FIXME: not sure if this is always an error */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |             av_log(s->avctx, AV_LOG_ERROR, | 
					
						
							| 
									
										
										
										
											2014-03-13 12:13:33 +01:00
										 |  |  |                    "frame[%"PRIu32"] would have to skip %i bits\n", | 
					
						
							|  |  |  |                    s->frame_num, | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |                    len - (get_bits_count(gb) - s->frame_offset) - 1); | 
					
						
							|  |  |  |             s->packet_loss = 1; | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* skip the rest of the frame data */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         skip_bits_long(gb, len - (get_bits_count(gb) - s->frame_offset) - 1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* decode trailer bit */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     more_frames = get_bits1(gb); | 
					
						
							|  |  |  |     ++s->frame_num; | 
					
						
							|  |  |  |     return more_frames; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |  * @brief Calculate remaining input buffer length. | 
					
						
							|  |  |  |  * @param s  codec context | 
					
						
							|  |  |  |  * @param gb bitstream reader context | 
					
						
							|  |  |  |  * @return remaining size in bits | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | static int remaining_bits(WmallDecodeCtx *s, GetBitContext *gb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return s->buf_bit_size - get_bits_count(gb); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |  * @brief Fill the bit reservoir with a (partial) frame. | 
					
						
							|  |  |  |  * @param s      codec context | 
					
						
							|  |  |  |  * @param gb     bitstream reader context | 
					
						
							|  |  |  |  * @param len    length of the partial frame | 
					
						
							|  |  |  |  * @param append decides whether to reset the buffer or not | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | static void save_bits(WmallDecodeCtx *s, GetBitContext* gb, int len, | 
					
						
							|  |  |  |                       int append) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int buflen; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     PutBitContext tmp; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     /* when the frame data does not need to be concatenated, the input buffer
 | 
					
						
							|  |  |  |         is reset and additional bits from the previous frame are copied | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         and skipped later so that a fast byte copy is possible */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!append) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         s->frame_offset   = get_bits_count(gb) & 7; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         s->num_saved_bits = s->frame_offset; | 
					
						
							| 
									
										
										
										
											2016-04-13 20:21:07 +02:00
										 |  |  |         init_put_bits(&s->pb, s->frame_data, s->max_frame_size); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     buflen = (s->num_saved_bits + len + 8) >> 3; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 20:21:07 +02:00
										 |  |  |     if (len <= 0 || buflen > s->max_frame_size) { | 
					
						
							| 
									
										
										
										
											2013-03-13 21:17:05 +01:00
										 |  |  |         avpriv_request_sample(s->avctx, "Too small input buffer"); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         s->packet_loss = 1; | 
					
						
							| 
									
										
										
										
											2018-03-11 00:13:57 +01:00
										 |  |  |         s->num_saved_bits = 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->num_saved_bits += len; | 
					
						
							|  |  |  |     if (!append) { | 
					
						
							|  |  |  |         avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |                          s->num_saved_bits); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         int align = 8 - (get_bits_count(gb) & 7); | 
					
						
							|  |  |  |         align = FFMIN(align, len); | 
					
						
							|  |  |  |         put_bits(&s->pb, align, get_bits(gb, align)); | 
					
						
							|  |  |  |         len -= align; | 
					
						
							|  |  |  |         avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     skip_bits_long(gb, len); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |     tmp = s->pb; | 
					
						
							|  |  |  |     flush_put_bits(&tmp); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     init_get_bits(&s->gb, s->frame_data, s->num_saved_bits); | 
					
						
							|  |  |  |     skip_bits(&s->gb, s->frame_offset); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  | static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, | 
					
						
							|  |  |  |                          AVPacket* avpkt) | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     WmallDecodeCtx *s = avctx->priv_data; | 
					
						
							|  |  |  |     GetBitContext* gb  = &s->pgb; | 
					
						
							|  |  |  |     const uint8_t* buf = avpkt->data; | 
					
						
							|  |  |  |     int buf_size       = avpkt->size; | 
					
						
							| 
									
										
										
										
											2012-04-13 14:00:20 -07:00
										 |  |  |     int num_bits_prev_frame, packet_sequence_number, spliced_packet; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-08 18:48:43 +02:00
										 |  |  |     s->frame->nb_samples = 0; | 
					
						
							| 
									
										
										
										
											2012-04-21 12:37:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-10 21:33:56 +02:00
										 |  |  |     if (!buf_size && s->num_saved_bits > get_bits_count(&s->gb)) { | 
					
						
							|  |  |  |         s->packet_done = 0; | 
					
						
							|  |  |  |         if (!decode_frame(s)) | 
					
						
							|  |  |  |             s->num_saved_bits = 0; | 
					
						
							|  |  |  |     } else if (s->packet_done || s->packet_loss) { | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         s->packet_done = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-25 01:09:59 +02:00
										 |  |  |         if (!buf_size) | 
					
						
							|  |  |  |             return 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 20:21:07 +02:00
										 |  |  |         s->next_packet_start = buf_size - FFMIN(avctx->block_align, buf_size); | 
					
						
							|  |  |  |         buf_size             = FFMIN(avctx->block_align, buf_size); | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         s->buf_bit_size      = buf_size << 3; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* parse packet header */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         init_get_bits(gb, buf, s->buf_bit_size); | 
					
						
							| 
									
										
										
										
											2012-04-13 14:00:22 -07:00
										 |  |  |         packet_sequence_number = get_bits(gb, 4); | 
					
						
							| 
									
										
										
										
											2016-04-27 13:45:23 -04:00
										 |  |  |         skip_bits(gb, 1);   // Skip seekable_frame_in_packet, currently unused
 | 
					
						
							| 
									
										
										
										
											2012-04-13 14:00:22 -07:00
										 |  |  |         spliced_packet = get_bits1(gb); | 
					
						
							| 
									
										
										
										
											2012-04-13 14:00:21 -07:00
										 |  |  |         if (spliced_packet) | 
					
						
							| 
									
										
										
										
											2013-03-13 21:18:34 +01:00
										 |  |  |             avpriv_request_sample(avctx, "Bitstream splicing"); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* get number of bits that need to be added to the previous frame */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         num_bits_prev_frame = get_bits(gb, s->log2_frame_size); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* check for packet loss */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         if (!s->packet_loss && | 
					
						
							|  |  |  |             ((s->packet_sequence_number + 1) & 0xF) != packet_sequence_number) { | 
					
						
							|  |  |  |             s->packet_loss = 1; | 
					
						
							| 
									
										
										
										
											2014-03-13 12:13:33 +01:00
										 |  |  |             av_log(avctx, AV_LOG_ERROR, | 
					
						
							|  |  |  |                    "Packet loss detected! seq %"PRIx8" vs %x\n", | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |                    s->packet_sequence_number, packet_sequence_number); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         s->packet_sequence_number = packet_sequence_number; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (num_bits_prev_frame > 0) { | 
					
						
							|  |  |  |             int remaining_packet_bits = s->buf_bit_size - get_bits_count(gb); | 
					
						
							|  |  |  |             if (num_bits_prev_frame >= remaining_packet_bits) { | 
					
						
							|  |  |  |                 num_bits_prev_frame = remaining_packet_bits; | 
					
						
							|  |  |  |                 s->packet_done = 1; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             /* Append the previous frame data to the remaining data from the
 | 
					
						
							|  |  |  |              * previous packet to create a full frame. */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |             save_bits(s, gb, num_bits_prev_frame, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             /* decode the cross packet frame if it is valid */ | 
					
						
							| 
									
										
										
										
											2012-04-30 08:56:35 -07:00
										 |  |  |             if (num_bits_prev_frame < remaining_packet_bits && !s->packet_loss) | 
					
						
							| 
									
										
										
										
											2012-05-02 08:43:36 -07:00
										 |  |  |                 decode_frame(s); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         } else if (s->num_saved_bits - s->frame_offset) { | 
					
						
							| 
									
										
										
										
											2015-03-16 08:57:36 +00:00
										 |  |  |             ff_dlog(avctx, "ignoring %x previously saved bits\n", | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |                     s->num_saved_bits - s->frame_offset); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (s->packet_loss) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             /* Reset number of saved bits so that the decoder does not start
 | 
					
						
							|  |  |  |              * to decode incomplete frames in the s->len_prefix == 0 case. */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |             s->num_saved_bits = 0; | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             s->packet_loss    = 0; | 
					
						
							| 
									
										
										
										
											2016-04-13 20:21:07 +02:00
										 |  |  |             init_put_bits(&s->pb, s->frame_data, s->max_frame_size); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         int frame_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3; | 
					
						
							|  |  |  |         init_get_bits(gb, avpkt->data, s->buf_bit_size); | 
					
						
							|  |  |  |         skip_bits(gb, s->packet_offset); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (s->len_prefix && remaining_bits(s, gb) > s->log2_frame_size && | 
					
						
							|  |  |  |             (frame_size = show_bits(gb, s->log2_frame_size)) && | 
					
						
							|  |  |  |             frame_size <= remaining_bits(s, gb)) { | 
					
						
							|  |  |  |             save_bits(s, gb, frame_size, 0); | 
					
						
							| 
									
										
										
										
											2018-03-25 01:51:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (!s->packet_loss) | 
					
						
							|  |  |  |                 s->packet_done = !decode_frame(s); | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         } else if (!s->len_prefix | 
					
						
							|  |  |  |                    && s->num_saved_bits > get_bits_count(&s->gb)) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |             /* when the frames do not have a length prefix, we don't know the
 | 
					
						
							|  |  |  |              * compressed length of the individual frames however, we know what | 
					
						
							|  |  |  |              * part of a new packet belongs to the previous frame therefore we | 
					
						
							|  |  |  |              * save the incoming packet first, then we append the "previous | 
					
						
							|  |  |  |              * frame" data from the next packet so that we get a buffer that | 
					
						
							|  |  |  |              * only contains full frames */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |             s->packet_done = !decode_frame(s); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             s->packet_done = 1; | 
					
						
							| 
									
										
										
										
											2011-11-30 15:21:46 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 20:30:34 +02:00
										 |  |  |     if (remaining_bits(s, gb) < 0) { | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "Overread %d\n", -remaining_bits(s, gb)); | 
					
						
							|  |  |  |         s->packet_loss = 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     if (s->packet_done && !s->packet_loss && | 
					
						
							|  |  |  |         remaining_bits(s, gb) > 0) { | 
					
						
							| 
									
										
										
										
											2012-03-01 12:43:00 +00:00
										 |  |  |         /* save the rest of the data so that it can be decoded
 | 
					
						
							|  |  |  |          * with the next packet */ | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |         save_bits(s, gb, remaining_bits(s, gb), 0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-08 18:48:43 +02:00
										 |  |  |     *got_frame_ptr   = s->frame->nb_samples > 0; | 
					
						
							|  |  |  |     av_frame_move_ref(data, s->frame); | 
					
						
							| 
									
										
										
										
											2013-03-12 03:20:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  |     s->packet_offset = get_bits_count(gb) & 7; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-10 21:33:56 +02:00
										 |  |  |     return (s->packet_loss) ? AVERROR_INVALIDDATA : buf_size ? get_bits_count(gb) >> 3 : 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-28 07:14:21 -07:00
										 |  |  | static void flush(AVCodecContext *avctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     WmallDecodeCtx *s    = avctx->priv_data; | 
					
						
							|  |  |  |     s->packet_loss       = 1; | 
					
						
							|  |  |  |     s->packet_done       = 0; | 
					
						
							|  |  |  |     s->num_saved_bits    = 0; | 
					
						
							|  |  |  |     s->frame_offset      = 0; | 
					
						
							|  |  |  |     s->next_packet_start = 0; | 
					
						
							|  |  |  |     s->cdlms[0][0].order = 0; | 
					
						
							| 
									
										
										
										
											2013-08-08 18:48:43 +02:00
										 |  |  |     s->frame->nb_samples = 0; | 
					
						
							| 
									
										
										
										
											2016-04-13 20:21:07 +02:00
										 |  |  |     init_put_bits(&s->pb, s->frame_data, s->max_frame_size); | 
					
						
							| 
									
										
										
										
											2012-03-28 07:14:21 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-08 18:48:43 +02:00
										 |  |  | static av_cold int decode_close(AVCodecContext *avctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     WmallDecodeCtx *s = avctx->priv_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     av_frame_free(&s->frame); | 
					
						
							| 
									
										
										
										
											2016-04-13 20:21:07 +02:00
										 |  |  |     av_freep(&s->frame_data); | 
					
						
							| 
									
										
										
										
											2013-08-08 18:48:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | AVCodec ff_wmalossless_decoder = { | 
					
						
							| 
									
										
										
										
											2012-02-01 02:08:23 +01:00
										 |  |  |     .name           = "wmalossless", | 
					
						
							| 
									
										
										
										
											2013-10-03 22:57:53 +02:00
										 |  |  |     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio Lossless"), | 
					
						
							| 
									
										
										
										
											2012-02-01 02:08:23 +01:00
										 |  |  |     .type           = AVMEDIA_TYPE_AUDIO, | 
					
						
							| 
									
										
										
										
											2012-08-05 11:11:04 +02:00
										 |  |  |     .id             = AV_CODEC_ID_WMALOSSLESS, | 
					
						
							| 
									
										
										
										
											2012-02-01 02:08:23 +01:00
										 |  |  |     .priv_data_size = sizeof(WmallDecodeCtx), | 
					
						
							|  |  |  |     .init           = decode_init, | 
					
						
							| 
									
										
										
										
											2013-08-08 18:48:43 +02:00
										 |  |  |     .close          = decode_close, | 
					
						
							| 
									
										
										
										
											2012-02-01 02:08:23 +01:00
										 |  |  |     .decode         = decode_packet, | 
					
						
							| 
									
										
										
										
											2012-03-28 07:14:21 -07:00
										 |  |  |     .flush          = flush, | 
					
						
							| 
									
										
										
										
											2015-07-07 01:41:27 +01:00
										 |  |  |     .capabilities   = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, | 
					
						
							| 
									
										
										
										
											2019-10-30 23:31:51 +01:00
										 |  |  |     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP, | 
					
						
							| 
									
										
										
										
											2012-08-25 19:09:40 -04:00
										 |  |  |     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, | 
					
						
							|  |  |  |                                                       AV_SAMPLE_FMT_S32P, | 
					
						
							|  |  |  |                                                       AV_SAMPLE_FMT_NONE }, | 
					
						
							| 
									
										
										
										
											2011-03-03 09:31:34 +01:00
										 |  |  | }; |