@ -45,7 +45,7 @@ extern VLC ff_msmp4_mb_i_vlc;
static const uint16_t table_mb_intra [ 64 ] [ 2 ] ;
static const uint16_t table_mb_intra [ 64 ] [ 2 ] ;
/* Some inhibiting stuff */
/* Some inhibiting stuff */
# define HAS_ADVANCED_PROFILE 1
# define HAS_ADVANCED_PROFILE 0
# define TRACE 1
# define TRACE 1
# if TRACE
# if TRACE
@ -190,7 +190,10 @@ typedef struct BitPlane {
uint8_t is_raw ; ///< Bit values must be read at MB level
uint8_t is_raw ; ///< Bit values must be read at MB level
} BitPlane ;
} BitPlane ;
/** The VC9 Context */
/** The VC9 Context
* @ fixme Change size wherever another size is more efficient
* Many members are only used for Advanced Profile
*/
typedef struct VC9Context {
typedef struct VC9Context {
MpegEncContext s ;
MpegEncContext s ;
@ -257,7 +260,13 @@ typedef struct VC9Context{
uint8_t dqsbedge ;
uint8_t dqsbedge ;
uint8_t dqbilevel ;
uint8_t dqbilevel ;
//@}
//@}
int ac_table_level ; ///< Index for AC tables from ACFRM element
/** AC coding set indexes
* @ see 8.1 .1 .10 , p ( 1 ) 10
*/
//@{
int c_ac_table_index ; ///< Chroma index from ACFRM element
int y_ac_table_index ; ///< Luma index from AC2FRM element
//@}
int ttfrm ; ///< Transform type info present at frame level
int ttfrm ; ///< Transform type info present at frame level
uint8_t ttmbf ; ///< Transform type flag
uint8_t ttmbf ; ///< Transform type flag
int ttmb ; ///< Transform type
int ttmb ; ///< Transform type
@ -312,7 +321,6 @@ typedef struct VC9Context{
BitPlane over_flags_plane ; ///< Overflags bitplane
BitPlane over_flags_plane ; ///< Overflags bitplane
uint8_t condover ;
uint8_t condover ;
uint16_t * hrd_rate , * hrd_buffer ;
uint16_t * hrd_rate , * hrd_buffer ;
int ac2_table_level ; ///< Index for AC2 tables from AC2FRM element
//@}
//@}
# endif
# endif
} VC9Context ;
} VC9Context ;
@ -1145,13 +1153,14 @@ static int decode_b_picture_primary_header(VC9Context *v)
if ( pqindex < 9 ) v - > halfpq = get_bits ( gb , 1 ) ;
if ( pqindex < 9 ) v - > halfpq = get_bits ( gb , 1 ) ;
if ( v - > quantizer_mode = = QUANT_FRAME_EXPLICIT )
if ( v - > quantizer_mode = = QUANT_FRAME_EXPLICIT )
v - > pquantizer = get_bits ( gb , 1 ) ;
v - > pquantizer = get_bits ( gb , 1 ) ;
# if HAS_ADVANCED_PROFILE
if ( v - > profile = = PROFILE_ADVANCED )
if ( v - > profile = = PROFILE_ADVANCED )
{
{
if ( v - > postprocflag ) v - > postproc = get_bits ( gb , 2 ) ;
if ( v - > postprocflag ) v - > postproc = get_bits ( gb , 2 ) ;
if ( v - > extended_mv = = 1 & & v - > s . pict_type ! = BI_TYPE )
if ( v - > extended_mv = = 1 & & v - > s . pict_type ! = BI_TYPE )
v - > mvrange = get_prefix ( gb , 0 , 3 ) ;
v - > mvrange = get_prefix ( gb , 0 , 3 ) ;
}
}
# endif
else
else
{
{
if ( v - > extended_mv = = 1 )
if ( v - > extended_mv = = 1 )
@ -1285,12 +1294,13 @@ static int decode_i_picture_primary_header(VC9Context *v)
/** I frame header decoding, secondary part
/** I frame header decoding, secondary part
* @ param v VC9 context
* @ param v VC9 context
* @ return Status
* @ return Status
* @ warning Not called in A / S / C profiles , it seems
* @ todo Support Advanced Profile headers
* @ todo Support Advanced Profile headers
*/
*/
static int decode_i_picture_secondary_header ( VC9Context * v )
static int decode_i_picture_secondary_header ( VC9Context * v )
{
{
int status ;
# if HAS_ADVANCED_PROFILE
# if HAS_ADVANCED_PROFILE
int status ;
if ( v - > profile = = PROFILE_ADVANCED )
if ( v - > profile = = PROFILE_ADVANCED )
{
{
v - > s . ac_pred = get_bits ( & v - > s . gb , 1 ) ;
v - > s . ac_pred = get_bits ( & v - > s . gb , 1 ) ;
@ -1492,10 +1502,10 @@ static int standard_decode_picture_secondary_header(VC9Context *v)
if ( status < 0 ) return FRAME_SKIPED ;
if ( status < 0 ) return FRAME_SKIPED ;
/* AC Syntax */
/* AC Syntax */
v - > ac_table_level = decode012 ( gb ) ;
v - > c_ac_table_index = decode012 ( gb ) ;
if ( v - > s . pict_type = = I_TYPE | | v - > s . pict_type = = BI_TYPE )
if ( v - > s . pict_type = = I_TYPE | | v - > s . pict_type = = BI_TYPE )
{
{
v - > ac2_table_level = decode012 ( gb ) ;
v - > y_ac_table_index = decode012 ( gb ) ;
}
}
/* DC Syntax */
/* DC Syntax */
v - > s . dc_table_index = decode012 ( gb ) ;
v - > s . dc_table_index = decode012 ( gb ) ;
@ -1513,7 +1523,7 @@ static int standard_decode_picture_secondary_header(VC9Context *v)
* check caller
* check caller
* @ {
* @ {
*/
*/
/** Frame header decoding, primary part
/** Frame header decoding, primary part
* @ param v VC9 context
* @ param v VC9 context
* @ return Status
* @ return Status
*/
*/
@ -1592,10 +1602,10 @@ static int advanced_decode_picture_secondary_header(VC9Context *v)
if ( status < 0 ) return FRAME_SKIPED ;
if ( status < 0 ) return FRAME_SKIPED ;
/* AC Syntax */
/* AC Syntax */
v - > ac_table_level = decode012 ( gb ) ;
v - > c_ac_table_index = decode012 ( gb ) ;
if ( v - > s . pict_type = = I_TYPE | | v - > s . pict_type = = BI_TYPE )
if ( v - > s . pict_type = = I_TYPE | | v - > s . pict_type = = BI_TYPE )
{
{
v - > ac2_table_level = decode012 ( gb ) ;
v - > y_ac_table_index = decode012 ( gb ) ;
}
}
/* DC Syntax */
/* DC Syntax */
v - > s . dc_table_index = decode012 ( gb ) ;
v - > s . dc_table_index = decode012 ( gb ) ;
@ -1616,6 +1626,8 @@ static int advanced_decode_picture_secondary_header(VC9Context *v)
/**
/**
* @ def GET_MQUANT
* @ def GET_MQUANT
* @ brief Get macroblock - level quantizer scale
* @ brief Get macroblock - level quantizer scale
* @ warning XXX : qdiff to the frame quant , not previous quant ?
* @ fixme XXX : Don ' t know how to initialize mquant otherwise in last case
*/
*/
# define GET_MQUANT() \
# define GET_MQUANT() \
if ( v - > dquantfrm ) \
if ( v - > dquantfrm ) \
@ -1633,14 +1645,16 @@ static int advanced_decode_picture_secondary_header(VC9Context *v)
else mquant = get_bits ( gb , 5 ) ; \
else mquant = get_bits ( gb , 5 ) ; \
} \
} \
} \
} \
else mquant = v - > pq ; \
}
}
/**
/**
* @ def GET_MVDATA ( _dmv_x , _dmv_y )
* @ def GET_MVDATA ( _dmv_x , _dmv_y )
* @ brief Get MV differentials
* @ brief Get MV differentials
* @ see MVDATA decoding from 8.3 .5 .2 , p ( 1 ) 20
* @ see MVDATA decoding from 8.3 .5 .2 , p ( 1 ) 20
* @ param dmv_x Horizontal differential for decoded MV
* @ param _dmv_x Horizontal differential for decoded MV
* @ param dmv_y Vertical differential for decoded MV
* @ param _dmv_y Vertical differential for decoded MV
* @ todo TODO : Use MpegEncContext arrays to store them
*/
*/
# define GET_MVDATA(_dmv_x, _dmv_y) \
# define GET_MVDATA(_dmv_x, _dmv_y) \
index = 1 + get_vlc2 ( gb , vc9_mv_diff_vlc [ s - > mv_table_index ] . table , \
index = 1 + get_vlc2 ( gb , vc9_mv_diff_vlc [ s - > mv_table_index ] . table , \
@ -1678,19 +1692,28 @@ static int advanced_decode_picture_secondary_header(VC9Context *v)
/** Get predicted DC value
/** Get predicted DC value
* prediction dir : left = 0 , top = 1
* prediction dir : left = 0 , top = 1
* @ param s MpegEncContext
* @ param [ in ] n block index in the current MB
* @ param dc_val_ptr Pointer to DC predictor
* @ param dir_ptr Prediction direction for use in AC prediction
* @ todo TODO : Actually do it the VC9 way
* @ todo TODO : Handle properly edges
*/
*/
static inline int vc9_pred_dc ( MpegEncContext * s , int n ,
static inline int vc9_pred_dc ( MpegEncContext * s , int n ,
uint16_t * * dc_val_ptr , int * dir_ptr )
uint16_t * * dc_val_ptr , int * dir_ptr )
{
{
int a , b , c , wrap , pred , scale ;
int a , b , c , wrap , pred , scale ;
int16_t * dc_val ;
int16_t * dc_val ;
static const uint16_t dcpred [ 31 ] = {
/* find prediction */
1024 , 512 , 341 , 256 , 205 , 171 , 146 , 128 ,
if ( n < 4 ) {
114 , 102 , 93 , 85 , 79 , 73 , 68 , 64 ,
scale = s - > y_dc_scale ;
60 , 57 , 54 , 51 , 49 , 47 , 45 , 43 ,
} else {
41 , 39 , 38 , 37 , 35 , 34 , 33
scale = s - > c_dc_scale ;
} ;
}
/* find prediction - wmv3_dc_scale always used here in fact */
if ( n < 4 ) scale = s - > y_dc_scale ;
else scale = s - > c_dc_scale ;
wrap = s - > block_wrap [ n ] ;
wrap = s - > block_wrap [ n ] ;
dc_val = s - > dc_val [ 0 ] + s - > block_index [ n ] ;
dc_val = s - > dc_val [ 0 ] + s - > block_index [ n ] ;
@ -1702,46 +1725,31 @@ static inline int vc9_pred_dc(MpegEncContext *s, int n,
b = dc_val [ - 1 - wrap ] ;
b = dc_val [ - 1 - wrap ] ;
c = dc_val [ - wrap ] ;
c = dc_val [ - wrap ] ;
if ( s - > first_slice_line & & ( n & 2 ) = = 0 ) b = c = 1024 ;
/* XXX: Rule B is used only for I and BI frames in S/M/C profile
* with overlap filtering off
/* XXX: the following solution consumes divisions, but it does not
necessitate to modify mpegvideo . c . The problem comes from the
fact they decided to store the quantized DC ( which would lead
to problems if Q could vary ! ) */
# if (defined(ARCH_X86) || defined(ARCH_X86_64)) && !defined PIC
asm volatile (
" movl %3, %%eax \n \t "
" shrl $1, %%eax \n \t "
" addl %%eax, %2 \n \t "
" addl %%eax, %1 \n \t "
" addl %0, %%eax \n \t "
" mull %4 \n \t "
" movl %%edx, %0 \n \t "
" movl %1, %%eax \n \t "
" mull %4 \n \t "
" movl %%edx, %1 \n \t "
" movl %2, %%eax \n \t "
" mull %4 \n \t "
" movl %%edx, %2 \n \t "
: " +b " ( a ) , " +c " ( b ) , " +D " ( c )
: " g " ( scale ) , " S " ( inverse [ scale ] )
: " %eax " , " %edx "
) ;
# else
/* #elif defined (ARCH_ALPHA) */
/* Divisions are extremely costly on Alpha; optimize the most
common case . But they are costly everywhere . . .
*/
*/
if ( scale = = 8 ) {
if ( ( s - > pict_type = = I_TYPE | | s - > pict_type = = BI_TYPE ) & &
a = ( a + ( 8 > > 1 ) ) / 8 ;
1 /* XXX: overlap filtering off */ )
b = ( b + ( 8 > > 1 ) ) / 8 ;
{
c = ( c + ( 8 > > 1 ) ) / 8 ;
/* Set outer values */
} else {
if ( s - > first_slice_line & & n ! = 2 ) b = c = dcpred [ scale ] ;
a = FASTDIV ( ( a + ( scale > > 1 ) ) , scale ) ;
if ( s - > mb_x = = 0 ) b = a = dcpred [ scale ] ;
b = FASTDIV ( ( b + ( scale > > 1 ) ) , scale ) ;
}
c = FASTDIV ( ( c + ( scale > > 1 ) ) , scale ) ;
else
{
/* Set outer values */
if ( s - > first_slice_line & & n ! = 2 ) b = c = 0 ;
if ( s - > mb_x = = 0 ) b = a = 0 ;
/* XXX: Rule A needs to know if blocks are inter or intra :/ */
if ( 0 )
{
/* update predictor */
* dc_val_ptr = & dc_val [ 0 ] ;
dir_ptr = 0 ;
return a ;
}
}
}
# endif
if ( abs ( a - b ) < = abs ( b - c ) ) {
if ( abs ( a - b ) < = abs ( b - c ) ) {
pred = c ;
pred = c ;
@ -1761,7 +1769,7 @@ static inline int vc9_pred_dc(MpegEncContext *s, int n,
* @ param block 8 x8 DCT block
* @ param block 8 x8 DCT block
* @ param n Block index in the current MB ( < 4 = > luma )
* @ param n Block index in the current MB ( < 4 = > luma )
* @ param coded If the block is coded
* @ param coded If the block is coded
* @ param MB quant , if decoded at the MB layer
* @ param mquant Quantizer step for the current block
* @ see Inter TT : Table 21 , p73 + p91 - 85
* @ see Inter TT : Table 21 , p73 + p91 - 85
* @ see Intra TT : Table 20 , p72 + p ( 1 ) 05 - ( 1 ) 07
* @ see Intra TT : Table 20 , p72 + p ( 1 ) 05 - ( 1 ) 07
* @ todo TODO : Process the blocks
* @ todo TODO : Process the blocks
@ -1776,6 +1784,13 @@ int vc9_decode_block(VC9Context *v, DCTELEM block[64], int n, int coded, int mqu
int dc_pred_dir ; /* Direction of the DC prediction used */
int dc_pred_dir ; /* Direction of the DC prediction used */
int run_diff , i ;
int run_diff , i ;
/* XXX: Guard against dumb values of mquant */
mquant = ( mquant < 1 ) ? 0 : ( ( mquant > 31 ) ? 31 : mquant ) ;
/* Set DC scale - y and c use the same */
s - > y_dc_scale = s - > y_dc_scale_table [ mquant ] ;
s - > c_dc_scale = s - > c_dc_scale_table [ mquant ] ;
if ( s - > mb_intra )
if ( s - > mb_intra )
{
{
int dcdiff ;
int dcdiff ;
@ -1788,7 +1803,7 @@ int vc9_decode_block(VC9Context *v, DCTELEM block[64], int n, int coded, int mqu
dcdiff = get_vlc2 ( & s - > gb , ff_msmp4_dc_chroma_vlc [ s - > dc_table_index ] . table , DC_VLC_BITS , 3 ) ;
dcdiff = get_vlc2 ( & s - > gb , ff_msmp4_dc_chroma_vlc [ s - > dc_table_index ] . table , DC_VLC_BITS , 3 ) ;
}
}
if ( dcdiff < 0 ) {
if ( dcdiff < 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " illegal dc vlc \n " ) ;
av_log ( s - > avctx , AV_LOG_ERROR , " Illegal DC VLC \n " ) ;
return - 1 ;
return - 1 ;
}
}
if ( dcdiff )
if ( dcdiff )
@ -1813,18 +1828,20 @@ int vc9_decode_block(VC9Context *v, DCTELEM block[64], int n, int coded, int mqu
/* Prediction */
/* Prediction */
dcdiff + = vc9_pred_dc ( s , n , & dc_val , & dc_pred_dir ) ;
dcdiff + = vc9_pred_dc ( s , n , & dc_val , & dc_pred_dir ) ;
* dc_val = dcdiff ;
/* Store the quantized DC coeff, used for prediction */
if ( n < 4 ) {
if ( n < 4 ) {
* dc_val = dcdiff * s - > y_dc_scale ;
block [ 0 ] = dcdiff * s - > y_dc_scale ;
} else {
} else {
* dc_val = dcdiff * s - > c_dc_scale ;
block [ 0 ] = dcdiff * s - > c_dc_scale ;
}
}
if ( dcdiff < 0 )
if ( block [ 0 ] < 0 ) {
{
# if TRACE
av_log ( s - > avctx , AV_LOG_ERROR , " DC=%i<0 \n " , dcdiff ) ;
//av_log(s->avctx, AV_LOG_ERROR, "DC=%i<0\n", dcdiff);
return - 1 ;
# endif
//return -1;
}
}
block [ 0 ] = dcdiff ; //XXX: Must be > 0
/* Skip ? */
/* Skip ? */
run_diff = 0 ;
run_diff = 0 ;
i = 0 ;
i = 0 ;
@ -1851,6 +1868,7 @@ int vc9_decode_block(VC9Context *v, DCTELEM block[64], int n, int coded, int mqu
}
}
//TODO AC Decoding
//TODO AC Decoding
i = 63 ; //XXX: nothing done yet
not_coded :
not_coded :
@ -1901,6 +1919,9 @@ static inline int vc9_coded_block_pred(MpegEncContext * s, int n, uint8_t **code
return pred ;
return pred ;
}
}
/** Decode one I-frame MB (in Simple/Main profile)
* @ todo TODO : Extend to AP
*/
int vc9_decode_i_mb ( VC9Context * v , DCTELEM block [ 6 ] [ 64 ] )
int vc9_decode_i_mb ( VC9Context * v , DCTELEM block [ 6 ] [ 64 ] )
{
{
int i , cbp , val ;
int i , cbp , val ;
@ -1922,15 +1943,19 @@ int vc9_decode_i_mb(VC9Context *v, DCTELEM block[6][64])
}
}
cbp | = val < < ( 5 - i ) ;
cbp | = val < < ( 5 - i ) ;
if ( vc9_decode_block ( v , block [ i ] , i , val , v - > pq ) < 0 ) //FIXME Should be mquant
if ( vc9_decode_block ( v , block [ i ] , i , val , v - > pq ) < 0 ) //FIXME Should be mquant
{
{
av_log ( v - > s . avctx , AV_LOG_ERROR ,
av_log ( v - > s . avctx , AV_LOG_ERROR ,
" \n error while decoding block: %d x %d (%d) \n " , v - > s . mb_x , v - > s . mb_y , i ) ;
" \n error while decoding block: %d x %d (%d) \n " , v - > s . mb_x , v - > s . mb_y , i ) ;
return - 1 ;
return - 1 ;
}
}
}
}
return 0 ;
return 0 ;
}
}
/** Decode one P-frame MB (in Simple/Main profile)
* @ todo TODO : Extend to AP
* @ fixme FIXME : DC value for inter blocks not set
*/
int vc9_decode_p_mb ( VC9Context * v , DCTELEM block [ 6 ] [ 64 ] )
int vc9_decode_p_mb ( VC9Context * v , DCTELEM block [ 6 ] [ 64 ] )
{
{
MpegEncContext * s = & v - > s ;
MpegEncContext * s = & v - > s ;
@ -1951,6 +1976,8 @@ int vc9_decode_p_mb(VC9Context *v, DCTELEM block[6][64])
int index , index1 ; /* LUT indices */
int index , index1 ; /* LUT indices */
int val , sign ; /* temp values */
int val , sign ; /* temp values */
mquant = v - > pq ; /* Loosy initialization */
if ( v - > mv_type_mb_plane . is_raw )
if ( v - > mv_type_mb_plane . is_raw )
v - > mv_type_mb_plane . data [ mb_offset ] = get_bits ( gb , 1 ) ;
v - > mv_type_mb_plane . data [ mb_offset ] = get_bits ( gb , 1 ) ;
if ( v - > skip_mb_plane . is_raw )
if ( v - > skip_mb_plane . is_raw )
@ -1965,11 +1992,19 @@ int vc9_decode_p_mb(VC9Context *v, DCTELEM block[6][64])
if ( v - > mv_mode = = MV_PMODE_1MV | |
if ( v - > mv_mode = = MV_PMODE_1MV | |
v - > mv_mode = = MV_PMODE_MIXED_MV )
v - > mv_mode = = MV_PMODE_MIXED_MV )
hybrid_pred = get_bits ( gb , 1 ) ;
hybrid_pred = get_bits ( gb , 1 ) ;
/* FIXME Set DC val for inter block ? */
if ( s - > mb_intra & & ! mb_has_coeffs )
if ( s - > mb_intra & & ! mb_has_coeffs )
{
{
GET_MQUANT ( ) ;
GET_MQUANT ( ) ;
s - > ac_pred = get_bits ( gb , 1 ) ;
s - > ac_pred = get_bits ( gb , 1 ) ;
/* XXX: how to handle cbp ? */
/* XXX: how to handle cbp ? */
cbp = 0 ;
for ( i = 0 ; i < 6 ; i + + )
{
s - > coded_block [ s - > block_index [ i ] ] = 0 ;
vc9_decode_block ( v , block [ i ] , i , 0 , mquant ) ;
}
return 0 ;
}
}
else if ( mb_has_coeffs )
else if ( mb_has_coeffs )
{
{
@ -1980,12 +2015,15 @@ int vc9_decode_p_mb(VC9Context *v, DCTELEM block[6][64])
else
else
{
{
mquant = v - > pq ;
mquant = v - > pq ;
/* XXX: How to handle cbp ? */
/* XXX: how to handle cbp ? */
/* XXX: how to set values for following predictions ? */
cbp = 0 ;
}
}
if ( ! v - > ttmbf )
if ( ! v - > ttmbf )
ttmb = get_vlc2 ( gb , vc9_ttmb_vlc [ v - > tt_index ] . table ,
ttmb = get_vlc2 ( gb , vc9_ttmb_vlc [ v - > tt_index ] . table ,
VC9_TTMB_VLC_BITS , 12 ) ;
VC9_TTMB_VLC_BITS , 12 ) ;
for ( i = 0 ; i < 6 ; i + + )
for ( i = 0 ; i < 6 ; i + + )
{
{
val = ( ( cbp > > ( 5 - i ) ) & 1 ) ;
val = ( ( cbp > > ( 5 - i ) ) & 1 ) ;
@ -2029,6 +2067,7 @@ int vc9_decode_p_mb(VC9Context *v, DCTELEM block[6][64])
if ( v - > mv_mode = = MV_PMODE_MIXED_MV /* Hybrid pred */ )
if ( v - > mv_mode = = MV_PMODE_MIXED_MV /* Hybrid pred */ )
hybrid_pred = get_bits ( gb , 1 ) ;
hybrid_pred = get_bits ( gb , 1 ) ;
GET_MQUANT ( ) ;
GET_MQUANT ( ) ;
if ( s - > mb_intra /* One of the 4 blocks is intra */ & &
if ( s - > mb_intra /* One of the 4 blocks is intra */ & &
index /* non-zero pred for that block */ )
index /* non-zero pred for that block */ )
s - > ac_pred = get_bits ( gb , 1 ) ;
s - > ac_pred = get_bits ( gb , 1 ) ;
@ -2041,12 +2080,15 @@ int vc9_decode_p_mb(VC9Context *v, DCTELEM block[6][64])
}
}
else //Skipped MB
else //Skipped MB
{
{
/* XXX: Skipped => cbp=0 and mquant doesn't matter ? */
for ( i = 0 ; i < 4 ; i + + )
for ( i = 0 ; i < 4 ; i + + )
{
{
if ( v - > mv_mode = = MV_PMODE_MIXED_MV /* Hybrid pred */ )
if ( v - > mv_mode = = MV_PMODE_MIXED_MV /* Hybrid pred */ )
hybrid_pred = get_bits ( gb , 1 ) ;
hybrid_pred = get_bits ( gb , 1 ) ;
vc9_decode_block ( v , block [ i ] , i , 0 /*cbp[i]*/ , mquant ) ; //FIXME
vc9_decode_block ( v , block [ i ] , i , 0 , v - > pq ) ; //FIXME
}
}
vc9_decode_block ( v , block [ 4 ] , 4 , 0 , v - > pq ) ; //FIXME
vc9_decode_block ( v , block [ 5 ] , 5 , 0 , v - > pq ) ; //FIXME
/* TODO: blah */
/* TODO: blah */
return 0 ;
return 0 ;
}
}
@ -2056,20 +2098,98 @@ int vc9_decode_p_mb(VC9Context *v, DCTELEM block[6][64])
return - 1 ;
return - 1 ;
}
}
/** Decode one B-frame MB (in Simple/Main profile)
* @ todo TODO : Extend to AP
* @ warning XXX : Used for decoding BI MBs
* @ fixme FIXME : DC value for inter blocks not set
*/
int vc9_decode_b_mb ( VC9Context * v , DCTELEM block [ 6 ] [ 64 ] )
int vc9_decode_b_mb ( VC9Context * v , DCTELEM block [ 6 ] [ 64 ] )
{
{
int i ;
MpegEncContext * s = & v - > s ;
//Decode CBP
GetBitContext * gb = & v - > s . gb ;
int mb_offset , i /* MB / B postion information */ ;
int b_mv_type = BMV_TYPE_BACKWARD ;
int mquant , mqdiff ; /* MB quant stuff */
int ttmb ; /* MacroBlock transform type */
static const int size_table [ 6 ] = { 0 , 2 , 3 , 4 , 5 , 8 } ,
offset_table [ 6 ] = { 0 , 1 , 3 , 7 , 15 , 31 } ;
int mb_has_coeffs = 1 ; /* last_flag */
int dmv1_x , dmv1_y , dmv2_x , dmv2_y ; /* Differential MV components */
int index , index1 ; /* LUT indices */
int val , sign ; /* MVDATA temp values */
mb_offset = s - > mb_width * s - > mb_y + s - > mb_x ; //FIXME: arrays aren't using stride
if ( v - > direct_mb_plane . is_raw )
v - > direct_mb_plane . data [ mb_offset ] = get_bits ( gb , 1 ) ;
if ( v - > skip_mb_plane . is_raw )
v - > skip_mb_plane . data [ mb_offset ] = get_bits ( gb , 1 ) ;
if ( ! v - > direct_mb_plane . data [ mb_offset ] )
{
if ( v - > skip_mb_plane . data [ mb_offset ] )
{
b_mv_type = decode012 ( gb ) ;
if ( v - > bfraction > 420 /*1/2*/ & &
b_mv_type < 3 ) b_mv_type = 1 - b_mv_type ;
}
else
{
GET_MVDATA ( dmv1_x , dmv1_y ) ;
if ( ! s - > mb_intra /* b_mv1 tells not intra */ )
{
b_mv_type = decode012 ( gb ) ;
if ( v - > bfraction > 420 /*1/2*/ & &
b_mv_type < 3 ) b_mv_type = 1 - b_mv_type ;
}
}
}
if ( ! v - > skip_mb_plane . data [ mb_offset ] )
{
if ( mb_has_coeffs /* BMV1 == "last" */ )
{
GET_MQUANT ( ) ;
if ( s - > mb_intra /* intra mb */ )
s - > ac_pred = get_bits ( gb , 1 ) ;
}
else
{
/* if bmv1 tells MVs are interpolated */
if ( b_mv_type = = BMV_TYPE_INTERPOLATED )
{
GET_MVDATA ( dmv2_x , dmv2_y ) ;
mquant = v - > pq ; //FIXME: initialization not necessary ?
}
/* GET_MVDATA has reset some stuff */
if ( mb_has_coeffs /* b_mv2 == "last" */ )
{
if ( s - > mb_intra /* intra_mb */ )
s - > ac_pred = get_bits ( gb , 1 ) ;
GET_MQUANT ( ) ;
}
}
}
//End1
if ( v - > ttmbf )
ttmb = get_vlc2 ( gb , vc9_ttmb_vlc [ v - > tt_index ] . table ,
VC9_TTMB_VLC_BITS , 12 ) ;
//End2
for ( i = 0 ; i < 6 ; i + + )
for ( i = 0 ; i < 6 ; i + + )
{
{
vc9_decode_block ( v , block [ i ] , i , 0 /*cbp[i]*/ , v - > pq /*Should be mquant*/ ) ; //FIXME
vc9_decode_block ( v , block [ i ] , i , 0 /*cbp[i]*/ , mquant ) ; //FIXME
}
}
return 0 ;
return 0 ;
}
}
/** Decode all MBs for an I frame in Simple/Main profile
* @ todo TODO : Move out of the loop the picture type case ?
( branch prediction should help there though )
*/
static int standard_decode_mbs ( VC9Context * v )
static int standard_decode_mbs ( VC9Context * v )
{
{
GetBitContext * gb = & v - > s . gb ;
MpegEncContext * s = & v - > s ;
MpegEncContext * s = & v - > s ;
/* Set transform type info depending on pq */
/* Set transform type info depending on pq */
@ -2113,381 +2233,16 @@ static int standard_decode_mbs(VC9Context *v)
//TODO Move out of the loop
//TODO Move out of the loop
switch ( s - > pict_type )
switch ( s - > pict_type )
{
{
case I_TYPE : vc9_decode_i_mb ( v , NULL ) ; break ;
case I_TYPE : vc9_decode_i_mb ( v , s - > block ) ; break ;
case P_TYPE : vc9_decode_i_mb ( v , NULL ) ; break ;
case P_TYPE : vc9_decode_p_mb ( v , s - > block ) ; break ;
case BI_TYPE :
case BI_TYPE :
case B_TYPE : vc9_decode_i_mb ( v , NULL ) ; break ;
case B_TYPE : vc9_decode_b_mb ( v , s - > block ) ; break ;
}
}
}
}
//Add a check for overconsumption ?
//Add a check for overconsumption ?
}
}
return 0 ;
return 0 ;
}
}
/**
* @ def GET_CBPCY ( table , bits )
* @ brief Get the Coded Block Pattern for luma and chroma
* @ param table VLC table to use ( get_vlc2 second parameter )
* @ param bits Average bitlength ( third parameter to get_vlc2 )
* @ see 8.1 .1 .5 , p ( 1 ) 02 - ( 1 ) 03
*/
# define GET_CBPCY(table, bits) \
predicted_cbpcy = get_vlc2 ( gb , table , bits , 2 ) ; \
cbpcy [ 0 ] = ( p_cbpcy [ - 1 ] = = p_cbpcy [ 2 ] ) \
? previous_cbpcy [ 1 ] : p_cbpcy [ + 2 ] ; \
cbpcy [ 0 ] ^ = ( ( predicted_cbpcy > > 5 ) & 0x01 ) ; \
cbpcy [ 1 ] = ( p_cbpcy [ 2 ] = = p_cbpcy [ 3 ] ) ? cbpcy [ 0 ] : p_cbpcy [ 3 ] ; \
cbpcy [ 1 ] ^ = ( ( predicted_cbpcy > > 4 ) & 0x01 ) ; \
cbpcy [ 2 ] = ( previous_cbpcy [ 1 ] = = cbpcy [ 0 ] ) \
? previous_cbpcy [ 3 ] : cbpcy [ 0 ] ; \
cbpcy [ 2 ] ^ = ( ( predicted_cbpcy > > 3 ) & 0x01 ) ; \
cbpcy [ 3 ] = ( cbpcy [ 1 ] = = cbpcy [ 0 ] ) ? cbpcy [ 2 ] : cbpcy [ 1 ] ; \
cbpcy [ 3 ] ^ = ( ( predicted_cbpcy > > 2 ) & 0x01 ) ;
/** Decode all MBs for an I frame in Simple/Main profile
* @ see 8.1 , p100
* @ todo TODO : Process the blocks
* @ todo TODO : Use M $ MPEG - 4 cbp prediction
*/
static int standard_decode_i_mbs ( VC9Context * v )
{
GetBitContext * gb = & v - > s . gb ;
MpegEncContext * s = & v - > s ;
int mb_offset = 0 ; /* MB/Block Position info */
uint8_t cbpcy [ 4 ] , previous_cbpcy [ 4 ] , predicted_cbpcy ,
* p_cbpcy /* Pointer to skip some math */ ;
/* Reset CBPCY predictors */
memset ( v - > previous_line_cbpcy , 0 , s - > mb_stride < < 2 ) ;
/* Select ttmb table depending on pq */
if ( v - > pq < 5 )
{
v - > tt_index = 0 ;
v - > ttblk4x4 = 3 ;
}
else if ( v - > pq < 13 )
{
v - > tt_index = 1 ;
v - > ttblk4x4 = 3 ;
}
else
{
v - > tt_index = 2 ;
v - > ttblk4x4 = 2 ;
}
for ( s - > mb_y = 0 ; s - > mb_y < s - > mb_height ; s - > mb_y + + )
{
/* Init CBPCY for line */
* ( ( uint32_t * ) previous_cbpcy ) = 0x00000000 ;
p_cbpcy = v - > previous_line_cbpcy + 4 ;
for ( s - > mb_x = 0 ; s - > mb_x < s - > mb_width ; s - > mb_x + + , p_cbpcy + = 4 )
{
/* Get CBPCY */
GET_CBPCY ( ff_msmp4_mb_i_vlc . table , MB_INTRA_VLC_BITS ) ;
s - > ac_pred = get_bits ( gb , 1 ) ;
/* TODO: Decode blocks from that mb wrt cbpcy */
/* Update for next block */
# if TRACE > 2
av_log ( s - > avctx , AV_LOG_DEBUG , " Block %4i: p_cbpcy=%i%i%i%i, previous_cbpcy=%i%i%i%i, "
" cbpcy=%i%i%i%i \n " , mb_offset ,
p_cbpcy [ 0 ] , p_cbpcy [ 1 ] , p_cbpcy [ 2 ] , p_cbpcy [ 3 ] ,
previous_cbpcy [ 0 ] , previous_cbpcy [ 1 ] , previous_cbpcy [ 2 ] , previous_cbpcy [ 3 ] ,
cbpcy [ 0 ] , cbpcy [ 1 ] , cbpcy [ 2 ] , cbpcy [ 3 ] ) ;
# endif
* ( ( uint32_t * ) p_cbpcy ) = * ( ( uint32_t * ) previous_cbpcy ) ;
* ( ( uint32_t * ) previous_cbpcy ) = * ( ( uint32_t * ) cbpcy ) ;
mb_offset + + ;
}
}
return 0 ;
}
/** Decode all MBs for an P frame in Simple/Main profile
* @ see 8.1 , p ( 1 ) 15
* @ todo TODO : Process the blocks
* @ todo TODO : Use M $ MPEG - 4 cbp prediction
*/
static int decode_p_mbs ( VC9Context * v )
{
MpegEncContext * s = & v - > s ;
GetBitContext * gb = & v - > s . gb ;
int mb_offset = 0 , i ; /* MB/Block Position info */
uint8_t cbpcy [ 4 ] , previous_cbpcy [ 4 ] , predicted_cbpcy ,
* p_cbpcy /* Pointer to skip some math */ ;
int hybrid_pred ; /* Prediction types */
int mv_mode_bit = 0 ;
int mqdiff , mquant ; /* MB quantization */
int ttmb ; /* MB Transform type */
static const int size_table [ 6 ] = { 0 , 2 , 3 , 4 , 5 , 8 } ,
offset_table [ 6 ] = { 0 , 1 , 3 , 7 , 15 , 31 } ;
int mb_has_coeffs = 1 ; /* last_flag */
int dmv_x , dmv_y ; /* Differential MV components */
int index , index1 ; /* LUT indices */
int val , sign ; /* MVDATA temp values */
/* Select ttmb table depending on pq */
if ( v - > pq < 5 )
{
v - > tt_index = 0 ;
v - > ttblk4x4 = 3 ;
}
else if ( v - > pq < 13 )
{
v - > tt_index = 1 ;
v - > ttblk4x4 = 3 ;
}
else
{
v - > tt_index = 2 ;
v - > ttblk4x4 = 2 ;
}
/* Select proper long MV range */
switch ( v - > mvrange )
{
case 1 : v - > k_x = 10 ; v - > k_y = 9 ; break ;
case 2 : v - > k_x = 12 ; v - > k_y = 10 ; break ;
case 3 : v - > k_x = 13 ; v - > k_y = 11 ; break ;
default : /*case 0 too */ v - > k_x = 9 ; v - > k_y = 8 ; break ;
}
s - > mspel = v - > mv_mode & 1 ; //MV_PMODE is HPEL
v - > k_x - = s - > mspel ;
v - > k_y - = s - > mspel ;
/* Reset CBPCY predictors */
memset ( v - > previous_line_cbpcy , 0 , s - > mb_stride < < 2 ) ;
for ( s - > mb_y = 0 ; s - > mb_y < s - > mb_height ; s - > mb_y + + )
{
/* Init CBPCY for line */
* ( ( uint32_t * ) previous_cbpcy ) = 0x00000000 ;
p_cbpcy = v - > previous_line_cbpcy + 4 ;
for ( s - > mb_x = 0 ; s - > mb_x < s - > mb_width ; s - > mb_x + + , p_cbpcy + = 4 )
{
if ( v - > mv_type_mb_plane . is_raw )
v - > mv_type_mb_plane . data [ mb_offset ] = get_bits ( gb , 1 ) ;
if ( v - > skip_mb_plane . is_raw )
v - > skip_mb_plane . data [ mb_offset ] = get_bits ( gb , 1 ) ;
if ( ! mv_mode_bit ) /* 1MV mode */
{
if ( ! v - > skip_mb_plane . data [ mb_offset ] )
{
GET_MVDATA ( dmv_x , dmv_y ) ;
/* hybrid mv pred, 8.3.5.3.4 */
if ( v - > mv_mode = = MV_PMODE_1MV | |
v - > mv_mode = = MV_PMODE_MIXED_MV )
hybrid_pred = get_bits ( gb , 1 ) ;
if ( s - > mb_intra & & ! mb_has_coeffs )
{
GET_MQUANT ( ) ;
s - > ac_pred = get_bits ( gb , 1 ) ;
}
else if ( mb_has_coeffs )
{
if ( s - > mb_intra ) s - > ac_pred = get_bits ( gb , 1 ) ;
predicted_cbpcy = get_vlc2 ( gb , v - > cbpcy_vlc - > table , VC9_CBPCY_P_VLC_BITS , 2 ) ;
GET_CBPCY ( v - > cbpcy_vlc - > table , VC9_CBPCY_P_VLC_BITS ) ;
GET_MQUANT ( ) ;
}
if ( ! v - > ttmbf )
ttmb = get_vlc2 ( gb , vc9_ttmb_vlc [ v - > tt_index ] . table ,
VC9_TTMB_VLC_BITS , 12 ) ;
/* TODO: decode blocks from that mb wrt cbpcy */
}
else //Skipped
{
/* hybrid mv pred, 8.3.5.3.4 */
if ( v - > mv_mode = = MV_PMODE_1MV | |
v - > mv_mode = = MV_PMODE_MIXED_MV )
hybrid_pred = get_bits ( gb , 1 ) ;
}
} //1MV mode
else //4MV mode
{
if ( ! v - > skip_mb_plane . data [ mb_offset ] /* unskipped MB */ )
{
/* Get CBPCY */
GET_CBPCY ( v - > cbpcy_vlc - > table , VC9_CBPCY_P_VLC_BITS ) ;
for ( i = 0 ; i < 4 ; i + + ) //For all 4 Y blocks
{
if ( cbpcy [ i ] /* cbpcy set for this block */ )
{
GET_MVDATA ( dmv_x , dmv_y ) ;
}
if ( v - > mv_mode = = MV_PMODE_MIXED_MV /* Hybrid pred */ )
hybrid_pred = get_bits ( gb , 1 ) ;
GET_MQUANT ( ) ;
if ( s - > mb_intra /* One of the 4 blocks is intra */ & &
index /* non-zero pred for that block */ )
s - > ac_pred = get_bits ( gb , 1 ) ;
if ( ! v - > ttmbf )
ttmb = get_vlc2 ( gb , vc9_ttmb_vlc [ v - > tt_index ] . table ,
VC9_TTMB_VLC_BITS , 12 ) ;
/* TODO: Process blocks wrt cbpcy */
}
}
else //Skipped MB
{
for ( i = 0 ; i < 4 ; i + + ) //All 4 Y blocks
{
if ( v - > mv_mode = = MV_PMODE_MIXED_MV /* Hybrid pred */ )
hybrid_pred = get_bits ( gb , 1 ) ;
/* TODO: do something */
}
}
}
/* Update for next block */
# if TRACE > 2
av_log ( s - > avctx , AV_LOG_DEBUG , " Block %4i: p_cbpcy=%i%i%i%i, previous_cbpcy=%i%i%i%i, "
" cbpcy=%i%i%i%i \n " , mb_offset ,
p_cbpcy [ 0 ] , p_cbpcy [ 1 ] , p_cbpcy [ 2 ] , p_cbpcy [ 3 ] ,
previous_cbpcy [ 0 ] , previous_cbpcy [ 1 ] , previous_cbpcy [ 2 ] , previous_cbpcy [ 3 ] ,
cbpcy [ 0 ] , cbpcy [ 1 ] , cbpcy [ 2 ] , cbpcy [ 3 ] ) ;
# endif
* ( ( uint32_t * ) p_cbpcy ) = * ( ( uint32_t * ) previous_cbpcy ) ;
* ( ( uint32_t * ) previous_cbpcy ) = * ( ( uint32_t * ) cbpcy ) ;
mb_offset + + ;
}
}
return 0 ;
}
/** Decode all MBs for an P frame in Simple/Main profile
* @ todo TODO : Process the blocks
* @ todo TODO : Use M $ MPEG - 4 cbp prediction
*/
static int decode_b_mbs ( VC9Context * v )
{
MpegEncContext * s = & v - > s ;
GetBitContext * gb = & v - > s . gb ;
int mb_offset = 0 , i /* MB / B postion information */ ;
int b_mv_type = BMV_TYPE_BACKWARD ;
int mquant , mqdiff ; /* MB quant stuff */
int ttmb ; /* MacroBlock transform type */
static const int size_table [ 6 ] = { 0 , 2 , 3 , 4 , 5 , 8 } ,
offset_table [ 6 ] = { 0 , 1 , 3 , 7 , 15 , 31 } ;
int mb_has_coeffs = 1 ; /* last_flag */
int dmv1_x , dmv1_y , dmv2_x , dmv2_y ; /* Differential MV components */
int k_x , k_y ; /* Long MV fixed bitlength */
int hpel_flag ; /* Some MB properties */
int index , index1 ; /* LUT indices */
int val , sign ; /* MVDATA temp values */
/* Select proper long MV range */
switch ( v - > mvrange )
{
case 1 : k_x = 10 ; k_y = 9 ; break ;
case 2 : k_x = 12 ; k_y = 10 ; break ;
case 3 : k_x = 13 ; k_y = 11 ; break ;
default : /*case 0 too */ k_x = 9 ; k_y = 8 ; break ;
}
hpel_flag = v - > mv_mode & 1 ; //MV_PMODE is HPEL
k_x - = hpel_flag ;
k_y - = hpel_flag ;
/* Select ttmb table depending on pq */
if ( v - > pq < 5 )
{
v - > tt_index = 0 ;
v - > ttblk4x4 = 3 ;
}
else if ( v - > pq < 13 )
{
v - > tt_index = 1 ;
v - > ttblk4x4 = 3 ;
}
else
{
v - > tt_index = 2 ;
v - > ttblk4x4 = 2 ;
}
for ( s - > mb_y = 0 ; s - > mb_y < s - > mb_height ; s - > mb_y + + )
{
for ( s - > mb_x = 0 ; s - > mb_x < s - > mb_width ; s - > mb_x + + )
{
if ( v - > direct_mb_plane . is_raw )
v - > direct_mb_plane . data [ mb_offset ] = get_bits ( gb , 1 ) ;
if ( v - > skip_mb_plane . is_raw )
v - > skip_mb_plane . data [ mb_offset ] = get_bits ( gb , 1 ) ;
if ( ! v - > direct_mb_plane . data [ mb_offset ] )
{
if ( v - > skip_mb_plane . data [ mb_offset ] )
{
b_mv_type = decode012 ( gb ) ;
if ( v - > bfraction > 420 /*1/2*/ & &
b_mv_type < 3 ) b_mv_type = 1 - b_mv_type ;
}
else
{
GET_MVDATA ( dmv1_x , dmv1_y ) ;
if ( ! s - > mb_intra /* b_mv1 tells not intra */ )
{
b_mv_type = decode012 ( gb ) ;
if ( v - > bfraction > 420 /*1/2*/ & &
b_mv_type < 3 ) b_mv_type = 1 - b_mv_type ;
}
}
}
if ( ! v - > skip_mb_plane . data [ mb_offset ] )
{
if ( mb_has_coeffs /* BMV1 == "last" */ )
{
GET_MQUANT ( ) ;
if ( s - > mb_intra /* intra mb */ )
s - > ac_pred = get_bits ( gb , 1 ) ;
}
else
{
/* if bmv1 tells MVs are interpolated */
if ( b_mv_type = = BMV_TYPE_INTERPOLATED )
{
GET_MVDATA ( dmv2_x , dmv2_y ) ;
}
/* GET_MVDATA has reset some stuff */
if ( mb_has_coeffs /* b_mv2 == "last" */ )
{
if ( s - > mb_intra /* intra_mb */ )
s - > ac_pred = get_bits ( gb , 1 ) ;
GET_MQUANT ( ) ;
}
}
}
//End1
if ( v - > ttmbf )
ttmb = get_vlc2 ( gb , vc9_ttmb_vlc [ v - > tt_index ] . table ,
VC9_TTMB_VLC_BITS , 12 ) ;
//End2
for ( i = 0 ; i < 6 ; i + + )
{
/* FIXME: process the block */
}
mb_offset + + ;
}
}
return 0 ;
}
/** @} */ //End for group std_mb
/** @} */ //End for group std_mb
# if HAS_ADVANCED_PROFILE
# if HAS_ADVANCED_PROFILE
@ -2612,7 +2367,7 @@ static int vc9_decode_frame(AVCodecContext *avctx,
{
{
VC9Context * v = avctx - > priv_data ;
VC9Context * v = avctx - > priv_data ;
MpegEncContext * s = & v - > s ;
MpegEncContext * s = & v - > s ;
int ret = FRAME_SKIPED , len , start_code ;
int ret = FRAME_SKIPED , len ;
AVFrame * pict = data ;
AVFrame * pict = data ;
uint8_t * tmp_buf ;
uint8_t * tmp_buf ;
v - > s . avctx = avctx ;
v - > s . avctx = avctx ;
@ -2782,14 +2537,7 @@ static int vc9_decode_frame(AVCodecContext *avctx,
else
else
# endif
# endif
{
{
switch ( s - > pict_type )
ret = standard_decode_mbs ( v ) ;
{
case I_TYPE : ret = standard_decode_i_mbs ( v ) ; break ;
case P_TYPE : ret = decode_p_mbs ( v ) ; break ;
case B_TYPE :
case BI_TYPE : ret = decode_b_mbs ( v ) ; break ;
default : ret = FRAME_SKIPED ;
}
if ( ret = = FRAME_SKIPED ) return buf_size ;
if ( ret = = FRAME_SKIPED ) return buf_size ;
}
}