@ -179,6 +179,14 @@ typedef struct Vp3DecodeContext {
int coded_fragment_list_index ;
int pixel_addresses_initialized ;
/* track which fragments have already been decoded; called 'fast'
* because this data structure avoids having to iterate through every
* fragment in coded_fragment_list ; once a fragment has been fully
* decoded , it is removed from this list */
int * fast_fragment_list ;
int fragment_list_y_head ;
int fragment_list_c_head ;
VLC dc_vlc [ 16 ] ;
VLC ac_vlc_1 [ 16 ] ;
VLC ac_vlc_2 [ 16 ] ;
@ -723,6 +731,25 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
/* end the list of coded C fragments */
s - > last_coded_c_fragment = s - > coded_fragment_list_index - 1 ;
for ( i = 0 ; i < s - > fragment_count - 1 ; i + + ) {
s - > fast_fragment_list [ i ] = i + 1 ;
}
s - > fast_fragment_list [ s - > fragment_count - 1 ] = - 1 ;
if ( s - > last_coded_y_fragment = = - 1 )
s - > fragment_list_y_head = - 1 ;
else {
s - > fragment_list_y_head = s - > first_coded_y_fragment ;
s - > fast_fragment_list [ s - > last_coded_y_fragment ] = - 1 ;
}
if ( s - > last_coded_c_fragment = = - 1 )
s - > fragment_list_c_head = - 1 ;
else {
s - > fragment_list_c_head = s - > first_coded_c_fragment ;
s - > fast_fragment_list [ s - > last_coded_c_fragment ] = - 1 ;
}
return 0 ;
}
@ -1029,7 +1056,7 @@ static int unpack_block_qpis(Vp3DecodeContext *s, GetBitContext *gb)
*/
static int unpack_vlcs ( Vp3DecodeContext * s , GetBitContext * gb ,
VLC * table , int coeff_index ,
int first_fragment , int last_fragment ,
int y_plane ,
int eob_run )
{
int i ;
@ -1038,6 +1065,10 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
DCTELEM coeff = 0 ;
Vp3Fragment * fragment ;
int bits_to_get ;
int next_fragment ;
int previous_fragment ;
int fragment_num ;
int * list_head ;
/* local references to structure members to avoid repeated deferences */
uint8_t * perm = s - > scantable . permutated ;
@ -1045,20 +1076,26 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
Vp3Fragment * all_fragments = s - > all_fragments ;
uint8_t * coeff_counts = s - > coeff_counts ;
VLC_TYPE ( * vlc_table ) [ 2 ] = table - > table ;
int * fast_fragment_list = s - > fast_fragment_list ;
if ( ( first_fragment > = s - > fragment_count ) | |
( last_fragment > = s - > fragment_count ) ) {
av_log ( s - > avctx , AV_LOG_ERROR , " vp3:unpack_vlcs(): bad fragment number (%d -> %d ?) \n " ,
first_fragment , last_fragment ) ;
return 0 ;
if ( y_plane ) {
next_fragment = s - > fragment_list_y_head ;
list_head = & s - > fragment_list_y_head ;
} else {
next_fragment = s - > fragment_list_c_head ;
list_head = & s - > fragment_list_c_head ;
}
for ( i = first_fragment ; i < = last_fragment ; i + + ) {
int fragment_num = coded_fragment_list [ i ] ;
i = next_fragment ;
previous_fragment = - 1 ; /* this indicates that the previous fragment is actually the list head */
while ( i ! = - 1 ) {
fragment_num = coded_fragment_list [ i ] ;
if ( coeff_counts [ fragment_num ] > coeff_index )
if ( coeff_counts [ fragment_num ] > coeff_index ) {
previous_fragment = i ;
i = fast_fragment_list [ i ] ;
continue ;
}
fragment = & all_fragments [ fragment_num ] ;
if ( ! eob_run ) {
@ -1091,10 +1128,20 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
s - > next_coeff - > next = NULL ;
fragment - > next_coeff = s - > next_coeff + + ;
}
/* previous fragment is now this fragment */
previous_fragment = i ;
} else {
coeff_counts [ fragment_num ] | = 128 ;
eob_run - - ;
/* remove this fragment from the list */
if ( previous_fragment ! = - 1 )
fast_fragment_list [ previous_fragment ] = fast_fragment_list [ i ] ;
else
* list_head = fast_fragment_list [ i ] ;
/* previous fragment remains unchanged */
}
i = fast_fragment_list [ i ] ;
}
return eob_run ;
@ -1123,14 +1170,14 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
/* unpack the Y plane DC coefficients */
residual_eob_run = unpack_vlcs ( s , gb , & s - > dc_vlc [ dc_y_table ] , 0 ,
s - > first_coded_y_fragment , s - > last_coded_y_fragment , residual_eob_run ) ;
1 , residual_eob_run ) ;
/* reverse prediction of the Y-plane DC coefficients */
reverse_dc_prediction ( s , 0 , s - > fragment_width , s - > fragment_height ) ;
/* unpack the C plane DC coefficients */
residual_eob_run = unpack_vlcs ( s , gb , & s - > dc_vlc [ dc_c_table ] , 0 ,
s - > first_coded_c_fragment , s - > last_coded_c_fragment , residual_eob_run ) ;
0 , residual_eob_run ) ;
/* reverse prediction of the C-plane DC coefficients */
if ( ! ( s - > avctx - > flags & CODEC_FLAG_GRAY ) )
@ -1148,37 +1195,37 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
/* unpack the group 1 AC coefficients (coeffs 1-5) */
for ( i = 1 ; i < = 5 ; i + + ) {
residual_eob_run = unpack_vlcs ( s , gb , & s - > ac_vlc_1 [ ac_y_table ] , i ,
s - > first_coded_y_fragment , s - > last_coded_y_fragment , residual_eob_run ) ;
1 , residual_eob_run ) ;
residual_eob_run = unpack_vlcs ( s , gb , & s - > ac_vlc_1 [ ac_c_table ] , i ,
s - > first_coded_c_fragment , s - > last_coded_c_fragment , residual_eob_run ) ;
0 , residual_eob_run ) ;
}
/* unpack the group 2 AC coefficients (coeffs 6-14) */
for ( i = 6 ; i < = 14 ; i + + ) {
residual_eob_run = unpack_vlcs ( s , gb , & s - > ac_vlc_2 [ ac_y_table ] , i ,
s - > first_coded_y_fragment , s - > last_coded_y_fragment , residual_eob_run ) ;
1 , residual_eob_run ) ;
residual_eob_run = unpack_vlcs ( s , gb , & s - > ac_vlc_2 [ ac_c_table ] , i ,
s - > first_coded_c_fragment , s - > last_coded_c_fragment , residual_eob_run ) ;
0 , residual_eob_run ) ;
}
/* unpack the group 3 AC coefficients (coeffs 15-27) */
for ( i = 15 ; i < = 27 ; i + + ) {
residual_eob_run = unpack_vlcs ( s , gb , & s - > ac_vlc_3 [ ac_y_table ] , i ,
s - > first_coded_y_fragment , s - > last_coded_y_fragment , residual_eob_run ) ;
1 , residual_eob_run ) ;
residual_eob_run = unpack_vlcs ( s , gb , & s - > ac_vlc_3 [ ac_c_table ] , i ,
s - > first_coded_c_fragment , s - > last_coded_c_fragment , residual_eob_run ) ;
0 , residual_eob_run ) ;
}
/* unpack the group 4 AC coefficients (coeffs 28-63) */
for ( i = 28 ; i < = 63 ; i + + ) {
residual_eob_run = unpack_vlcs ( s , gb , & s - > ac_vlc_4 [ ac_y_table ] , i ,
s - > first_coded_y_fragment , s - > last_coded_y_fragment , residual_eob_run ) ;
1 , residual_eob_run ) ;
residual_eob_run = unpack_vlcs ( s , gb , & s - > ac_vlc_4 [ ac_c_table ] , i ,
s - > first_coded_c_fragment , s - > last_coded_c_fragment , residual_eob_run ) ;
0 , residual_eob_run ) ;
}
return 0 ;
@ -1756,9 +1803,10 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
s - > coeff_counts = av_malloc ( s - > fragment_count * sizeof ( * s - > coeff_counts ) ) ;
s - > coeffs = av_malloc ( s - > fragment_count * sizeof ( Coeff ) * 65 ) ;
s - > coded_fragment_list = av_malloc ( s - > fragment_count * sizeof ( int ) ) ;
s - > fast_fragment_list = av_malloc ( s - > fragment_count * sizeof ( int ) ) ;
s - > pixel_addresses_initialized = 0 ;
if ( ! s - > superblock_coding | | ! s - > all_fragments | | ! s - > coeff_counts | |
! s - > coeffs | | ! s - > coded_fragment_list ) {
! s - > coeffs | | ! s - > coded_fragment_list | | ! s - > fast_fragment_list ) {
vp3_decode_end ( avctx ) ;
return - 1 ;
}
@ -2057,6 +2105,7 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx)
av_free ( s - > coeff_counts ) ;
av_free ( s - > coeffs ) ;
av_free ( s - > coded_fragment_list ) ;
av_free ( s - > fast_fragment_list ) ;
av_free ( s - > superblock_fragments ) ;
av_free ( s - > superblock_macroblocks ) ;
av_free ( s - > macroblock_fragments ) ;