2007-02-27 06:30:40 +00:00
/*
* DCA compatible decoder
* Copyright (C) 2004 Gildas Bazin
* Copyright (C) 2004 Benjamin Zores
* Copyright (C) 2006 Benjamin Larsson
* Copyright (C) 2007 Konstantin Shishkov
*
2011-03-18 17:35:10 +00:00
* This file is part of Libav.
2007-02-27 06:30:40 +00:00
*
2011-03-18 17:35:10 +00:00
* Libav is free software; you can redistribute it and/or
2007-02-27 06:30:40 +00:00
* 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.
*
2011-03-18 17:35:10 +00:00
* Libav is distributed in the hope that it will be useful,
2007-02-27 06:30:40 +00:00
* 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
2011-03-18 17:35:10 +00:00
* License along with Libav; if not, write to the Free Software
2007-02-27 06:30:40 +00:00
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <math.h>
#include <stddef.h>
#include <stdio.h>
2011-01-06 22:34:12 +00:00
#include "libavutil/common.h"
2010-04-12 16:05:10 +00:00
#include "libavutil/intmath.h"
2010-04-12 11:14:48 +00:00
#include "libavutil/intreadwrite.h"
2011-02-07 14:37:08 +01:00
#include "libavutil/audioconvert.h"
2007-02-27 06:30:40 +00:00
#include "avcodec.h"
#include "dsputil.h"
2010-03-06 14:34:46 +00:00
#include "fft.h"
2009-04-13 16:20:26 +00:00
#include "get_bits.h"
2009-04-12 08:35:26 +00:00
#include "put_bits.h"
2007-02-27 06:30:40 +00:00
#include "dcadata.h"
#include "dcahuff.h"
2007-05-03 23:50:24 +00:00
#include "dca.h"
2009-10-28 10:51:51 +00:00
#include "synth_filter.h"
2010-04-12 20:45:25 +00:00
#include "dcadsp.h"
2011-01-30 15:06:46 +00:00
#include "fmtconvert.h"
2007-02-27 06:30:40 +00:00
2011-09-28 21:53:03 +01:00
#if ARCH_ARM
# include "arm/dca.h"
#endif
2007-02-27 06:30:40 +00:00
//#define TRACE
2010-06-22 08:34:51 +00:00
#define DCA_PRIM_CHANNELS_MAX (7)
2007-02-27 06:30:40 +00:00
#define DCA_SUBBANDS (32)
#define DCA_ABITS_MAX (32) /* Should be 28 */
2010-06-20 22:07:32 +00:00
#define DCA_SUBSUBFRAMES_MAX (4)
2010-06-22 08:34:51 +00:00
#define DCA_SUBFRAMES_MAX (16)
2010-06-22 08:32:01 +00:00
#define DCA_BLOCKS_MAX (16)
2007-02-27 06:30:40 +00:00
#define DCA_LFE_MAX (3)
enum DCAMode {
DCA_MONO = 0 ,
DCA_CHANNEL ,
DCA_STEREO ,
DCA_STEREO_SUMDIFF ,
DCA_STEREO_TOTAL ,
DCA_3F ,
DCA_2F1R ,
DCA_3F1R ,
DCA_2F2R ,
DCA_3F2R ,
DCA_4F2R
};
2011-01-06 22:34:12 +00:00
/* these are unconfirmed but should be mostly correct */
enum DCAExSSSpeakerMask {
DCA_EXSS_FRONT_CENTER = 0x0001 ,
DCA_EXSS_FRONT_LEFT_RIGHT = 0x0002 ,
DCA_EXSS_SIDE_REAR_LEFT_RIGHT = 0x0004 ,
DCA_EXSS_LFE = 0x0008 ,
DCA_EXSS_REAR_CENTER = 0x0010 ,
DCA_EXSS_FRONT_HIGH_LEFT_RIGHT = 0x0020 ,
DCA_EXSS_REAR_LEFT_RIGHT = 0x0040 ,
DCA_EXSS_FRONT_HIGH_CENTER = 0x0080 ,
DCA_EXSS_OVERHEAD = 0x0100 ,
DCA_EXSS_CENTER_LEFT_RIGHT = 0x0200 ,
DCA_EXSS_WIDE_LEFT_RIGHT = 0x0400 ,
DCA_EXSS_SIDE_LEFT_RIGHT = 0x0800 ,
DCA_EXSS_LFE2 = 0x1000 ,
DCA_EXSS_SIDE_HIGH_LEFT_RIGHT = 0x2000 ,
DCA_EXSS_REAR_HIGH_CENTER = 0x4000 ,
DCA_EXSS_REAR_HIGH_LEFT_RIGHT = 0x8000 ,
};
enum DCAExtensionMask {
DCA_EXT_CORE = 0x001 , ///< core in core substream
DCA_EXT_XXCH = 0x002 , ///< XXCh channels extension in core substream
DCA_EXT_X96 = 0x004 , ///< 96/24 extension in core substream
DCA_EXT_XCH = 0x008 , ///< XCh channel extension in core substream
DCA_EXT_EXSS_CORE = 0x010 , ///< core in ExSS (extension substream)
DCA_EXT_EXSS_XBR = 0x020 , ///< extended bitrate extension in ExSS
DCA_EXT_EXSS_XXCH = 0x040 , ///< XXCh channels extension in ExSS
DCA_EXT_EXSS_X96 = 0x080 , ///< 96/24 extension in ExSS
DCA_EXT_EXSS_LBR = 0x100 , ///< low bitrate component in ExSS
DCA_EXT_EXSS_XLL = 0x200 , ///< lossless extension in ExSS
};
2011-02-18 19:49:44 +00:00
/* -1 are reserved or unknown */
static const int dca_ext_audio_descr_mask [] = {
DCA_EXT_XCH ,
- 1 ,
DCA_EXT_X96 ,
DCA_EXT_XCH | DCA_EXT_X96 ,
- 1 ,
- 1 ,
DCA_EXT_XXCH ,
- 1 ,
};
/* extensions that reside in core substream */
#define DCA_CORE_EXTS (DCA_EXT_XCH | DCA_EXT_XXCH | DCA_EXT_X96)
2008-11-01 20:27:05 +00:00
/* Tables for mapping dts channel configurations to libavcodec multichannel api.
* Some compromises have been made for special configurations. Most configurations
* are never used so complete accuracy is not needed.
*
* L = left, R = right, C = center, S = surround, F = front, R = rear, T = total, OV = overhead.
2008-11-11 08:46:29 +00:00
* S -> side, when both rear and back are configured move one of them to the side channel
2008-11-01 20:27:05 +00:00
* OV -> center back
2011-02-03 14:26:09 +01:00
* All 2 channel configurations -> AV_CH_LAYOUT_STEREO
2008-11-01 20:27:05 +00:00
*/
static const int64_t dca_core_channel_layout [] = {
2010-11-21 20:06:22 +00:00
AV_CH_FRONT_CENTER , ///< 1, A
AV_CH_LAYOUT_STEREO , ///< 2, A + B (dual mono)
AV_CH_LAYOUT_STEREO , ///< 2, L + R (stereo)
AV_CH_LAYOUT_STEREO , ///< 2, (L+R) + (L-R) (sum-difference)
AV_CH_LAYOUT_STEREO , ///< 2, LT +RT (left and right total)
AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER , ///< 3, C+L+R
AV_CH_LAYOUT_STEREO | AV_CH_BACK_CENTER , ///< 3, L+R+S
2011-02-03 14:26:09 +01:00
AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER | AV_CH_BACK_CENTER , ///< 4, C + L + R+ S
2010-11-21 20:06:22 +00:00
AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT , ///< 4, L + R +SL+ SR
AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT , ///< 5, C + L + R+ SL+SR
AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT | AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER , ///< 6, CL + CR + L + R + SL + SR
AV_CH_LAYOUT_STEREO | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_FRONT_CENTER | AV_CH_BACK_CENTER , ///< 6, C + L + R+ LR + RR + OV
AV_CH_FRONT_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_BACK_CENTER | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT , ///< 6, CF+ CR+LF+ RF+LR + RR
AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT , ///< 7, CL + C + CR + L + R + SL + SR
AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT , ///< 8, CL + CR + L + R + SL1 + SL2+ SR1 + SR2
AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_BACK_CENTER | AV_CH_SIDE_RIGHT , ///< 8, CL + C+ CR + L + R + SL + S+ SR
2008-11-01 20:27:05 +00:00
};
2008-11-15 20:31:03 +00:00
static const int8_t dca_lfe_index [] = {
1 , 2 , 2 , 2 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 1 , 3 , 2 , 3
};
2010-06-22 08:34:02 +00:00
static const int8_t dca_channel_reorder_lfe [][ 9 ] = {
{ 0 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 3 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 4 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 3 , 4 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 4 , 5 , - 1 , - 1 , - 1 , - 1 },
{ 3 , 4 , 0 , 1 , 5 , 6 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 4 , 5 , 6 , - 1 , - 1 , - 1 },
{ 0 , 6 , 4 , 5 , 2 , 3 , - 1 , - 1 , - 1 },
{ 4 , 2 , 5 , 0 , 1 , 6 , 7 , - 1 , - 1 },
{ 5 , 6 , 0 , 1 , 7 , 3 , 8 , 4 , - 1 },
{ 4 , 2 , 5 , 0 , 1 , 6 , 8 , 7 , - 1 },
2008-11-15 20:31:03 +00:00
};
2010-06-22 08:34:02 +00:00
static const int8_t dca_channel_reorder_lfe_xch [][ 9 ] = {
{ 0 , 2 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 3 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 3 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 3 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 3 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 4 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 3 , 4 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 4 , 5 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 4 , 5 , 3 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 5 , 6 , 4 , - 1 , - 1 , - 1 },
{ 3 , 4 , 0 , 1 , 6 , 7 , 5 , - 1 , - 1 },
{ 2 , 0 , 1 , 4 , 5 , 6 , 7 , - 1 , - 1 },
{ 0 , 6 , 4 , 5 , 2 , 3 , 7 , - 1 , - 1 },
{ 4 , 2 , 5 , 0 , 1 , 7 , 8 , 6 , - 1 },
{ 5 , 6 , 0 , 1 , 8 , 3 , 9 , 4 , 7 },
{ 4 , 2 , 5 , 0 , 1 , 6 , 9 , 8 , 7 },
2008-11-15 20:31:03 +00:00
};
2010-06-22 08:34:02 +00:00
static const int8_t dca_channel_reorder_nolfe [][ 9 ] = {
{ 0 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 2 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 3 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 2 , 3 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 3 , 4 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 3 , 0 , 1 , 4 , 5 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 3 , 4 , 5 , - 1 , - 1 , - 1 },
{ 0 , 5 , 3 , 4 , 1 , 2 , - 1 , - 1 , - 1 },
{ 3 , 2 , 4 , 0 , 1 , 5 , 6 , - 1 , - 1 },
{ 4 , 5 , 0 , 1 , 6 , 2 , 7 , 3 , - 1 },
{ 3 , 2 , 4 , 0 , 1 , 5 , 7 , 6 , - 1 },
};
static const int8_t dca_channel_reorder_nolfe_xch [][ 9 ] = {
{ 0 , 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 2 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 2 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 2 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 2 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 3 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 2 , 3 , - 1 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 3 , 4 , - 1 , - 1 , - 1 , - 1 },
{ 0 , 1 , 3 , 4 , 2 , - 1 , - 1 , - 1 , - 1 },
{ 2 , 0 , 1 , 4 , 5 , 3 , - 1 , - 1 , - 1 },
{ 2 , 3 , 0 , 1 , 5 , 6 , 4 , - 1 , - 1 },
{ 2 , 0 , 1 , 3 , 4 , 5 , 6 , - 1 , - 1 },
{ 0 , 5 , 3 , 4 , 1 , 2 , 6 , - 1 , - 1 },
{ 3 , 2 , 4 , 0 , 1 , 6 , 7 , 5 , - 1 },
{ 4 , 5 , 0 , 1 , 7 , 2 , 8 , 3 , 6 },
{ 3 , 2 , 4 , 0 , 1 , 5 , 8 , 7 , 6 },
};
2008-11-01 20:27:05 +00:00
2007-02-27 06:30:40 +00:00
#define DCA_DOLBY 101 /* FIXME */
#define DCA_CHANNEL_BITS 6
#define DCA_CHANNEL_MASK 0x3F
#define DCA_LFE 0x80
#define HEADER_SIZE 14
2008-08-23 13:29:13 +00:00
#define DCA_MAX_FRAME_SIZE 16384
2011-01-06 22:34:12 +00:00
#define DCA_MAX_EXSS_HEADER_SIZE 4096
2007-02-27 06:30:40 +00:00
2011-01-09 23:01:01 +00:00
#define DCA_BUFFER_PADDING_SIZE 1024
2007-02-27 06:30:40 +00:00
/** Bit allocation */
typedef struct {
int offset ; ///< code values offset
int maxbits [ 8 ]; ///< max bits in VLC
int wrap ; ///< wrap for get_vlc2()
VLC vlc [ 8 ]; ///< actual codes
} BitAlloc ;
static BitAlloc dca_bitalloc_index ; ///< indexes for samples VLC select
static BitAlloc dca_tmode ; ///< transition mode VLCs
static BitAlloc dca_scalefactor ; ///< scalefactor VLCs
static BitAlloc dca_smpl_bitalloc [ 11 ]; ///< samples VLCs
2007-05-05 12:18:14 +00:00
static av_always_inline int get_bitalloc ( GetBitContext * gb , BitAlloc * ba , int idx )
2007-02-27 06:30:40 +00:00
{
return get_vlc2 ( gb , ba -> vlc [ idx ]. table , ba -> vlc [ idx ]. bits , ba -> wrap ) + ba -> offset ;
}
typedef struct {
AVCodecContext * avctx ;
/* Frame header */
int frame_type ; ///< type of the current frame
int samples_deficit ; ///< deficit sample count
int crc_present ; ///< crc is present in the bitstream
int sample_blocks ; ///< number of PCM sample blocks
int frame_size ; ///< primary frame byte size
int amode ; ///< audio channels arrangement
int sample_rate ; ///< audio sampling rate
int bit_rate ; ///< transmission bit rate
2008-10-28 14:50:46 +00:00
int bit_rate_index ; ///< transmission bit rate index
2007-02-27 06:30:40 +00:00
int downmix ; ///< embedded downmix enabled
int dynrange ; ///< embedded dynamic range flag
int timestamp ; ///< embedded time stamp flag
int aux_data ; ///< auxiliary data flag
int hdcd ; ///< source material is mastered in HDCD
int ext_descr ; ///< extension audio descriptor flag
int ext_coding ; ///< extended coding flag
int aspf ; ///< audio sync word insertion flag
int lfe ; ///< low frequency effects flag
int predictor_history ; ///< predictor history flag
int header_crc ; ///< header crc check bytes
int multirate_inter ; ///< multirate interpolator switch
int version ; ///< encoder software revision
int copy_history ; ///< copy history
int source_pcm_res ; ///< source pcm resolution
int front_sum ; ///< front sum/difference flag
int surround_sum ; ///< surround sum/difference flag
int dialog_norm ; ///< dialog normalisation parameter
/* Primary audio coding header */
int subframes ; ///< number of subframes
2011-01-18 11:30:33 -05:00
int is_channels_set ; ///< check for if the channel number is already set
2008-03-06 14:22:02 +00:00
int total_channels ; ///< number of channels including extensions
2007-02-27 06:30:40 +00:00
int prim_channels ; ///< number of primary audio channels
int subband_activity [ DCA_PRIM_CHANNELS_MAX ]; ///< subband activity count
int vq_start_subband [ DCA_PRIM_CHANNELS_MAX ]; ///< high frequency vq start subband
int joint_intensity [ DCA_PRIM_CHANNELS_MAX ]; ///< joint intensity coding index
int transient_huffman [ DCA_PRIM_CHANNELS_MAX ]; ///< transient mode code book
int scalefactor_huffman [ DCA_PRIM_CHANNELS_MAX ]; ///< scale factor code book
int bitalloc_huffman [ DCA_PRIM_CHANNELS_MAX ]; ///< bit allocation quantizer select
int quant_index_huffman [ DCA_PRIM_CHANNELS_MAX ][ DCA_ABITS_MAX ]; ///< quantization index codebook select
float scalefactor_adj [ DCA_PRIM_CHANNELS_MAX ][ DCA_ABITS_MAX ]; ///< scale factor adjustment
/* Primary audio coding side information */
2010-06-22 08:34:51 +00:00
int subsubframes [ DCA_SUBFRAMES_MAX ]; ///< number of subsubframes
int partial_samples [ DCA_SUBFRAMES_MAX ]; ///< partial subsubframe samples count
2007-02-27 06:30:40 +00:00
int prediction_mode [ DCA_PRIM_CHANNELS_MAX ][ DCA_SUBBANDS ]; ///< prediction mode (ADPCM used or not)
int prediction_vq [ DCA_PRIM_CHANNELS_MAX ][ DCA_SUBBANDS ]; ///< prediction VQ coefs
int bitalloc [ DCA_PRIM_CHANNELS_MAX ][ DCA_SUBBANDS ]; ///< bit allocation index
int transition_mode [ DCA_PRIM_CHANNELS_MAX ][ DCA_SUBBANDS ]; ///< transition mode (transients)
int scale_factor [ DCA_PRIM_CHANNELS_MAX ][ DCA_SUBBANDS ][ 2 ]; ///< scale factors (2 if transient)
int joint_huff [ DCA_PRIM_CHANNELS_MAX ]; ///< joint subband scale factors codebook
int joint_scale_factor [ DCA_PRIM_CHANNELS_MAX ][ DCA_SUBBANDS ]; ///< joint subband scale factors
int downmix_coef [ DCA_PRIM_CHANNELS_MAX ][ 2 ]; ///< stereo downmix coefficients
int dynrange_coef ; ///< dynamic range coefficient
int high_freq_vq [ DCA_PRIM_CHANNELS_MAX ][ DCA_SUBBANDS ]; ///< VQ encoded high frequency subbands
2010-06-22 08:33:00 +00:00
float lfe_data [ 2 * DCA_LFE_MAX * ( DCA_BLOCKS_MAX + 4 )]; ///< Low frequency effect data
2007-02-27 06:30:40 +00:00
int lfe_scale_factor ;
/* Subband samples history (for ADPCM) */
2011-09-28 21:53:03 +01:00
DECLARE_ALIGNED ( 16 , float , subband_samples_hist )[ DCA_PRIM_CHANNELS_MAX ][ DCA_SUBBANDS ][ 4 ];
2011-04-25 11:39:01 +02:00
DECLARE_ALIGNED ( 32 , float , subband_fir_hist )[ DCA_PRIM_CHANNELS_MAX ][ 512 ];
DECLARE_ALIGNED ( 32 , float , subband_fir_noidea )[ DCA_PRIM_CHANNELS_MAX ][ 32 ];
2008-08-30 10:41:53 +00:00
int hist_index [ DCA_PRIM_CHANNELS_MAX ];
2011-04-25 11:39:01 +02:00
DECLARE_ALIGNED ( 32 , float , raXin )[ 32 ];
2007-02-27 06:30:40 +00:00
int output ; ///< type of output
2008-10-26 09:54:53 +00:00
float scale_bias ; ///< output scale
2007-02-27 06:30:40 +00:00
2011-04-25 11:39:01 +02:00
DECLARE_ALIGNED ( 32 , float , subband_samples )[ DCA_BLOCKS_MAX ][ DCA_PRIM_CHANNELS_MAX ][ DCA_SUBBANDS ][ 8 ];
DECLARE_ALIGNED ( 32 , float , samples )[( DCA_PRIM_CHANNELS_MAX + 1 ) * 256 ];
2010-06-22 08:34:51 +00:00
const float * samples_chanptr [ DCA_PRIM_CHANNELS_MAX + 1 ];
2007-02-27 06:30:40 +00:00
2011-01-09 23:01:01 +00:00
uint8_t dca_buffer [ DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE + DCA_BUFFER_PADDING_SIZE ];
2007-02-27 06:30:40 +00:00
int dca_buffer_size ; ///< how much data is in the dca_buffer
2008-11-15 20:31:03 +00:00
const int8_t * channel_order_tab ; ///< channel reordering table, lfe and non lfe
2007-02-27 06:30:40 +00:00
GetBitContext gb ;
/* Current position in DCA frame */
int current_subframe ;
int current_subsubframe ;
2011-02-18 19:49:44 +00:00
int core_ext_mask ; ///< present extensions in the core substream
2010-07-12 09:00:17 +00:00
2011-02-18 19:49:44 +00:00
/* XCh extension information */
int xch_present ; ///< XCh extension present and valid
int xch_base_channel ; ///< index of first (only) channel containing XCH data
2011-01-06 22:34:12 +00:00
/* ExSS header parser */
int static_fields ; ///< static fields present
int mix_metadata ; ///< mixing metadata present
int num_mix_configs ; ///< number of mix out configurations
int mix_config_num_ch [ 4 ]; ///< number of channels in each mix out configuration
int profile ;
2007-02-27 06:30:40 +00:00
int debug_flag ; ///< used for suppressing repeated error messages output
DSPContext dsp ;
2009-09-20 17:30:20 +00:00
FFTContext imdct ;
2010-04-10 16:27:53 +00:00
SynthFilterContext synth ;
2010-04-12 20:45:25 +00:00
DCADSPContext dcadsp ;
2011-01-30 15:06:46 +00:00
FmtConvertContext fmt_conv ;
2007-02-27 06:30:40 +00:00
} DCAContext ;
2009-04-21 17:37:03 +00:00
static const uint16_t dca_vlc_offs [] = {
0 , 512 , 640 , 768 , 1282 , 1794 , 2436 , 3080 , 3770 , 4454 , 5364 ,
5372 , 5380 , 5388 , 5392 , 5396 , 5412 , 5420 , 5428 , 5460 , 5492 , 5508 ,
5572 , 5604 , 5668 , 5796 , 5860 , 5892 , 6412 , 6668 , 6796 , 7308 , 7564 ,
7820 , 8076 , 8620 , 9132 , 9388 , 9910 , 10166 , 10680 , 11196 , 11726 , 12240 ,
12752 , 13298 , 13810 , 14326 , 14840 , 15500 , 16022 , 16540 , 17158 , 17678 , 18264 ,
18796 , 19352 , 19926 , 20468 , 21472 , 22398 , 23014 , 23622 ,
};
2008-03-21 03:11:20 +00:00
static av_cold void dca_init_vlcs ( void )
2007-02-27 06:30:40 +00:00
{
2008-02-13 09:26:10 +00:00
static int vlcs_initialized = 0 ;
2009-04-21 17:37:03 +00:00
int i , j , c = 14 ;
static VLC_TYPE dca_table [ 23622 ][ 2 ];
2007-02-27 06:30:40 +00:00
2008-02-13 09:26:10 +00:00
if ( vlcs_initialized )
2007-02-27 06:30:40 +00:00
return ;
dca_bitalloc_index . offset = 1 ;
2007-05-24 04:08:48 +00:00
dca_bitalloc_index . wrap = 2 ;
2009-04-21 17:37:03 +00:00
for ( i = 0 ; i < 5 ; i ++ ) {
dca_bitalloc_index . vlc [ i ]. table = & dca_table [ dca_vlc_offs [ i ]];
dca_bitalloc_index . vlc [ i ]. table_allocated = dca_vlc_offs [ i + 1 ] - dca_vlc_offs [ i ];
2007-02-27 06:30:40 +00:00
init_vlc ( & dca_bitalloc_index . vlc [ i ], bitalloc_12_vlc_bits [ i ], 12 ,
bitalloc_12_bits [ i ], 1 , 1 ,
2009-04-21 17:37:03 +00:00
bitalloc_12_codes [ i ], 2 , 2 , INIT_VLC_USE_NEW_STATIC );
}
2007-02-27 06:30:40 +00:00
dca_scalefactor . offset = - 64 ;
dca_scalefactor . wrap = 2 ;
2009-04-21 17:37:03 +00:00
for ( i = 0 ; i < 5 ; i ++ ) {
dca_scalefactor . vlc [ i ]. table = & dca_table [ dca_vlc_offs [ i + 5 ]];
dca_scalefactor . vlc [ i ]. table_allocated = dca_vlc_offs [ i + 6 ] - dca_vlc_offs [ i + 5 ];
2007-02-27 06:30:40 +00:00
init_vlc ( & dca_scalefactor . vlc [ i ], SCALES_VLC_BITS , 129 ,
scales_bits [ i ], 1 , 1 ,
2009-04-21 17:37:03 +00:00
scales_codes [ i ], 2 , 2 , INIT_VLC_USE_NEW_STATIC );
}
2007-02-27 06:30:40 +00:00
dca_tmode . offset = 0 ;
dca_tmode . wrap = 1 ;
2009-04-21 17:37:03 +00:00
for ( i = 0 ; i < 4 ; i ++ ) {
dca_tmode . vlc [ i ]. table = & dca_table [ dca_vlc_offs [ i + 10 ]];
dca_tmode . vlc [ i ]. table_allocated = dca_vlc_offs [ i + 11 ] - dca_vlc_offs [ i + 10 ];
2007-02-27 06:30:40 +00:00
init_vlc ( & dca_tmode . vlc [ i ], tmode_vlc_bits [ i ], 4 ,
tmode_bits [ i ], 1 , 1 ,
2009-04-21 17:37:03 +00:00
tmode_codes [ i ], 2 , 2 , INIT_VLC_USE_NEW_STATIC );
}
2007-02-27 06:30:40 +00:00
2010-06-22 08:35:44 +00:00
for ( i = 0 ; i < 10 ; i ++ )
for ( j = 0 ; j < 7 ; j ++ ){
if ( ! bitalloc_codes [ i ][ j ]) break ;
2007-02-27 06:30:40 +00:00
dca_smpl_bitalloc [ i + 1 ]. offset = bitalloc_offsets [ i ];
dca_smpl_bitalloc [ i + 1 ]. wrap = 1 + ( j > 4 );
2009-04-21 17:37:03 +00:00
dca_smpl_bitalloc [ i + 1 ]. vlc [ j ]. table = & dca_table [ dca_vlc_offs [ c ]];
dca_smpl_bitalloc [ i + 1 ]. vlc [ j ]. table_allocated = dca_vlc_offs [ c + 1 ] - dca_vlc_offs [ c ];
2007-02-27 06:30:40 +00:00
init_vlc ( & dca_smpl_bitalloc [ i + 1 ]. vlc [ j ], bitalloc_maxbits [ i ][ j ],
bitalloc_sizes [ i ],
bitalloc_bits [ i ][ j ], 1 , 1 ,
2009-04-21 17:37:03 +00:00
bitalloc_codes [ i ][ j ], 2 , 2 , INIT_VLC_USE_NEW_STATIC );
c ++ ;
2007-02-27 06:30:40 +00:00
}
2008-02-13 09:26:10 +00:00
vlcs_initialized = 1 ;
2007-02-27 06:30:40 +00:00
}
static inline void get_array ( GetBitContext * gb , int * dst , int len , int bits )
{
while ( len -- )
* dst ++ = get_bits ( gb , bits );
}
2010-06-22 08:34:51 +00:00
static int dca_parse_audio_coding_header ( DCAContext * s , int base_channel )
2007-02-27 06:30:40 +00:00
{
int i , j ;
static const float adj_table [ 4 ] = { 1.0 , 1.1250 , 1.2500 , 1.4375 };
static const int bitlen [ 11 ] = { 0 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 };
static const int thr [ 11 ] = { 0 , 1 , 3 , 3 , 3 , 3 , 7 , 7 , 7 , 7 , 7 };
2010-06-22 08:34:51 +00:00
s -> total_channels = get_bits ( & s -> gb , 3 ) + 1 + base_channel ;
2010-06-22 08:33:00 +00:00
s -> prim_channels = s -> total_channels ;
2010-06-22 08:34:51 +00:00
2010-06-22 08:33:00 +00:00
if ( s -> prim_channels > DCA_PRIM_CHANNELS_MAX )
2010-06-22 08:34:51 +00:00
s -> prim_channels = DCA_PRIM_CHANNELS_MAX ;
2010-06-22 08:33:00 +00:00
2010-06-22 08:34:51 +00:00
for ( i = base_channel ; i < s -> prim_channels ; i ++ ) {
2010-06-22 08:33:00 +00:00
s -> subband_activity [ i ] = get_bits ( & s -> gb , 5 ) + 2 ;
if ( s -> subband_activity [ i ] > DCA_SUBBANDS )
s -> subband_activity [ i ] = DCA_SUBBANDS ;
}
2010-06-22 08:34:51 +00:00
for ( i = base_channel ; i < s -> prim_channels ; i ++ ) {
2010-06-22 08:33:00 +00:00
s -> vq_start_subband [ i ] = get_bits ( & s -> gb , 5 ) + 1 ;
if ( s -> vq_start_subband [ i ] > DCA_SUBBANDS )
s -> vq_start_subband [ i ] = DCA_SUBBANDS ;
}
2010-06-22 08:34:51 +00:00
get_array ( & s -> gb , s -> joint_intensity + base_channel , s -> prim_channels - base_channel , 3 );
get_array ( & s -> gb , s -> transient_huffman + base_channel , s -> prim_channels - base_channel , 2 );
get_array ( & s -> gb , s -> scalefactor_huffman + base_channel , s -> prim_channels - base_channel , 3 );
get_array ( & s -> gb , s -> bitalloc_huffman + base_channel , s -> prim_channels - base_channel , 3 );
2010-06-22 08:33:00 +00:00
/* Get codebooks quantization indexes */
2010-06-22 08:34:51 +00:00
if ( ! base_channel )
memset ( s -> quant_index_huffman , 0 , sizeof ( s -> quant_index_huffman ));
2010-06-22 08:33:00 +00:00
for ( j = 1 ; j < 11 ; j ++ )
2010-06-22 08:34:51 +00:00
for ( i = base_channel ; i < s -> prim_channels ; i ++ )
2010-06-22 08:33:00 +00:00
s -> quant_index_huffman [ i ][ j ] = get_bits ( & s -> gb , bitlen [ j ]);
/* Get scale factor adjustment */
for ( j = 0 ; j < 11 ; j ++ )
2010-06-22 08:34:51 +00:00
for ( i = base_channel ; i < s -> prim_channels ; i ++ )
2010-06-22 08:33:00 +00:00
s -> scalefactor_adj [ i ][ j ] = 1 ;
for ( j = 1 ; j < 11 ; j ++ )
2010-06-22 08:34:51 +00:00
for ( i = base_channel ; i < s -> prim_channels ; i ++ )
2010-06-22 08:33:00 +00:00
if ( s -> quant_index_huffman [ i ][ j ] < thr [ j ])
s -> scalefactor_adj [ i ][ j ] = adj_table [ get_bits ( & s -> gb , 2 )];
if ( s -> crc_present ) {
/* Audio header CRC check */
get_bits ( & s -> gb , 16 );
}
s -> current_subframe = 0 ;
s -> current_subsubframe = 0 ;
#ifdef TRACE
av_log ( s -> avctx , AV_LOG_DEBUG , "subframes: %i \n " , s -> subframes );
av_log ( s -> avctx , AV_LOG_DEBUG , "prim channels: %i \n " , s -> prim_channels );
2010-06-22 08:34:51 +00:00
for ( i = base_channel ; i < s -> prim_channels ; i ++ ){
2010-06-22 08:33:00 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "subband activity: %i \n " , s -> subband_activity [ i ]);
av_log ( s -> avctx , AV_LOG_DEBUG , "vq start subband: %i \n " , s -> vq_start_subband [ i ]);
av_log ( s -> avctx , AV_LOG_DEBUG , "joint intensity: %i \n " , s -> joint_intensity [ i ]);
av_log ( s -> avctx , AV_LOG_DEBUG , "transient mode codebook: %i \n " , s -> transient_huffman [ i ]);
av_log ( s -> avctx , AV_LOG_DEBUG , "scale factor codebook: %i \n " , s -> scalefactor_huffman [ i ]);
av_log ( s -> avctx , AV_LOG_DEBUG , "bit allocation quantizer: %i \n " , s -> bitalloc_huffman [ i ]);
av_log ( s -> avctx , AV_LOG_DEBUG , "quant index huff:" );
for ( j = 0 ; j < 11 ; j ++ )
av_log ( s -> avctx , AV_LOG_DEBUG , " %i" ,
s -> quant_index_huffman [ i ][ j ]);
av_log ( s -> avctx , AV_LOG_DEBUG , " \n " );
av_log ( s -> avctx , AV_LOG_DEBUG , "scalefac adj:" );
for ( j = 0 ; j < 11 ; j ++ )
av_log ( s -> avctx , AV_LOG_DEBUG , " %1.3f" , s -> scalefactor_adj [ i ][ j ]);
av_log ( s -> avctx , AV_LOG_DEBUG , " \n " );
}
#endif
return 0 ;
}
static int dca_parse_frame_header ( DCAContext * s )
{
2007-02-27 06:30:40 +00:00
init_get_bits ( & s -> gb , s -> dca_buffer , s -> dca_buffer_size * 8 );
/* Sync code */
get_bits ( & s -> gb , 32 );
/* Frame header */
s -> frame_type = get_bits ( & s -> gb , 1 );
s -> samples_deficit = get_bits ( & s -> gb , 5 ) + 1 ;
s -> crc_present = get_bits ( & s -> gb , 1 );
s -> sample_blocks = get_bits ( & s -> gb , 7 ) + 1 ;
s -> frame_size = get_bits ( & s -> gb , 14 ) + 1 ;
if ( s -> frame_size < 95 )
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2007-02-27 06:30:40 +00:00
s -> amode = get_bits ( & s -> gb , 6 );
s -> sample_rate = dca_sample_rates [ get_bits ( & s -> gb , 4 )];
if ( ! s -> sample_rate )
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2008-10-28 15:20:52 +00:00
s -> bit_rate_index = get_bits ( & s -> gb , 5 );
2008-10-28 14:50:46 +00:00
s -> bit_rate = dca_bit_rates [ s -> bit_rate_index ];
2007-02-27 06:30:40 +00:00
if ( ! s -> bit_rate )
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2007-02-27 06:30:40 +00:00
s -> downmix = get_bits ( & s -> gb , 1 );
s -> dynrange = get_bits ( & s -> gb , 1 );
s -> timestamp = get_bits ( & s -> gb , 1 );
s -> aux_data = get_bits ( & s -> gb , 1 );
s -> hdcd = get_bits ( & s -> gb , 1 );
s -> ext_descr = get_bits ( & s -> gb , 3 );
s -> ext_coding = get_bits ( & s -> gb , 1 );
s -> aspf = get_bits ( & s -> gb , 1 );
s -> lfe = get_bits ( & s -> gb , 2 );
s -> predictor_history = get_bits ( & s -> gb , 1 );
/* TODO: check CRC */
if ( s -> crc_present )
s -> header_crc = get_bits ( & s -> gb , 16 );
s -> multirate_inter = get_bits ( & s -> gb , 1 );
s -> version = get_bits ( & s -> gb , 4 );
s -> copy_history = get_bits ( & s -> gb , 2 );
s -> source_pcm_res = get_bits ( & s -> gb , 3 );
s -> front_sum = get_bits ( & s -> gb , 1 );
s -> surround_sum = get_bits ( & s -> gb , 1 );
s -> dialog_norm = get_bits ( & s -> gb , 4 );
/* FIXME: channels mixing levels */
2007-05-02 20:31:32 +00:00
s -> output = s -> amode ;
2010-06-22 08:35:44 +00:00
if ( s -> lfe ) s -> output |= DCA_LFE ;
2007-02-27 06:30:40 +00:00
#ifdef TRACE
av_log ( s -> avctx , AV_LOG_DEBUG , "frame type: %i \n " , s -> frame_type );
av_log ( s -> avctx , AV_LOG_DEBUG , "samples deficit: %i \n " , s -> samples_deficit );
av_log ( s -> avctx , AV_LOG_DEBUG , "crc present: %i \n " , s -> crc_present );
av_log ( s -> avctx , AV_LOG_DEBUG , "sample blocks: %i (%i samples) \n " ,
s -> sample_blocks , s -> sample_blocks * 32 );
av_log ( s -> avctx , AV_LOG_DEBUG , "frame size: %i bytes \n " , s -> frame_size );
av_log ( s -> avctx , AV_LOG_DEBUG , "amode: %i (%i channels) \n " ,
s -> amode , dca_channels [ s -> amode ]);
2008-10-26 09:50:15 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "sample rate: %i Hz \n " ,
s -> sample_rate );
av_log ( s -> avctx , AV_LOG_DEBUG , "bit rate: %i bits/s \n " ,
s -> bit_rate );
2007-02-27 06:30:40 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "downmix: %i \n " , s -> downmix );
av_log ( s -> avctx , AV_LOG_DEBUG , "dynrange: %i \n " , s -> dynrange );
av_log ( s -> avctx , AV_LOG_DEBUG , "timestamp: %i \n " , s -> timestamp );
av_log ( s -> avctx , AV_LOG_DEBUG , "aux_data: %i \n " , s -> aux_data );
av_log ( s -> avctx , AV_LOG_DEBUG , "hdcd: %i \n " , s -> hdcd );
av_log ( s -> avctx , AV_LOG_DEBUG , "ext descr: %i \n " , s -> ext_descr );
av_log ( s -> avctx , AV_LOG_DEBUG , "ext coding: %i \n " , s -> ext_coding );
av_log ( s -> avctx , AV_LOG_DEBUG , "aspf: %i \n " , s -> aspf );
av_log ( s -> avctx , AV_LOG_DEBUG , "lfe: %i \n " , s -> lfe );
av_log ( s -> avctx , AV_LOG_DEBUG , "predictor history: %i \n " ,
s -> predictor_history );
av_log ( s -> avctx , AV_LOG_DEBUG , "header crc: %i \n " , s -> header_crc );
av_log ( s -> avctx , AV_LOG_DEBUG , "multirate inter: %i \n " ,
s -> multirate_inter );
av_log ( s -> avctx , AV_LOG_DEBUG , "version number: %i \n " , s -> version );
av_log ( s -> avctx , AV_LOG_DEBUG , "copy history: %i \n " , s -> copy_history );
av_log ( s -> avctx , AV_LOG_DEBUG ,
"source pcm resolution: %i (%i bits/sample) \n " ,
s -> source_pcm_res , dca_bits_per_sample [ s -> source_pcm_res ]);
av_log ( s -> avctx , AV_LOG_DEBUG , "front sum: %i \n " , s -> front_sum );
av_log ( s -> avctx , AV_LOG_DEBUG , "surround sum: %i \n " , s -> surround_sum );
av_log ( s -> avctx , AV_LOG_DEBUG , "dialog norm: %i \n " , s -> dialog_norm );
av_log ( s -> avctx , AV_LOG_DEBUG , " \n " );
#endif
/* Primary audio coding header */
s -> subframes = get_bits ( & s -> gb , 4 ) + 1 ;
2010-06-22 08:34:51 +00:00
return dca_parse_audio_coding_header ( s , 0 );
2007-02-27 06:30:40 +00:00
}
2007-04-24 17:31:39 +00:00
static inline int get_scale ( GetBitContext * gb , int level , int value )
2007-02-27 06:30:40 +00:00
{
if ( level < 5 ) {
/* huffman encoded */
2007-04-24 17:31:39 +00:00
value += get_bitalloc ( gb , & dca_scalefactor , level );
2010-06-22 08:35:44 +00:00
} else if ( level < 8 )
2007-02-27 06:30:40 +00:00
value = get_bits ( gb , level + 1 );
return value ;
}
2010-06-22 08:34:51 +00:00
static int dca_subframe_header ( DCAContext * s , int base_channel , int block_index )
2007-02-27 06:30:40 +00:00
{
/* Primary audio coding side information */
int j , k ;
2011-01-09 23:01:01 +00:00
if ( get_bits_left ( & s -> gb ) < 0 )
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2011-01-09 23:01:01 +00:00
2010-06-22 08:34:51 +00:00
if ( ! base_channel ) {
s -> subsubframes [ s -> current_subframe ] = get_bits ( & s -> gb , 2 ) + 1 ;
s -> partial_samples [ s -> current_subframe ] = get_bits ( & s -> gb , 3 );
}
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
for ( k = 0 ; k < s -> subband_activity [ j ]; k ++ )
s -> prediction_mode [ j ][ k ] = get_bits ( & s -> gb , 1 );
}
/* Get prediction codebook */
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
for ( k = 0 ; k < s -> subband_activity [ j ]; k ++ ) {
if ( s -> prediction_mode [ j ][ k ] > 0 ) {
/* (Prediction coefficient VQ address) */
s -> prediction_vq [ j ][ k ] = get_bits ( & s -> gb , 12 );
}
}
}
/* Bit allocation index */
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
for ( k = 0 ; k < s -> vq_start_subband [ j ]; k ++ ) {
if ( s -> bitalloc_huffman [ j ] == 6 )
s -> bitalloc [ j ][ k ] = get_bits ( & s -> gb , 5 );
else if ( s -> bitalloc_huffman [ j ] == 5 )
s -> bitalloc [ j ][ k ] = get_bits ( & s -> gb , 4 );
2008-03-06 14:22:02 +00:00
else if ( s -> bitalloc_huffman [ j ] == 7 ) {
av_log ( s -> avctx , AV_LOG_ERROR ,
"Invalid bit allocation index \n " );
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2008-03-06 14:22:02 +00:00
} else {
2007-02-27 06:30:40 +00:00
s -> bitalloc [ j ][ k ] =
2007-04-24 17:31:39 +00:00
get_bitalloc ( & s -> gb , & dca_bitalloc_index , s -> bitalloc_huffman [ j ]);
2007-02-27 06:30:40 +00:00
}
if ( s -> bitalloc [ j ][ k ] > 26 ) {
// av_log(s->avctx,AV_LOG_DEBUG,"bitalloc index [%i][%i] too big (%i)\n",
// j, k, s->bitalloc[j][k]);
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2007-02-27 06:30:40 +00:00
}
}
}
/* Transition mode */
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
for ( k = 0 ; k < s -> subband_activity [ j ]; k ++ ) {
s -> transition_mode [ j ][ k ] = 0 ;
2010-06-22 08:34:51 +00:00
if ( s -> subsubframes [ s -> current_subframe ] > 1 &&
2007-02-27 06:30:40 +00:00
k < s -> vq_start_subband [ j ] && s -> bitalloc [ j ][ k ] > 0 ) {
s -> transition_mode [ j ][ k ] =
get_bitalloc ( & s -> gb , & dca_tmode , s -> transient_huffman [ j ]);
}
}
}
2011-01-09 23:01:01 +00:00
if ( get_bits_left ( & s -> gb ) < 0 )
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2011-01-09 23:01:01 +00:00
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2008-02-01 01:40:46 +00:00
const uint32_t * scale_table ;
2007-02-27 06:30:40 +00:00
int scale_sum ;
memset ( s -> scale_factor [ j ], 0 , s -> subband_activity [ j ] * sizeof ( s -> scale_factor [ 0 ][ 0 ][ 0 ]) * 2 );
if ( s -> scalefactor_huffman [ j ] == 6 )
2008-02-01 01:40:46 +00:00
scale_table = scale_factor_quant7 ;
2007-02-27 06:30:40 +00:00
else
2008-02-01 01:40:46 +00:00
scale_table = scale_factor_quant6 ;
2007-02-27 06:30:40 +00:00
/* When huffman coded, only the difference is encoded */
scale_sum = 0 ;
for ( k = 0 ; k < s -> subband_activity [ j ]; k ++ ) {
if ( k >= s -> vq_start_subband [ j ] || s -> bitalloc [ j ][ k ] > 0 ) {
2007-04-24 17:31:39 +00:00
scale_sum = get_scale ( & s -> gb , s -> scalefactor_huffman [ j ], scale_sum );
2007-02-27 06:30:40 +00:00
s -> scale_factor [ j ][ k ][ 0 ] = scale_table [ scale_sum ];
}
if ( k < s -> vq_start_subband [ j ] && s -> transition_mode [ j ][ k ]) {
/* Get second scale factor */
2007-04-24 17:31:39 +00:00
scale_sum = get_scale ( & s -> gb , s -> scalefactor_huffman [ j ], scale_sum );
2007-02-27 06:30:40 +00:00
s -> scale_factor [ j ][ k ][ 1 ] = scale_table [ scale_sum ];
}
}
}
/* Joint subband scale factor codebook select */
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
/* Transmitted only if joint subband coding enabled */
if ( s -> joint_intensity [ j ] > 0 )
s -> joint_huff [ j ] = get_bits ( & s -> gb , 3 );
}
2011-01-09 23:01:01 +00:00
if ( get_bits_left ( & s -> gb ) < 0 )
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2011-01-09 23:01:01 +00:00
2007-02-27 06:30:40 +00:00
/* Scale factors for joint subband coding */
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
int source_channel ;
/* Transmitted only if joint subband coding enabled */
if ( s -> joint_intensity [ j ] > 0 ) {
int scale = 0 ;
source_channel = s -> joint_intensity [ j ] - 1 ;
/* When huffman coded, only the difference is encoded
* (is this valid as well for joint scales ???) */
for ( k = s -> subband_activity [ j ]; k < s -> subband_activity [ source_channel ]; k ++ ) {
2007-04-24 17:31:39 +00:00
scale = get_scale ( & s -> gb , s -> joint_huff [ j ], 0 );
2007-02-27 06:30:40 +00:00
scale += 64 ; /* bias */
s -> joint_scale_factor [ j ][ k ] = scale ; /*joint_scale_table[scale]; */
}
2009-10-10 08:49:57 +00:00
if ( ! ( s -> debug_flag & 0x02 )) {
2007-02-27 06:30:40 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG ,
"Joint stereo coding not supported \n " );
s -> debug_flag |= 0x02 ;
}
}
}
/* Stereo downmix coefficients */
2010-06-22 08:34:51 +00:00
if ( ! base_channel && s -> prim_channels > 2 ) {
2010-06-22 08:35:44 +00:00
if ( s -> downmix ) {
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-05-02 20:42:44 +00:00
s -> downmix_coef [ j ][ 0 ] = get_bits ( & s -> gb , 7 );
s -> downmix_coef [ j ][ 1 ] = get_bits ( & s -> gb , 7 );
}
2007-05-02 20:33:32 +00:00
} else {
int am = s -> amode & DCA_CHANNEL_MASK ;
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-05-02 20:33:32 +00:00
s -> downmix_coef [ j ][ 0 ] = dca_default_coeffs [ am ][ j ][ 0 ];
s -> downmix_coef [ j ][ 1 ] = dca_default_coeffs [ am ][ j ][ 1 ];
}
}
2007-02-27 06:30:40 +00:00
}
/* Dynamic range coefficient */
2010-07-31 22:15:59 +00:00
if ( ! base_channel && s -> dynrange )
2007-02-27 06:30:40 +00:00
s -> dynrange_coef = get_bits ( & s -> gb , 8 );
/* Side information CRC check word */
if ( s -> crc_present ) {
get_bits ( & s -> gb , 16 );
}
/*
* Primary audio data arrays
*/
/* VQ encoded high frequency subbands */
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ )
2007-02-27 06:30:40 +00:00
for ( k = s -> vq_start_subband [ j ]; k < s -> subband_activity [ j ]; k ++ )
/* 1 vector -> 32 samples */
s -> high_freq_vq [ j ][ k ] = get_bits ( & s -> gb , 10 );
/* Low frequency effect data */
2010-06-22 08:34:51 +00:00
if ( ! base_channel && s -> lfe ) {
2007-02-27 06:30:40 +00:00
/* LFE samples */
2010-06-22 08:33:00 +00:00
int lfe_samples = 2 * s -> lfe * ( 4 + block_index );
2010-06-22 08:34:51 +00:00
int lfe_end_sample = 2 * s -> lfe * ( 4 + block_index + s -> subsubframes [ s -> current_subframe ]);
2007-02-27 06:30:40 +00:00
float lfe_scale ;
2010-06-22 08:33:00 +00:00
for ( j = lfe_samples ; j < lfe_end_sample ; j ++ ) {
2007-02-27 06:30:40 +00:00
/* Signed 8 bits int */
s -> lfe_data [ j ] = get_sbits ( & s -> gb , 8 );
}
/* Scale factor index */
s -> lfe_scale_factor = scale_factor_quant7 [ get_bits ( & s -> gb , 8 )];
/* Quantization step size * scale factor */
lfe_scale = 0.035 * s -> lfe_scale_factor ;
2010-06-22 08:33:00 +00:00
for ( j = lfe_samples ; j < lfe_end_sample ; j ++ )
2007-02-27 06:30:40 +00:00
s -> lfe_data [ j ] *= lfe_scale ;
}
#ifdef TRACE
2010-06-22 08:34:51 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "subsubframes: %i \n " , s -> subsubframes [ s -> current_subframe ]);
2007-02-27 06:30:40 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "partial samples: %i \n " ,
2010-06-22 08:34:51 +00:00
s -> partial_samples [ s -> current_subframe ]);
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "prediction mode:" );
for ( k = 0 ; k < s -> subband_activity [ j ]; k ++ )
av_log ( s -> avctx , AV_LOG_DEBUG , " %i" , s -> prediction_mode [ j ][ k ]);
av_log ( s -> avctx , AV_LOG_DEBUG , " \n " );
}
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
for ( k = 0 ; k < s -> subband_activity [ j ]; k ++ )
av_log ( s -> avctx , AV_LOG_DEBUG ,
"prediction coefs: %f, %f, %f, %f \n " ,
( float ) adpcm_vb [ s -> prediction_vq [ j ][ k ]][ 0 ] / 8192 ,
( float ) adpcm_vb [ s -> prediction_vq [ j ][ k ]][ 1 ] / 8192 ,
( float ) adpcm_vb [ s -> prediction_vq [ j ][ k ]][ 2 ] / 8192 ,
( float ) adpcm_vb [ s -> prediction_vq [ j ][ k ]][ 3 ] / 8192 );
}
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "bitalloc index: " );
for ( k = 0 ; k < s -> vq_start_subband [ j ]; k ++ )
av_log ( s -> avctx , AV_LOG_DEBUG , "%2.2i " , s -> bitalloc [ j ][ k ]);
av_log ( s -> avctx , AV_LOG_DEBUG , " \n " );
}
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "Transition mode:" );
for ( k = 0 ; k < s -> subband_activity [ j ]; k ++ )
av_log ( s -> avctx , AV_LOG_DEBUG , " %i" , s -> transition_mode [ j ][ k ]);
av_log ( s -> avctx , AV_LOG_DEBUG , " \n " );
}
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "Scale factor:" );
for ( k = 0 ; k < s -> subband_activity [ j ]; k ++ ) {
if ( k >= s -> vq_start_subband [ j ] || s -> bitalloc [ j ][ k ] > 0 )
av_log ( s -> avctx , AV_LOG_DEBUG , " %i" , s -> scale_factor [ j ][ k ][ 0 ]);
if ( k < s -> vq_start_subband [ j ] && s -> transition_mode [ j ][ k ])
av_log ( s -> avctx , AV_LOG_DEBUG , " %i(t)" , s -> scale_factor [ j ][ k ][ 1 ]);
}
av_log ( s -> avctx , AV_LOG_DEBUG , " \n " );
}
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ ) {
2007-02-27 06:30:40 +00:00
if ( s -> joint_intensity [ j ] > 0 ) {
2007-05-24 04:02:47 +00:00
int source_channel = s -> joint_intensity [ j ] - 1 ;
2007-02-27 06:30:40 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "Joint scale factor index: \n " );
for ( k = s -> subband_activity [ j ]; k < s -> subband_activity [ source_channel ]; k ++ )
av_log ( s -> avctx , AV_LOG_DEBUG , " %i" , s -> joint_scale_factor [ j ][ k ]);
av_log ( s -> avctx , AV_LOG_DEBUG , " \n " );
}
}
2010-06-22 08:34:51 +00:00
if ( ! base_channel && s -> prim_channels > 2 && s -> downmix ) {
2007-02-27 06:30:40 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "Downmix coeffs: \n " );
for ( j = 0 ; j < s -> prim_channels ; j ++ ) {
av_log ( s -> avctx , AV_LOG_DEBUG , "Channel 0,%d = %f \n " , j , dca_downmix_coeffs [ s -> downmix_coef [ j ][ 0 ]]);
av_log ( s -> avctx , AV_LOG_DEBUG , "Channel 1,%d = %f \n " , j , dca_downmix_coeffs [ s -> downmix_coef [ j ][ 1 ]]);
}
av_log ( s -> avctx , AV_LOG_DEBUG , " \n " );
}
2010-06-22 08:34:51 +00:00
for ( j = base_channel ; j < s -> prim_channels ; j ++ )
2007-02-27 06:30:40 +00:00
for ( k = s -> vq_start_subband [ j ]; k < s -> subband_activity [ j ]; k ++ )
av_log ( s -> avctx , AV_LOG_DEBUG , "VQ index: %i \n " , s -> high_freq_vq [ j ][ k ]);
2010-06-22 08:34:51 +00:00
if ( ! base_channel && s -> lfe ) {
2010-06-22 08:33:00 +00:00
int lfe_samples = 2 * s -> lfe * ( 4 + block_index );
int lfe_end_sample = 2 * s -> lfe * ( 4 + block_index + s -> subsubframes [ s -> current_subframe ]);
2007-02-27 06:30:40 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , "LFE samples: \n " );
2010-06-22 08:33:00 +00:00
for ( j = lfe_samples ; j < lfe_end_sample ; j ++ )
2007-02-27 06:30:40 +00:00
av_log ( s -> avctx , AV_LOG_DEBUG , " %f" , s -> lfe_data [ j ]);
av_log ( s -> avctx , AV_LOG_DEBUG , " \n " );
}
#endif
return 0 ;
}
static void qmf_32_subbands ( DCAContext * s , int chans ,
float samples_in [ 32 ][ 8 ], float * samples_out ,
2011-01-27 15:20:43 +00:00
float scale )
2007-02-27 06:30:40 +00:00
{
2007-12-02 21:12:43 +00:00
const float * prCoeff ;
2009-10-28 14:40:05 +00:00
int i ;
2007-02-27 06:30:40 +00:00
2010-04-12 11:14:51 +00:00
int sb_act = s -> subband_activity [ chans ];
2008-08-30 10:47:13 +00:00
int subindex ;
2007-02-27 06:30:40 +00:00
2008-08-30 10:47:13 +00:00
scale *= sqrt ( 1 / 8.0 );
2007-02-27 06:30:40 +00:00
/* Select filter */
if ( ! s -> multirate_inter ) /* Non-perfect reconstruction */
2007-12-02 21:12:43 +00:00
prCoeff = fir_32bands_nonperfect ;
2007-02-27 06:30:40 +00:00
else /* Perfect reconstruction */
2007-12-02 21:12:43 +00:00
prCoeff = fir_32bands_perfect ;
2007-02-27 06:30:40 +00:00
2011-09-28 21:00:35 +01:00
for ( i = sb_act ; i < 32 ; i ++ )
s -> raXin [ i ] = 0.0 ;
2007-02-27 06:30:40 +00:00
/* Reconstructed channel sample index */
for ( subindex = 0 ; subindex < 8 ; subindex ++ ) {
/* Load in one sample from each subband and clear inactive subbands */
2010-04-12 11:14:51 +00:00
for ( i = 0 ; i < sb_act ; i ++ ){
2011-10-08 13:49:42 +01:00
unsigned sign = ( i - 1 ) & 2 ;
uint32_t v = AV_RN32A ( & samples_in [ i ][ subindex ]) ^ sign << 30 ;
2010-04-12 11:14:48 +00:00
AV_WN32A ( & s -> raXin [ i ], v );
2008-08-30 10:47:13 +00:00
}
2007-02-27 06:30:40 +00:00
2010-04-10 16:27:53 +00:00
s -> synth . synth_filter_float ( & s -> imdct ,
2009-10-28 10:51:51 +00:00
s -> subband_fir_hist [ chans ], & s -> hist_index [ chans ],
s -> subband_fir_noidea [ chans ], prCoeff ,
2011-01-31 19:26:02 +00:00
samples_out , s -> raXin , scale );
2008-08-30 10:47:13 +00:00
samples_out += 32 ;
2007-02-27 06:30:40 +00:00
}
}
2010-04-12 20:45:25 +00:00
static void lfe_interpolation_fir ( DCAContext * s , int decimation_select ,
2007-02-27 06:30:40 +00:00
int num_deci_sample , float * samples_in ,
2011-01-27 15:20:43 +00:00
float * samples_out , float scale )
2007-02-27 06:30:40 +00:00
{
/* samples_in: An array holding decimated samples.
* Samples in current subframe starts from samples_in[0],
* while samples_in[-1], samples_in[-2], ..., stores samples
* from last subframe as history.
*
* samples_out: An array holding interpolated samples
*/
2010-04-12 20:45:25 +00:00
int decifactor ;
2007-02-27 06:30:40 +00:00
const float * prCoeff ;
int deciindex ;
/* Select decimation filter */
if ( decimation_select == 1 ) {
2010-04-12 11:14:55 +00:00
decifactor = 64 ;
2007-02-27 06:30:40 +00:00
prCoeff = lfe_fir_128 ;
} else {
2010-04-12 11:14:55 +00:00
decifactor = 32 ;
2007-02-27 06:30:40 +00:00
prCoeff = lfe_fir_64 ;
}
/* Interpolation */
for ( deciindex = 0 ; deciindex < num_deci_sample ; deciindex ++ ) {
2010-04-12 20:45:25 +00:00
s -> dcadsp . lfe_fir ( samples_out , samples_in , prCoeff , decifactor ,
2011-01-31 19:26:02 +00:00
scale );
2010-04-12 11:14:55 +00:00
samples_in ++ ;
2010-04-12 20:45:25 +00:00
samples_out += 2 * decifactor ;
2007-02-27 06:30:40 +00:00
}
}
/* downmixing routines */
2007-05-02 20:33:32 +00:00
#define MIX_REAR1(samples, si1, rs, coef) \
2011-01-27 15:20:43 +00:00
samples[i] += samples[si1] * coef[rs][0]; \
samples[i+256] += samples[si1] * coef[rs][1];
2007-02-27 06:30:40 +00:00
2007-05-02 20:33:32 +00:00
#define MIX_REAR2(samples, si1, si2, rs, coef) \
2011-01-27 15:20:43 +00:00
samples[i] += samples[si1] * coef[rs][0] + samples[si2] * coef[rs+1][0]; \
samples[i+256] += samples[si1] * coef[rs][1] + samples[si2] * coef[rs+1][1];
2007-02-27 06:30:40 +00:00
2007-05-02 20:33:32 +00:00
#define MIX_FRONT3(samples, coef) \
2011-01-27 15:20:43 +00:00
t = samples[i+c]; \
u = samples[i+l]; \
v = samples[i+r]; \
samples[i] = t * coef[0][0] + u * coef[1][0] + v * coef[2][0]; \
samples[i+256] = t * coef[0][1] + u * coef[1][1] + v * coef[2][1];
2007-02-27 06:30:40 +00:00
#define DOWNMIX_TO_STEREO(op1, op2) \
2010-06-22 08:35:44 +00:00
for (i = 0; i < 256; i++){ \
2007-02-27 06:30:40 +00:00
op1 \
op2 \
}
2007-05-02 20:33:32 +00:00
static void dca_downmix ( float * samples , int srcfmt ,
2010-07-27 21:45:43 +00:00
int downmix_coef [ DCA_PRIM_CHANNELS_MAX ][ 2 ],
2011-01-27 15:20:43 +00:00
const int8_t * channel_mapping )
2007-02-27 06:30:40 +00:00
{
2010-07-27 21:45:43 +00:00
int c , l , r , sl , sr , s ;
2007-02-27 06:30:40 +00:00
int i ;
2010-07-27 21:45:43 +00:00
float t , u , v ;
2007-05-02 20:33:32 +00:00
float coef [ DCA_PRIM_CHANNELS_MAX ][ 2 ];
2010-06-22 08:35:44 +00:00
for ( i = 0 ; i < DCA_PRIM_CHANNELS_MAX ; i ++ ) {
2007-05-02 20:33:32 +00:00
coef [ i ][ 0 ] = dca_downmix_coeffs [ downmix_coef [ i ][ 0 ]];
coef [ i ][ 1 ] = dca_downmix_coeffs [ downmix_coef [ i ][ 1 ]];
}
2007-02-27 06:30:40 +00:00
switch ( srcfmt ) {
case DCA_MONO :
case DCA_CHANNEL :
case DCA_STEREO_TOTAL :
case DCA_STEREO_SUMDIFF :
case DCA_4F2R :
av_log ( NULL , 0 , "Not implemented! \n " );
break ;
case DCA_STEREO :
break ;
case DCA_3F :
2010-07-27 21:45:43 +00:00
c = channel_mapping [ 0 ] * 256 ;
l = channel_mapping [ 1 ] * 256 ;
r = channel_mapping [ 2 ] * 256 ;
2007-05-02 20:33:32 +00:00
DOWNMIX_TO_STEREO ( MIX_FRONT3 ( samples , coef ),);
2007-02-27 06:30:40 +00:00
break ;
case DCA_2F1R :
2010-07-27 21:45:43 +00:00
s = channel_mapping [ 2 ] * 256 ;
DOWNMIX_TO_STEREO ( MIX_REAR1 ( samples , i + s , 2 , coef ),);
2007-02-27 06:30:40 +00:00
break ;
case DCA_3F1R :
2010-07-27 21:45:43 +00:00
c = channel_mapping [ 0 ] * 256 ;
l = channel_mapping [ 1 ] * 256 ;
r = channel_mapping [ 2 ] * 256 ;
s = channel_mapping [ 3 ] * 256 ;
2007-05-02 20:33:32 +00:00
DOWNMIX_TO_STEREO ( MIX_FRONT3 ( samples , coef ),
2010-07-27 21:45:43 +00:00
MIX_REAR1 ( samples , i + s , 3 , coef ));
2007-02-27 06:30:40 +00:00
break ;
case DCA_2F2R :
2010-07-27 21:45:43 +00:00
sl = channel_mapping [ 2 ] * 256 ;
sr = channel_mapping [ 3 ] * 256 ;
DOWNMIX_TO_STEREO ( MIX_REAR2 ( samples , i + sl , i + sr , 2 , coef ),);
2007-02-27 06:30:40 +00:00
break ;
case DCA_3F2R :
2010-07-27 21:45:43 +00:00
c = channel_mapping [ 0 ] * 256 ;
l = channel_mapping [ 1 ] * 256 ;
r = channel_mapping [ 2 ] * 256 ;
sl = channel_mapping [ 3 ] * 256 ;
sr = channel_mapping [ 4 ] * 256 ;
2007-05-02 20:33:32 +00:00
DOWNMIX_TO_STEREO ( MIX_FRONT3 ( samples , coef ),
2010-07-27 21:45:43 +00:00
MIX_REAR2 ( samples , i + sl , i + sr , 3 , coef ));
2007-02-27 06:30:40 +00:00
break ;
}
}
/* Very compact version of the block code decoder that does not use table
* look-up but is slightly slower */
static int decode_blockcode ( int code , int levels , int * values )
{
int i ;
int offset = ( levels - 1 ) >> 1 ;
for ( i = 0 ; i < 4 ; i ++ ) {
2010-04-12 16:05:10 +00:00
int div = FASTDIV ( code , levels );
values [ i ] = code - offset - div * levels ;
code = div ;
2007-02-27 06:30:40 +00:00
}
if ( code == 0 )
return 0 ;
else {
av_log ( NULL , AV_LOG_ERROR , "ERROR: block code look-up failed \n " );
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2007-02-27 06:30:40 +00:00
}
}
static const uint8_t abits_sizes [ 7 ] = { 7 , 10 , 12 , 13 , 15 , 17 , 19 };
static const uint8_t abits_levels [ 7 ] = { 3 , 5 , 7 , 9 , 13 , 17 , 25 };
2011-09-28 21:53:03 +01:00
#ifndef int8x8_fmul_int32
static inline void int8x8_fmul_int32 ( float * dst , const int8_t * src , int scale )
{
float fscale = scale / 16.0 ;
int i ;
for ( i = 0 ; i < 8 ; i ++ )
dst [ i ] = src [ i ] * fscale ;
}
#endif
2010-06-22 08:34:51 +00:00
static int dca_subsubframe ( DCAContext * s , int base_channel , int block_index )
2007-02-27 06:30:40 +00:00
{
int k , l ;
int subsubframe = s -> current_subsubframe ;
2008-02-01 01:40:46 +00:00
const float * quant_step_table ;
2007-02-27 06:30:40 +00:00
/* FIXME */
2010-06-22 08:32:01 +00:00
float ( * subband_samples )[ DCA_SUBBANDS ][ 8 ] = s -> subband_samples [ block_index ];
2010-04-13 10:15:00 +00:00
LOCAL_ALIGNED_16 ( int , block , [ 8 ]);
2007-02-27 06:30:40 +00:00
/*
* Audio data
*/
/* Select quantization step size table */
2008-10-28 14:50:46 +00:00
if ( s -> bit_rate_index == 0x1f )
2008-02-01 01:40:46 +00:00
quant_step_table = lossless_quant_d ;
2007-02-27 06:30:40 +00:00
else
2008-02-01 01:40:46 +00:00
quant_step_table = lossy_quant_d ;
2007-02-27 06:30:40 +00:00
2010-06-22 08:34:51 +00:00
for ( k = base_channel ; k < s -> prim_channels ; k ++ ) {
2011-01-09 23:01:01 +00:00
if ( get_bits_left ( & s -> gb ) < 0 )
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2011-01-09 23:01:01 +00:00
2007-02-27 06:30:40 +00:00
for ( l = 0 ; l < s -> vq_start_subband [ k ]; l ++ ) {
int m ;
/* Select the mid-tread linear quantizer */
int abits = s -> bitalloc [ k ][ l ];
float quant_step_size = quant_step_table [ abits ];
/*
* Determine quantization index code book and its type
*/
/* Select quantization index code book */
int sel = s -> quant_index_huffman [ k ][ abits ];
/*
* Extract bits from the bit stream
*/
2010-06-22 08:35:44 +00:00
if ( ! abits ){
2007-02-27 06:30:40 +00:00
memset ( subband_samples [ k ][ l ], 0 , 8 * sizeof ( subband_samples [ 0 ][ 0 ][ 0 ]));
2010-04-13 10:15:00 +00:00
} else {
/* Deal with transients */
int sfi = s -> transition_mode [ k ][ l ] && subsubframe >= s -> transition_mode [ k ][ l ];
float rscale = quant_step_size * s -> scale_factor [ k ][ l ][ sfi ] * s -> scalefactor_adj [ k ][ sel ];
2010-06-22 08:35:44 +00:00
if ( abits >= 11 || ! dca_smpl_bitalloc [ abits ]. vlc [ sel ]. table ){
if ( abits <= 7 ){
2010-04-13 10:15:05 +00:00
/* Block code */
int block_code1 , block_code2 , size , levels ;
2007-02-27 06:30:40 +00:00
2010-04-13 10:15:05 +00:00
size = abits_sizes [ abits - 1 ];
levels = abits_levels [ abits - 1 ];
2007-02-27 06:30:40 +00:00
2010-04-13 10:15:05 +00:00
block_code1 = get_bits ( & s -> gb , size );
/* FIXME Should test return value */
decode_blockcode ( block_code1 , levels , block );
block_code2 = get_bits ( & s -> gb , size );
decode_blockcode ( block_code2 , levels , & block [ 4 ]);
} else {
/* no coding */
for ( m = 0 ; m < 8 ; m ++ )
block [ m ] = get_sbits ( & s -> gb , abits - 3 );
}
2007-02-27 06:30:40 +00:00
} else {
2010-04-13 10:15:05 +00:00
/* Huffman coded */
2007-02-27 06:30:40 +00:00
for ( m = 0 ; m < 8 ; m ++ )
2010-04-13 10:15:05 +00:00
block [ m ] = get_bitalloc ( & s -> gb , & dca_smpl_bitalloc [ abits ], sel );
2007-02-27 06:30:40 +00:00
}
2011-01-30 15:06:46 +00:00
s -> fmt_conv . int32_to_float_fmul_scalar ( subband_samples [ k ][ l ],
2010-04-13 10:15:00 +00:00
block , rscale , 8 );
}
2007-02-27 06:30:40 +00:00
/*
* Inverse ADPCM if in prediction mode
*/
if ( s -> prediction_mode [ k ][ l ]) {
int n ;
for ( m = 0 ; m < 8 ; m ++ ) {
for ( n = 1 ; n <= 4 ; n ++ )
if ( m >= n )
subband_samples [ k ][ l ][ m ] +=
( adpcm_vb [ s -> prediction_vq [ k ][ l ]][ n - 1 ] *
subband_samples [ k ][ l ][ m - n ] / 8192 );
else if ( s -> predictor_history )
subband_samples [ k ][ l ][ m ] +=
( adpcm_vb [ s -> prediction_vq [ k ][ l ]][ n - 1 ] *
s -> subband_samples_hist [ k ][ l ][ m - n +
4 ] / 8192 );
}
}
}
/*
* Decode VQ encoded high frequencies
*/
for ( l = s -> vq_start_subband [ k ]; l < s -> subband_activity [ k ]; l ++ ) {
/* 1 vector -> 32 samples but we only need the 8 samples
* for this subsubframe. */
2011-09-28 21:53:03 +01:00
int hfvq = s -> high_freq_vq [ k ][ l ];
2007-02-27 06:30:40 +00:00
if ( ! s -> debug_flag & 0x01 ) {
av_log ( s -> avctx , AV_LOG_DEBUG , "Stream with high frequencies VQ coding \n " );
s -> debug_flag |= 0x01 ;
}
2011-09-28 21:53:03 +01:00
int8x8_fmul_int32 ( subband_samples [ k ][ l ],
& high_freq_vq [ hfvq ][ subsubframe * 8 ],
s -> scale_factor [ k ][ l ][ 0 ]);
2007-02-27 06:30:40 +00:00
}
}
/* Check for DSYNC after subsubframe */
2010-06-22 08:34:51 +00:00
if ( s -> aspf || subsubframe == s -> subsubframes [ s -> current_subframe ] - 1 ) {
2007-02-27 06:30:40 +00:00
if ( 0xFFFF == get_bits ( & s -> gb , 16 )) { /* 0xFFFF */
#ifdef TRACE
av_log ( s -> avctx , AV_LOG_DEBUG , "Got subframe DSYNC \n " );
#endif
} else {
av_log ( s -> avctx , AV_LOG_ERROR , "Didn't get subframe DSYNC \n " );
}
}
/* Backup predictor history for adpcm */
2010-06-22 08:34:51 +00:00
for ( k = base_channel ; k < s -> prim_channels ; k ++ )
2007-02-27 06:30:40 +00:00
for ( l = 0 ; l < s -> vq_start_subband [ k ]; l ++ )
memcpy ( s -> subband_samples_hist [ k ][ l ], & subband_samples [ k ][ l ][ 4 ],
4 * sizeof ( subband_samples [ 0 ][ 0 ][ 0 ]));
2010-06-22 08:33:00 +00:00
return 0 ;
}
static int dca_filter_channels ( DCAContext * s , int block_index )
{
float ( * subband_samples )[ DCA_SUBBANDS ][ 8 ] = s -> subband_samples [ block_index ];
int k ;
2007-02-27 06:30:40 +00:00
/* 32 subbands QMF */
for ( k = 0 ; k < s -> prim_channels ; k ++ ) {
/* static float pcm_to_double[8] =
{32768.0, 32768.0, 524288.0, 524288.0, 0, 8388608.0, 8388608.0};*/
2008-11-15 20:31:03 +00:00
qmf_32_subbands ( s , k , subband_samples [ k ], & s -> samples [ 256 * s -> channel_order_tab [ k ]],
2011-01-27 15:20:43 +00:00
M_SQRT1_2 * s -> scale_bias /*pcm_to_double[s->source_pcm_res] */ );
2007-02-27 06:30:40 +00:00
}
/* Down mixing */
2010-06-22 08:33:00 +00:00
if ( s -> avctx -> request_channels == 2 && s -> prim_channels > 2 ) {
2011-01-27 15:20:43 +00:00
dca_downmix ( s -> samples , s -> amode , s -> downmix_coef , s -> channel_order_tab );
2007-02-27 06:30:40 +00:00
}
/* Generate LFE samples for this subsubframe FIXME!!! */
if ( s -> output & DCA_LFE ) {
2010-04-12 20:45:25 +00:00
lfe_interpolation_fir ( s , s -> lfe , 2 * s -> lfe ,
2010-06-22 08:33:00 +00:00
s -> lfe_data + 2 * s -> lfe * ( block_index + 4 ),
2008-11-15 20:31:03 +00:00
& s -> samples [ 256 * dca_lfe_index [ s -> amode ]],
2011-01-27 15:20:43 +00:00
( 1.0 / 256.0 ) * s -> scale_bias );
2007-02-27 06:30:40 +00:00
/* Outputs 20bits pcm samples */
}
return 0 ;
}
2010-06-22 08:34:51 +00:00
static int dca_subframe_footer ( DCAContext * s , int base_channel )
2007-02-27 06:30:40 +00:00
{
int aux_data_count = 0 , i ;
/*
* Unpack optional information
*/
2010-06-22 08:34:51 +00:00
/* presumably optional information only appears in the core? */
if ( ! base_channel ) {
2010-06-22 08:35:44 +00:00
if ( s -> timestamp )
get_bits ( & s -> gb , 32 );
2007-02-27 06:30:40 +00:00
2010-06-22 08:35:44 +00:00
if ( s -> aux_data )
aux_data_count = get_bits ( & s -> gb , 6 );
2007-02-27 06:30:40 +00:00
2010-06-22 08:35:44 +00:00
for ( i = 0 ; i < aux_data_count ; i ++ )
get_bits ( & s -> gb , 8 );
2007-02-27 06:30:40 +00:00
2010-06-22 08:35:44 +00:00
if ( s -> crc_present && ( s -> downmix || s -> dynrange ))
get_bits ( & s -> gb , 16 );
2010-06-22 08:34:51 +00:00
}
2007-02-27 06:30:40 +00:00
return 0 ;
}
/**
* Decode a dca frame block
*
* @param s pointer to the DCAContext
*/
2010-06-22 08:34:51 +00:00
static int dca_decode_block ( DCAContext * s , int base_channel , int block_index )
2007-02-27 06:30:40 +00:00
{
2011-10-27 11:41:02 -04:00
int ret ;
2007-02-27 06:30:40 +00:00
/* Sanity check */
if ( s -> current_subframe >= s -> subframes ) {
av_log ( s -> avctx , AV_LOG_DEBUG , "check failed: %i>%i" ,
s -> current_subframe , s -> subframes );
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2007-02-27 06:30:40 +00:00
}
if ( ! s -> current_subsubframe ) {
#ifdef TRACE
av_log ( s -> avctx , AV_LOG_DEBUG , "DSYNC dca_subframe_header \n " );
#endif
/* Read subframe header */
2011-10-27 11:41:02 -04:00
if (( ret = dca_subframe_header ( s , base_channel , block_index )))
return ret ;
2007-02-27 06:30:40 +00:00
}
/* Read subsubframe */
#ifdef TRACE
av_log ( s -> avctx , AV_LOG_DEBUG , "DSYNC dca_subsubframe \n " );
#endif
2011-10-27 11:41:02 -04:00
if (( ret = dca_subsubframe ( s , base_channel , block_index )))
return ret ;
2007-02-27 06:30:40 +00:00
/* Update state */
s -> current_subsubframe ++ ;
2010-06-22 08:34:51 +00:00
if ( s -> current_subsubframe >= s -> subsubframes [ s -> current_subframe ]) {
2007-02-27 06:30:40 +00:00
s -> current_subsubframe = 0 ;
s -> current_subframe ++ ;
}
if ( s -> current_subframe >= s -> subframes ) {
#ifdef TRACE
av_log ( s -> avctx , AV_LOG_DEBUG , "DSYNC dca_subframe_footer \n " );
#endif
/* Read subframe footer */
2011-10-27 11:41:02 -04:00
if (( ret = dca_subframe_footer ( s , base_channel )))
return ret ;
2007-02-27 06:30:40 +00:00
}
return 0 ;
}
/**
* Convert bitstream to one representation based on sync marker
*/
2008-02-01 01:40:46 +00:00
static int dca_convert_bitstream ( const uint8_t * src , int src_size , uint8_t * dst ,
2007-02-27 06:30:40 +00:00
int max_size )
{
uint32_t mrk ;
int i , tmp ;
2008-02-01 01:40:46 +00:00
const uint16_t * ssrc = ( const uint16_t * ) src ;
uint16_t * sdst = ( uint16_t * ) dst ;
2007-02-27 06:30:40 +00:00
PutBitContext pb ;
2010-06-22 08:35:44 +00:00
if (( unsigned ) src_size > ( unsigned ) max_size ) {
2011-06-30 20:53:59 +02:00
// av_log(NULL, AV_LOG_ERROR, "Input frame size larger than DCA_MAX_FRAME_SIZE!\n");
2008-11-29 10:06:37 +00:00
// return -1;
src_size = max_size ;
2007-05-18 10:06:07 +00:00
}
2007-04-27 12:41:55 +00:00
2007-02-27 06:30:40 +00:00
mrk = AV_RB32 ( src );
switch ( mrk ) {
case DCA_MARKER_RAW_BE :
2008-08-23 13:35:12 +00:00
memcpy ( dst , src , src_size );
return src_size ;
2007-02-27 06:30:40 +00:00
case DCA_MARKER_RAW_LE :
2008-08-23 13:35:12 +00:00
for ( i = 0 ; i < ( src_size + 1 ) >> 1 ; i ++ )
2010-07-10 22:12:30 +00:00
* sdst ++ = av_bswap16 ( * ssrc ++ );
2008-08-23 13:35:12 +00:00
return src_size ;
2007-02-27 06:30:40 +00:00
case DCA_MARKER_14B_BE :
case DCA_MARKER_14B_LE :
init_put_bits ( & pb , dst , max_size );
for ( i = 0 ; i < ( src_size + 1 ) >> 1 ; i ++ , src += 2 ) {
tmp = (( mrk == DCA_MARKER_14B_BE ) ? AV_RB16 ( src ) : AV_RL16 ( src )) & 0x3FFF ;
put_bits ( & pb , 14 , tmp );
}
flush_put_bits ( & pb );
return ( put_bits_count ( & pb ) + 7 ) >> 3 ;
default :
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2007-02-27 06:30:40 +00:00
}
}
2011-01-06 22:34:12 +00:00
/**
* Return the number of channels in an ExSS speaker mask (HD)
*/
static int dca_exss_mask2count ( int mask )
{
/* count bits that mean speaker pairs twice */
return av_popcount ( mask )
+ av_popcount ( mask & (
DCA_EXSS_CENTER_LEFT_RIGHT
| DCA_EXSS_FRONT_LEFT_RIGHT
| DCA_EXSS_FRONT_HIGH_LEFT_RIGHT
| DCA_EXSS_WIDE_LEFT_RIGHT
| DCA_EXSS_SIDE_LEFT_RIGHT
| DCA_EXSS_SIDE_HIGH_LEFT_RIGHT
| DCA_EXSS_SIDE_REAR_LEFT_RIGHT
| DCA_EXSS_REAR_LEFT_RIGHT
| DCA_EXSS_REAR_HIGH_LEFT_RIGHT
));
}
/**
* Skip mixing coefficients of a single mix out configuration (HD)
*/
static void dca_exss_skip_mix_coeffs ( GetBitContext * gb , int channels , int out_ch )
{
2011-02-01 04:12:26 +00:00
int i ;
for ( i = 0 ; i < channels ; i ++ ) {
2011-01-06 22:34:12 +00:00
int mix_map_mask = get_bits ( gb , out_ch );
int num_coeffs = av_popcount ( mix_map_mask );
skip_bits_long ( gb , num_coeffs * 6 );
}
}
/**
* Parse extension substream asset header (HD)
*/
static int dca_exss_parse_asset_header ( DCAContext * s )
{
int header_pos = get_bits_count ( & s -> gb );
int header_size ;
int channels ;
int embedded_stereo = 0 ;
int embedded_6ch = 0 ;
int drc_code_present ;
int extensions_mask ;
int i , j ;
if ( get_bits_left ( & s -> gb ) < 16 )
return - 1 ;
/* We will parse just enough to get to the extensions bitmask with which
* we can set the profile value. */
header_size = get_bits ( & s -> gb , 9 ) + 1 ;
skip_bits ( & s -> gb , 3 ); // asset index
if ( s -> static_fields ) {
if ( get_bits1 ( & s -> gb ))
skip_bits ( & s -> gb , 4 ); // asset type descriptor
if ( get_bits1 ( & s -> gb ))
skip_bits_long ( & s -> gb , 24 ); // language descriptor
if ( get_bits1 ( & s -> gb )) {
/* How can one fit 1024 bytes of text here if the maximum value
* for the asset header size field above was 512 bytes? */
int text_length = get_bits ( & s -> gb , 10 ) + 1 ;
if ( get_bits_left ( & s -> gb ) < text_length * 8 )
return - 1 ;
skip_bits_long ( & s -> gb , text_length * 8 ); // info text
}
skip_bits ( & s -> gb , 5 ); // bit resolution - 1
skip_bits ( & s -> gb , 4 ); // max sample rate code
channels = get_bits ( & s -> gb , 8 ) + 1 ;
if ( get_bits1 ( & s -> gb )) { // 1-to-1 channels to speakers
int spkr_remap_sets ;
int spkr_mask_size = 16 ;
int num_spkrs [ 7 ];
if ( channels > 2 )
embedded_stereo = get_bits1 ( & s -> gb );
if ( channels > 6 )
embedded_6ch = get_bits1 ( & s -> gb );
if ( get_bits1 ( & s -> gb )) {
spkr_mask_size = ( get_bits ( & s -> gb , 2 ) + 1 ) << 2 ;
skip_bits ( & s -> gb , spkr_mask_size ); // spkr activity mask
}
spkr_remap_sets = get_bits ( & s -> gb , 3 );
for ( i = 0 ; i < spkr_remap_sets ; i ++ ) {
/* std layout mask for each remap set */
num_spkrs [ i ] = dca_exss_mask2count ( get_bits ( & s -> gb , spkr_mask_size ));
}
for ( i = 0 ; i < spkr_remap_sets ; i ++ ) {
int num_dec_ch_remaps = get_bits ( & s -> gb , 5 ) + 1 ;
if ( get_bits_left ( & s -> gb ) < 0 )
return - 1 ;
for ( j = 0 ; j < num_spkrs [ i ]; j ++ ) {
int remap_dec_ch_mask = get_bits_long ( & s -> gb , num_dec_ch_remaps );
int num_dec_ch = av_popcount ( remap_dec_ch_mask );
skip_bits_long ( & s -> gb , num_dec_ch * 5 ); // remap codes
}
}
} else {
skip_bits ( & s -> gb , 3 ); // representation type
}
}
drc_code_present = get_bits1 ( & s -> gb );
if ( drc_code_present )
get_bits ( & s -> gb , 8 ); // drc code
if ( get_bits1 ( & s -> gb ))
skip_bits ( & s -> gb , 5 ); // dialog normalization code
if ( drc_code_present && embedded_stereo )
get_bits ( & s -> gb , 8 ); // drc stereo code
if ( s -> mix_metadata && get_bits1 ( & s -> gb )) {
skip_bits ( & s -> gb , 1 ); // external mix
skip_bits ( & s -> gb , 6 ); // post mix gain code
if ( get_bits ( & s -> gb , 2 ) != 3 ) // mixer drc code
skip_bits ( & s -> gb , 3 ); // drc limit
else
skip_bits ( & s -> gb , 8 ); // custom drc code
if ( get_bits1 ( & s -> gb )) // channel specific scaling
for ( i = 0 ; i < s -> num_mix_configs ; i ++ )
skip_bits_long ( & s -> gb , s -> mix_config_num_ch [ i ] * 6 ); // scale codes
else
skip_bits_long ( & s -> gb , s -> num_mix_configs * 6 ); // scale codes
for ( i = 0 ; i < s -> num_mix_configs ; i ++ ) {
if ( get_bits_left ( & s -> gb ) < 0 )
return - 1 ;
dca_exss_skip_mix_coeffs ( & s -> gb , channels , s -> mix_config_num_ch [ i ]);
if ( embedded_6ch )
dca_exss_skip_mix_coeffs ( & s -> gb , 6 , s -> mix_config_num_ch [ i ]);
if ( embedded_stereo )
dca_exss_skip_mix_coeffs ( & s -> gb , 2 , s -> mix_config_num_ch [ i ]);
}
}
switch ( get_bits ( & s -> gb , 2 )) {
case 0 : extensions_mask = get_bits ( & s -> gb , 12 ); break ;
case 1 : extensions_mask = DCA_EXT_EXSS_XLL ; break ;
case 2 : extensions_mask = DCA_EXT_EXSS_LBR ; break ;
case 3 : extensions_mask = 0 ; /* aux coding */ break ;
}
/* not parsed further, we were only interested in the extensions mask */
if ( get_bits_left ( & s -> gb ) < 0 )
return - 1 ;
if ( get_bits_count ( & s -> gb ) - header_pos > header_size * 8 ) {
av_log ( s -> avctx , AV_LOG_WARNING , "Asset header size mismatch. \n " );
return - 1 ;
}
skip_bits_long ( & s -> gb , header_pos + header_size * 8 - get_bits_count ( & s -> gb ));
if ( extensions_mask & DCA_EXT_EXSS_XLL )
s -> profile = FF_PROFILE_DTS_HD_MA ;
2011-01-21 20:00:40 +00:00
else if ( extensions_mask & ( DCA_EXT_EXSS_XBR | DCA_EXT_EXSS_X96 |
DCA_EXT_EXSS_XXCH ))
2011-01-06 22:34:12 +00:00
s -> profile = FF_PROFILE_DTS_HD_HRA ;
if ( ! ( extensions_mask & DCA_EXT_CORE ))
av_log ( s -> avctx , AV_LOG_WARNING , "DTS core detection mismatch. \n " );
2011-02-18 19:49:44 +00:00
if (( extensions_mask & DCA_CORE_EXTS ) != s -> core_ext_mask )
av_log ( s -> avctx , AV_LOG_WARNING , "DTS extensions detection mismatch (%d, %d) \n " ,
extensions_mask & DCA_CORE_EXTS , s -> core_ext_mask );
2011-01-06 22:34:12 +00:00
return 0 ;
}
/**
* Parse extension substream header (HD)
*/
static void dca_exss_parse_header ( DCAContext * s )
{
int ss_index ;
int blownup ;
int num_audiop = 1 ;
int num_assets = 1 ;
int active_ss_mask [ 8 ];
int i , j ;
if ( get_bits_left ( & s -> gb ) < 52 )
return ;
skip_bits ( & s -> gb , 8 ); // user data
ss_index = get_bits ( & s -> gb , 2 );
blownup = get_bits1 ( & s -> gb );
2011-06-01 17:26:27 +01:00
skip_bits ( & s -> gb , 8 + 4 * blownup ); // header_size
skip_bits ( & s -> gb , 16 + 4 * blownup ); // hd_size
2011-01-06 22:34:12 +00:00
s -> static_fields = get_bits1 ( & s -> gb );
if ( s -> static_fields ) {
skip_bits ( & s -> gb , 2 ); // reference clock code
skip_bits ( & s -> gb , 3 ); // frame duration code
if ( get_bits1 ( & s -> gb ))
skip_bits_long ( & s -> gb , 36 ); // timestamp
/* a single stream can contain multiple audio assets that can be
* combined to form multiple audio presentations */
num_audiop = get_bits ( & s -> gb , 3 ) + 1 ;
if ( num_audiop > 1 ) {
av_log_ask_for_sample ( s -> avctx , "Multiple DTS-HD audio presentations." );
/* ignore such streams for now */
return ;
}
num_assets = get_bits ( & s -> gb , 3 ) + 1 ;
if ( num_assets > 1 ) {
av_log_ask_for_sample ( s -> avctx , "Multiple DTS-HD audio assets." );
/* ignore such streams for now */
return ;
}
for ( i = 0 ; i < num_audiop ; i ++ )
active_ss_mask [ i ] = get_bits ( & s -> gb , ss_index + 1 );
for ( i = 0 ; i < num_audiop ; i ++ )
for ( j = 0 ; j <= ss_index ; j ++ )
if ( active_ss_mask [ i ] & ( 1 << j ))
skip_bits ( & s -> gb , 8 ); // active asset mask
s -> mix_metadata = get_bits1 ( & s -> gb );
if ( s -> mix_metadata ) {
int mix_out_mask_size ;
skip_bits ( & s -> gb , 2 ); // adjustment level
mix_out_mask_size = ( get_bits ( & s -> gb , 2 ) + 1 ) << 2 ;
s -> num_mix_configs = get_bits ( & s -> gb , 2 ) + 1 ;
for ( i = 0 ; i < s -> num_mix_configs ; i ++ ) {
int mix_out_mask = get_bits ( & s -> gb , mix_out_mask_size );
s -> mix_config_num_ch [ i ] = dca_exss_mask2count ( mix_out_mask );
}
}
}
for ( i = 0 ; i < num_assets ; i ++ )
skip_bits_long ( & s -> gb , 16 + 4 * blownup ); // asset size
for ( i = 0 ; i < num_assets ; i ++ ) {
if ( dca_exss_parse_asset_header ( s ))
return ;
}
/* not parsed further, we were only interested in the extensions mask
* from the asset header */
}
2007-02-27 06:30:40 +00:00
/**
* Main frame decoding function
* FIXME add arguments
*/
static int dca_decode_frame ( AVCodecContext * avctx ,
void * data , int * data_size ,
2009-04-07 15:59:50 +00:00
AVPacket * avpkt )
2007-02-27 06:30:40 +00:00
{
2009-04-07 15:59:50 +00:00
const uint8_t * buf = avpkt -> data ;
int buf_size = avpkt -> size ;
2007-02-27 06:30:40 +00:00
2010-06-22 08:33:00 +00:00
int lfe_samples ;
2010-06-22 08:34:51 +00:00
int num_core_channels = 0 ;
2011-10-27 11:42:23 -04:00
int i , ret ;
2011-04-22 21:30:19 -04:00
float * samples_flt = data ;
int16_t * samples_s16 = data ;
int out_size ;
2007-02-27 06:30:40 +00:00
DCAContext * s = avctx -> priv_data ;
int channels ;
2011-01-06 22:34:12 +00:00
int core_ss_end ;
2007-02-27 06:30:40 +00:00
2010-07-12 09:00:17 +00:00
s -> xch_present = 0 ;
2011-01-06 22:34:12 +00:00
s -> dca_buffer_size = dca_convert_bitstream ( buf , buf_size , s -> dca_buffer ,
DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE );
2011-10-27 11:41:02 -04:00
if ( s -> dca_buffer_size == AVERROR_INVALIDDATA ) {
2007-05-18 10:06:07 +00:00
av_log ( avctx , AV_LOG_ERROR , "Not a valid DCA frame \n " );
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2007-02-27 06:30:40 +00:00
}
init_get_bits ( & s -> gb , s -> dca_buffer , s -> dca_buffer_size * 8 );
2011-10-27 11:42:23 -04:00
if (( ret = dca_parse_frame_header ( s )) < 0 ) {
2007-02-27 06:30:40 +00:00
//seems like the frame is corrupt, try with the next one
2011-10-27 11:42:23 -04:00
return ret ;
2007-02-27 06:30:40 +00:00
}
//set AVCodec values with parsed data
avctx -> sample_rate = s -> sample_rate ;
avctx -> bit_rate = s -> bit_rate ;
2011-07-04 09:55:19 -07:00
avctx -> frame_size = s -> sample_blocks * 32 ;
2007-02-27 06:30:40 +00:00
2011-01-06 22:34:12 +00:00
s -> profile = FF_PROFILE_DTS ;
2010-06-22 08:33:00 +00:00
for ( i = 0 ; i < ( s -> sample_blocks / 8 ); i ++ ) {
2011-10-27 11:45:50 -04:00
if (( ret = dca_decode_block ( s , 0 , i ))) {
av_log ( avctx , AV_LOG_ERROR , "error decoding block \n " );
return ret ;
}
2010-06-22 08:34:51 +00:00
}
/* record number of core channels incase less than max channels are requested */
num_core_channels = s -> prim_channels ;
2011-02-18 19:49:44 +00:00
if ( s -> ext_coding )
s -> core_ext_mask = dca_ext_audio_descr_mask [ s -> ext_descr ];
else
s -> core_ext_mask = 0 ;
2010-06-22 08:34:51 +00:00
2011-01-06 22:34:12 +00:00
core_ss_end = FFMIN ( s -> frame_size , s -> dca_buffer_size ) * 8 ;
2011-02-18 19:49:44 +00:00
/* only scan for extensions if ext_descr was unknown or indicated a
* supported XCh extension */
if ( s -> core_ext_mask < 0 || s -> core_ext_mask & DCA_EXT_XCH ) {
/* if ext_descr was unknown, clear s->core_ext_mask so that the
* extensions scan can fill it up */
s -> core_ext_mask = FFMAX ( s -> core_ext_mask , 0 );
/* extensions start at 32-bit boundaries into bitstream */
skip_bits_long ( & s -> gb , ( - get_bits_count ( & s -> gb )) & 31 );
2011-01-06 22:34:12 +00:00
while ( core_ss_end - get_bits_count ( & s -> gb ) >= 32 ) {
2010-07-05 01:43:47 +00:00
uint32_t bits = get_bits_long ( & s -> gb , 32 );
2010-06-22 08:34:51 +00:00
switch ( bits ) {
case 0x5a5a5a5a : {
2010-07-05 08:16:43 +00:00
int ext_amode , xch_fsize ;
2010-07-12 09:00:17 +00:00
s -> xch_base_channel = s -> prim_channels ;
2010-07-05 08:16:43 +00:00
/* validate sync word using XCHFSIZE field */
xch_fsize = show_bits ( & s -> gb , 10 );
if (( s -> frame_size != ( get_bits_count ( & s -> gb ) >> 3 ) - 4 + xch_fsize ) &&
( s -> frame_size != ( get_bits_count ( & s -> gb ) >> 3 ) - 4 + xch_fsize + 1 ))
continue ;
2010-06-22 08:34:51 +00:00
/* skip length-to-end-of-frame field for the moment */
skip_bits ( & s -> gb , 10 );
2011-02-18 19:49:44 +00:00
s -> core_ext_mask |= DCA_EXT_XCH ;
2011-01-06 22:34:12 +00:00
2010-06-22 08:34:51 +00:00
/* extension amode should == 1, number of channels in extension */
/* AFAIK XCh is not used for more channels */
if (( ext_amode = get_bits ( & s -> gb , 4 )) != 1 ) {
av_log ( avctx , AV_LOG_ERROR , "XCh extension amode %d not"
" supported! \n " , ext_amode );
continue ;
}
/* much like core primary audio coding header */
2010-07-12 09:00:17 +00:00
dca_parse_audio_coding_header ( s , s -> xch_base_channel );
2010-06-22 08:34:51 +00:00
for ( i = 0 ; i < ( s -> sample_blocks / 8 ); i ++ ) {
2011-10-27 11:45:50 -04:00
if (( ret = dca_decode_block ( s , s -> xch_base_channel , i ))) {
av_log ( avctx , AV_LOG_ERROR , "error decoding XCh extension \n " );
continue ;
}
2010-06-22 08:34:51 +00:00
}
2010-07-12 09:00:17 +00:00
s -> xch_present = 1 ;
2010-06-22 08:34:51 +00:00
break ;
}
2011-01-06 22:34:12 +00:00
case 0x47004a03 :
/* XXCh: extended channels */
/* usually found either in core or HD part in DTS-HD HRA streams,
* but not in DTS-ES which contains XCh extensions instead */
2011-02-18 19:49:44 +00:00
s -> core_ext_mask |= DCA_EXT_XXCH ;
2011-01-06 22:34:12 +00:00
break ;
2011-01-06 22:24:39 +00:00
case 0x1d95f262 : {
int fsize96 = show_bits ( & s -> gb , 12 ) + 1 ;
if ( s -> frame_size != ( get_bits_count ( & s -> gb ) >> 3 ) - 4 + fsize96 )
continue ;
av_log ( avctx , AV_LOG_DEBUG , "X96 extension found at %d bits \n " , get_bits_count ( & s -> gb ));
skip_bits ( & s -> gb , 12 );
av_log ( avctx , AV_LOG_DEBUG , "FSIZE96 = %d bytes \n " , fsize96 );
2010-06-22 08:34:51 +00:00
av_log ( avctx , AV_LOG_DEBUG , "REVNO = %d \n " , get_bits ( & s -> gb , 4 ));
2011-01-06 22:34:12 +00:00
2011-02-18 19:49:44 +00:00
s -> core_ext_mask |= DCA_EXT_X96 ;
2010-06-22 08:34:51 +00:00
break ;
}
2011-01-06 22:24:39 +00:00
}
2010-06-22 08:34:51 +00:00
2010-07-05 01:43:47 +00:00
skip_bits_long ( & s -> gb , ( - get_bits_count ( & s -> gb )) & 31 );
2010-06-22 08:33:00 +00:00
}
2011-02-18 19:49:44 +00:00
} else {
/* no supported extensions, skip the rest of the core substream */
skip_bits_long ( & s -> gb , core_ss_end - get_bits_count ( & s -> gb ));
}
if ( s -> core_ext_mask & DCA_EXT_X96 )
s -> profile = FF_PROFILE_DTS_96_24 ;
else if ( s -> core_ext_mask & ( DCA_EXT_XCH | DCA_EXT_XXCH ))
s -> profile = FF_PROFILE_DTS_ES ;
2011-01-06 22:34:12 +00:00
/* check for ExSS (HD part) */
if ( s -> dca_buffer_size - s -> frame_size > 32
&& get_bits_long ( & s -> gb , 32 ) == DCA_HD_MARKER )
dca_exss_parse_header ( s );
avctx -> profile = s -> profile ;
2007-05-02 20:31:32 +00:00
channels = s -> prim_channels + !! s -> lfe ;
2008-11-15 20:31:03 +00:00
if ( s -> amode < 16 ) {
2008-11-01 20:27:05 +00:00
avctx -> channel_layout = dca_core_channel_layout [ s -> amode ];
2010-07-12 09:00:17 +00:00
if ( s -> xch_present && ( ! avctx -> request_channels ||
2010-07-27 21:44:09 +00:00
avctx -> request_channels > num_core_channels + !! s -> lfe )) {
2010-11-21 20:06:22 +00:00
avctx -> channel_layout |= AV_CH_BACK_CENTER ;
2010-06-22 08:34:51 +00:00
if ( s -> lfe ) {
2010-11-21 20:06:22 +00:00
avctx -> channel_layout |= AV_CH_LOW_FREQUENCY ;
2010-06-22 08:34:51 +00:00
s -> channel_order_tab = dca_channel_reorder_lfe_xch [ s -> amode ];
} else {
s -> channel_order_tab = dca_channel_reorder_nolfe_xch [ s -> amode ];
}
} else {
2010-07-27 21:44:09 +00:00
channels = num_core_channels + !! s -> lfe ;
s -> xch_present = 0 ; /* disable further xch processing */
2010-06-22 08:34:51 +00:00
if ( s -> lfe ) {
2010-11-21 20:06:22 +00:00
avctx -> channel_layout |= AV_CH_LOW_FREQUENCY ;
2010-06-22 08:34:51 +00:00
s -> channel_order_tab = dca_channel_reorder_lfe [ s -> amode ];
} else
s -> channel_order_tab = dca_channel_reorder_nolfe [ s -> amode ];
}
2008-11-15 20:31:03 +00:00
2010-07-27 21:44:09 +00:00
if ( channels > !! s -> lfe &&
s -> channel_order_tab [ channels - 1 - !! s -> lfe ] < 0 )
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2010-02-26 18:50:01 +00:00
2010-06-22 08:35:44 +00:00
if ( avctx -> request_channels == 2 && s -> prim_channels > 2 ) {
2008-11-15 20:31:03 +00:00
channels = 2 ;
s -> output = DCA_STEREO ;
2010-11-21 20:06:22 +00:00
avctx -> channel_layout = AV_CH_LAYOUT_STEREO ;
2008-11-15 20:31:03 +00:00
}
} else {
av_log ( avctx , AV_LOG_ERROR , "Non standard configuration %d ! \n " , s -> amode );
2011-10-27 11:41:02 -04:00
return AVERROR_INVALIDDATA ;
2008-11-15 20:31:03 +00:00
}
2007-05-02 20:31:32 +00:00
2008-04-10 06:15:17 +00:00
/* There is nothing that prevents a dts frame to change channel configuration
2011-04-23 16:39:03 +02:00
but Libav doesn't support that so only set the channels if it is previously
2008-04-10 06:15:17 +00:00
unset. Ideally during the first probe for channels the crc should be checked
and only set avctx->channels when the crc is ok. Right now the decoder could
set the channels based on a broken first frame.*/
2011-01-18 11:30:33 -05:00
if ( s -> is_channels_set == 0 ) {
s -> is_channels_set = 1 ;
2011-01-18 11:40:13 -05:00
avctx -> channels = channels ;
2011-01-18 11:30:33 -05:00
}
if ( avctx -> channels != channels ) {
av_log ( avctx , AV_LOG_ERROR , "DCA decoder does not support number of "
"channels changing in stream. Skipping frame. \n " );
2011-10-27 11:41:02 -04:00
return AVERROR_PATCHWELCOME ;
2011-01-18 11:30:33 -05:00
}
2008-04-10 06:15:17 +00:00
2011-04-22 21:30:19 -04:00
out_size = 256 / 8 * s -> sample_blocks * channels *
2011-06-07 13:40:22 -04:00
av_get_bytes_per_sample ( avctx -> sample_fmt );
2011-04-22 21:30:19 -04:00
if ( * data_size < out_size )
2011-10-27 11:41:02 -04:00
return AVERROR ( EINVAL );
2011-04-22 21:30:19 -04:00
* data_size = out_size ;
2010-06-22 08:33:00 +00:00
/* filter to get final output */
2007-02-27 06:30:40 +00:00
for ( i = 0 ; i < ( s -> sample_blocks / 8 ); i ++ ) {
2010-06-22 08:33:00 +00:00
dca_filter_channels ( s , i );
2010-07-12 09:10:53 +00:00
/* If this was marked as a DTS-ES stream we need to subtract back- */
/* channel from SL & SR to remove matrixed back-channel signal */
if (( s -> source_pcm_res & 1 ) && s -> xch_present ) {
float * back_chan = s -> samples + s -> channel_order_tab [ s -> xch_base_channel ] * 256 ;
float * lt_chan = s -> samples + s -> channel_order_tab [ s -> xch_base_channel - 2 ] * 256 ;
float * rt_chan = s -> samples + s -> channel_order_tab [ s -> xch_base_channel - 1 ] * 256 ;
2011-09-28 14:34:04 +01:00
s -> dsp . vector_fmac_scalar ( lt_chan , back_chan , - M_SQRT1_2 , 256 );
s -> dsp . vector_fmac_scalar ( rt_chan , back_chan , - M_SQRT1_2 , 256 );
2010-07-12 09:10:53 +00:00
}
2011-04-22 21:30:19 -04:00
if ( avctx -> sample_fmt == AV_SAMPLE_FMT_FLT ) {
s -> fmt_conv . float_interleave ( samples_flt , s -> samples_chanptr , 256 ,
channels );
samples_flt += 256 * channels ;
} else {
s -> fmt_conv . float_to_int16_interleave ( samples_s16 ,
s -> samples_chanptr , 256 ,
channels );
samples_s16 += 256 * channels ;
}
2007-02-27 06:30:40 +00:00
}
2010-06-22 08:33:00 +00:00
/* update lfe history */
lfe_samples = 2 * s -> lfe * ( s -> sample_blocks / 8 );
for ( i = 0 ; i < 2 * s -> lfe * 4 ; i ++ ) {
s -> lfe_data [ i ] = s -> lfe_data [ i + lfe_samples ];
}
2007-02-27 06:30:40 +00:00
return buf_size ;
}
/**
* DCA initialization
*
* @param avctx pointer to the AVCodecContext
*/
2008-03-21 03:11:20 +00:00
static av_cold int dca_decode_init ( AVCodecContext * avctx )
2007-02-27 06:30:40 +00:00
{
DCAContext * s = avctx -> priv_data ;
2008-08-29 10:09:51 +00:00
int i ;
2007-02-27 06:30:40 +00:00
s -> avctx = avctx ;
dca_init_vlcs ();
dsputil_init ( & s -> dsp , avctx );
2009-05-16 14:17:08 +00:00
ff_mdct_init ( & s -> imdct , 6 , 1 , 1.0 );
2010-04-10 16:27:53 +00:00
ff_synth_filter_init ( & s -> synth );
2010-04-12 20:45:25 +00:00
ff_dcadsp_init ( & s -> dcadsp );
2011-01-30 15:06:46 +00:00
ff_fmt_convert_init ( & s -> fmt_conv , avctx );
2008-01-05 21:23:57 +00:00
2010-06-22 08:33:00 +00:00
for ( i = 0 ; i < DCA_PRIM_CHANNELS_MAX + 1 ; i ++ )
2008-08-29 10:09:51 +00:00
s -> samples_chanptr [ i ] = s -> samples + i * 256 ;
2008-10-26 09:54:53 +00:00
2011-04-22 21:30:19 -04:00
if ( avctx -> request_sample_fmt == AV_SAMPLE_FMT_FLT ) {
avctx -> sample_fmt = AV_SAMPLE_FMT_FLT ;
s -> scale_bias = 1.0 / 32768.0 ;
} else {
avctx -> sample_fmt = AV_SAMPLE_FMT_S16 ;
s -> scale_bias = 1.0 ;
}
2008-10-26 09:54:53 +00:00
2011-01-27 14:21:26 +00:00
/* allow downmixing to stereo */
if ( avctx -> channels > 0 && avctx -> request_channels < avctx -> channels &&
avctx -> request_channels == 2 ) {
avctx -> channels = avctx -> request_channels ;
}
2008-10-26 09:54:53 +00:00
2007-02-27 06:30:40 +00:00
return 0 ;
}
2008-08-30 10:47:13 +00:00
static av_cold int dca_decode_end ( AVCodecContext * avctx )
{
DCAContext * s = avctx -> priv_data ;
ff_mdct_end ( & s -> imdct );
return 0 ;
}
2007-02-27 06:30:40 +00:00
2011-01-21 22:58:55 +00:00
static const AVProfile profiles [] = {
{ FF_PROFILE_DTS , "DTS" },
{ FF_PROFILE_DTS_ES , "DTS-ES" },
{ FF_PROFILE_DTS_96_24 , "DTS 96/24" },
{ FF_PROFILE_DTS_HD_HRA , "DTS-HD HRA" },
{ FF_PROFILE_DTS_HD_MA , "DTS-HD MA" },
{ FF_PROFILE_UNKNOWN },
};
2011-01-25 21:40:11 +00:00
AVCodec ff_dca_decoder = {
2007-02-27 06:30:40 +00:00
. name = "dca" ,
2010-03-30 23:30:55 +00:00
. type = AVMEDIA_TYPE_AUDIO ,
2007-02-27 06:30:40 +00:00
. id = CODEC_ID_DTS ,
. priv_data_size = sizeof ( DCAContext ),
. init = dca_decode_init ,
. decode = dca_decode_frame ,
2008-08-30 10:47:13 +00:00
. close = dca_decode_end ,
2008-06-12 21:50:13 +00:00
. long_name = NULL_IF_CONFIG_SMALL ( "DCA (DTS Coherent Acoustics)" ),
2010-10-02 22:18:02 +00:00
. capabilities = CODEC_CAP_CHANNEL_CONF ,
2011-04-22 21:30:19 -04:00
. sample_fmts = ( const enum AVSampleFormat []) {
AV_SAMPLE_FMT_FLT , AV_SAMPLE_FMT_S16 , AV_SAMPLE_FMT_NONE
},
2011-01-21 22:58:55 +00:00
. profiles = NULL_IF_CONFIG_SMALL ( profiles ),
2007-02-27 06:30:40 +00:00
};