- renaming the AC coding set variable names to more meaningful ones

- removed old MB decoding functions, and moved around macros to be used in
the previously unused code, which match better msmpeg4.c/whole MPV
framework
- cleaned (not yet functionnal, lots missing) DC prediction
- trying to pass the proper coded status to block decoder
patch by anonymous

Originally committed as revision 3973 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
anonymous 2005-02-23 17:24:17 +00:00 committed by Michael Niedermayer
parent 0ce5275d78
commit 8da75fb272

View File

@ -45,7 +45,7 @@ extern VLC ff_msmp4_mb_i_vlc;
static const uint16_t table_mb_intra[64][2];
/* Some inhibiting stuff */
#define HAS_ADVANCED_PROFILE 1
#define HAS_ADVANCED_PROFILE 0
#define TRACE 1
#if TRACE
@ -190,7 +190,10 @@ typedef struct BitPlane {
uint8_t is_raw; ///< Bit values must be read at MB level
} 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{
MpegEncContext s;
@ -257,7 +260,13 @@ typedef struct VC9Context{
uint8_t dqsbedge;
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
uint8_t ttmbf; ///< Transform type flag
int ttmb; ///< Transform type
@ -312,7 +321,6 @@ typedef struct VC9Context{
BitPlane over_flags_plane; ///< Overflags bitplane
uint8_t condover;
uint16_t *hrd_rate, *hrd_buffer;
int ac2_table_level; ///< Index for AC2 tables from AC2FRM element
//@}
#endif
} VC9Context;
@ -1145,13 +1153,14 @@ static int decode_b_picture_primary_header(VC9Context *v)
if (pqindex < 9) v->halfpq = get_bits(gb, 1);
if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
v->pquantizer = get_bits(gb, 1);
#if HAS_ADVANCED_PROFILE
if (v->profile == PROFILE_ADVANCED)
{
if (v->postprocflag) v->postproc = get_bits(gb, 2);
if (v->extended_mv == 1 && v->s.pict_type != BI_TYPE)
v->mvrange = get_prefix(gb, 0, 3);
}
#endif
else
{
if (v->extended_mv == 1)
@ -1285,12 +1294,13 @@ static int decode_i_picture_primary_header(VC9Context *v)
/** I frame header decoding, secondary part
* @param v VC9 context
* @return Status
* @warning Not called in A/S/C profiles, it seems
* @todo Support Advanced Profile headers
*/
static int decode_i_picture_secondary_header(VC9Context *v)
{
int status;
#if HAS_ADVANCED_PROFILE
int status;
if (v->profile == PROFILE_ADVANCED)
{
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;
/* 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)
{
v->ac2_table_level = decode012(gb);
v->y_ac_table_index = decode012(gb);
}
/* DC Syntax */
v->s.dc_table_index = decode012(gb);
@ -1513,7 +1523,7 @@ static int standard_decode_picture_secondary_header(VC9Context *v)
* check caller
* @{
*/
/** Frame header decoding, primary part
/** Frame header decoding, primary part
* @param v VC9 context
* @return Status
*/
@ -1592,10 +1602,10 @@ static int advanced_decode_picture_secondary_header(VC9Context *v)
if (status<0) return FRAME_SKIPED;
/* 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)
{
v->ac2_table_level = decode012(gb);
v->y_ac_table_index = decode012(gb);
}
/* DC Syntax */
v->s.dc_table_index = decode012(gb);
@ -1616,6 +1626,8 @@ static int advanced_decode_picture_secondary_header(VC9Context *v)
/**
* @def GET_MQUANT
* @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() \
if (v->dquantfrm) \
@ -1633,14 +1645,16 @@ static int advanced_decode_picture_secondary_header(VC9Context *v)
else mquant = get_bits(gb, 5); \
} \
} \
else mquant = v->pq; \
}
/**
* @def GET_MVDATA(_dmv_x, _dmv_y)
* @brief Get MV differentials
* @see MVDATA decoding from 8.3.5.2, p(1)20
* @param dmv_x Horizontal differential for decoded MV
* @param dmv_y Vertical differential for decoded MV
* @param _dmv_x Horizontal 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) \
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
* 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)
{
int a, b, c, wrap, pred, scale;
int16_t *dc_val;
static const uint16_t dcpred[31] = {
1024, 512, 341, 256, 205, 171, 146, 128,
114, 102, 93, 85, 79, 73, 68, 64,
60, 57, 54, 51, 49, 47, 45, 43,
41, 39, 38, 37, 35, 34, 33
};
/* find prediction */
if (n < 4) {
scale = s->y_dc_scale;
} else {
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];
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];
c = dc_val[ - wrap];
if(s->first_slice_line && (n&2)==0) b=c=1024;
/* 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...
/* XXX: Rule B is used only for I and BI frames in S/M/C profile
* with overlap filtering off
*/
if (scale == 8) {
a = (a + (8 >> 1)) / 8;
b = (b + (8 >> 1)) / 8;
c = (c + (8 >> 1)) / 8;
} else {
a = FASTDIV((a + (scale >> 1)), scale);
b = FASTDIV((b + (scale >> 1)), scale);
c = FASTDIV((c + (scale >> 1)), scale);
if ((s->pict_type == I_TYPE || s->pict_type == BI_TYPE) &&
1 /* XXX: overlap filtering off */)
{
/* Set outer values */
if (s->first_slice_line && n!=2) b=c=dcpred[scale];
if (s->mb_x == 0) b=a=dcpred[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)) {
pred = c;
@ -1761,7 +1769,7 @@ static inline int vc9_pred_dc(MpegEncContext *s, int n,
* @param block 8x8 DCT block
* @param n Block index in the current MB (<4=>luma)
* @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 Intra TT: Table 20, p72 + p(1)05-(1)07
* @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 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)
{
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);
}
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;
}
if (dcdiff)
@ -1813,18 +1828,20 @@ int vc9_decode_block(VC9Context *v, DCTELEM block[64], int n, int coded, int mqu
/* Prediction */
dcdiff += vc9_pred_dc(s, n, &dc_val, &dc_pred_dir);
if (n < 4) {
*dc_val = dcdiff * s->y_dc_scale;
} else {
*dc_val = dcdiff * s->c_dc_scale;
}
if (dcdiff < 0)
{
av_log(s->avctx, AV_LOG_ERROR, "DC=%i<0\n", dcdiff);
return -1;
}
block[0] = dcdiff; //XXX: Must be > 0
*dc_val = dcdiff;
/* Store the quantized DC coeff, used for prediction */
if (n < 4) {
block[0] = dcdiff * s->y_dc_scale;
} else {
block[0] = dcdiff * s->c_dc_scale;
}
if (block[0] < 0) {
#if TRACE
//av_log(s->avctx, AV_LOG_ERROR, "DC=%i<0\n", dcdiff);
#endif
//return -1;
}
/* Skip ? */
run_diff = 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
i = 63; //XXX: nothing done yet
not_coded:
@ -1901,6 +1919,9 @@ static inline int vc9_coded_block_pred(MpegEncContext * s, int n, uint8_t **code
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 i, cbp, val;
@ -1922,15 +1943,19 @@ int vc9_decode_i_mb(VC9Context *v, DCTELEM block[6][64])
}
cbp |= val << (5 - i);
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,
"\nerror while decoding block: %d x %d (%d)\n", v->s.mb_x, v->s.mb_y, i);
return -1;
}
return -1;
}
}
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])
{
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 val, sign; /* temp values */
mquant = v->pq; /* Loosy initialization */
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)
@ -1965,11 +1992,19 @@ int vc9_decode_p_mb(VC9Context *v, DCTELEM block[6][64])
if (v->mv_mode == MV_PMODE_1MV ||
v->mv_mode == MV_PMODE_MIXED_MV)
hybrid_pred = get_bits(gb, 1);
/* FIXME Set DC val for inter block ? */
if (s->mb_intra && !mb_has_coeffs)
{
GET_MQUANT();
s->ac_pred = get_bits(gb, 1);
/* 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)
{
@ -1980,12 +2015,15 @@ int vc9_decode_p_mb(VC9Context *v, DCTELEM block[6][64])
else
{
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)
ttmb = get_vlc2(gb, vc9_ttmb_vlc[v->tt_index].table,
VC9_TTMB_VLC_BITS, 12);
for (i=0; i<6; i++)
{
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 */)
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);
@ -2041,12 +2080,15 @@ int vc9_decode_p_mb(VC9Context *v, DCTELEM block[6][64])
}
else //Skipped MB
{
/* XXX: Skipped => cbp=0 and mquant doesn't matter ? */
for (i=0; i<4; i++)
{
if (v->mv_mode == MV_PMODE_MIXED_MV /* Hybrid pred */)
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 */
return 0;
}
@ -2056,20 +2098,98 @@ int vc9_decode_p_mb(VC9Context *v, DCTELEM block[6][64])
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 i;
//Decode CBP
MpegEncContext *s = &v->s;
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++)
{
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;
}
/** 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)
{
GetBitContext *gb = &v->s.gb;
MpegEncContext *s = &v->s;
/* Set transform type info depending on pq */
@ -2113,381 +2233,16 @@ static int standard_decode_mbs(VC9Context *v)
//TODO Move out of the loop
switch (s->pict_type)
{
case I_TYPE: vc9_decode_i_mb(v, NULL); break;
case P_TYPE: vc9_decode_i_mb(v, NULL); break;
case I_TYPE: vc9_decode_i_mb(v, s->block); break;
case P_TYPE: vc9_decode_p_mb(v, s->block); break;
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 ?
}
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
#if HAS_ADVANCED_PROFILE
@ -2612,7 +2367,7 @@ static int vc9_decode_frame(AVCodecContext *avctx,
{
VC9Context *v = avctx->priv_data;
MpegEncContext *s = &v->s;
int ret = FRAME_SKIPED, len, start_code;
int ret = FRAME_SKIPED, len;
AVFrame *pict = data;
uint8_t *tmp_buf;
v->s.avctx = avctx;
@ -2782,14 +2537,7 @@ static int vc9_decode_frame(AVCodecContext *avctx,
else
#endif
{
switch(s->pict_type)
{
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;
}
ret = standard_decode_mbs(v);
if (ret == FRAME_SKIPED) return buf_size;
}