@ -1453,6 +1453,114 @@ static float dca_dmix_code(unsigned code)
return ( ( ff_dca_dmixtable [ code ] ^ sign ) - sign ) * ( 1.0 / ( 1 < < 15 ) ) ;
}
static int scan_for_extensions ( AVCodecContext * avctx )
{
DCAContext * s = avctx - > priv_data ;
int core_ss_end , ret ;
core_ss_end = FFMIN ( s - > frame_size , s - > dca_buffer_size ) * 8 ;
/* 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 | DCA_EXT_XXCH ) ) {
/* 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 ) ;
while ( core_ss_end - get_bits_count ( & s - > gb ) > = 32 ) {
uint32_t bits = get_bits_long ( & s - > gb , 32 ) ;
int i ;
switch ( bits ) {
case DCA_SYNCWORD_XCH : {
int ext_amode , xch_fsize ;
s - > xch_base_channel = s - > prim_channels ;
/* 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 ;
/* skip length-to-end-of-frame field for the moment */
skip_bits ( & s - > gb , 10 ) ;
s - > core_ext_mask | = DCA_EXT_XCH ;
/* extension amode(number of channels in extension) should be 1 */
/* 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 ;
}
if ( s - > xch_base_channel < 2 ) {
avpriv_request_sample ( avctx , " XCh with fewer than 2 base channels " ) ;
continue ;
}
/* much like core primary audio coding header */
dca_parse_audio_coding_header ( s , s - > xch_base_channel , 0 ) ;
for ( i = 0 ; i < ( s - > sample_blocks / 8 ) ; i + + )
if ( ( ret = dca_decode_block ( s , s - > xch_base_channel , i ) ) ) {
av_log ( avctx , AV_LOG_ERROR , " error decoding XCh extension \n " ) ;
continue ;
}
s - > xch_present = 1 ;
break ;
}
case DCA_SYNCWORD_XXCH :
/* 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 */
s - > core_ext_mask | = DCA_EXT_XXCH ;
ff_dca_xxch_decode_frame ( s ) ;
break ;
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 ) ;
av_log ( avctx , AV_LOG_DEBUG , " REVNO = %d \n " , get_bits ( & s - > gb , 4 ) ) ;
s - > core_ext_mask | = DCA_EXT_X96 ;
break ;
}
}
skip_bits_long ( & s - > gb , ( - get_bits_count ( & s - > gb ) ) & 31 ) ;
}
} 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 ;
/* check for ExSS (HD part) */
if ( s - > dca_buffer_size - s - > frame_size > 32 & &
get_bits_long ( & s - > gb , 32 ) = = DCA_SYNCWORD_SUBSTREAM )
ff_dca_exss_parse_header ( s ) ;
return ret ;
}
/**
* Main frame decoding function
* FIXME add arguments
@ -1472,7 +1580,6 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
float * src_chan ;
float * dst_chan ;
DCAContext * s = avctx - > priv_data ;
int core_ss_end ;
int channels , full_channels ;
float scale ;
int achan ;
@ -1564,104 +1671,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
else
s - > core_ext_mask = 0 ;
core_ss_end = FFMIN ( s - > frame_size , s - > dca_buffer_size ) * 8 ;
/* 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 | DCA_EXT_XXCH ) ) {
/* 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 ) ;
while ( core_ss_end - get_bits_count ( & s - > gb ) > = 32 ) {
uint32_t bits = get_bits_long ( & s - > gb , 32 ) ;
switch ( bits ) {
case DCA_SYNCWORD_XCH : {
int ext_amode , xch_fsize ;
s - > xch_base_channel = s - > prim_channels ;
/* 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 ;
/* skip length-to-end-of-frame field for the moment */
skip_bits ( & s - > gb , 10 ) ;
s - > core_ext_mask | = DCA_EXT_XCH ;
/* extension amode(number of channels in extension) should be 1 */
/* 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 ;
}
if ( s - > xch_base_channel < 2 ) {
avpriv_request_sample ( avctx , " XCh with fewer than 2 base channels " ) ;
continue ;
}
/* much like core primary audio coding header */
dca_parse_audio_coding_header ( s , s - > xch_base_channel , 0 ) ;
for ( i = 0 ; i < ( s - > sample_blocks / 8 ) ; i + + )
if ( ( ret = dca_decode_block ( s , s - > xch_base_channel , i ) ) ) {
av_log ( avctx , AV_LOG_ERROR , " error decoding XCh extension \n " ) ;
continue ;
}
s - > xch_present = 1 ;
break ;
}
case DCA_SYNCWORD_XXCH :
/* 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 */
s - > core_ext_mask | = DCA_EXT_XXCH ;
ff_dca_xxch_decode_frame ( s ) ;
break ;
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 ) ;
av_log ( avctx , AV_LOG_DEBUG , " REVNO = %d \n " , get_bits ( & s - > gb , 4 ) ) ;
s - > core_ext_mask | = DCA_EXT_X96 ;
break ;
}
}
skip_bits_long ( & s - > gb , ( - get_bits_count ( & s - > gb ) ) & 31 ) ;
}
} 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 ;
/* check for ExSS (HD part) */
if ( s - > dca_buffer_size - s - > frame_size > 32 & &
get_bits_long ( & s - > gb , 32 ) = = DCA_SYNCWORD_SUBSTREAM )
ff_dca_exss_parse_header ( s ) ;
ret = scan_for_extensions ( avctx ) ;
avctx - > profile = s - > profile ;