# HG changeset patch # User michael # Date 1107102897 0 # Node ID 81a9f883a17aea4a935828fff43afc05eba40528 # Parent 73afecc117a3f0d011f8fb55ab00949775ce8c70 In that patch: - avctx and gb elements were removed from VC9Context, hence a larger diff - some code was added to h263dec.c regarding CODEC_ID_WMV3 (should apply to CODEC_ID_VC9 too) - VLC tables and other related tables were made global whenever this seemed necessary; appropriate changes were therefore made to other parts of the code using those tables - the change for the bitplane management to a struct (some of them should eventually be mapped to MpegEncContext arrays) wasn't associated with the proper frees; should be fixed now patch by anonymous better names for globalized tables by me diff -r 73afecc117a3 -r 81a9f883a17a h263dec.c --- a/h263dec.c Sun Jan 30 14:10:30 2005 +0000 +++ b/h263dec.c Sun Jan 30 16:34:57 2005 +0000 @@ -85,6 +85,11 @@ s->h263_pred = 1; s->msmpeg4_version=5; break; + case CODEC_ID_WMV3: + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->msmpeg4_version=6; + break; case CODEC_ID_H263I: break; case CODEC_ID_FLV1: diff -r 73afecc117a3 -r 81a9f883a17a msmpeg4.c --- a/msmpeg4.c Sun Jan 30 14:10:30 2005 +0000 +++ b/msmpeg4.c Sun Jan 30 16:34:57 2005 +0000 @@ -75,6 +75,8 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); static int wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); +/* vc9 externs */ +extern uint8_t wmv3_dc_scale_table[32]; #ifdef DEBUG int intra_count = 0; @@ -175,6 +177,11 @@ s->y_dc_scale_table= wmv1_y_dc_scale_table; s->c_dc_scale_table= wmv1_c_dc_scale_table; break; + case 6: + s->y_dc_scale_table= wmv3_dc_scale_table; + s->c_dc_scale_table= wmv3_dc_scale_table; + break; + } @@ -629,7 +636,7 @@ if (s->pict_type == I_TYPE) { set_stat(ST_INTRA_MB); put_bits(&s->pb, - table_mb_intra[coded_cbp][1], table_mb_intra[coded_cbp][0]); + ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); } else { if (s->use_skip_mb_code) put_bits(&s->pb, 1, 0); /* mb coded */ @@ -1030,9 +1037,9 @@ /* decoding stuff */ static VLC mb_non_intra_vlc[4]; -static VLC mb_intra_vlc; -static VLC dc_lum_vlc[2]; -static VLC dc_chroma_vlc[2]; +VLC ff_msmp4_mb_i_vlc; +VLC ff_msmp4_dc_luma_vlc[2]; +VLC ff_msmp4_dc_chroma_vlc[2]; static VLC v2_dc_lum_vlc; static VLC v2_dc_chroma_vlc; static VLC cbpy_vlc; @@ -1121,16 +1128,16 @@ mv->table_mv_code, 2, 2, 1); } - init_vlc(&dc_lum_vlc[0], DC_VLC_BITS, 120, + init_vlc(&ff_msmp4_dc_luma_vlc[0], DC_VLC_BITS, 120, &ff_table0_dc_lum[0][1], 8, 4, &ff_table0_dc_lum[0][0], 8, 4, 1); - init_vlc(&dc_chroma_vlc[0], DC_VLC_BITS, 120, + init_vlc(&ff_msmp4_dc_chroma_vlc[0], DC_VLC_BITS, 120, &ff_table0_dc_chroma[0][1], 8, 4, &ff_table0_dc_chroma[0][0], 8, 4, 1); - init_vlc(&dc_lum_vlc[1], DC_VLC_BITS, 120, + init_vlc(&ff_msmp4_dc_luma_vlc[1], DC_VLC_BITS, 120, &ff_table1_dc_lum[0][1], 8, 4, &ff_table1_dc_lum[0][0], 8, 4, 1); - init_vlc(&dc_chroma_vlc[1], DC_VLC_BITS, 120, + init_vlc(&ff_msmp4_dc_chroma_vlc[1], DC_VLC_BITS, 120, &ff_table1_dc_chroma[0][1], 8, 4, &ff_table1_dc_chroma[0][0], 8, 4, 1); @@ -1160,9 +1167,9 @@ &wmv2_inter_table[i][0][0], 8, 4, 1); //FIXME name? } - init_vlc(&mb_intra_vlc, MB_INTRA_VLC_BITS, 64, - &table_mb_intra[0][1], 4, 2, - &table_mb_intra[0][0], 4, 2, 1); + init_vlc(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64, + &ff_msmp4_mb_i_table[0][1], 4, 2, + &ff_msmp4_mb_i_table[0][0], 4, 2, 1); init_vlc(&v1_intra_cbpc_vlc, V1_INTRA_CBPC_VLC_BITS, 8, intra_MCBPC_bits, 1, 1, @@ -1187,6 +1194,8 @@ break; case 5: s->decode_mb= wmv2_decode_mb; + case 6: + //FIXME + TODO VC9 decode mb break; } @@ -1588,7 +1597,7 @@ } else { set_stat(ST_INTRA_MB); s->mb_intra = 1; - code = get_vlc2(&s->gb, mb_intra_vlc.table, MB_INTRA_VLC_BITS, 2); + code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); if (code < 0) return -1; /* predict coded block pattern */ @@ -1911,9 +1920,9 @@ level-=256; }else{ //FIXME optimize use unified tables & index if (n < 4) { - level = get_vlc2(&s->gb, dc_lum_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); + level = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); } else { - level = get_vlc2(&s->gb, dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); + level = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); } if (level < 0){ av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n"); diff -r 73afecc117a3 -r 81a9f883a17a msmpeg4data.h --- a/msmpeg4data.h Sun Jan 30 14:10:30 2005 +0000 +++ b/msmpeg4data.h Sun Jan 30 16:34:57 2005 +0000 @@ -4,7 +4,7 @@ */ /* intra picture macro block coded block pattern */ -static const uint16_t table_mb_intra[64][2] = { +const uint16_t ff_msmp4_mb_i_table[64][2] = { { 0x1, 1 },{ 0x17, 6 },{ 0x9, 5 },{ 0x5, 5 }, { 0x6, 5 },{ 0x47, 9 },{ 0x20, 7 },{ 0x10, 7 }, { 0x2, 5 },{ 0x7c, 9 },{ 0x3a, 7 },{ 0x1d, 7 }, diff -r 73afecc117a3 -r 81a9f883a17a vc9.c --- a/vc9.c Sun Jan 30 14:10:30 2005 +0000 +++ b/vc9.c Sun Jan 30 16:34:57 2005 +0000 @@ -32,8 +32,14 @@ #include "avcodec.h" #include "mpegvideo.h" #include "vc9data.h" + extern const uint32_t ff_table0_dc_lum[120][2], ff_table1_dc_lum[120][2]; extern const uint32_t ff_table0_dc_chroma[120][2], ff_table1_dc_chroma[120][2]; +extern VLC ff_msmp4_dc_luma_vlc[2], ff_msmp4_dc_chroma_vlc[2]; +#define MB_INTRA_VLC_BITS 9 +extern VLC ff_msmp4_mb_i_vlc; +#define DC_VLC_BITS 9 +static const uint16_t table_mb_intra[64][2]; /* Some inhibiting stuff */ #define HAS_ADVANCED_PROFILE 1 @@ -45,7 +51,7 @@ if (init_vlc(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size, \ codes, codes_wrap, codes_size, use_static) < 0) \ { \ - av_log(v->avctx, AV_LOG_ERROR, "Error for " # vlc " (%i)\n", i); \ + av_log(v->s.avctx, AV_LOG_ERROR, "Error for " # vlc " (%i)\n", i); \ return -1; \ } #else @@ -134,15 +140,10 @@ static VLC vc9_ttmb_vlc[3]; #define VC9_MV_DIFF_VLC_BITS 9 //15 static VLC vc9_mv_diff_vlc[4]; -#define VC9_CBPCY_I_VLC_BITS 9 //13 -static VLC vc9_cbpcy_i_vlc; #define VC9_CBPCY_P_VLC_BITS 9 //14 static VLC vc9_cbpcy_p_vlc[4]; #define VC9_4MV_BLOCK_PATTERN_VLC_BITS 6 static VLC vc9_4mv_block_pattern_vlc[4]; -#define VC9_DC_VLC_BITS 9 -static VLC vc9_luma_dc_vlc[2]; -static VLC vc9_chroma_dc_vlc[2]; //We mainly need data and is_raw, so this struct could be avoided //to save a level of indirection; feel free to modify @@ -155,8 +156,7 @@ typedef struct VC9Context{ /* No MpegEnc context, might be good to use it */ - GetBitContext gb; - AVCodecContext *avctx; + MpegEncContext s; /***************************/ /* Sequence Header */ @@ -167,7 +167,6 @@ int multires; //frame-level RESPIC syntax element present int res_fasttx; //always 1 int res_transtab; //always 0 - int syncmarker; //Sync markers presents int rangered; //RANGEREDFRM (range reduction) syntax element present int res_rtm_flag; //reserved, set to 1 int reserved; //duh @@ -196,8 +195,9 @@ int loopfilter; int fastuvmc; //Rounding of qpel vector to hpel ? (not in Simple) int extended_mv; //Ext MV in P/B (not in Simple) - int dquant; //Q varies with MBs, 2bits (not in Simple) + int dquant; //How qscale varies with MBs, 2bits (not in Simple) int vstransform; //variable-size transform46 + int overlap; //overlapped transforms in use int quantizer_mode; //2, quantizer mode used for sequence, see QUANT_* @@ -209,10 +209,8 @@ /*****************************/ /* All profiles */ uint8_t mv_mode, mv_mode2; /* MV coding mode */ - uint8_t pict_type; /* Picture type, mapped on MPEG types */ uint8_t pq, altpq; /* Quantizers */ uint8_t dquantfrm, dqprofile, dqsbedge, dqbilevel; /* pquant parameters */ - int width_mb, height_mb; int tile; /* 3x2 if (width_mb%3) else 2x3 */ VLC *luma_ac_vlc, *chroma_ac_vlc, *luma_dc_vlc, *chroma_dc_vlc; /* transac/dcfrm bits are indexes */ @@ -251,7 +249,6 @@ uint8_t toplefty; uint8_t bottomrightx; uint8_t bottomrighty; - uint8_t rndctrl; uint8_t uvsamp; uint8_t postproc; int hrd_num_leaky_buckets; @@ -299,7 +296,7 @@ #endif } -static int init_common(VC9Context *v) +static int vc9_init_common(VC9Context *v) { static int done = 0; int i; @@ -339,24 +336,9 @@ INIT_VLC(&vc9_norm6_vlc, VC9_NORM6_VLC_BITS, 64, vc9_norm6_bits, 1, 1, vc9_norm6_codes, 2, 2, 1); - INIT_VLC(&vc9_cbpcy_i_vlc, VC9_CBPCY_I_VLC_BITS, 64, - vc9_cbpcy_i_bits, 1, 1, - vc9_cbpcy_i_codes, 2, 2, 1); INIT_VLC(&vc9_imode_vlc, VC9_IMODE_VLC_BITS, 7, vc9_imode_bits, 1, 1, vc9_imode_codes, 1, 1, 1); - INIT_VLC(&vc9_luma_dc_vlc[0], VC9_DC_VLC_BITS, 120, - &ff_table0_dc_lum[0][1], 8, 4, - &ff_table0_dc_lum[0][0], 8, 4, 1); - INIT_VLC(&vc9_chroma_dc_vlc[0], VC9_DC_VLC_BITS, 120, - &ff_table0_dc_chroma[0][1], 8, 4, - &ff_table0_dc_chroma[0][0], 8, 4, 1); - INIT_VLC(&vc9_luma_dc_vlc[1], VC9_DC_VLC_BITS, 120, - &ff_table1_dc_lum[0][1], 8, 4, - &ff_table1_dc_lum[0][0], 8, 4, 1); - INIT_VLC(&vc9_chroma_dc_vlc[1], VC9_DC_VLC_BITS, 120, - &ff_table1_dc_chroma[0][1], 8, 4, - &ff_table1_dc_chroma[0][0], 8, 4, 1); for (i=0; i<3; i++) { INIT_VLC(&vc9_ttmb_vlc[i], VC9_TTMB_VLC_BITS, 16, @@ -676,11 +658,11 @@ if (v->profile <= PROFILE_MAIN) #endif { - v->syncmarker = get_bits(gb, 1); + v->s.resync_marker = get_bits(gb, 1); v->rangered = get_bits(gb, 1); } - avctx->max_b_frames = get_bits(gb, 3); //common + v->s.max_b_frames = avctx->max_b_frames = get_bits(gb, 3); //common v->quantizer_mode = get_bits(gb, 2); //common #if HAS_ADVANCED_PROFILE @@ -703,7 +685,7 @@ "DQuant=%i, Quantizer mode=%i, Max B frames=%i\n", v->profile, v->frmrtq_postproc, v->bitrtq_postproc, v->loopfilter, v->multires, v->fastuvmc, v->extended_mv, - v->rangered, v->vstransform, v->overlap, v->syncmarker, + v->rangered, v->vstransform, v->overlap, v->s.resync_marker, v->dquant, v->quantizer_mode, avctx->max_b_frames ); return 0; @@ -778,15 +760,22 @@ return 0; } +void free_bitplane(BitPlane *bp) +{ + bp->width = bp->stride = bp->height = 0; + if (bp->data) av_freep(&bp->data); +} + static void decode_rowskip(uint8_t* plane, int width, int height, int stride, VC9Context *v){ int x, y; + GetBitContext *gb = &v->s.gb; for (y=0; ygb, 1)) //rowskip + if (!get_bits(gb, 1)) //rowskip memset(plane, 0, width); else for (x=0; xgb, 1); + plane[x] = get_bits(gb, 1); plane += stride; } } @@ -794,14 +783,15 @@ //FIXME optimize static void decode_colskip(uint8_t* plane, int width, int height, int stride, VC9Context *v){ int x, y; + GetBitContext *gb = &v->s.gb; for (x=0; xgb, 1)) //colskip + if (!get_bits(gb, 1)) //colskip for (y=0; ygb, 1); + plane[y*stride] = get_bits(gb, 1); plane ++; } } @@ -813,11 +803,13 @@ // later on) static int bitplane_decoding(BitPlane *bp, VC9Context *v) { + GetBitContext *gb = &v->s.gb; + int imode, x, y, code, use_vertical_tile, tile_w, tile_h; uint8_t invert, *planep = bp->data; - invert = get_bits(&v->gb, 1); - imode = get_vlc2(&v->gb, vc9_imode_vlc.table, VC9_IMODE_VLC_BITS, 2); + invert = get_bits(gb, 1); + imode = get_vlc2(gb, vc9_imode_vlc.table, VC9_IMODE_VLC_BITS, 2); bp->is_raw = 0; switch (imode) @@ -828,9 +820,9 @@ return invert; case IMODE_DIFF2: case IMODE_NORM2: - if ((bp->height*bp->width) & 1) *(++planep) = get_bits(&v->gb, 1); + if ((bp->height*bp->width) & 1) *(++planep) = get_bits(gb, 1); for(x=0; x<(bp->height*bp->width)>>1; x++){ - code = get_vlc2(&v->gb, vc9_norm2_vlc.table, VC9_NORM2_VLC_BITS, 2); + code = get_vlc2(gb, vc9_norm2_vlc.table, VC9_NORM2_VLC_BITS, 2); *(++planep) = code&1; //lsb => left *(++planep) = code&2; //msb => right - bitplane => only !0 matters //FIXME width->stride @@ -844,9 +836,9 @@ for(y= bp->height%tile_h; y< bp->height; y+=tile_h){ for(x= bp->width%tile_w; x< bp->width; x+=tile_w){ - code = get_vlc2(&v->gb, vc9_norm6_vlc.table, VC9_NORM6_VLC_BITS, 2); + code = get_vlc2(gb, vc9_norm6_vlc.table, VC9_NORM6_VLC_BITS, 2); if(code<0){ - av_log(v->avctx, AV_LOG_DEBUG, "inavlid NORM-6 VLC\n"); + av_log(v->s.avctx, AV_LOG_DEBUG, "inavlid NORM-6 VLC\n"); return -1; } //FIXME following is a pure guess and probably wrong @@ -912,35 +904,36 @@ /*****************************************************************************/ static int vop_dquant_decoding(VC9Context *v) { + GetBitContext *gb = &v->s.gb; int pqdiff; //variable size if (v->dquant == 2) { - pqdiff = get_bits(&v->gb, 3); - if (pqdiff == 7) v->altpq = get_bits(&v->gb, 5); + pqdiff = get_bits(gb, 3); + if (pqdiff == 7) v->altpq = get_bits(gb, 5); else v->altpq = v->pq + pqdiff + 1; } else { - v->dquantfrm = get_bits(&v->gb, 1); + v->dquantfrm = get_bits(gb, 1); if ( v->dquantfrm ) { - v->dqprofile = get_bits(&v->gb, 2); + v->dqprofile = get_bits(gb, 2); switch (v->dqprofile) { case DQPROFILE_SINGLE_EDGE: case DQPROFILE_DOUBLE_EDGES: - v->dqsbedge = get_bits(&v->gb, 2); + v->dqsbedge = get_bits(gb, 2); break; case DQPROFILE_ALL_MBS: - v->dqbilevel = get_bits(&v->gb, 1); + v->dqbilevel = get_bits(gb, 1); default: break; //Forbidden ? } if (!v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS) { - pqdiff = get_bits(&v->gb, 3); - if (pqdiff == 7) v->altpq = get_bits(&v->gb, 5); + pqdiff = get_bits(gb, 3); + if (pqdiff == 7) v->altpq = get_bits(gb, 5); else v->altpq = v->pq + pqdiff + 1; } } @@ -961,38 +954,40 @@ - for A Profile, PTYPE already tells so and we can go directly there */ + GetBitContext *gb = &v->s.gb; int pqindex; /* Read the quantization stuff */ - pqindex = get_bits(&v->gb, 5); + pqindex = get_bits(gb, 5); if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) v->pq = pquant_table[0][pqindex]; else { v->pq = pquant_table[v->quantizer_mode-1][pqindex]; } - if (pqindex < 9) v->halfpq = get_bits(&v->gb, 1); + if (pqindex < 9) v->halfpq = get_bits(gb, 1); if (v->quantizer_mode == QUANT_FRAME_EXPLICIT) - v->pquantizer = get_bits(&v->gb, 1); + v->pquantizer = get_bits(gb, 1); /* Read the MV type/mode */ if (v->extended_mv == 1) - v->mvrange = get_prefix(&v->gb, 0, 3); + v->mvrange = get_prefix(gb, 0, 3); /* FIXME: what table are used in that case ? */ v->mv_diff_vlc = &vc9_mv_diff_vlc[0]; - v->cbpcy_vlc = &vc9_cbpcy_i_vlc; + v->cbpcy_vlc = &ff_msmp4_mb_i_vlc; - av_log(v->avctx, AV_LOG_DEBUG, "B frame, QP=%i\n", v->pq); - av_log(v->avctx, AV_LOG_ERROR, "BI_TYPE not supported yet\n"); + av_log(v->s.avctx, AV_LOG_DEBUG, "B frame, QP=%i\n", v->pq); + av_log(v->s.avctx, AV_LOG_ERROR, "BI_TYPE not supported yet\n"); /* Epilog should be done in caller */ return -1; } /* Tables 11+12, p62-65 */ -static int decode_b_picture_header(VC9Context *v) +static int decode_b_picture_primary_header(VC9Context *v) { - int pqindex, status; + GetBitContext *gb = &v->s.gb; + int pqindex, status; /* Prolog common to all frametypes should be done in caller */ if (v->profile == PROFILE_SIMPLE) @@ -1001,7 +996,7 @@ return FRAME_SKIPED; } - v->bfraction = vc9_bfraction_lut[get_vlc2(&v->gb, vc9_bfraction_vlc.table, + v->bfraction = vc9_bfraction_lut[get_vlc2(gb, vc9_bfraction_vlc.table, VC9_BFRACTION_VLC_BITS, 2)]; if (v->bfraction < -1) { @@ -1015,26 +1010,26 @@ } /* Read the quantization stuff */ - pqindex = get_bits(&v->gb, 5); + pqindex = get_bits(gb, 5); if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) v->pq = pquant_table[0][pqindex]; else { v->pq = pquant_table[v->quantizer_mode-1][pqindex]; } - if (pqindex < 9) v->halfpq = get_bits(&v->gb, 1); + if (pqindex < 9) v->halfpq = get_bits(gb, 1); if (v->quantizer_mode == QUANT_FRAME_EXPLICIT) - v->pquantizer = get_bits(&v->gb, 1); + v->pquantizer = get_bits(gb, 1); /* Read the MV type/mode */ if (v->extended_mv == 1) - v->mvrange = get_prefix(&v->gb, 0, 3); - v->mv_mode = get_bits(&v->gb, 1); + v->mvrange = get_prefix(gb, 0, 3); + v->mv_mode = get_bits(gb, 1); if (v->pq < 13) { if (!v->mv_mode) { - v->mv_mode = get_bits(&v->gb, 2); + v->mv_mode = get_bits(gb, 2); if (v->mv_mode) av_log(v, AV_LOG_ERROR, "mv_mode for lowquant B frame was %i\n", v->mv_mode); @@ -1044,20 +1039,31 @@ { if (!v->mv_mode) { - if (get_bits(&v->gb, 1)) + if (get_bits(gb, 1)) av_log(v, AV_LOG_ERROR, "mv_mode for highquant B frame was %i\n", v->mv_mode); } v->mv_mode = 1-v->mv_mode; //To match (pq < 13) mapping } + return 0; +} + +static int decode_b_picture_secondary_header(VC9Context *v) +{ + GetBitContext *gb = &v->s.gb; + int status; + + bitplane_decoding(&v->skip_mb_plane, v); + if (status < 0) return -1; +#if TRACE if (v->mv_mode == MV_PMODE_MIXED_MV) { status = bitplane_decoding(&v->mv_type_mb_plane, v); if (status < 0) return -1; #if TRACE - av_log(v->avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: " + av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); #endif } @@ -1066,20 +1072,17 @@ status = bitplane_decoding(&v->direct_mb_plane, v); if (status < 0) return -1; #if TRACE - av_log(v->avctx, AV_LOG_DEBUG, "MB Direct plane encoding: " + av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); #endif - bitplane_decoding(&v->skip_mb_plane, v); - if (status < 0) return -1; -#if TRACE - av_log(v->avctx, AV_LOG_DEBUG, "Skip MB plane encoding: " + av_log(v->s.avctx, AV_LOG_DEBUG, "Skip MB plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); #endif /* FIXME: what is actually chosen for B frames ? */ - v->mv_diff_vlc = &vc9_mv_diff_vlc[get_bits(&v->gb, 2)]; - v->cbpcy_vlc = &vc9_cbpcy_p_vlc[get_bits(&v->gb, 2)]; + v->mv_diff_vlc = &vc9_mv_diff_vlc[get_bits(gb, 2)]; + v->cbpcy_vlc = &vc9_cbpcy_p_vlc[get_bits(gb, 2)]; if (v->dquant) { vop_dquant_decoding(v); @@ -1087,10 +1090,10 @@ if (v->vstransform) { - v->ttmbf = get_bits(&v->gb, 1); + v->ttmbf = get_bits(gb, 1); if (v->ttmbf) { - v->ttfrm = get_bits(&v->gb, 2); + v->ttfrm = get_bits(gb, 2); av_log(v, AV_LOG_INFO, "Transform used: %ix%i\n", (v->ttfrm & 2) ? 4 : 8, (v->ttfrm & 1) ? 4 : 8); } @@ -1102,53 +1105,54 @@ /* Tables 5+7, p53-54 and 55-57 */ static int decode_i_picture_header(VC9Context *v) { - int pqindex, status = 0, ac_pred; + GetBitContext *gb = &v->s.gb; + int pqindex, status = 0; /* Prolog common to all frametypes should be done in caller */ //BF = Buffer Fullness - if (v->profile <= PROFILE_MAIN && get_bits(&v->gb, 7)) + if (v->profile <= PROFILE_MAIN && get_bits(gb, 7)) { av_log(v, AV_LOG_DEBUG, "I BufferFullness not 0\n"); } /* Quantizer stuff */ - pqindex = get_bits(&v->gb, 5); + pqindex = get_bits(gb, 5); if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) v->pq = pquant_table[0][pqindex]; else { v->pq = pquant_table[v->quantizer_mode-1][pqindex]; } - if (pqindex < 9) v->halfpq = get_bits(&v->gb, 1); + if (pqindex < 9) v->halfpq = get_bits(gb, 1); if (v->quantizer_mode == QUANT_FRAME_EXPLICIT) - v->pquantizer = get_bits(&v->gb, 1); - av_log(v->avctx, AV_LOG_DEBUG, "I frame: QP=%i (+%i/2)\n", + v->pquantizer = get_bits(gb, 1); + av_log(v->s.avctx, AV_LOG_DEBUG, "I frame: QP=%i (+%i/2)\n", v->pq, v->halfpq); #if HAS_ADVANCED_PROFILE if (v->profile <= PROFILE_MAIN) #endif { - if (v->extended_mv) v->mvrange = get_prefix(&v->gb, 0, 3); - if (v->multires) v->respic = get_bits(&v->gb, 2); + if (v->extended_mv) v->mvrange = get_prefix(gb, 0, 3); + if (v->multires) v->respic = get_bits(gb, 2); } #if HAS_ADVANCED_PROFILE else { - ac_pred = get_bits(&v->gb, 1); - if (v->postprocflag) v->postproc = get_bits(&v->gb, 1); + v->s.ac_pred = get_bits(gb, 1); + if (v->postprocflag) v->postproc = get_bits(gb, 1); /* 7.1.1.34 + 8.5.2 */ if (v->overlap && v->pq<9) { - v->condover = get_bits(&v->gb, 1); + v->condover = get_bits(gb, 1); if (v->condover) { - v->condover = 2+get_bits(&v->gb, 1); + v->condover = 2+get_bits(gb, 1); if (v->condover == 3) { status = bitplane_decoding(&v->over_flags_plane, v); if (status < 0) return -1; #if TRACE - av_log(v->avctx, AV_LOG_DEBUG, "Overflags plane encoding: " + av_log(v->s.avctx, AV_LOG_DEBUG, "Overflags plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); #endif } @@ -1162,41 +1166,48 @@ } /* Table 9, p58-60 */ -static int decode_p_picture_header(VC9Context *v) +static int decode_p_picture_primary_header(VC9Context *v) { /* INTERFRM, FRMCNT, RANGEREDFRM read in caller */ + GetBitContext *gb = &v->s.gb; int lowquant, pqindex, status = 0; - pqindex = get_bits(&v->gb, 5); + pqindex = get_bits(gb, 5); if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) v->pq = pquant_table[0][pqindex]; else { v->pq = pquant_table[v->quantizer_mode-1][pqindex]; } - if (pqindex < 9) v->halfpq = get_bits(&v->gb, 1); + if (pqindex < 9) v->halfpq = get_bits(gb, 1); if (v->quantizer_mode == QUANT_FRAME_EXPLICIT) - v->pquantizer = get_bits(&v->gb, 1); - av_log(v->avctx, AV_LOG_DEBUG, "P Frame: QP=%i (+%i/2)\n", + v->pquantizer = get_bits(gb, 1); + av_log(v->s.avctx, AV_LOG_DEBUG, "P Frame: QP=%i (+%i/2)\n", v->pq, v->halfpq); - if (v->extended_mv == 1) v->mvrange = get_prefix(&v->gb, 0, 3); + if (v->extended_mv == 1) v->mvrange = get_prefix(gb, 0, 3); #if HAS_ADVANCED_PROFILE if (v->profile > PROFILE_MAIN) { - if (v->postprocflag) v->postproc = get_bits(&v->gb, 1); + if (v->postprocflag) v->postproc = get_bits(gb, 1); } else #endif - if (v->multires) v->respic = get_bits(&v->gb, 2); + if (v->multires) v->respic = get_bits(gb, 2); lowquant = (v->pquantizer>12) ? 0 : 1; - v->mv_mode = mv_pmode_table[lowquant][get_prefix(&v->gb, 1, 4)]; + v->mv_mode = mv_pmode_table[lowquant][get_prefix(gb, 1, 4)]; if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { - v->mv_mode2 = mv_pmode_table[lowquant][get_prefix(&v->gb, 1, 3)]; - v->lumscale = get_bits(&v->gb, 6); - v->lumshift = get_bits(&v->gb, 6); + v->mv_mode2 = mv_pmode_table[lowquant][get_prefix(gb, 1, 3)]; + v->lumscale = get_bits(gb, 6); + v->lumshift = get_bits(gb, 6); } + return 0; +} +static int decode_p_picture_secondary_header(VC9Context *v) +{ + GetBitContext *gb = &v->s.gb; + int status = 0; if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_MIXED_MV) || v->mv_mode == MV_PMODE_MIXED_MV) @@ -1204,7 +1215,7 @@ status = bitplane_decoding(&v->mv_type_mb_plane, v); if (status < 0) return -1; #if TRACE - av_log(v->avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: " + av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); #endif } @@ -1212,27 +1223,27 @@ status = bitplane_decoding(&v->skip_mb_plane, v); if (status < 0) return -1; #if TRACE - av_log(v->avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " + av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); #endif /* Hopefully this is correct for P frames */ - v->mv_diff_vlc = &vc9_mv_diff_vlc[get_bits(&v->gb, 2)]; - v->cbpcy_vlc = &vc9_cbpcy_p_vlc[get_bits(&v->gb, 2)]; + v->mv_diff_vlc = &vc9_mv_diff_vlc[get_bits(gb, 2)]; + v->cbpcy_vlc = &vc9_cbpcy_p_vlc[get_bits(gb, 2)]; if (v->dquant) { - av_log(v->avctx, AV_LOG_INFO, "VOP DQuant info\n"); + av_log(v->s.avctx, AV_LOG_INFO, "VOP DQuant info\n"); vop_dquant_decoding(v); } if (v->vstransform) { - v->ttmbf = get_bits(&v->gb, 1); + v->ttmbf = get_bits(gb, 1); if (v->ttmbf) { - v->ttfrm = get_bits(&v->gb, 2); - av_log(v->avctx, AV_LOG_INFO, "Transform used: %ix%i\n", + v->ttfrm = get_bits(gb, 2); + av_log(v->s.avctx, AV_LOG_INFO, "Transform used: %ix%i\n", (v->ttfrm & 2) ? 4 : 8, (v->ttfrm & 1) ? 4 : 8); } } @@ -1241,27 +1252,28 @@ } -static int standard_decode_picture_header(VC9Context *v) +static int standard_decode_picture_primary_header(VC9Context *v) { - int status = 0, index; + GetBitContext *gb = &v->s.gb; + int status = 0; - if (v->finterpflag) v->interpfrm = get_bits(&v->gb, 1); - skip_bits(&v->gb, 2); //framecnt unused - if (v->rangered) v->rangeredfrm = get_bits(&v->gb, 1); - v->pict_type = get_bits(&v->gb, 1); - if (v->avctx->max_b_frames && !v->pict_type) + if (v->finterpflag) v->interpfrm = get_bits(gb, 1); + skip_bits(gb, 2); //framecnt unused + if (v->rangered) v->rangeredfrm = get_bits(gb, 1); + v->s.pict_type = get_bits(gb, 1); + if (v->s.avctx->max_b_frames && !v->s.pict_type) { - if (get_bits(&v->gb, 1)) v->pict_type = I_TYPE; - else v->pict_type = P_TYPE; + if (get_bits(gb, 1)) v->s.pict_type = I_TYPE; + else v->s.pict_type = P_TYPE; } - else v->pict_type++; //P_TYPE + else v->s.pict_type++; //P_TYPE - switch (v->pict_type) + switch (v->s.pict_type) { case I_TYPE: status = decode_i_picture_header(v); break; - case BI_TYPE: status = decode_b_picture_header(v); break; - case P_TYPE: status = decode_p_picture_header(v); break; - case B_TYPE: status = decode_b_picture_header(v); break; + case BI_TYPE: status = decode_bi_picture_header(v); break; + case P_TYPE: status = decode_p_picture_primary_header(v); break; + case B_TYPE: status = decode_b_picture_primary_header(v); break; } if (status == FRAME_SKIPED) @@ -1269,21 +1281,34 @@ av_log(v, AV_LOG_INFO, "Skipping frame...\n"); return status; } + return 0; +} + +static int standard_decode_picture_secondary_header(VC9Context *v) +{ + GetBitContext *gb = &v->s.gb; + int status = 0, index; + + switch (v->s.pict_type) + { + case P_TYPE: status = decode_p_picture_secondary_header(v); break; + case B_TYPE: status = decode_b_picture_secondary_header(v); break; + } /* AC Syntax */ - index = decode012(&v->gb); + index = decode012(gb); v->luma_ac_vlc = NULL + index; //FIXME Add AC table v->chroma_ac_vlc = NULL + index; - if (v->pict_type == I_TYPE || v->pict_type == BI_TYPE) + if (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE) { - index = decode012(&v->gb); + index = decode012(gb); v->luma_ac2_vlc = NULL + index; //FIXME Add AC2 table v->chroma_ac2_vlc = NULL + index; } /* DC Syntax */ - index = decode012(&v->gb); - v->luma_dc_vlc = vc9_luma_dc_vlc + index; - v->chroma_dc_vlc = vc9_chroma_dc_vlc + index; + index = decode012(gb); + v->luma_dc_vlc = &ff_msmp4_dc_luma_vlc[index]; + v->chroma_dc_vlc = &ff_msmp4_dc_chroma_vlc[index]; return 0; } @@ -1293,30 +1318,31 @@ /******************************************************************************/ /* Advanced Profile picture header decoding specific functions */ /******************************************************************************/ -static int advanced_decode_picture_header(VC9Context *v) +static int advanced_decode_picture_primary_header(VC9Context *v) { + GetBitContext *gb = &v->s.gb; static const int type_table[4] = { P_TYPE, B_TYPE, I_TYPE, BI_TYPE }; - int type, i, index; + int type, i; if (v->interlace) { - v->fcm = get_bits(&v->gb, 1); - if (v->fcm) v->fcm = 2+get_bits(&v->gb, 1); + v->fcm = get_bits(gb, 1); + if (v->fcm) v->fcm = 2+get_bits(gb, 1); } - type = get_prefix(&v->gb, 0, 4); + type = get_prefix(gb, 0, 4); if (type > 4 || type < 0) return FRAME_SKIPED; - v->pict_type = type_table[type]; - av_log(v->avctx, AV_LOG_INFO, "AP Frame Type: %i\n", v->pict_type); + v->s.pict_type = type_table[type]; + av_log(v->s.avctx, AV_LOG_INFO, "AP Frame Type: %i\n", v->s.pict_type); - if (v->tfcntrflag) v->tfcntr = get_bits(&v->gb, 8); + if (v->tfcntrflag) v->tfcntr = get_bits(gb, 8); if (v->broadcast) { - if (!v->interlace) v->rptfrm = get_bits(&v->gb, 2); + if (!v->interlace) v->rptfrm = get_bits(gb, 2); else { - v->tff = get_bits(&v->gb, 1); - v->rff = get_bits(&v->gb, 1); + v->tff = get_bits(gb, 1); + v->rff = get_bits(gb, 1); } } @@ -1325,42 +1351,56 @@ #if 0 for (i=0; inumpanscanwin; i++) { - v->topleftx[i] = get_bits(&v->gb, 16); - v->toplefty[i] = get_bits(&v->gb, 16); - v->bottomrightx[i] = get_bits(&v->gb, 16); - v->bottomrighty[i] = get_bits(&v->gb, 16); + v->topleftx[i] = get_bits(gb, 16); + v->toplefty[i] = get_bits(gb, 16); + v->bottomrightx[i] = get_bits(gb, 16); + v->bottomrighty[i] = get_bits(gb, 16); } #else - skip_bits(&v->gb, 16*4*v->numpanscanwin); + skip_bits(gb, 16*4*v->numpanscanwin); #endif } - v->rndctrl = get_bits(&v->gb, 1); - v->uvsamp = get_bits(&v->gb, 1); - if (v->finterpflag == 1) v->interpfrm = get_bits(&v->gb, 1); + v->s.no_rounding = !get_bits(gb, 1); + v->uvsamp = get_bits(gb, 1); + if (v->finterpflag == 1) v->interpfrm = get_bits(gb, 1); - switch(v->pict_type) + switch(v->s.pict_type) { case I_TYPE: if (decode_i_picture_header(v) < 0) return -1; - case P_TYPE: if (decode_p_picture_header(v) < 0) return -1; + case P_TYPE: if (decode_p_picture_primary_header(v) < 0) return -1; case BI_TYPE: - case B_TYPE: if (decode_b_picture_header(v) < 0) return FRAME_SKIPED; + case B_TYPE: if (decode_b_picture_primary_header(v) < 0) return FRAME_SKIPED; + default: break; + } + return 0; +} + +static int advanced_decode_picture_secondary_header(VC9Context *v) +{ + GetBitContext *gb = &v->s.gb; + int index; + + switch(v->s.pict_type) + { + case P_TYPE: if (decode_p_picture_secondary_header(v) < 0) return -1; + case B_TYPE: if (decode_b_picture_secondary_header(v) < 0) return FRAME_SKIPED; default: break; } /* AC Syntax */ - index = decode012(&v->gb); + index = decode012(gb); v->luma_ac_vlc = NULL + index; //FIXME v->chroma_ac_vlc = NULL + index; //FIXME - if (v->pict_type == I_TYPE || v->pict_type == BI_TYPE) + if (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE) { - index = decode012(&v->gb); //FIXME + index = decode012(gb); //FIXME v->luma_ac2_vlc = NULL + index; v->chroma_ac2_vlc = NULL + index; } /* DC Syntax */ - index = decode012(&v->gb); - v->luma_dc_vlc = vc9_luma_dc_vlc + index; - v->chroma_dc_vlc = vc9_chroma_dc_vlc + index; + index = decode012(gb); + v->luma_dc_vlc = &ff_msmp4_dc_luma_vlc[index]; + v->chroma_dc_vlc = &ff_msmp4_dc_chroma_vlc[index]; return 0; } @@ -1373,27 +1413,28 @@ /* FIXME proper integration (unusable and lots of parameters to send */ int decode_luma_intra_block(VC9Context *v, int mquant) { + GetBitContext *gb = &v->s.gb; int dcdiff; - dcdiff = get_vlc2(&v->gb, v->luma_dc_vlc->table, - VC9_DC_VLC_BITS, 2); + dcdiff = get_vlc2(gb, v->luma_dc_vlc->table, + DC_VLC_BITS, 2); if (dcdiff) { if (dcdiff == 119 /* ESC index value */) { /* TODO: Optimize */ - if (mquant == 1) dcdiff = get_bits(&v->gb, 10); - else if (mquant == 2) dcdiff = get_bits(&v->gb, 9); - else dcdiff = get_bits(&v->gb, 8); + if (mquant == 1) dcdiff = get_bits(gb, 10); + else if (mquant == 2) dcdiff = get_bits(gb, 9); + else dcdiff = get_bits(gb, 8); } else { if (mquant == 1) - dcdiff = (dcdiff<<2) + get_bits(&v->gb, 2) - 3; + dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3; else if (mquant == 2) - dcdiff = (dcdiff<<1) + get_bits(&v->gb, 1) - 1; + dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1; } - if (get_bits(&v->gb, 1)) + if (get_bits(gb, 1)) dcdiff = -dcdiff; } /* FIXME: 8.1.1.15, p(1)13, coeff scaling for Adv Profile */ @@ -1407,7 +1448,7 @@ /* 8.1.1.5, p(1)02-(1)03 */ /* We only need to store 3 flags, but math with 4 is easier */ #define GET_CBPCY(table, bits) \ - predicted_cbpcy = get_vlc2(&v->gb, table, bits, 2); \ + 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); \ @@ -1422,32 +1463,33 @@ /* 8.1, p100 */ static int standard_decode_i_mbs(VC9Context *v) { - int x, y, current_mb = 0; /* MB/Block Position info */ - int ac_pred; + GetBitContext *gb = &v->s.gb; + MpegEncContext *s = &v->s; + int current_mb = 0; /* MB/Block Position info */ /* FIXME: better to use a pointer than using (x<<4) */ 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, (v->width_mb+1)<<2); + memset(v->previous_line_cbpcy, 0, s->mb_stride<<2); /* Select ttmb table depending on pq */ if (v->pq < 5) v->ttmb_vlc = &vc9_ttmb_vlc[0]; else if (v->pq < 13) v->ttmb_vlc = &vc9_ttmb_vlc[1]; else v->ttmb_vlc = &vc9_ttmb_vlc[2]; - for (y=0; yheight_mb; y++) + for (s->mb_y=0; s->mb_ymb_height; s->mb_y++) { /* Init CBPCY for line */ *((uint32_t*)previous_cbpcy) = 0x00000000; p_cbpcy = v->previous_line_cbpcy+4; - for (x=0; xwidth_mb; x++, p_cbpcy += 4) + for (s->mb_x=0; s->mb_xmb_width; s->mb_x++, p_cbpcy += 4) { /* Get CBPCY */ - GET_CBPCY(vc9_cbpcy_i_vlc.table, VC9_CBPCY_I_VLC_BITS); + GET_CBPCY(ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS); - ac_pred = get_bits(&v->gb, 1); + s->ac_pred = get_bits(gb, 1); /* TODO: Decode blocks from that mb wrt cbpcy */ @@ -1467,20 +1509,20 @@ { \ if (v->dqbilevel) \ { \ - mquant = (get_bits(&v->gb, 1)) ? v->pq : v->altpq; \ + mquant = (get_bits(gb, 1)) ? v->pq : v->altpq; \ } \ else \ { \ - mqdiff = get_bits(&v->gb, 3); \ + mqdiff = get_bits(gb, 3); \ if (mqdiff != 7) mquant = v->pq + mqdiff; \ - else mquant = get_bits(&v->gb, 5); \ + else mquant = get_bits(gb, 5); \ } \ } \ } /* MVDATA decoding from 8.3.5.2, p(1)20 */ #define GET_MVDATA(_dmv_x, _dmv_y) \ - index = 1 + get_vlc2(&v->gb, v->mv_diff_vlc->table, \ + index = 1 + get_vlc2(gb, v->mv_diff_vlc->table, \ VC9_MV_DIFF_VLC_BITS, 2); \ if (index > 36) \ { \ @@ -1492,8 +1534,8 @@ if (!index) { _dmv_x = _dmv_y = 0; } \ else if (index == 35) \ { \ - _dmv_x = get_bits(&v->gb, k_x); \ - _dmv_y = get_bits(&v->gb, k_y); \ + _dmv_x = get_bits(gb, k_x); \ + _dmv_y = get_bits(gb, k_y); \ mb_is_intra = 1; \ } \ else \ @@ -1501,14 +1543,14 @@ index1 = index%6; \ if (hpel_flag && index1 == 5) val = 1; \ else val = 0; \ - val = get_bits(&v->gb, size_table[index1] - val); \ + val = get_bits(gb, size_table[index1] - val); \ sign = 0 - (val&1); \ _dmv_x = (sign ^ ((val>>1) + offset_table[index1])) - sign; \ \ index1 = index/6; \ if (hpel_flag && index1 == 5) val = 1; \ else val = 0; \ - val = get_bits(&v->gb, size_table[index1] - val); \ + val = get_bits(gb, size_table[index1] - val); \ sign = 0 - (val&1); \ _dmv_y = (sign ^ ((val>>1) + offset_table[index1])) - sign; \ } @@ -1516,10 +1558,12 @@ /* 8.1, p(1)15 */ static int decode_p_mbs(VC9Context *v) { - int x, y, current_mb = 0, i; /* MB/Block Position info */ + MpegEncContext *s = &v->s; + GetBitContext *gb = &v->s.gb; + int current_mb = 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, ac_pred; /* Prediction types */ + int hybrid_pred; /* Prediction types */ int mv_mode_bit = 0; int mqdiff, mquant; /* MB quantization */ int ttmb; /* MB Transform type */ @@ -1552,20 +1596,20 @@ k_y -= hpel_flag; /* Reset CBPCY predictors */ - memset(v->previous_line_cbpcy, 0, (v->width_mb+1)<<2); + memset(v->previous_line_cbpcy, 0, s->mb_stride<<2); - for (y=0; yheight_mb; y++) + for (s->mb_y=0; s->mb_ymb_height; s->mb_y++) { /* Init CBPCY for line */ *((uint32_t*)previous_cbpcy) = 0x00000000; p_cbpcy = v->previous_line_cbpcy+4; - for (x=0; xwidth_mb; x++) + for (s->mb_x=0; s->mb_xmb_width; s->mb_x++) { if (v->mv_type_mb_plane.is_raw) - v->mv_type_mb_plane.data[current_mb] = get_bits(&v->gb, 1); + v->mv_type_mb_plane.data[current_mb] = get_bits(gb, 1); if (v->skip_mb_plane.is_raw) - v->skip_mb_plane.data[current_mb] = get_bits(&v->gb, 1); + v->skip_mb_plane.data[current_mb] = get_bits(gb, 1); if (!mv_mode_bit) /* 1MV mode */ { if (!v->skip_mb_plane.data[current_mb]) @@ -1575,20 +1619,20 @@ /* 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(&v->gb, 1); + hybrid_pred = get_bits(gb, 1); if (mb_is_intra && !mb_has_coeffs) { GET_MQUANT(); - ac_pred = get_bits(&v->gb, 1); + s->ac_pred = get_bits(gb, 1); } else if (mb_has_coeffs) { - if (mb_is_intra) ac_pred = get_bits(&v->gb, 1); + if (mb_is_intra) s->ac_pred = get_bits(gb, 1); GET_CBPCY(v->cbpcy_vlc->table, VC9_CBPCY_P_VLC_BITS); GET_MQUANT(); } if (!v->ttmbf) - ttmb = get_vlc2(&v->gb, v->ttmb_vlc->table, + ttmb = get_vlc2(gb, v->ttmb_vlc->table, VC9_TTMB_VLC_BITS, 12); /* TODO: decode blocks from that mb wrt cbpcy */ } @@ -1597,7 +1641,7 @@ /* 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(&v->gb, 1); + hybrid_pred = get_bits(gb, 1); } } //1MV mode else //4MV mode @@ -1613,13 +1657,13 @@ GET_MVDATA(dmv_x, dmv_y); } if (v->mv_mode == MV_PMODE_MIXED_MV /* Hybrid pred */) - hybrid_pred = get_bits(&v->gb, 1); + hybrid_pred = get_bits(gb, 1); GET_MQUANT(); if (mb_is_intra /* One of the 4 blocks is intra */ && index /* non-zero pred for that block */) - ac_pred = get_bits(&v->gb, 1); + s->ac_pred = get_bits(gb, 1); if (!v->ttmbf) - ttmb = get_vlc2(&v->gb, v->ttmb_vlc->table, + ttmb = get_vlc2(gb, v->ttmb_vlc->table, VC9_TTMB_VLC_BITS, 12); /* TODO: Process blocks wrt cbpcy */ @@ -1631,7 +1675,7 @@ for (i=0; i<4; i++) //All 4 Y blocks { if (v->mv_mode == MV_PMODE_MIXED_MV /* Hybrid pred */) - hybrid_pred = get_bits(&v->gb, 1); + hybrid_pred = get_bits(gb, 1); /* TODO: do something */ } @@ -1640,7 +1684,7 @@ /* Update for next block */ #if TRACE > 2 - av_log(v->avctx, AV_LOG_DEBUG, "Block %4i: p_cbpcy=%i%i%i%i, previous_cbpcy=%i%i%i%i," + 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", current_mb, p_cbpcy[0], p_cbpcy[1], p_cbpcy[2], p_cbpcy[3], previous_cbpcy[0], previous_cbpcy[1], previous_cbpcy[2], previous_cbpcy[3], @@ -1656,8 +1700,9 @@ static int decode_b_mbs(VC9Context *v) { - int x, y, current_mb = 0, i /* MB / B postion information */; - int ac_pred; + MpegEncContext *s = &v->s; + GetBitContext *gb = &v->s.gb; + int current_mb = 0, i /* MB / B postion information */; int b_mv_type = BMV_TYPE_BACKWARD; int mquant, mqdiff; /* MB quant stuff */ int ttmb; /* MacroBlock transform type */ @@ -1688,20 +1733,20 @@ else if (v->pq < 13) v->ttmb_vlc = &vc9_ttmb_vlc[1]; else v->ttmb_vlc = &vc9_ttmb_vlc[2]; - for (y=0; yheight_mb; y++) + for (s->mb_y=0; s->mb_ymb_height; s->mb_y++) { - for (x=0; xwidth_mb; x++) + for (s->mb_x=0; s->mb_xmb_width; s->mb_x++) { if (v->direct_mb_plane.is_raw) - v->direct_mb_plane.data[current_mb] = get_bits(&v->gb, 1); + v->direct_mb_plane.data[current_mb] = get_bits(gb, 1); if (v->skip_mb_plane.is_raw) - v->skip_mb_plane.data[current_mb] = get_bits(&v->gb, 1); + v->skip_mb_plane.data[current_mb] = get_bits(gb, 1); if (!v->direct_mb_plane.data[current_mb]) { if (v->skip_mb_plane.data[current_mb]) { - b_mv_type = decode012(&v->gb); + b_mv_type = decode012(gb); if (v->bfraction > 420 /*1/2*/ && b_mv_type < 3) b_mv_type = 1-b_mv_type; } @@ -1712,7 +1757,7 @@ if (!mb_is_intra /* b_mv1 tells not intra */) { /* FIXME: actually read it */ - b_mv_type = decode012(&v->gb); + b_mv_type = decode012(gb); if (v->bfraction > 420 /*1/2*/ && b_mv_type < 3) b_mv_type = 1-b_mv_type; } @@ -1724,7 +1769,7 @@ { GET_MQUANT(); if (mb_is_intra /* intra mb */) - ac_pred = get_bits(&v->gb, 1); + s->ac_pred = get_bits(gb, 1); } else { @@ -1737,14 +1782,14 @@ if (mb_has_coeffs /* b_mv2 == "last" */) { if (mb_is_intra /* intra_mb */) - ac_pred = get_bits(&v->gb, 1); + s->ac_pred = get_bits(gb, 1); GET_MQUANT(); } } } //End1 if (v->ttmbf) - ttmb = get_vlc2(&v->gb, v->ttmb_vlc->table, + ttmb = get_vlc2(gb, v->ttmb_vlc->table, VC9_TTMB_VLC_BITS, 12); //End2 @@ -1762,16 +1807,20 @@ #if HAS_ADVANCED_PROFILE static int advanced_decode_i_mbs(VC9Context *v) { - int x, y, mqdiff, mquant, ac_pred, current_mb = 0, over_flags_mb = 0; + MpegEncContext *s = &v->s; + GetBitContext *gb = &v->s.gb; + int mqdiff, mquant, current_mb = 0, over_flags_mb = 0; - for (y=0; yheight_mb; y++) + for (s->mb_y=0; s->mb_ymb_height; s->mb_y++) { - for (x=0; xwidth_mb; x++) + for (s->mb_x=0; s->mb_xmb_width; s->mb_x++) { - if (v->ac_pred_plane.data[current_mb]) - ac_pred = get_bits(&v->gb, 1); + if (v->ac_pred_plane.is_raw) + s->ac_pred = get_bits(gb, 1); + else + s->ac_pred = v->ac_pred_plane.data[current_mb]; if (v->condover == 3 && v->over_flags_plane.is_raw) - over_flags_mb = get_bits(&v->gb, 1); + over_flags_mb = get_bits(gb, 1); GET_MQUANT(); /* TODO: lots */ @@ -1785,13 +1834,16 @@ static int vc9_decode_init(AVCodecContext *avctx) { VC9Context *v = avctx->priv_data; + MpegEncContext *s = &v->s; GetBitContext gb; if (!avctx->extradata_size || !avctx->extradata) return -1; avctx->pix_fmt = PIX_FMT_YUV420P; - v->avctx = avctx; + v->s.avctx = avctx; - if (init_common(v) < 0) return -1; + if(ff_h263_decode_init(avctx) < 0) + return -1; + if (vc9_init_common(v) < 0) return -1; avctx->coded_width = avctx->width; avctx->coded_height = avctx->height; @@ -1799,68 +1851,68 @@ { int count = 0; - // looks like WMV3 has a sequence header stored in the extradata - // advanced sequence header may be before the first frame - // the last byte of the extradata is a version number, 1 for the - // samples we can decode + // looks like WMV3 has a sequence header stored in the extradata + // advanced sequence header may be before the first frame + // the last byte of the extradata is a version number, 1 for the + // samples we can decode - init_get_bits(&gb, avctx->extradata, avctx->extradata_size); - - decode_sequence_header(avctx, &gb); + init_get_bits(&gb, avctx->extradata, avctx->extradata_size); + + decode_sequence_header(avctx, &gb); - count = avctx->extradata_size*8 - get_bits_count(&gb); - if (count>0) - { - av_log(avctx, AV_LOG_INFO, "Extra data: %i bits left, value: %X\n", - count, get_bits(&gb, count)); - } - else - { - av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count); - } + count = avctx->extradata_size*8 - get_bits_count(&gb); + if (count>0) + { + av_log(avctx, AV_LOG_INFO, "Extra data: %i bits left, value: %X\n", + count, get_bits(&gb, count)); + } + else + { + av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count); + } } + avctx->has_b_frames= !!(avctx->max_b_frames); - /* Done with header parsing */ - //FIXME I feel like this is wrong - v->width_mb = (avctx->coded_width+15)>>4; - v->height_mb = (avctx->coded_height+15)>>4; + s->mb_width = (avctx->coded_width+15)>>4; + s->mb_height = (avctx->coded_height+15)>>4; /* Allocate mb bitplanes */ - if (alloc_bitplane(&v->mv_type_mb_plane, v->width_mb, v->height_mb) < 0) + if (alloc_bitplane(&v->mv_type_mb_plane, s->mb_width, s->mb_height) < 0) return -1; - if (alloc_bitplane(&v->mv_type_mb_plane, v->width_mb, v->height_mb) < 0) + if (alloc_bitplane(&v->mv_type_mb_plane, s->mb_width, s->mb_height) < 0) return -1; - if (alloc_bitplane(&v->skip_mb_plane, v->width_mb, v->height_mb) < 0) + if (alloc_bitplane(&v->skip_mb_plane, s->mb_width, s->mb_height) < 0) return -1; - if (alloc_bitplane(&v->direct_mb_plane, v->width_mb, v->height_mb) < 0) + if (alloc_bitplane(&v->direct_mb_plane, s->mb_width, s->mb_height) < 0) return -1; /* For predictors */ - v->previous_line_cbpcy = (uint8_t *)av_malloc((v->width_mb+1)*4); + v->previous_line_cbpcy = (uint8_t *)av_malloc(s->mb_stride*4); if (!v->previous_line_cbpcy) return -1; #if HAS_ADVANCED_PROFILE if (v->profile > PROFILE_MAIN) { - if (alloc_bitplane(&v->over_flags_plane, v->width_mb, v->height_mb) < 0) + if (alloc_bitplane(&v->over_flags_plane, s->mb_width, s->mb_height) < 0) return -1; - if (alloc_bitplane(&v->ac_pred_plane, v->width_mb, v->height_mb) < 0) + if (alloc_bitplane(&v->ac_pred_plane, s->mb_width, s->mb_height) < 0) return -1; } #endif return 0; -} + } static int vc9_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) { VC9Context *v = avctx->priv_data; + MpegEncContext *s = &v->s; int ret = FRAME_SKIPED, len, start_code; AVFrame *pict = data; uint8_t *tmp_buf; - v->avctx = avctx; + v->s.avctx = avctx; //buf_size = 0 -> last frame if (!buf_size) return 0; @@ -1871,41 +1923,7 @@ avpicture_fill((AVPicture *)pict, tmp_buf, avctx->pix_fmt, avctx->width, avctx->height); - if (avctx->codec_id == CODEC_ID_WMV3) - { - //No IDU - init_get_bits(&v->gb, buf, buf_size*8); - -#if HAS_ADVANCED_PROFILE - if (v->profile > PROFILE_MAIN) - { - if (advanced_decode_picture_header(v) == FRAME_SKIPED) return buf_size; - switch(v->pict_type) - { - case I_TYPE: ret = advanced_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; //We ignore for now failures - } - else -#endif - { - if (standard_decode_picture_header(v) == FRAME_SKIPED) return buf_size; - switch(v->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; - } - if (ret == FRAME_SKIPED) return buf_size; - } - } - else + if (avctx->codec_id == CODEC_ID_VC9) { #if 0 // search for IDU's @@ -1923,7 +1941,7 @@ scs = buf[i++]; - init_get_bits(&v->gb, buf+i, (buf_size-i)*8); + init_get_bits(gb, buf+i, (buf_size-i)*8); switch(scs) { @@ -1941,24 +1959,162 @@ if (v->profile <= MAIN_PROFILE) av_log(avctx, AV_LOG_ERROR, "Found an entry point in profile %i\n", v->profile); - advanced_entry_point_process(avctx, &v->gb); + advanced_entry_point_process(avctx, gb); break; case 0x0F: //Sequence header Start Code - decode_sequence_header(avctx, &v->gb); + decode_sequence_header(avctx, gb); break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported IDU suffix %lX\n", scs); } - i += get_bits_count(&v->gb)*8; + i += get_bits_count(gb)*8; } #else av_abort(); #endif } + else + init_get_bits(&v->s.gb, buf, buf_size*8); + + s->flags= avctx->flags; + s->flags2= avctx->flags2; + + /* no supplementary picture */ + if (buf_size == 0) { + /* special case for last picture */ + if (s->low_delay==0 && s->next_picture_ptr) { + *pict= *(AVFrame*)s->next_picture_ptr; + s->next_picture_ptr= NULL; + + *data_size = sizeof(AVFrame); + } + + return 0; + } + + //No IDU - we mimic ff_h263_decode_frame + s->bitstream_buffer_size=0; + + if (!s->context_initialized) { + if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix + return -1; + } + + //we need to set current_picture_ptr before reading the header, otherwise we cant store anyting im there + if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){ + s->current_picture_ptr= &s->picture[ff_find_unused_picture(s, 0)]; + } +#if HAS_ADVANCED_PROFILE + if (v->profile > PROFILE_MAIN) + ret= advanced_decode_picture_primary_header(v); + else +#endif + ret= standard_decode_picture_primary_header(v); + if (ret == FRAME_SKIPED) return buf_size; + /* skip if the header was thrashed */ + if (ret < 0){ + av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); + return -1; + } + + //No bug workaround yet, no DCT conformance + + //WMV9 does have resized images + if (v->profile <= PROFILE_MAIN && v->multires){ + //Parse context stuff in here, don't know how appliable it is + } + //Not sure about context initialization + + // for hurry_up==5 + s->current_picture.pict_type= s->pict_type; + s->current_picture.key_frame= s->pict_type == I_TYPE; + + /* skip b frames if we dont have reference frames */ + if(s->last_picture_ptr==NULL && (s->pict_type==B_TYPE || s->dropable)) + return buf_size; //FIXME simulating all buffer consumed + /* skip b frames if we are in a hurry */ + if(avctx->hurry_up && s->pict_type==B_TYPE) + return buf_size; //FIXME simulating all buffer consumed + /* skip everything if we are in a hurry>=5 */ + if(avctx->hurry_up>=5) + return buf_size; //FIXME simulating all buffer consumed + + if(s->next_p_frame_damaged){ + if(s->pict_type==B_TYPE) + return buf_size; //FIXME simulating all buffer consumed + else + s->next_p_frame_damaged=0; + } + + if(MPV_frame_start(s, avctx) < 0) + return -1; + + ff_er_frame_start(s); + + //wmv9 may or may not have skip bits +#if HAS_ADVANCED_PROFILE + if (v->profile > PROFILE_MAIN) + ret= advanced_decode_picture_secondary_header(v); + else +#endif + ret = standard_decode_picture_secondary_header(v); + if (ret<0) return FRAME_SKIPED; //FIXME Non fatal for now + + //We consider the image coded in only one slice +#if HAS_ADVANCED_PROFILE + if (v->profile > PROFILE_MAIN) + { + switch(s->pict_type) + { + case I_TYPE: ret = advanced_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; //We ignore for now failures + } + 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; + } + if (ret == FRAME_SKIPED) return buf_size; + } + + ff_er_frame_end(s); + + MPV_frame_end(s); + + assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type); + assert(s->current_picture.pict_type == s->pict_type); + if(s->pict_type==B_TYPE || s->low_delay){ + *pict= *(AVFrame*)&s->current_picture; + ff_print_debug_info(s, pict); + } else { + *pict= *(AVFrame*)&s->last_picture; + if(pict) + ff_print_debug_info(s, pict); + } + + /* Return the Picture timestamp as the frame number */ + /* we substract 1 because it is added on utils.c */ + avctx->frame_number = s->picture_number - 1; + + /* dont output the last pic after seeking */ + if(s->last_picture_ptr || s->low_delay) + *data_size = sizeof(AVFrame); + av_log(avctx, AV_LOG_DEBUG, "Consumed %i/%i bits\n", - get_bits_count(&v->gb), buf_size*8); + get_bits_count(&s->gb), buf_size*8); /* Fake consumption of all data */ *data_size = len; @@ -1973,9 +2129,10 @@ av_freep(&v->hrd_rate); av_freep(&v->hrd_buffer); #endif - av_freep(&v->mv_type_mb_plane); - av_freep(&v->skip_mb_plane); - av_freep(&v->direct_mb_plane); + MPV_common_end(&v->s); + free_bitplane(&v->mv_type_mb_plane); + free_bitplane(&v->skip_mb_plane); + free_bitplane(&v->direct_mb_plane); return 0; } diff -r 73afecc117a3 -r 81a9f883a17a vc9data.h --- a/vc9data.h Sun Jan 30 14:10:30 2005 +0000 +++ b/vc9data.h Sun Jan 30 16:34:57 2005 +0000 @@ -167,23 +167,8 @@ { 2, 4, 4, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4} }; -/* I-Picture CBPCY VLC tables */ -//same as msmpeg4 table_mb_intra -static const uint16_t vc9_cbpcy_i_codes[64] = { - 1, 23, 9, 5, 6, 71, 32, 16, - 2, 124, 58, 29, 2, 236, 119, 0, - 3, 183, 44, 19, 1, 360, 70, 63, - 30, 1810, 181, 66, 34, 453, 286, 135, - 6, 3, 30, 28, 18, 904, 68, 112, - 31, 574, 57, 142, 1, 454, 182, 69, - 20, 575, 125, 24, 7, 455, 134, 25, - 21, 475, 2, 70, 13, 1811, 474, 361 -}; -static const uint8_t vc9_cbpcy_i_bits[64] = { - 1, 6, 5, 5, 5, 9, 7, 7, 5, 9, 7, 7, 6, 9, 8, 8, - 5, 9, 7, 7, 6, 10, 8, 8, 6, 13, 9, 8, 7, 11, 10, 9, - 4, 9, 7, 6, 7, 12, 9, 9, 6, 11, 8, 9, 7, 11, 9, 9, - 6, 11, 9, 9, 7, 11, 9, 9, 6, 10, 9, 9, 8, 13, 10, 10 +const uint8_t wmv3_dc_scale_table[32]={ + 0, 4, 6, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21 }; /* P-Picture CBPCY VLC tables */ diff -r 73afecc117a3 -r 81a9f883a17a wmv2.c --- a/wmv2.c Sun Jan 30 14:10:30 2005 +0000 +++ b/wmv2.c Sun Jan 30 16:34:57 2005 +0000 @@ -244,7 +244,7 @@ if (s->pict_type == I_TYPE) { set_stat(ST_INTRA_MB); put_bits(&s->pb, - table_mb_intra[coded_cbp][1], table_mb_intra[coded_cbp][0]); + ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); } else { put_bits(&s->pb, wmv2_inter_table[w->cbp_table_index][cbp][1], @@ -734,7 +734,7 @@ cbp = code & 0x3f; } else { s->mb_intra = 1; - code = get_vlc2(&s->gb, mb_intra_vlc.table, MB_INTRA_VLC_BITS, 2); + code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); if (code < 0){ av_log(s->avctx, AV_LOG_ERROR, "II-cbp illegal at %d %d\n", s->mb_x, s->mb_y); return -1;