summaryrefslogtreecommitdiff
path: root/libavcodec/vc9.c
diff options
context:
space:
mode:
authoranonymous <>2005-01-24 23:01:18 +0000
committerMichael Niedermayer <michaelni@gmx.at>2005-01-24 23:01:18 +0000
commite5540b3fd30367ce3cc33b2f34a04b660dbc4b38 (patch)
treed5eba8a6df2a7df76bc0ef532cdded4bedd5c3ed /libavcodec/vc9.c
parentb299f0d907c1974a8d1f8d4c2580bdd83daf4960 (diff)
Fixes:
- i/p/b_decode_mbs functions now checks the proper values (from bitplane). I didn't find it very clear, but it seems "raw" = "to read at the MB layer". I used a structure, but we could spare that indirection and add a flag in the VC9Context for each array. - Properly decode (or so I think) the CBPCY (as it is predicted) - many more things patch by anonymous Originally committed as revision 3882 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/vc9.c')
-rw-r--r--libavcodec/vc9.c759
1 files changed, 497 insertions, 262 deletions
diff --git a/libavcodec/vc9.c b/libavcodec/vc9.c
index 3910174fe2..9da148fee7 100644
--- a/libavcodec/vc9.c
+++ b/libavcodec/vc9.c
@@ -2,6 +2,7 @@
* VC-9 and WMV3 decoder
* Copyright (c) 2005 Anonymous
* Copyright (c) 2005 Alex Beregszaszi
+ * Copyright (c) 2005 Michael Niedermayer
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,6 +26,7 @@
*
* TODO: Norm-6 bitplane imode, most AP stuff, optimize, all of MB layer :)
* TODO: use MPV_ !!
+ * TODO: export decode012 in bitstream.h ?
*/
#include "common.h"
#include "dsputil.h"
@@ -79,22 +81,6 @@
#define DQDOUBLE_BEDGE_BOTTOMRIGHT 2
#define DQDOUBLE_BEDGE_BOTTOMLEFT 3
-
-/* Start Codes */
-#define SEQ_SC 0x00000010F /* Sequence Start Code */
-#define SEQ_EC 0x00000000A /* Sequence End code */
-#define SEQ_HDR /* Sequence Header */
-#define ENTRY_SC 0x00000010E /* Entry Point Start Code */
-#define ENTRY_HDR /* Entry Point Header */
-#define FRM_SC 0x00000010D /* Frame Start Code */
-#define FRM_DAT /* Frame Data (includes a Frame Header) */
-#define FLD_SC 0x00000010C /* Field Start Code */
-#define FLD1_DAT /* Field 1 Data (includes a Frame Header) */
-#define FLD2_DAT /* Field 2 Data (includes a Field Header) */
-#define SLC_SC 0x00000010B /* Slice Start Code */
-#define SLC_HDR /* Slice Header */
-#define SLC_DAT /* Slice Data (FrH or FiH possible) */
-
/* MV P modes */
#define MV_PMODE_1MV_HPEL_BILIN 0
#define MV_PMODE_1MV 1
@@ -102,6 +88,10 @@
#define MV_PMODE_MIXED_MV 3
#define MV_PMODE_INTENSITY_COMP 4
+#define BMV_TYPE_BACKWARD 0
+#define BMV_TYPE_FORWARD 1
+#define BMV_TYPE_INTERPOLATED 3
+
/* MV P mode - the 5th element is only used for mode 1 */
static const uint8_t mv_pmode_table[2][5] = {
{ MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_MIXED_MV, MV_PMODE_INTENSITY_COMP },
@@ -139,18 +129,29 @@ static VLC vc9_norm2_vlc;
#define VC9_NORM6_VLC_BITS 9
static VLC vc9_norm6_vlc;
/* Could be optimized, one table only needs 8 bits */
-#define VC9_TTMB_VLC_BITS 12
+#define VC9_TTMB_VLC_BITS 9 //12
static VLC vc9_ttmb_vlc[3];
-#define VC9_MV_DIFF_VLC_BITS 15
+#define VC9_MV_DIFF_VLC_BITS 9 //15
static VLC vc9_mv_diff_vlc[4];
-#define VC9_CBPCY_I_VLC_BITS 13
+#define VC9_CBPCY_I_VLC_BITS 9 //13
static VLC vc9_cbpcy_i_vlc;
-#define VC9_CBPCY_P_VLC_BITS 14
+#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_LUMA_DC_VLC_BITS 9
static VLC vc9_luma_dc_vlc[2];
+#define VC9_CHROMA_DC_VLC_BITS 9
+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
+typedef struct BitPlane {
+ uint8_t *data;
+ int width, stride;
+ int height;
+ uint8_t is_raw;
+} BitPlane;
typedef struct VC9Context{
/* No MpegEnc context, might be good to use it */
@@ -213,7 +214,8 @@ typedef struct VC9Context{
uint8_t dquantfrm, dqprofile, dqsbedge, dqbilevel; /* pquant parameters */
int width_mb, height_mb;
int tile; /* 3x2 if (width_mb%3) else 2x3 */
- int transacfrm2, transacfrm, transacdctab; //1bit elements
+ VLC *luma_ac_vlc, *chroma_ac_vlc,
+ *luma_dc_vlc, *chroma_dc_vlc; /* transac/dcfrm bits are indexes */
uint8_t ttmbf, ttfrm; /* Transform type */
uint8_t lumscale, lumshift; /* Luma compensation parameters */
int16_t bfraction; /* Relative position % anchors=> how to scale MVs */
@@ -227,15 +229,17 @@ typedef struct VC9Context{
*/
uint8_t mvrange;
uint8_t pquantizer;
+ uint8_t *previous_line_cbpcy; /* To use for predicted CBPCY */
VLC *cbpcy_vlc /* Current CBPCY VLC table */,
*mv_diff_vlc /* Current MV Diff VLC table */,
*ttmb_vlc /* Current MB Transform Type VLC table */;
- uint8_t *mv_type_mb_plane; /* bitplane for mv_type == "raw" */
- uint8_t *skip_mb_plane, /* bitplane for skipped MBs */
- *direct_mb_plane; /* bitplane for "direct" MBs */
+ BitPlane mv_type_mb_plane; /* bitplane for mv_type == (4MV) */
+ BitPlane skip_mb_plane, /* bitplane for skipped MBs */
+ direct_mb_plane; /* bitplane for "direct" MBs */
/* S/M only ? */
- uint8_t rangeredfrm, interpfrm;
+ uint8_t rangeredfrm; /* out_sample = CLIP((in_sample-128)*2+128) */
+ uint8_t interpfrm;
#if HAS_ADVANCED_PROFILE
/* Advanced */
@@ -253,15 +257,18 @@ typedef struct VC9Context{
int hrd_num_leaky_buckets;
uint8_t bit_rate_exponent;
uint8_t buffer_size_exponent;
- uint8_t *ac_pred_plane;
- uint8_t *over_flags_plane;
+ BitPlane ac_pred_plane; //AC prediction flags bitplane
+ BitPlane over_flags_plane; //Overflags bitplane
+ uint8_t condover;
uint16_t *hrd_rate, *hrd_buffer;
+ VLC *luma_ac2_vlc, *chroma_ac2_vlc;
#endif
} VC9Context;
/* FIXME Slow and ugly */
static int get_prefix(GetBitContext *gb, int stop, int len)
{
+#if 1
int i = 0, tmp = !stop;
while (i != len && tmp != stop)
@@ -270,6 +277,36 @@ static int get_prefix(GetBitContext *gb, int stop, int len)
i++;
}
return i;
+#else
+ unsigned int buf;
+ int log;
+
+ OPEN_READER(re, gb);
+ UPDATE_CACHE(re, gb);
+ buf=GET_CACHE(re, gb); //Still not sure
+ if (stop) buf = ~buf;
+
+ log= av_log2(-buf); //FIXME: -?
+ if (log < limit){
+ LAST_SKIP_BITS(re, gb, log+1);
+ CLOSE_READER(re, gb);
+ return log;
+ }
+
+ LAST_SKIP_BITS(re, gb, limit);
+ CLOSE_READER(re, gb);
+ return limit;
+#endif
+}
+
+static int decode012(GetBitContext *gb)
+{
+ int n;
+ n = get_bits1(gb);
+ if (n == 0)
+ return 0;
+ else
+ return get_bits1(gb) + 1;
}
static int init_common(VC9Context *v)
@@ -277,12 +314,17 @@ static int init_common(VC9Context *v)
static int done = 0;
int i;
- v->mv_type_mb_plane = v->direct_mb_plane = v->skip_mb_plane = NULL;
- v->pq = -1;
+ /* Set the bit planes */
+ /* FIXME memset better ? (16bytes) */
+ v->mv_type_mb_plane = (struct BitPlane) { NULL, 0, 0, 0 };
+ v->direct_mb_plane = (struct BitPlane) { NULL, 0, 0, 0 };
+ v->skip_mb_plane = (struct BitPlane) { NULL, 0, 0, 0 };
#if HAS_ADVANCED_PROFILE
- v->ac_pred_plane = v->over_flags_plane = NULL;
+ v->ac_pred_plane = v->over_flags_plane = (struct BitPlane) { NULL, 0, 0, 0 };
v->hrd_rate = v->hrd_buffer = NULL;
#endif
+
+ /* VLC tables */
#if 0 // spec -> actual tables converter
for(i=0; i<64; i++){
int code= (vc9_norm6_spec[i][1] << vc9_norm6_spec[i][4]) + vc9_norm6_spec[i][3];
@@ -313,7 +355,22 @@ static int init_common(VC9Context *v)
INIT_VLC(&vc9_imode_vlc, VC9_IMODE_VLC_BITS, 7,
vc9_imode_bits, 1, 1,
vc9_imode_codes, 1, 1, 1);
- for(i=0; i<3; i++)
+ for (i=0; i<2; i++)
+ {
+ INIT_VLC(&vc9_luma_dc_vlc[i], VC9_LUMA_DC_VLC_BITS, 26,
+ vc9_luma_dc_bits[i], 1, 1,
+ vc9_luma_dc_codes[i], 4, 4, 1);
+ INIT_VLC(&vc9_chroma_dc_vlc[i], VC9_CHROMA_DC_VLC_BITS, 26,
+ vc9_chroma_dc_bits[i], 1, 1,
+ vc9_chroma_dc_codes[i], 4, 4, 1);
+ }
+ for (i=0; i<3; i++)
+ {
+ INIT_VLC(&vc9_ttmb_vlc[i], VC9_TTMB_VLC_BITS, 16,
+ vc9_ttmb_bits[i], 1, 1,
+ vc9_ttmb_codes[i], 2, 2, 1);
+ }
+ for(i=0; i<4; i++)
{
INIT_VLC(&vc9_4mv_block_pattern_vlc[i], VC9_4MV_BLOCK_PATTERN_VLC_BITS, 16,
vc9_4mv_block_pattern_bits[i], 1, 1,
@@ -321,25 +378,21 @@ static int init_common(VC9Context *v)
INIT_VLC(&vc9_cbpcy_p_vlc[i], VC9_CBPCY_P_VLC_BITS, 64,
vc9_cbpcy_p_bits[i], 1, 1,
vc9_cbpcy_p_codes[i], 2, 2, 1);
- }
- for (i=0; i<2; i++)
- {
INIT_VLC(&vc9_mv_diff_vlc[i], VC9_MV_DIFF_VLC_BITS, 73,
vc9_mv_diff_bits[i], 1, 1,
vc9_mv_diff_codes[i], 2, 2, 1);
- INIT_VLC(&vc9_luma_dc_vlc[i], VC9_LUMA_DC_VLC_BITS, 120,
- vc9_luma_dc_bits[i], 1, 1,
- vc9_luma_dc_codes[i], 4, 4, 1);
- INIT_VLC(&vc9_ttmb_vlc[i], VC9_TTMB_VLC_BITS, 16,
- vc9_ttmb_bits[i], 1, 1,
- vc9_ttmb_codes[i], 2, 2, 1);
}
}
+ /* Other defaults */
+ v->pq = -1;
+ v->mvrange = 0; /* 7.1.1.18, p80 */
+
return 0;
}
#if HAS_ADVANCED_PROFILE
+/* 6.2.1, p32 */
static int decode_hrd(VC9Context *v, GetBitContext *gb)
{
int i, num;
@@ -350,14 +403,14 @@ static int decode_hrd(VC9Context *v, GetBitContext *gb)
{
av_freep(&v->hrd_rate);
}
- if (!v->hrd_rate) v->hrd_rate = av_malloc(num);
+ if (!v->hrd_rate) v->hrd_rate = av_malloc(num*sizeof(uint16_t));
if (!v->hrd_rate) return -1;
if (v->hrd_buffer || num != v->hrd_num_leaky_buckets)
{
av_freep(&v->hrd_buffer);
}
- if (!v->hrd_buffer) v->hrd_buffer = av_malloc(num);
+ if (!v->hrd_buffer) v->hrd_buffer = av_malloc(num*sizeof(uint16_t));
if (!v->hrd_buffer) return -1;
v->hrd_num_leaky_buckets = num;
@@ -388,6 +441,7 @@ static int decode_hrd(VC9Context *v, GetBitContext *gb)
return 0;
}
+/* Table 2, p18 */
static int decode_advanced_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
{
VC9Context *v = avctx->priv_data;
@@ -410,6 +464,7 @@ static int decode_advanced_sequence_header(AVCodecContext *avctx, GetBitContext
if (v->extended_mv)
v->extended_dmv = get_bits(gb, 1);
+ /* 6.1.7, p21 */
if (get_bits(gb, 1) /* pic_size_flag */)
{
avctx->coded_width = get_bits(gb, 12);
@@ -420,6 +475,7 @@ static int decode_advanced_sequence_header(AVCodecContext *avctx, GetBitContext
avctx->height = get_bits(gb, 14);
}
+ /* 6.1.7.4, p22 */
if ( get_bits(gb, 1) /* aspect_ratio_flag */)
{
aspect_ratio = get_bits(gb, 4); //SAR
@@ -444,6 +500,7 @@ static int decode_advanced_sequence_header(AVCodecContext *avctx, GetBitContext
avctx->coded_height = avctx->height;
}
+ /* 6.1.8, p23 */
if ( get_bits(gb, 1) /* framerateflag */)
{
if ( get_bits(gb, 1) /* framerateind */)
@@ -481,6 +538,7 @@ static int decode_advanced_sequence_header(AVCodecContext *avctx, GetBitContext
}
}
+ /* 6.1.9, p25 */
if ( get_bits(gb, 1) /* color_format_flag */)
{
//Chromacity coordinates of color primaries
@@ -530,6 +588,7 @@ static int decode_advanced_sequence_header(AVCodecContext *avctx, GetBitContext
}
#endif
+/* Figure 7-8, p16-17 */
static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
{
VC9Context *v = avctx->priv_data;
@@ -654,10 +713,11 @@ static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
v->rangered, v->vstransform, v->overlap, v->syncmarker,
v->dquant, v->quantizer_mode, avctx->max_b_frames
);
+ return 0;
#endif
}
#if HAS_ADVANCED_PROFILE
- else decode_advanced_sequence_header(avctx, gb);
+ else return decode_advanced_sequence_header(avctx, gb);
#endif
}
@@ -706,7 +766,7 @@ static int advanced_entry_point_process(AVCodecContext *avctx, GetBitContext *gb
#endif
/******************************************************************************/
-/* Bitplane decoding */
+/* Bitplane decoding: 8.7, p56 */
/******************************************************************************/
#define IMODE_RAW 0
#define IMODE_NORM2 1
@@ -715,6 +775,15 @@ static int advanced_entry_point_process(AVCodecContext *avctx, GetBitContext *gb
#define IMODE_DIFF6 4
#define IMODE_ROWSKIP 5
#define IMODE_COLSKIP 6
+int alloc_bitplane(BitPlane *bp, int width, int height)
+{
+ if (!bp || bp->width<0 || bp->height<0) return -1;
+ bp->data = (uint8_t*)av_malloc(width*height);
+ if (!bp->data) return -1;
+ bp->width = bp->stride = width; //FIXME Needed for aligned data ?
+ bp->height = height;
+ return 0;
+}
static void decode_rowskip(uint8_t* plane, int width, int height, int stride, VC9Context *v){
int x, y;
@@ -745,75 +814,72 @@ static void decode_colskip(uint8_t* plane, int width, int height, int stride, VC
}
//FIXME optimize
-//FIXME is this supposed to set elements to 0/FF or 0/1?
-static int bitplane_decoding(uint8_t* plane, int width, int height, VC9Context *v)
+//FIXME is this supposed to set elements to 0/FF or 0/1? 0/x!=0, not used for
+// prediction
+//FIXME Use BitPlane struct or return if table is raw (no bits read here but
+// later on)
+static int bitplane_decoding(BitPlane *bp, VC9Context *v)
{
- int imode, x, y, i, code, use_vertical_tile, tile_w, tile_h;
- uint8_t invert, *planep = plane;
- int stride= width;
+ 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);
- av_log(v->avctx, AV_LOG_DEBUG, "Bitplane: imode=%i, invert=%i\n",
- imode, invert);
+ bp->is_raw = 0;
switch (imode)
{
case IMODE_RAW:
- for (y=0; y<height; y++)
- {
- for (x=0; x<width; x++)
- planep[x] = (-get_bits(&v->gb, 1)); //-1=0xFF
- planep += stride;
- }
- invert=0; //spec says ignore invert if raw
- break;
+ //Data is actually read in the MB layer (same for all tests == "raw")
+ bp->is_raw = 1; //invert ignored
+ return invert;
case IMODE_DIFF2:
case IMODE_NORM2:
- if ((height*width) & 1) *(++planep) = get_bits(&v->gb, 1);
- for(i=0; i<(height*width)>>1; i++){
+ if ((bp->height*bp->width) & 1) *(++planep) = get_bits(&v->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);
*(++planep) = code&1; //lsb => left
- *(++planep) = code&2; //msb => right - this is a bitplane, so only !0 matters
+ *(++planep) = code&2; //msb => right - bitplane => only !0 matters
//FIXME width->stride
}
break;
case IMODE_DIFF6:
case IMODE_NORM6:
- use_vertical_tile= height%3==0 && width%3!=0;
+ use_vertical_tile= bp->height%3==0 && bp->width%3!=0;
tile_w= use_vertical_tile ? 2 : 3;
tile_h= use_vertical_tile ? 3 : 2;
- for(y= height%tile_h; y<height; y+=tile_h){
- for(x= width%tile_w; x<width; x+=tile_w){
+ 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);
//FIXME following is a pure guess and probably wrong
- planep[x + 0*stride]= (code>>0)&1;
- planep[x + 1 + 0*stride]= (code>>1)&1;
+ //FIXME A bitplane (0 | !0), so could the shifts be avoided ?
+ planep[x + 0*bp->stride]= (code>>0)&1;
+ planep[x + 1 + 0*bp->stride]= (code>>1)&1;
if(use_vertical_tile){
- planep[x + 0 + 1*stride]= (code>>2)&1;
- planep[x + 1 + 1*stride]= (code>>3)&1;
- planep[x + 0 + 2*stride]= (code>>4)&1;
- planep[x + 1 + 2*stride]= (code>>5)&1;
+ planep[x + 0 + 1*bp->stride]= (code>>2)&1;
+ planep[x + 1 + 1*bp->stride]= (code>>3)&1;
+ planep[x + 0 + 2*bp->stride]= (code>>4)&1;
+ planep[x + 1 + 2*bp->stride]= (code>>5)&1;
}else{
- planep[x + 2 + 0*stride]= (code>>2)&1;
- planep[x + 0 + 1*stride]= (code>>3)&1;
- planep[x + 1 + 1*stride]= (code>>4)&1;
- planep[x + 2 + 1*stride]= (code>>5)&1;
+ planep[x + 2 + 0*bp->stride]= (code>>2)&1;
+ planep[x + 0 + 1*bp->stride]= (code>>3)&1;
+ planep[x + 1 + 1*bp->stride]= (code>>4)&1;
+ planep[x + 2 + 1*bp->stride]= (code>>5)&1;
}
}
}
- x= width % tile_w;
- decode_colskip(plane , x, height , stride, v);
- decode_rowskip(plane+x, width - x, height % tile_h, stride, v);
+ x= bp->width % tile_w;
+ decode_colskip(bp->data , x, bp->height , bp->stride, v);
+ decode_rowskip(bp->data+x, bp->width - x, bp->height % tile_h, bp->stride, v);
break;
case IMODE_ROWSKIP:
- decode_rowskip(plane, width, height, stride, v);
+ decode_rowskip(bp->data, bp->width, bp->height, bp->stride, v);
break;
case IMODE_COLSKIP: //Teh ugly
- decode_colskip(plane, width, height, stride, v);
+ decode_colskip(bp->data, bp->width, bp->height, bp->stride, v);
break;
default: break;
}
@@ -821,27 +887,27 @@ static int bitplane_decoding(uint8_t* plane, int width, int height, VC9Context *
/* Applying diff operator */
if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)
{
- planep = plane;
+ planep = bp->data;
planep[0] ^= invert;
- for (x=1; x<width; x++)
+ for (x=1; x<bp->width; x++)
planep[x] ^= planep[x-1];
- for (y=1; y<height; y++)
+ for (y=1; y<bp->height; y++)
{
- planep += stride;
- planep[0] ^= planep[-stride];
- for (x=1; x<width; x++)
+ planep += bp->stride;
+ planep[0] ^= planep[-bp->stride];
+ for (x=1; x<bp->width; x++)
{
- if (planep[x-1] != planep[x-stride]) planep[x] ^= invert;
- else planep[x] ^= planep[x-1];
+ if (planep[x-1] != planep[x-bp->stride]) planep[x] ^= invert;
+ else planep[x] ^= planep[x-1];
}
}
}
else if (invert)
{
- planep = plane;
- for (x=0; x<width*height; x++) planep[x] = !planep[x]; //FIXME stride
+ planep = bp->data;
+ for (x=0; x<bp->width*bp->height; x++) planep[x] = !planep[x]; //FIXME stride
}
- return 0;
+ return (imode<<1) + invert;
}
/*****************************************************************************/
@@ -926,9 +992,10 @@ static int decode_bi_picture_header(VC9Context *v)
return -1;
}
+/* Tables 11+12, p62-65 */
static int decode_b_picture_header(VC9Context *v)
{
- int pqindex;
+ int pqindex, status;
/* Prolog common to all frametypes should be done in caller */
if (v->profile == PROFILE_SIMPLE)
@@ -989,14 +1056,29 @@ static int decode_b_picture_header(VC9Context *v)
if (v->mv_mode == MV_PMODE_MIXED_MV)
{
- if (bitplane_decoding( v->mv_type_mb_plane, v->width_mb,
- v->height_mb, v)<0)
+ 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: "
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
+#endif
}
//bitplane
- bitplane_decoding(v->direct_mb_plane, v->width_mb, v->height_mb, v);
- bitplane_decoding(v->skip_mb_plane, v->width_mb, v->height_mb, v);
+ 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: "
+ "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: "
+ "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)];
@@ -1020,9 +1102,10 @@ static int decode_b_picture_header(VC9Context *v)
return 0;
}
+/* Tables 5+7, p53-54 and 55-57 */
static int decode_i_picture_header(VC9Context *v)
{
- int pqindex, status = 0, ac_pred, condover;
+ int pqindex, status = 0, ac_pred;
/* Prolog common to all frametypes should be done in caller */
//BF = Buffer Fullness
@@ -1059,13 +1142,19 @@ static int decode_i_picture_header(VC9Context *v)
/* 7.1.1.34 + 8.5.2 */
if (v->overlap && v->pq<9)
{
- condover = get_bits(&v->gb, 1);
- if (condover)
+ v->condover = get_bits(&v->gb, 1);
+ if (v->condover)
{
- condover = 2+get_bits(&v->gb, 1);
- if (condover == 3)
- status = bitplane_decoding(v->over_flags_plane,
- v->width_mb, v->height_mb, v);
+ v->condover = 2+get_bits(&v->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: "
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
+#endif
+ }
}
}
}
@@ -1075,10 +1164,11 @@ static int decode_i_picture_header(VC9Context *v)
return status;
}
+/* Table 9, p58-60 */
static int decode_p_picture_header(VC9Context *v)
{
/* INTERFRM, FRMCNT, RANGEREDFRM read in caller */
- int lowquant, pqindex;
+ int lowquant, pqindex, status = 0;
pqindex = get_bits(&v->gb, 5);
if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
@@ -1114,14 +1204,20 @@ static int decode_p_picture_header(VC9Context *v)
v->mv_mode2 == MV_PMODE_MIXED_MV)
|| v->mv_mode == MV_PMODE_MIXED_MV)
{
- if (bitplane_decoding(v->mv_type_mb_plane, v->width_mb,
- v->height_mb, v) < 0)
- return -1;
+ 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: "
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
+#endif
}
- if (bitplane_decoding(v->skip_mb_plane, v->width_mb,
- v->height_mb, v) < 0)
- return -1;
+ 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: "
+ "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)];
@@ -1150,7 +1246,7 @@ static int decode_p_picture_header(VC9Context *v)
static int standard_decode_picture_header(VC9Context *v)
{
- int status = 0;
+ int status = 0, index;
if (v->finterpflag) v->interpfrm = get_bits(&v->gb, 1);
skip_bits(&v->gb, 2); //framecnt unused
@@ -1177,15 +1273,20 @@ static int standard_decode_picture_header(VC9Context *v)
return status;
}
- /* AC/DC Syntax */
- v->transacfrm = get_bits(&v->gb, 1);
- if (v->transacfrm) v->transacfrm += get_bits(&v->gb, 1);
+ /* AC Syntax */
+ index = decode012(&v->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)
{
- v->transacfrm2 = get_bits(&v->gb, 1);
- if (v->transacfrm2) v->transacfrm2 += get_bits(&v->gb, 1);
+ index = decode012(&v->gb);
+ v->luma_ac2_vlc = NULL + index; //FIXME Add AC2 table
+ v->chroma_ac2_vlc = NULL + index;
}
- v->transacdctab = get_bits(&v->gb, 1);
+ /* DC Syntax */
+ index = decode012(&v->gb);
+ v->luma_dc_vlc = vc9_luma_dc_vlc + index;
+ v->chroma_dc_vlc = vc9_chroma_dc_vlc + index;
return 0;
}
@@ -1198,7 +1299,7 @@ static int standard_decode_picture_header(VC9Context *v)
static int advanced_decode_picture_header(VC9Context *v)
{
static const int type_table[4] = { P_TYPE, B_TYPE, I_TYPE, BI_TYPE };
- int type, i, ret;
+ int type, i, index;
if (v->interlace)
{
@@ -1249,27 +1350,89 @@ static int advanced_decode_picture_header(VC9Context *v)
default: break;
}
- /* AC/DC Syntax */
- v->transacfrm = get_bits(&v->gb, 1);
- if (v->transacfrm) v->transacfrm += get_bits(&v->gb, 1);
+ /* AC Syntax */
+ index = decode012(&v->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)
{
- v->transacfrm2 = get_bits(&v->gb, 1);
- if (v->transacfrm2) v->transacfrm2 += get_bits(&v->gb, 1);
+ index = decode012(&v->gb); //FIXME
+ v->luma_ac2_vlc = NULL + index;
+ v->chroma_ac2_vlc = NULL + index;
}
- v->transacdctab = get_bits(&v->gb, 1);
- if (v->pict_type == I_TYPE) vop_dquant_decoding(v);
+ /* DC Syntax */
+ index = decode012(&v->gb);
+ v->luma_dc_vlc = vc9_luma_dc_vlc + index;
+ v->chroma_dc_vlc = vc9_chroma_dc_vlc + index;
return 0;
}
#endif
/******************************************************************************/
+/* Block decoding functions */
+/******************************************************************************/
+/* 7.1.4, p91 and 8.1.1.7, p(1)04 */
+/* FIXME proper integration (unusable and lots of parameters to send */
+int decode_luma_intra_block(VC9Context *v, int mquant)
+{
+ int dcdiff;
+
+ dcdiff = get_vlc2(&v->gb, v->luma_dc_vlc->table,
+ VC9_LUMA_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);
+ }
+ else
+ {
+ if (mquant == 1)
+ dcdiff = (dcdiff<<2) + get_bits(&v->gb, 2) - 3;
+ else if (mquant == 2)
+ dcdiff = (dcdiff<<1) + get_bits(&v->gb, 1) - 1;
+ }
+ if (get_bits(&v->gb, 1))
+ dcdiff = -dcdiff;
+ }
+ /* FIXME: 8.1.1.15, p(1)13, coeff scaling for Adv Profile */
+
+ return 0;
+}
+
+/******************************************************************************/
/* MacroBlock decoding functions */
/******************************************************************************/
+/* 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); \
+ 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);
+
+/* 8.1, p100 */
static int standard_decode_i_mbs(VC9Context *v)
{
- int x, y, ac_pred, cbpcy;
+ int x, y, current_mb = 0; /* MB/Block Position info */
+ int ac_pred;
+ /* 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);
/* Select ttmb table depending on pq */
if (v->pq < 5) v->ttmb_vlc = &vc9_ttmb_vlc[0];
@@ -1278,12 +1441,23 @@ static int standard_decode_i_mbs(VC9Context *v)
for (y=0; y<v->height_mb; y++)
{
- for (x=0; x<v->width_mb; x++)
+ /* Init CBPCY for line */
+ *((uint32_t*)previous_cbpcy) = 0x00000000;
+ p_cbpcy = v->previous_line_cbpcy+4;
+
+ for (x=0; x<v->width_mb; x++, p_cbpcy += 4)
{
- cbpcy = get_vlc2(&v->gb, vc9_cbpcy_i_vlc.table,
- VC9_CBPCY_I_VLC_BITS, 2);
+ /* Get CBPCY */
+ GET_CBPCY(vc9_cbpcy_i_vlc.table, VC9_CBPCY_I_VLC_BITS);
+
ac_pred = get_bits(&v->gb, 1);
- //Decode blocks from that mb wrt cbpcy
+
+ /* TODO: Decode blocks from that mb wrt cbpcy */
+
+ /* Update for next block */
+ *((uint32_t*)p_cbpcy) = *((uint32_t*)previous_cbpcy);
+ *((uint32_t*)previous_cbpcy) = *((uint32_t*)cbpcy);
+ current_mb++;
}
}
return 0;
@@ -1307,57 +1481,60 @@ static int standard_decode_i_mbs(VC9Context *v)
} \
}
-/* MVDATA decoding from 8.3.5.2 */
-#define GET_MVDATA() \
- index = 1 + get_vlc2(&v->gb, v->mv_diff_vlc->table, \
- VC9_MV_DIFF_VLC_BITS, 2); \
- if (index > 36) \
- { \
- mb_has_coeffs = 1; \
- index -= 37; \
- } \
- else mb_has_coeffs = 0; \
- mb_is_intra = 0; \
- 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); \
- mb_is_intra = 1; \
- } \
- else \
- { \
- index1 = index%6; \
- if (hpel_flag && index1 == 5) val = 1; \
- else val = 0; \
- val = get_bits(&v->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); \
- sign = 0 - (val&1); \
- dmv_y = (sign ^ ((val>>1) + offset_table[index1])) - sign; \
+/* 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, \
+ VC9_MV_DIFF_VLC_BITS, 2); \
+ if (index > 36) \
+ { \
+ mb_has_coeffs = 1; \
+ index -= 37; \
+ } \
+ else mb_has_coeffs = 0; \
+ mb_is_intra = 0; \
+ 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); \
+ mb_is_intra = 1; \
+ } \
+ else \
+ { \
+ index1 = index%6; \
+ if (hpel_flag && index1 == 5) val = 1; \
+ else val = 0; \
+ val = get_bits(&v->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); \
+ sign = 0 - (val&1); \
+ _dmv_y = (sign ^ ((val>>1) + offset_table[index1])) - sign; \
}
+/* 8.1, p(1)15 */
static int decode_p_mbs(VC9Context *v)
{
int x, y, current_mb = 0, i; /* MB/Block Position info */
- int skip_mb_bit = 0, cbpcy; /* MB/B skip */
+ uint8_t cbpcy[4], previous_cbpcy[4], predicted_cbpcy,
+ *p_cbpcy /* Pointer to skip some math */;
int hybrid_pred, ac_pred; /* Prediction types */
- int mb_has_coeffs = 1 /* last_flag */, mb_is_intra;
- int dmv_x, dmv_y; /* Differential MV components */
- int mv_mode_bit = 0; /* mv_mode_bit: 1MV=0, 4MV=0 */
+ int mv_mode_bit = 0;
int mqdiff, mquant; /* MB quantization */
- int tt_block; /* MB Transform type */
+ 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 */, mb_is_intra;
+ int dmv_x, dmv_y; /* Differential MV components */
int k_x, k_y; /* Long MV fixed bitlength */
- int hpel_flag, intra_flag; /* Some MB properties */
+ int hpel_flag; /* Some MB properties */
int index, index1; /* LUT indices */
- int val, sign;
+ int val, sign; /* MVDATA temp values */
/* Select ttmb table depending on pq */
if (v->pq < 5) v->ttmb_vlc = &vc9_ttmb_vlc[0];
@@ -1377,19 +1554,26 @@ static int decode_p_mbs(VC9Context *v)
k_x -= hpel_flag;
k_y -= hpel_flag;
+ /* Reset CBPCY predictors */
+ memset(v->previous_line_cbpcy, 0, (v->width_mb+1)<<2);
+
for (y=0; y<v->height_mb; y++)
{
+ /* Init CBPCY for line */
+ *((uint32_t*)previous_cbpcy) = 0x00000000;
+ p_cbpcy = v->previous_line_cbpcy+4;
+
for (x=0; x<v->width_mb; x++)
{
- if (v->mv_type_mb_plane[current_mb])
- mv_mode_bit = get_bits(&v->gb, 1);
- if (0) //skipmb is rawmode
- skip_mb_bit = get_bits(&v->gb, 1);
+ if (v->mv_type_mb_plane.is_raw)
+ v->mv_type_mb_plane.data[current_mb] = get_bits(&v->gb, 1);
+ if (v->skip_mb_plane.is_raw)
+ v->skip_mb_plane.data[current_mb] = get_bits(&v->gb, 1);
if (!mv_mode_bit) /* 1MV mode */
{
- if (!v->skip_mb_plane[current_mb])
+ if (!v->skip_mb_plane.data[current_mb])
{
- GET_MVDATA();
+ GET_MVDATA(dmv_x, dmv_y);
/* hybrid mv pred, 8.3.5.3.4 */
if (v->mv_mode == MV_PMODE_1MV ||
@@ -1403,14 +1587,13 @@ static int decode_p_mbs(VC9Context *v)
else if (mb_has_coeffs)
{
if (mb_is_intra) ac_pred = get_bits(&v->gb, 1);
- cbpcy = get_vlc2(&v->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)
- v->ttfrm = get_vlc2(&v->gb, v->ttmb_vlc->table,
- VC9_TTMB_VLC_BITS, 2);
- //Decode blocks from that mb wrt cbpcy
+ ttmb = get_vlc2(&v->gb, v->ttmb_vlc->table,
+ VC9_TTMB_VLC_BITS, 12);
+ /* TODO: decode blocks from that mb wrt cbpcy */
}
else //Skipped
{
@@ -1422,15 +1605,15 @@ static int decode_p_mbs(VC9Context *v)
} //1MV mode
else //4MV mode
{
- if (!v->skip_mb_plane[current_mb] /* unskipped MB */)
+ if (!v->skip_mb_plane.data[current_mb] /* unskipped MB */)
{
- cbpcy = get_vlc2(&v->gb, v->cbpcy_vlc->table,
- VC9_CBPCY_P_VLC_BITS, 2);
+ /* 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 & (1<<6) /* cbpcy set for this block */)
+ if (cbpcy[i] /* cbpcy set for this block */)
{
- GET_MVDATA();
+ GET_MVDATA(dmv_x, dmv_y);
}
if (v->mv_mode == MV_PMODE_MIXED_MV /* Hybrid pred */)
hybrid_pred = get_bits(&v->gb, 1);
@@ -1439,13 +1622,11 @@ static int decode_p_mbs(VC9Context *v)
index /* non-zero pred for that block */)
ac_pred = get_bits(&v->gb, 1);
if (!v->ttmbf)
- tt_block = get_vlc2(&v->gb, v->ttmb_vlc->table,
- VC9_TTMB_VLC_BITS, 2);
+ ttmb = get_vlc2(&v->gb, v->ttmb_vlc->table,
+ VC9_TTMB_VLC_BITS, 12);
/* TODO: Process blocks wrt cbpcy */
- /* Prepare cbpcy for next block */
- cbpcy <<= 1;
}
}
else //Skipped MB
@@ -1455,98 +1636,128 @@ static int decode_p_mbs(VC9Context *v)
if (v->mv_mode == MV_PMODE_MIXED_MV /* Hybrid pred */)
hybrid_pred = get_bits(&v->gb, 1);
- /* FIXME: do something */
+ /* TODO: do something */
}
}
}
+
+ /* 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,"
+ " 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],
+ cbpcy[0], cbpcy[1], cbpcy[2], cbpcy[3]);
+#endif
+ *((uint32_t*)p_cbpcy) = *((uint32_t*)previous_cbpcy);
+ *((uint32_t*)previous_cbpcy) = *((uint32_t*)cbpcy);
+ current_mb++;
}
- current_mb++;
}
return 0;
}
static int decode_b_mbs(VC9Context *v)
{
- int x, y, current_mb = 0 , last_mb = v->height_mb*v->width_mb,
- i /* MB / B postion information */;
- int direct_b_bit = 0, skip_mb_bit = 0;
+ int x, y, current_mb = 0, i /* MB / B postion information */;
int ac_pred;
- int b_mv1 = 0, b_mv2 = 0, b_mv_type = 0;
+ int b_mv_type = BMV_TYPE_BACKWARD;
int mquant, mqdiff; /* MB quant stuff */
- int tt_block; /* Block transform type */
+ 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 */, mb_is_intra = 1;
+ 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->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; y<v->height_mb; y++)
{
for (x=0; x<v->width_mb; x++)
{
- if (v->direct_mb_plane[current_mb])
- direct_b_bit = get_bits(&v->gb, 1);
- if (1 /* Skip mode is raw */)
- {
- /* FIXME getting tired commenting */
-#if 0
- skip_mb_bit = get_bits(&v->gb, n); //vlc
-#endif
- }
- if (!direct_b_bit)
+ if (v->direct_mb_plane.is_raw)
+ v->direct_mb_plane.data[current_mb] = get_bits(&v->gb, 1);
+ if (v->skip_mb_plane.is_raw)
+ v->skip_mb_plane.data[current_mb] = get_bits(&v->gb, 1);
+
+ if (!v->direct_mb_plane.data[current_mb])
{
- if (skip_mb_bit)
+ if (v->skip_mb_plane.data[current_mb])
{
- /* FIXME getting tired commenting */
-#if 0
- b_mv_type = get_bits(&v->gb, n); //vlc
-#endif
+ b_mv_type = decode012(&v->gb);
+ if (v->bfraction > 420 /*1/2*/ &&
+ b_mv_type < 3) b_mv_type = 1-b_mv_type;
}
else
{
/* FIXME getting tired commenting */
-#if 0
- b_mv1 = get_bits(&v->gb, n); //VLC
-#endif
- if (1 /* b_mv1 isn't intra */)
+ GET_MVDATA(dmv1_x, dmv1_y);
+ if (!mb_is_intra /* b_mv1 tells not intra */)
{
/* FIXME: actually read it */
- b_mv_type = 0; //vlc
+ b_mv_type = decode012(&v->gb);
+ if (v->bfraction > 420 /*1/2*/ &&
+ b_mv_type < 3) b_mv_type = 1-b_mv_type;
}
}
}
- if (!skip_mb_bit)
+ if (!v->skip_mb_plane.data[current_mb])
{
- if (b_mv1 != last_mb)
+ if (mb_has_coeffs /* BMV1 == "last" */)
{
GET_MQUANT();
- if (1 /* intra mb */)
+ if (mb_is_intra /* intra mb */)
ac_pred = get_bits(&v->gb, 1);
}
else
{
- if (1 /* forward_mb is interpolate */)
+ /* if bmv1 tells MVs are interpolated */
+ if (b_mv_type == BMV_TYPE_INTERPOLATED)
{
- /* FIXME: actually read it */
- b_mv2 = 0; //vlc
+ GET_MVDATA(dmv2_x, dmv2_y);
}
- if (1 /* b_mv2 isn't the last */)
+ /* GET_MVDATA has reset some stuff */
+ if (mb_has_coeffs /* b_mv2 == "last" */)
{
- if (1 /* intra_mb */)
+ if (mb_is_intra /* intra_mb */)
ac_pred = get_bits(&v->gb, 1);
GET_MQUANT();
}
}
}
//End1
- /* FIXME getting tired, commenting */
-#if 0
if (v->ttmbf)
- v->ttmb = get_bits(&v->gb, n); //vlc
-#endif
- }
- //End2
- for (i=0; i<6; i++)
- {
- /* FIXME: process the block */
- }
+ ttmb = get_vlc2(&v->gb, v->ttmb_vlc->table,
+ VC9_TTMB_VLC_BITS, 12);
- current_mb++;
+ //End2
+ for (i=0; i<6; i++)
+ {
+ /* FIXME: process the block */
+ }
+
+ current_mb++;
+ }
}
return 0;
}
@@ -1554,18 +1765,19 @@ static int decode_b_mbs(VC9Context *v)
#if HAS_ADVANCED_PROFILE
static int advanced_decode_i_mbs(VC9Context *v)
{
- int i, x, y, cbpcy, mqdiff, absmq, mquant, ac_pred, condover,
- current_mb = 0, over_flags_mb = 0;
+ int x, y, mqdiff, mquant, ac_pred, current_mb = 0, over_flags_mb = 0;
for (y=0; y<v->height_mb; y++)
{
for (x=0; x<v->width_mb; x++)
{
- if (v->ac_pred_plane[i])
+ if (v->ac_pred_plane.data[current_mb])
ac_pred = get_bits(&v->gb, 1);
- if (condover == 3 && v->over_flags_plane)
+ if (v->condover == 3 && v->over_flags_plane.is_raw)
over_flags_mb = get_bits(&v->gb, 1);
GET_MQUANT();
+
+ /* TODO: lots */
}
current_mb++;
}
@@ -1584,6 +1796,8 @@ static int vc9_decode_init(AVCodecContext *avctx)
if (init_common(v) < 0) return -1;
+ avctx->coded_width = avctx->width;
+ avctx->coded_height = avctx->height;
if (avctx->codec_id == CODEC_ID_WMV3)
{
int count = 0;
@@ -1615,20 +1829,26 @@ static int vc9_decode_init(AVCodecContext *avctx)
v->height_mb = (avctx->coded_height+15)>>4;
/* Allocate mb bitplanes */
- v->mv_type_mb_plane = (uint8_t *)av_malloc(v->width_mb*v->height_mb);
- if (!v->mv_type_mb_plane) return -1;
- v->skip_mb_plane = (uint8_t *)av_malloc(v->width_mb*v->height_mb);
- if (!v->skip_mb_plane) return -1;
- v->direct_mb_plane = (uint8_t *)av_malloc(v->width_mb*v->height_mb);
- if (!v->direct_mb_plane) return -1;
+ if (alloc_bitplane(&v->mv_type_mb_plane, v->width_mb, v->height_mb) < 0)
+ return -1;
+ if (alloc_bitplane(&v->mv_type_mb_plane, v->width_mb, v->height_mb) < 0)
+ return -1;
+ if (alloc_bitplane(&v->skip_mb_plane, v->width_mb, v->height_mb) < 0)
+ return -1;
+ if (alloc_bitplane(&v->direct_mb_plane, v->width_mb, v->height_mb) < 0)
+ return -1;
+
+ /* For predictors */
+ v->previous_line_cbpcy = (uint8_t *)av_malloc((v->width_mb+1)*4);
+ if (!v->previous_line_cbpcy) return -1;
#if HAS_ADVANCED_PROFILE
if (v->profile > PROFILE_MAIN)
{
- v->over_flags_plane = (uint8_t *)av_malloc(v->width_mb*v->height_mb);
- if (!v->over_flags_plane) return -1;
- v->ac_pred_plane = (uint8_t *)av_malloc(v->width_mb*v->height_mb);
- if (!v->ac_pred_plane) return -1;
+ if (alloc_bitplane(&v->over_flags_plane, v->width_mb, v->height_mb) < 0)
+ return -1;
+ if (alloc_bitplane(&v->ac_pred_plane, v->width_mb, v->height_mb) < 0)
+ return -1;
}
#endif
@@ -1656,8 +1876,8 @@ static int vc9_decode_frame(AVCodecContext *avctx,
if (avctx->codec_id == CODEC_ID_WMV3)
{
+ //No IDU
init_get_bits(&v->gb, buf, buf_size*8);
- av_log(avctx, AV_LOG_INFO, "Frame: %i bits to decode\n", buf_size*8);
#if HAS_ADVANCED_PROFILE
if (v->profile > PROFILE_MAIN)
@@ -1687,10 +1907,6 @@ static int vc9_decode_frame(AVCodecContext *avctx,
}
if (ret == FRAME_SKIPED) return buf_size;
}
-
- /* Size of the output data = image */
- av_log(avctx, AV_LOG_DEBUG, "Consumed %i/%i bits\n",
- get_bits_count(&v->gb), buf_size*8);
}
else
{
@@ -1714,11 +1930,29 @@ static int vc9_decode_frame(AVCodecContext *avctx,
switch(scs)
{
- case 0xf:
- decode_sequence_header(avctx, &v->gb);
- break;
- // to be finished
- }
+ case 0x0A: //Sequence End Code
+ return 0;
+ case 0x0B: //Slice Start Code
+ av_log(avctx, AV_LOG_ERROR, "Slice coding not supported\n");
+ return -1;
+ case 0x0C: //Field start code
+ av_log(avctx, AV_LOG_ERROR, "Interlaced coding not supported\n");
+ return -1;
+ case 0x0D: //Frame start code
+ break;
+ case 0x0E: //Entry point Start Code
+ 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);
+ break;
+ case 0x0F: //Sequence header Start Code
+ decode_sequence_header(avctx, &v->gb);
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR,
+ "Unsupported IDU suffix %lX\n", scs);
+ }
i += get_bits_count(&v->gb)*8;
}
@@ -1726,10 +1960,11 @@ static int vc9_decode_frame(AVCodecContext *avctx,
av_abort();
#endif
}
-
- *data_size = len;
+ av_log(avctx, AV_LOG_DEBUG, "Consumed %i/%i bits\n",
+ get_bits_count(&v->gb), buf_size*8);
/* Fake consumption of all data */
+ *data_size = len;
return buf_size; //Number of bytes consumed
}