[Ffmpeg-cvslog] r5530 - in trunk/libavcodec: vc1.c vc1acdata.h vc1data.h
kostya
subversion
Tue Jun 27 05:12:01 CEST 2006
Author: kostya
Date: Tue Jun 27 05:11:51 2006
New Revision: 5530
Added:
trunk/libavcodec/vc1acdata.h
Modified:
trunk/libavcodec/vc1.c
trunk/libavcodec/vc1data.h
Log:
VC-1 decoder with I-frames support and partial P-frames decoding
Modified: trunk/libavcodec/vc1.c
==============================================================================
--- trunk/libavcodec/vc1.c (original)
+++ trunk/libavcodec/vc1.c Tue Jun 27 05:11:51 2006
@@ -1,8 +1,7 @@
/*
* VC-1 and WMV3 decoder
- * Copyright (c) 2005 Anonymous
- * Copyright (c) 2005 Alex Beregszaszi
- * Copyright (c) 2005 Michael Niedermayer
+ * Copyright (c) 2006 Konstantin Shishkov
+ * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,14 +23,13 @@
* @file vc1.c
* VC-1 and WMV3 decoder
*
- * TODO: most AP stuff, optimize, most of MB layer, transform, filtering and motion compensation, etc
- * TODO: use MPV_ !!
*/
#include "common.h"
#include "dsputil.h"
#include "avcodec.h"
#include "mpegvideo.h"
#include "vc1data.h"
+#include "vc1acdata.h"
#undef NDEBUG
#include <assert.h>
@@ -41,92 +39,108 @@
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;
+extern const uint16_t ff_msmp4_mb_i_table[64][2];
#define DC_VLC_BITS 9
+#define AC_VLC_BITS 9
static const uint16_t table_mb_intra[64][2];
-/* Some inhibiting stuff */
-#define HAS_ADVANCED_PROFILE 0
-#define TRACE 1
-
-#if TRACE
-# define INIT_VLC(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size, \
- codes, codes_wrap, codes_size, use_static) \
- if (init_vlc(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size, \
- codes, codes_wrap, codes_size, use_static) < 0) \
- { \
- av_log(v->s.avctx, AV_LOG_ERROR, "Error for " # vlc " (%i)\n", i); \
- return -1; \
- }
-#else
-# define INIT_VLC(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size, \
- codes, codes_wrap, codes_size, use_static) \
- init_vlc(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size, \
- codes, codes_wrap, codes_size, use_static)
-#endif
/** Available Profiles */
//@{
-#define PROFILE_SIMPLE 0
-#define PROFILE_MAIN 1
-#define PROFILE_COMPLEX 2 ///< TODO: WMV9 specific
-#define PROFILE_ADVANCED 3
+enum Profile {
+ PROFILE_SIMPLE,
+ PROFILE_MAIN,
+ PROFILE_COMPLEX, ///< TODO: WMV9 specific
+ PROFILE_ADVANCED
+};
//@}
/** Sequence quantizer mode */
//@{
-#define QUANT_FRAME_IMPLICIT 0 ///< Implicitly specified at frame level
-#define QUANT_FRAME_EXPLICIT 1 ///< Explicitly specified at frame level
-#define QUANT_NON_UNIFORM 2 ///< Non-uniform quant used for all frames
-#define QUANT_UNIFORM 3 ///< Uniform quant used for all frames
+enum QuantMode {
+ QUANT_FRAME_IMPLICIT, ///< Implicitly specified at frame level
+ QUANT_FRAME_EXPLICIT, ///< Explicitly specified at frame level
+ QUANT_NON_UNIFORM, ///< Non-uniform quant used for all frames
+ QUANT_UNIFORM ///< Uniform quant used for all frames
+};
//@}
/** Where quant can be changed */
//@{
-#define DQPROFILE_FOUR_EDGES 0
-#define DQPROFILE_DOUBLE_EDGES 1
-#define DQPROFILE_SINGLE_EDGE 2
-#define DQPROFILE_ALL_MBS 3
+enum DQProfile {
+ DQPROFILE_FOUR_EDGES,
+ DQPROFILE_DOUBLE_EDGES,
+ DQPROFILE_SINGLE_EDGE,
+ DQPROFILE_ALL_MBS
+};
//@}
/** @name Where quant can be changed
*/
//@{
-#define DQPROFILE_FOUR_EDGES 0
-#define DQSINGLE_BEDGE_LEFT 0
-#define DQSINGLE_BEDGE_TOP 1
-#define DQSINGLE_BEDGE_RIGHT 2
-#define DQSINGLE_BEDGE_BOTTOM 3
+enum DQSingleEdge {
+ DQSINGLE_BEDGE_LEFT,
+ DQSINGLE_BEDGE_TOP,
+ DQSINGLE_BEDGE_RIGHT,
+ DQSINGLE_BEDGE_BOTTOM
+};
//@}
/** Which pair of edges is quantized with ALTPQUANT */
//@{
-#define DQDOUBLE_BEDGE_TOPLEFT 0
-#define DQDOUBLE_BEDGE_TOPRIGHT 1
-#define DQDOUBLE_BEDGE_BOTTOMRIGHT 2
-#define DQDOUBLE_BEDGE_BOTTOMLEFT 3
+enum DQDoubleEdge {
+ DQDOUBLE_BEDGE_TOPLEFT,
+ DQDOUBLE_BEDGE_TOPRIGHT,
+ DQDOUBLE_BEDGE_BOTTOMRIGHT,
+ DQDOUBLE_BEDGE_BOTTOMLEFT
+};
//@}
/** MV modes for P frames */
//@{
-#define MV_PMODE_1MV_HPEL_BILIN 0
-#define MV_PMODE_1MV 1
-#define MV_PMODE_1MV_HPEL 2
-#define MV_PMODE_MIXED_MV 3
-#define MV_PMODE_INTENSITY_COMP 4
+enum MVModes {
+ MV_PMODE_1MV_HPEL_BILIN,
+ MV_PMODE_1MV,
+ MV_PMODE_1MV_HPEL,
+ MV_PMODE_MIXED_MV,
+ MV_PMODE_INTENSITY_COMP
+};
//@}
/** @name MV types for B frames */
//@{
-#define BMV_TYPE_BACKWARD 0
-#define BMV_TYPE_BACKWARD 0
-#define BMV_TYPE_FORWARD 1
-#define BMV_TYPE_INTERPOLATED 3
+enum BMVTypes {
+ BMV_TYPE_BACKWARD,
+ BMV_TYPE_FORWARD,
+ BMV_TYPE_INTERPOLATED = 3 //XXX: ??
+};
+//@}
+
+/** @name Block types for P/B frames */
+//@{
+enum TransformTypes {
+ TT_8X8,
+ TT_8X4_BOTTOM,
+ TT_8X4_TOP,
+ TT_8X4, //Both halves
+ TT_4X8_RIGHT,
+ TT_4X8_LEFT,
+ TT_4X8, //Both halves
+ TT_4X4
+};
//@}
+/** Table for conversion between TTBLK and TTMB */
+static const int ttblk_to_tt[3][8] = {
+ { TT_8X4, TT_4X8, TT_8X8, TT_4X4, TT_8X4_TOP, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT },
+ { TT_8X8, TT_4X8_RIGHT, TT_4X8_LEFT, TT_4X4, TT_8X4, TT_4X8, TT_8X4_BOTTOM, TT_8X4_TOP },
+ { TT_8X8, TT_4X8, TT_4X4, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT, TT_8X4, TT_8X4_TOP }
+};
+
/** 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 },
- { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_INTENSITY_COMP }
+ { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_MIXED_MV },
+ { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_1MV_HPEL_BILIN }
};
/** One more frame type */
@@ -174,8 +188,21 @@
static VLC vc1_ttblk_vlc[3];
#define VC1_SUBBLKPAT_VLC_BITS 6
static VLC vc1_subblkpat_vlc[3];
+
+static VLC vc1_ac_coeff_table[8];
//@}
+enum CodingSet {
+ CS_HIGH_MOT_INTRA = 0,
+ CS_HIGH_MOT_INTER,
+ CS_LOW_MOT_INTRA,
+ CS_LOW_MOT_INTER,
+ CS_MID_RATE_INTRA,
+ CS_MID_RATE_INTER,
+ CS_HIGH_RATE_INTRA,
+ CS_HIGH_RATE_INTER
+};
+
/** Bitplane struct
* We mainly need data and is_raw, so this struct could be avoided
* to save a level of indirection; feel free to modify
@@ -190,6 +217,16 @@
uint8_t is_raw; ///< Bit values must be read at MB level
} BitPlane;
+
+/** Block data for DC/AC prediction
+*/
+typedef struct Block {
+ uint16_t dc;
+ int16_t hor_ac[7];
+ int16_t vert_ac[7];
+ int16_t dcstep, step;
+} Block;
+
/** The VC1 Context
* @fixme Change size wherever another size is more efficient
* Many members are only used for Advanced Profile
@@ -197,6 +234,8 @@
typedef struct VC1Context{
MpegEncContext s;
+ int bits;
+
/** Simple/Main Profile sequence header */
//@{
int res_sm; ///< reserved, 2b
@@ -210,7 +249,6 @@
int reserved; ///< reserved
//@}
-#if HAS_ADVANCED_PROFILE
/** Advanced Profile */
//@{
int level; ///< 3bits, for Advanced/Simple Profile, provided by TS layer
@@ -227,8 +265,6 @@
int hrd_param_flag; ///< Presence of Hypothetical Reference
///< Decoder parameters
//@}
-#endif
-
/** Sequence header data for all Profiles
* TODO: choose between ints, uint8_ts and monobit flags
@@ -252,6 +288,7 @@
uint8_t mv_mode2; ///< Secondary MV coding mode (B frames)
int k_x; ///< Number of bits for MVs (depends on MV range)
int k_y; ///< Number of bits for MVs (depends on MV range)
+ int range_x, range_y; ///< MV range
uint8_t pq, altpq; ///< Current/alternate frame quantizer scale
/** pquant parameters */
//@{
@@ -271,6 +308,11 @@
uint8_t ttmbf; ///< Transform type flag
int ttmb; ///< Transform type
uint8_t ttblk4x4; ///< Value of ttblk which indicates a 4x4 transform
+ int codingset; ///< index of current table set from 11.8 to use for luma block decoding
+ int codingset2; ///< index of current table set from 11.8 to use for chroma block decoding
+ int pqindex; ///< raw pqindex used in coding set selection
+
+
/** Luma compensation parameters */
//@{
uint8_t lumscale;
@@ -301,7 +343,6 @@
uint8_t interpfrm;
//@}
-#if HAS_ADVANCED_PROFILE
/** Frame decoding info for Advanced profile */
//@{
uint8_t fcm; ///< 0->Progressive, 2->Frame-Interlace, 3->Field-Interlace
@@ -327,7 +368,6 @@
uint8_t range_mapy;
uint8_t range_mapuv;
//@}
-#endif
} VC1Context;
/**
@@ -341,7 +381,11 @@
static int get_prefix(GetBitContext *gb, int stop, int len)
{
#if 1
- int i = 0, tmp = !stop;
+ int i;
+
+ for(i = 0; i < len && get_bits1(gb) != stop; i++);
+ return i;
+/* int i = 0, tmp = !stop;
while (i != len && tmp != stop)
{
@@ -349,7 +393,7 @@
i++;
}
if (i == len && tmp != stop) return len+1;
- return i;
+ return i;*/
#else
unsigned int buf;
int log;
@@ -372,6 +416,15 @@
#endif
}
+static inline int decode210(GetBitContext *gb){
+ int n;
+ n = get_bits1(gb);
+ if (n == 1)
+ return 0;
+ else
+ return 2 - get_bits1(gb);
+}
+
/**
* Init VC-1 specific tables and VC1Context members
* @param v The VC1Context to initialize
@@ -386,63 +439,56 @@
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 = (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= (vc1_norm6_spec[i][1] << vc1_norm6_spec[i][4]) + vc1_norm6_spec[i][3];
- av_log(NULL, AV_LOG_DEBUG, "0x%03X, ", code);
- if(i%16==15) av_log(NULL, AV_LOG_DEBUG, "\n");
- }
- for(i=0; i<64; i++){
- int code= vc1_norm6_spec[i][2] + vc1_norm6_spec[i][4];
- av_log(NULL, AV_LOG_DEBUG, "%2d, ", code);
- if(i%16==15) av_log(NULL, AV_LOG_DEBUG, "\n");
- }
-#endif
if(!done)
{
done = 1;
- INIT_VLC(&vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23,
+ init_vlc(&vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23,
vc1_bfraction_bits, 1, 1,
vc1_bfraction_codes, 1, 1, 1);
- INIT_VLC(&vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4,
+ init_vlc(&vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4,
vc1_norm2_bits, 1, 1,
vc1_norm2_codes, 1, 1, 1);
- INIT_VLC(&vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64,
+ init_vlc(&vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64,
vc1_norm6_bits, 1, 1,
vc1_norm6_codes, 2, 2, 1);
- INIT_VLC(&vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7,
+ init_vlc(&vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7,
vc1_imode_bits, 1, 1,
vc1_imode_codes, 1, 1, 1);
for (i=0; i<3; i++)
{
- INIT_VLC(&vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16,
+ init_vlc(&vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16,
vc1_ttmb_bits[i], 1, 1,
vc1_ttmb_codes[i], 2, 2, 1);
- INIT_VLC(&vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8,
+ init_vlc(&vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8,
vc1_ttblk_bits[i], 1, 1,
vc1_ttblk_codes[i], 1, 1, 1);
- INIT_VLC(&vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15,
+ init_vlc(&vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15,
vc1_subblkpat_bits[i], 1, 1,
vc1_subblkpat_codes[i], 1, 1, 1);
}
for(i=0; i<4; i++)
{
- INIT_VLC(&vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16,
+ init_vlc(&vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16,
vc1_4mv_block_pattern_bits[i], 1, 1,
vc1_4mv_block_pattern_codes[i], 1, 1, 1);
- INIT_VLC(&vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64,
+ init_vlc(&vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64,
vc1_cbpcy_p_bits[i], 1, 1,
vc1_cbpcy_p_codes[i], 2, 2, 1);
- INIT_VLC(&vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73,
+ init_vlc(&vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73,
vc1_mv_diff_bits[i], 1, 1,
vc1_mv_diff_codes[i], 2, 2, 1);
}
+ for(i=0; i<8; i++)
+ init_vlc(&vc1_ac_coeff_table[i], AC_VLC_BITS, vc1_ac_sizes[i],
+ &vc1_ac_tables[i][0][1], 8, 4,
+ &vc1_ac_tables[i][0][0], 8, 4, 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);
}
/* Other defaults */
@@ -452,279 +498,538 @@
return 0;
}
-#if HAS_ADVANCED_PROFILE
+/***********************************************************************/
/**
- * Decode sequence header's Hypothetic Reference Decoder data
- * @see 6.2.1, p32
- * @param v The VC1Context to initialize
- * @param gb A GetBitContext initialized from AVCodecContext extra_data
+ * @defgroup bitplane VC9 Bitplane decoding
+ * @see 8.7, p56
+ * @{
+ */
+
+/** @addtogroup bitplane
+ * Imode types
+ * @{
+ */
+enum Imode {
+ IMODE_RAW,
+ IMODE_NORM2,
+ IMODE_DIFF2,
+ IMODE_NORM6,
+ IMODE_DIFF6,
+ IMODE_ROWSKIP,
+ IMODE_COLSKIP
+};
+/** @} */ //imode defines
+
+/** Allocate the buffer from a bitplane, given its dimensions
+ * @param bp Bitplane which buffer is to allocate
+ * @param[in] width Width of the buffer
+ * @param[in] height Height of the buffer
* @return Status
+ * @todo TODO: Take into account stride
+ * @todo TODO: Allow use of external buffers ?
*/
-static int decode_hrd(VC1Context *v, GetBitContext *gb)
+static int alloc_bitplane(BitPlane *bp, int width, int height)
{
- int i, num;
-
- num = 1 + get_bits(gb, 5);
+ 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;
+ bp->height = height;
+ return 0;
+}
- /*hrd rate*/
- if (v->hrd_rate || num != v->hrd_num_leaky_buckets)
- {
- av_freep(&v->hrd_rate);
- }
- if (!v->hrd_rate) v->hrd_rate = av_malloc(num*sizeof(uint16_t));
- if (!v->hrd_rate) return -1;
+/** Free the bitplane's buffer
+ * @param bp Bitplane which buffer is to free
+ */
+static void free_bitplane(BitPlane *bp)
+{
+ bp->width = bp->stride = bp->height = 0;
+ if (bp->data) av_freep(&bp->data);
+}
- /*hrd buffer*/
- 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*sizeof(uint16_t));
- if (!v->hrd_buffer)
- {
- av_freep(&v->hrd_rate);
- return -1;
- }
+/** Decode rows by checking if they are skipped
+ * @param plane Buffer to store decoded bits
+ * @param[in] width Width of this buffer
+ * @param[in] height Height of this buffer
+ * @param[in] stride of this buffer
+ */
+static void decode_rowskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
+ int x, y;
- /*hrd fullness*/
- if (v->hrd_fullness || num != v->hrd_num_leaky_buckets)
- {
- av_freep(&v->hrd_buffer);
- }
- if (!v->hrd_fullness) v->hrd_fullness = av_malloc(num*sizeof(uint8_t));
- if (!v->hrd_fullness)
- {
- av_freep(&v->hrd_rate);
- av_freep(&v->hrd_buffer);
- return -1;
+ for (y=0; y<height; y++){
+ if (!get_bits(gb, 1)) //rowskip
+ memset(plane, 0, width);
+ else
+ for (x=0; x<width; x++)
+ plane[x] = get_bits(gb, 1);
+ plane += stride;
}
- v->hrd_num_leaky_buckets = num;
+}
- //exponent in base-2 for rate
- v->bit_rate_exponent = 6 + get_bits(gb, 4);
- //exponent in base-2 for buffer_size
- v->buffer_size_exponent = 4 + get_bits(gb, 4);
+/** Decode columns by checking if they are skipped
+ * @param plane Buffer to store decoded bits
+ * @param[in] width Width of this buffer
+ * @param[in] height Height of this buffer
+ * @param[in] stride of this buffer
+ * @fixme FIXME: Optimize
+ */
+static void decode_colskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
+ int x, y;
- for (i=0; i<num; i++)
- {
- //mantissae, ordered (if not, use a function ?
- v->hrd_rate[i] = 1 + get_bits(gb, 16);
- if (i && v->hrd_rate[i-1]>=v->hrd_rate[i])
- {
- av_log(v->s.avctx, AV_LOG_ERROR, "HDR Rates aren't strictly increasing:"
- "%i vs %i\n", v->hrd_rate[i-1], v->hrd_rate[i]);
- return -1;
- }
- v->hrd_buffer[i] = 1 + get_bits(gb, 16);
- if (i && v->hrd_buffer[i-1]<v->hrd_buffer[i])
- {
- av_log(v->s.avctx, AV_LOG_ERROR, "HDR Buffers aren't decreasing:"
- "%i vs %i\n", v->hrd_buffer[i-1], v->hrd_buffer[i]);
- return -1;
- }
+ for (x=0; x<width; x++){
+ if (!get_bits(gb, 1)) //colskip
+ for (y=0; y<height; y++)
+ plane[y*stride] = 0;
+ else
+ for (y=0; y<height; y++)
+ plane[y*stride] = get_bits(gb, 1);
+ plane ++;
}
- return 0;
}
-/**
- * Decode sequence header for Advanced Profile
- * @see Table 2, p18
- * @see 6.1.7, pp21-27
- * @param v The VC1Context to initialize
- * @param gb A GetBitContext initialized from AVCodecContext extra_data
+/** Decode a bitplane's bits
+ * @param bp Bitplane where to store the decode bits
+ * @param v VC-1 context for bit reading and logging
* @return Status
+ * @fixme FIXME: Optimize
+ * @todo TODO: Decide if a struct is needed
*/
-static int decode_advanced_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
+static int bitplane_decoding(BitPlane *bp, VC1Context *v)
{
- VC1Context *v = avctx->priv_data;
- int nr, dr, aspect_ratio;
+ GetBitContext *gb = &v->s.gb;
- v->postprocflag = get_bits(gb, 1);
- v->broadcast = get_bits(gb, 1);
- v->interlace = get_bits(gb, 1);
-
- v->tfcntrflag = get_bits(gb, 1);
- v->finterpflag = get_bits(gb, 1); //common
- v->panscanflag = get_bits(gb, 1);
- v->reserved = get_bits(gb, 1);
- if (v->reserved)
- {
- av_log(avctx, AV_LOG_ERROR, "RESERVED should be 0 (is %i)\n",
- v->reserved);
- return -1;
- }
- if (v->extended_mv)
- v->extended_dmv = get_bits(gb, 1);
+ int imode, x, y, code, offset;
+ uint8_t invert, *planep = bp->data;
+
+ invert = get_bits(gb, 1);
+ imode = get_vlc2(gb, vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1);
- /* 6.1.7, p21 */
- if (get_bits(gb, 1) /* pic_size_flag */)
+ bp->is_raw = 0;
+ switch (imode)
{
- avctx->coded_width = get_bits(gb, 12) << 1;
- avctx->coded_height = get_bits(gb, 12) << 1;
- if ( get_bits(gb, 1) /* disp_size_flag */)
+ case IMODE_RAW:
+ //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 ((bp->height * bp->width) & 1)
{
- avctx->width = get_bits(gb, 14);
- avctx->height = get_bits(gb, 14);
+ *planep++ = get_bits(gb, 1);
+ offset = 1;
}
-
- /* 6.1.7.4, p23 */
- if ( get_bits(gb, 1) /* aspect_ratio_flag */)
- {
- aspect_ratio = get_bits(gb, 4); //SAR
- if (aspect_ratio == 0x0F) //FF_ASPECT_EXTENDED
- {
- avctx->sample_aspect_ratio.num = 1 + get_bits(gb, 8);
- avctx->sample_aspect_ratio.den = 1 + get_bits(gb, 8);
+ else offset = 0;
+ // decode bitplane as one long line
+ for (y = offset; y < bp->height * bp->width; y += 2) {
+ code = get_vlc2(gb, vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1);
+ *planep++ = code & 1;
+ offset++;
+ if(offset == bp->width) {
+ offset = 0;
+ planep += bp->stride - bp->width;
+ }
+ *planep++ = code >> 1;
+ offset++;
+ if(offset == bp->width) {
+ offset = 0;
+ planep += bp->stride - bp->width;
}
- else if (aspect_ratio == 0x0E)
- {
- av_log(avctx, AV_LOG_DEBUG, "Reserved AR found\n");
+ }
+ break;
+ case IMODE_DIFF6:
+ case IMODE_NORM6:
+ if(!(bp->height % 3) && (bp->width % 3)) { // use 2x3 decoding
+ for(y = 0; y < bp->height; y+= 3) {
+ for(x = bp->width & 1; x < bp->width; x += 2) {
+ code = get_vlc2(gb, vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
+ if(code < 0){
+ av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
+ return -1;
+ }
+ planep[x + 0] = (code >> 0) & 1;
+ planep[x + 1] = (code >> 1) & 1;
+ planep[x + 0 + bp->stride] = (code >> 2) & 1;
+ planep[x + 1 + bp->stride] = (code >> 3) & 1;
+ planep[x + 0 + bp->stride * 2] = (code >> 4) & 1;
+ planep[x + 1 + bp->stride * 2] = (code >> 5) & 1;
+ }
+ planep += bp->stride * 3;
}
- else
- {
- avctx->sample_aspect_ratio = vc1_pixel_aspect[aspect_ratio];
+ if(bp->width & 1) decode_colskip(bp->data, 1, bp->height, bp->stride, &v->s.gb);
+ } else { // 3x2
+ for(y = bp->height & 1; y < bp->height; y += 2) {
+ for(x = bp->width % 3; x < bp->width; x += 3) {
+ code = get_vlc2(gb, vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
+ if(code < 0){
+ av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
+ return -1;
+ }
+ planep[x + 0] = (code >> 0) & 1;
+ planep[x + 1] = (code >> 1) & 1;
+ planep[x + 2] = (code >> 2) & 1;
+ planep[x + 0 + bp->stride] = (code >> 3) & 1;
+ planep[x + 1 + bp->stride] = (code >> 4) & 1;
+ planep[x + 2 + bp->stride] = (code >> 5) & 1;
+ }
+ planep += bp->stride * 2;
}
+ x = bp->width % 3;
+ if(x) decode_colskip(bp->data , x, bp->height , bp->stride, &v->s.gb);
+ if(bp->height & 1) decode_rowskip(bp->data+x, bp->width - x, bp->height & 1, bp->stride, &v->s.gb);
}
- }
- else
- {
- avctx->coded_width = avctx->width;
- avctx->coded_height = avctx->height;
+ break;
+ case IMODE_ROWSKIP:
+ decode_rowskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);
+ break;
+ case IMODE_COLSKIP:
+ decode_colskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);
+ break;
+ default: break;
}
- /* 6.1.8, p23 */
- if ( get_bits(gb, 1) /* framerateflag */)
+ /* Applying diff operator */
+ if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)
{
- if ( !get_bits(gb, 1) /* framerateind */)
+ planep = bp->data;
+ planep[0] ^= invert;
+ for (x=1; x<bp->width; x++)
+ planep[x] ^= planep[x-1];
+ for (y=1; y<bp->height; y++)
{
- nr = get_bits(gb, 8);
- dr = get_bits(gb, 4);
- if (nr<1)
- {
- av_log(avctx, AV_LOG_ERROR, "0 is forbidden for FRAMERATENR\n");
- return -1;
- }
- if (nr>5)
- {
- av_log(avctx, AV_LOG_ERROR,
- "Reserved FRAMERATENR %i not handled\n", nr);
- nr = 5; /* overflow protection */
- }
- if (dr<1)
- {
- av_log(avctx, AV_LOG_ERROR, "0 is forbidden for FRAMERATEDR\n");
- return -1;
- }
- if (dr>2)
+ planep += bp->stride;
+ planep[0] ^= planep[-bp->stride];
+ for (x=1; x<bp->width; x++)
{
- av_log(avctx, AV_LOG_ERROR,
- "Reserved FRAMERATEDR %i not handled\n", dr);
- dr = 2; /* overflow protection */
+ if (planep[x-1] != planep[x-bp->stride]) planep[x] ^= invert;
+ else planep[x] ^= planep[x-1];
}
- avctx->time_base.num = fps_nr[dr - 1];
- avctx->time_base.den = fps_nr[nr - 1];
- }
- else
- {
- nr = get_bits(gb, 16);
- // 0.03125->2048Hz / 0.03125Hz
- avctx->time_base.den = 1000000;
- avctx->time_base.num = 31250*(1+nr);
- }
- }
-
- /* 6.1.9, p25 */
- if ( get_bits(gb, 1) /* color_format_flag */)
- {
- //Chromacity coordinates of color primaries
- //like ITU-R BT.709-2, BT.470-2, ...
- v->color_prim = get_bits(gb, 8);
- if (v->color_prim<1)
- {
- av_log(avctx, AV_LOG_ERROR, "0 for COLOR_PRIM is forbidden\n");
- return -1;
- }
- if (v->color_prim == 3 || v->color_prim>6)
- {
- av_log(avctx, AV_LOG_DEBUG, "Reserved COLOR_PRIM %i found\n",
- v->color_prim);
- return -1;
- }
-
- //Opto-electronic transfer characteristics
- v->transfer_char = get_bits(gb, 8);
- if (v->transfer_char < 1)
- {
- av_log(avctx, AV_LOG_ERROR, "0 for TRAMSFER_CHAR is forbidden\n");
- return -1;
- }
- if (v->transfer_char == 3 || v->transfer_char>8)
- {
- av_log(avctx, AV_LOG_DEBUG, "Reserved TRANSFERT_CHAR %i found\n",
- v->color_prim);
- return -1;
- }
-
- //Matrix coefficient for primariev->YCbCr
- v->matrix_coef = get_bits(gb, 8);
- if (v->matrix_coef < 1)
- {
- av_log(avctx, AV_LOG_ERROR, "0 for MATRIX_COEF is forbidden\n");
- return -1;
- }
- if ((v->matrix_coef > 2 && v->matrix_coef < 6) || v->matrix_coef > 7)
- {
- av_log(avctx, AV_LOG_DEBUG, "Reserved MATRIX_COEF %i found\n",
- v->color_prim);
- return -1;
}
}
-
- //Hypothetical reference decoder indicator flag
- v->hrd_param_flag = get_bits(gb, 1);
- if (v->hrd_param_flag)
+ else if (invert)
{
- if (decode_hrd(v, gb) < 0) return -1;
+ planep = bp->data;
+ for (x=0; x<bp->width*bp->height; x++) planep[x] = !planep[x]; //FIXME stride
}
-
- /*reset scaling ranges, 6.2.2 & 6.2.3, p33*/
- v->range_mapy_flag = 0;
- v->range_mapuv_flag = 0;
-
- av_log(avctx, AV_LOG_DEBUG, "Advanced profile not supported yet\n");
- return -1;
+ return (imode<<1) + invert;
}
-#endif
+/** @} */ //Bitplane group
-/**
- * Decode Simple/Main Profiles sequence header
- * @see Figure 7-8, p16-17
- * @param avctx Codec context
- * @param gb GetBit context initialized from Codec context extra_data
- * @return Status
+/***********************************************************************/
+/** VOP Dquant decoding
+ * @param v VC-1 Context
*/
-static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
+static int vop_dquant_decoding(VC1Context *v)
{
- VC1Context *v = avctx->priv_data;
+ GetBitContext *gb = &v->s.gb;
+ int pqdiff;
- av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits(gb, 32));
- v->profile = get_bits(gb, 2);
- if (v->profile == 2)
+ //variable size
+ if (v->dquant == 2)
{
- av_log(avctx, AV_LOG_ERROR, "Profile value 2 is forbidden\n");
- return -1;
+ pqdiff = get_bits(gb, 3);
+ if (pqdiff == 7) v->altpq = get_bits(gb, 5);
+ else v->altpq = v->pq + pqdiff + 1;
}
-
-#if HAS_ADVANCED_PROFILE
- if (v->profile == PROFILE_ADVANCED)
+ else
{
- v->level = get_bits(gb, 3);
- if(v->level >= 5)
+ v->dquantfrm = get_bits(gb, 1);
+ if ( v->dquantfrm )
{
- av_log(avctx, AV_LOG_ERROR, "Reserved LEVEL %i\n",v->level);
- }
- v->chromaformat = get_bits(gb, 2);
- if (v->chromaformat != 1)
+ v->dqprofile = get_bits(gb, 2);
+ switch (v->dqprofile)
+ {
+ case DQPROFILE_SINGLE_EDGE:
+ case DQPROFILE_DOUBLE_EDGES:
+ v->dqsbedge = get_bits(gb, 2);
+ break;
+ case DQPROFILE_ALL_MBS:
+ v->dqbilevel = get_bits(gb, 1);
+ default: break; //Forbidden ?
+ }
+ if (!v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS)
+ {
+ pqdiff = get_bits(gb, 3);
+ if (pqdiff == 7) v->altpq = get_bits(gb, 5);
+ else v->altpq = v->pq + pqdiff + 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/** Do inverse transform
+ */
+static void vc1_inv_trans(DCTELEM block[64], int M, int N)
+{
+ int i;
+ register int t1,t2,t3,t4,t5,t6,t7,t8;
+ DCTELEM *src, *dst;
+
+ src = block;
+ dst = block;
+ if(M==4){
+ for(i = 0; i < N; i++){
+ t1 = 17 * (src[0] + src[2]);
+ t2 = 17 * (src[0] - src[2]);
+ t3 = 22 * src[1];
+ t4 = 22 * src[3];
+ t5 = 10 * src[1];
+ t6 = 10 * src[3];
+
+ dst[0] = (t1 + t3 + t6 + 4) >> 3;
+ dst[1] = (t2 - t4 + t5 + 4) >> 3;
+ dst[2] = (t2 + t4 - t5 + 4) >> 3;
+ dst[3] = (t1 - t3 - t6 + 4) >> 3;
+
+ src += 8;
+ dst += 8;
+ }
+ }else{
+ for(i = 0; i < N; i++){
+ t1 = 12 * (src[0] + src[4]);
+ t2 = 12 * (src[0] - src[4]);
+ t3 = 16 * src[2] + 6 * src[6];
+ t4 = 6 * src[2] - 16 * src[6];
+
+ t5 = t1 + t3;
+ t6 = t2 + t4;
+ t7 = t2 - t4;
+ t8 = t1 - t3;
+
+ t1 = 16 * src[1] + 15 * src[3] + 9 * src[5] + 4 * src[7];
+ t2 = 15 * src[1] - 4 * src[3] - 16 * src[5] - 9 * src[7];
+ t3 = 9 * src[1] - 16 * src[3] + 4 * src[5] + 15 * src[7];
+ t4 = 4 * src[1] - 9 * src[3] + 15 * src[5] - 16 * src[7];
+
+ dst[0] = (t5 + t1 + 4) >> 3;
+ dst[1] = (t6 + t2 + 4) >> 3;
+ dst[2] = (t7 + t3 + 4) >> 3;
+ dst[3] = (t8 + t4 + 4) >> 3;
+ dst[4] = (t8 - t4 + 4) >> 3;
+ dst[5] = (t7 - t3 + 4) >> 3;
+ dst[6] = (t6 - t2 + 4) >> 3;
+ dst[7] = (t5 - t1 + 4) >> 3;
+
+ src += 8;
+ dst += 8;
+ }
+ }
+
+ src = block;
+ dst = block;
+ if(N==4){
+ for(i = 0; i < M; i++){
+ t1 = 17 * (src[ 0] + src[16]);
+ t2 = 17 * (src[ 0] - src[16]);
+ t3 = 22 * src[ 8];
+ t4 = 22 * src[24];
+ t5 = 10 * src[ 8];
+ t6 = 10 * src[24];
+
+ dst[ 0] = (t1 + t3 + t6 + 64) >> 7;
+ dst[ 8] = (t2 - t4 + t5 + 64) >> 7;
+ dst[16] = (t2 + t4 - t5 + 64) >> 7;
+ dst[24] = (t1 - t3 - t6 + 64) >> 7;
+
+ src ++;
+ dst ++;
+ }
+ }else{
+ for(i = 0; i < M; i++){
+ t1 = 12 * (src[ 0] + src[32]);
+ t2 = 12 * (src[ 0] - src[32]);
+ t3 = 16 * src[16] + 6 * src[48];
+ t4 = 6 * src[16] - 16 * src[48];
+
+ t5 = t1 + t3;
+ t6 = t2 + t4;
+ t7 = t2 - t4;
+ t8 = t1 - t3;
+
+ t1 = 16 * src[ 8] + 15 * src[24] + 9 * src[40] + 4 * src[56];
+ t2 = 15 * src[ 8] - 4 * src[24] - 16 * src[40] - 9 * src[56];
+ t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56];
+ t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56];
+
+ dst[ 0] = (t5 + t1 + 64) >> 7;
+ dst[ 8] = (t6 + t2 + 64) >> 7;
+ dst[16] = (t7 + t3 + 64) >> 7;
+ dst[24] = (t8 + t4 + 64) >> 7;
+ dst[32] = (t8 - t4 + 64 + 1) >> 7;
+ dst[40] = (t7 - t3 + 64 + 1) >> 7;
+ dst[48] = (t6 - t2 + 64 + 1) >> 7;
+ dst[56] = (t5 - t1 + 64 + 1) >> 7;
+
+ src++;
+ dst++;
+ }
+ }
+}
+
+/** Apply overlap transform
+ * @todo optimize
+ * @todo move to DSPContext
+ */
+static void vc1_overlap_block(MpegEncContext *s, DCTELEM block[64], int n, int do_hor, int do_vert)
+{
+ int i;
+
+ if(do_hor) { //TODO
+ }
+ if(do_vert) { //TODO
+ }
+
+ for(i = 0; i < 64; i++)
+ block[i] += 128;
+}
+
+
+/** Put block onto picture
+ * @todo move to DSPContext
+ */
+static void vc1_put_block(VC1Context *v, DCTELEM block[6][64])
+{
+ uint8_t *Y;
+ int ys, us, vs;
+ DSPContext *dsp = &v->s.dsp;
+
+ ys = v->s.current_picture.linesize[0];
+ us = v->s.current_picture.linesize[1];
+ vs = v->s.current_picture.linesize[2];
+ Y = v->s.dest[0];
+
+ dsp->put_pixels_clamped(block[0], Y, ys);
+ dsp->put_pixels_clamped(block[1], Y + 8, ys);
+ Y += ys * 8;
+ dsp->put_pixels_clamped(block[2], Y, ys);
+ dsp->put_pixels_clamped(block[3], Y + 8, ys);
+
+ dsp->put_pixels_clamped(block[4], v->s.dest[1], us);
+ dsp->put_pixels_clamped(block[5], v->s.dest[2], vs);
+}
+
+/** Do motion compensation over 1 macroblock
+ * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
+ */
+static void vc1_mc_1mv(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ DSPContext *dsp = &v->s.dsp;
+ uint8_t *srcY, *srcU, *srcV;
+ int dxy, mx, my, src_x, src_y;
+ int width = s->mb_width * 16, height = s->mb_height * 16;
+
+ if(!v->s.last_picture.data[0])return;
+
+ mx = s->mv[0][0][0] >> s->mspel;
+ my = s->mv[0][0][1] >> s->mspel;
+ srcY = s->last_picture.data[0];
+ srcU = s->last_picture.data[1];
+ srcV = s->last_picture.data[2];
+
+ if(s->mspel) { // hpel mc
+ dxy = ((my & 1) << 1) | (mx & 1);
+ src_x = s->mb_x * 16 + (mx >> 1);
+ src_y = s->mb_y * 16 + (my >> 1);
+/* src_x = clip(src_x, -16, width); //FIXME unneeded for emu?
+ if (src_x == width)
+ dxy &= ~1;
+ src_y = clip(src_y, -16, height);
+ if (src_y == height)
+ dxy &= ~2;*/
+ srcY += src_y * s->linesize + src_x;
+ srcU += (src_y >> 1) * s->uvlinesize + (src_x >> 1);
+ srcV += (src_y >> 1) * s->uvlinesize + (src_x >> 1);
+
+ if((unsigned)src_x > s->h_edge_pos - (mx&1) - 16
+ || (unsigned)src_y > s->v_edge_pos - (my&1) - 16){
+ uint8_t *uvbuf= s->edge_emu_buffer + 18 * s->linesize;
+
+ ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 16+1, 16+1,
+ src_x, src_y, s->h_edge_pos, s->v_edge_pos);
+ srcY = s->edge_emu_buffer;
+ ff_emulated_edge_mc(uvbuf, srcU, s->uvlinesize, 8+1, 8+1,
+ src_x >> 1, src_y >> 1, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
+ src_x >> 1, src_y >> 1, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ srcU = uvbuf;
+ srcV = uvbuf + 16;
+ }
+ dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
+ dsp->put_no_rnd_pixels_tab[1][0](s->dest[1], srcU, s->uvlinesize, 8);
+ dsp->put_no_rnd_pixels_tab[1][0](s->dest[2], srcV, s->uvlinesize, 8);
+ } else {
+ int motion_x = mx, motion_y = my, uvdxy, uvsrc_x, uvsrc_y;
+ dxy = ((motion_y & 3) << 2) | (motion_x & 3);
+ src_x = s->mb_x * 16 + (mx >> 2);
+ src_y = s->mb_y * 16 + (my >> 2);
+
+ mx= motion_x/2;
+ my= motion_y/2;
+
+ mx= (mx>>1)|(mx&1);
+ my= (my>>1)|(my&1);
+
+ uvdxy= (mx&1) | ((my&1)<<1);
+ mx>>=1;
+ my>>=1;
+
+ uvsrc_x = s->mb_x * 8 + mx;
+ uvsrc_y = s->mb_y * 8 + my;
+
+ srcY = s->last_picture.data[0] + src_y * s->linesize + src_x;
+ srcU = s->last_picture.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV = s->last_picture.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+
+ if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 16
+ || (unsigned)src_y > s->v_edge_pos - (motion_y&3) - 16 ){
+ uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize;
+ ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17, 17,
+ src_x, src_y, s->h_edge_pos, s->v_edge_pos);
+ srcY = s->edge_emu_buffer;
+ ff_emulated_edge_mc(uvbuf, srcU, s->uvlinesize, 9, 9,
+ uvsrc_x, uvsrc_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+ ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 9, 9,
+ uvsrc_x, uvsrc_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+ srcU = uvbuf;
+ srcV = uvbuf + 16;
+ }
+
+ dsp->put_no_rnd_qpel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize);
+ dsp->put_no_rnd_pixels_tab[1][uvdxy](s->dest[1], srcU, s->uvlinesize, 8);
+ dsp->put_no_rnd_pixels_tab[1][uvdxy](s->dest[2], srcV, s->uvlinesize, 8);
+ }
+}
+
+/**
+ * Decode Simple/Main Profiles sequence header
+ * @see Figure 7-8, p16-17
+ * @param avctx Codec context
+ * @param gb GetBit context initialized from Codec context extra_data
+ * @return Status
+ */
+static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
+{
+ VC1Context *v = avctx->priv_data;
+
+ av_log(avctx, AV_LOG_INFO, "Header: %0X\n", show_bits(gb, 32));
+ v->profile = get_bits(gb, 2);
+ if (v->profile == 2)
+ {
+ av_log(avctx, AV_LOG_ERROR, "Profile value 2 is forbidden (and WMV3 Complex Profile is unsupported)\n");
+ return -1;
+ }
+
+ if (v->profile == PROFILE_ADVANCED)
+ {
+ v->level = get_bits(gb, 3);
+ if(v->level >= 5)
+ {
+ av_log(avctx, AV_LOG_ERROR, "Reserved LEVEL %i\n",v->level);
+ }
+ v->chromaformat = get_bits(gb, 2);
+ if (v->chromaformat != 1)
{
av_log(avctx, AV_LOG_ERROR,
"Only 4:2:0 chroma format supported\n");
@@ -732,7 +1037,6 @@
}
}
else
-#endif
{
v->res_sm = get_bits(gb, 2); //reserved
if (v->res_sm)
@@ -754,9 +1058,7 @@
"LOOPFILTER shell not be enabled in simple profile\n");
}
-#if HAS_ADVANCED_PROFILE
if (v->profile < PROFILE_ADVANCED)
-#endif
{
v->res_x8 = get_bits(gb, 1); //reserved
if (v->res_x8)
@@ -792,9 +1094,7 @@
v->dquant = get_bits(gb, 2); //common
v->vstransform = get_bits(gb, 1); //common
-#if HAS_ADVANCED_PROFILE
if (v->profile < PROFILE_ADVANCED)
-#endif
{
v->res_transtab = get_bits(gb, 1);
if (v->res_transtab)
@@ -807,15 +1107,13 @@
v->overlap = get_bits(gb, 1); //common
-#if HAS_ADVANCED_PROFILE
if (v->profile < PROFILE_ADVANCED)
-#endif
{
v->s.resync_marker = get_bits(gb, 1);
v->rangered = get_bits(gb, 1);
if (v->rangered && v->profile == PROFILE_SIMPLE)
{
- av_log(avctx, AV_LOG_DEBUG,
+ av_log(avctx, AV_LOG_INFO,
"RANGERED should be set to 0 in simple profile\n");
}
}
@@ -823,9 +1121,7 @@
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
if (v->profile < PROFILE_ADVANCED)
-#endif
{
v->finterpflag = get_bits(gb, 1); //common
v->res_rtm_flag = get_bits(gb, 1); //reserved
@@ -835,828 +1131,134 @@
"0 for reserved RES_RTM_FLAG is forbidden\n");
//return -1;
}
-#if TRACE
- av_log(avctx, AV_LOG_INFO,
+ av_log(avctx, AV_LOG_DEBUG,
"Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
"LoopFilter=%i, MultiRes=%i, FastUVMV=%i, Extended MV=%i\n"
"Rangered=%i, VSTransform=%i, Overlap=%i, SyncMarker=%i\n"
"DQuant=%i, Quantizer mode=%i, Max B frames=%i\n",
v->profile, v->frmrtq_postproc, v->bitrtq_postproc,
v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv,
- v->rangered, v->vstransform, v->overlap, v->s.resync_marker,
- v->dquant, v->quantizer_mode, avctx->max_b_frames
- );
- return 0;
-#endif
- }
-#if HAS_ADVANCED_PROFILE
- else return decode_advanced_sequence_header(avctx, gb);
-#endif
-}
-
-
-#if HAS_ADVANCED_PROFILE
-/** Entry point decoding (Advanced Profile)
- * @param avctx Codec context
- * @param gb GetBit context initialized from avctx->extra_data
- * @return Status
- */
-static int advanced_entry_point_process(AVCodecContext *avctx, GetBitContext *gb)
-{
- VC1Context *v = avctx->priv_data;
- int i;
- if (v->profile != PROFILE_ADVANCED)
- {
- av_log(avctx, AV_LOG_ERROR,
- "Entry point are only defined in Advanced Profile!\n");
- return -1; //Only for advanced profile!
- }
- if (v->hrd_param_flag)
- {
- //Update buffer fullness
- av_log(avctx, AV_LOG_DEBUG, "Buffer fullness update\n");
- assert(v->hrd_num_leaky_buckets > 0);
- for (i=0; i<v->hrd_num_leaky_buckets; i++)
- v->hrd_fullness[i] = get_bits(gb, 8);
- }
- if ((v->range_mapy_flag = get_bits(gb, 1)))
- {
- //RANGE_MAPY
- av_log(avctx, AV_LOG_DEBUG, "RANGE_MAPY\n");
- v->range_mapy = get_bits(gb, 3);
- }
- if ((v->range_mapuv_flag = get_bits(gb, 1)))
- {
- //RANGE_MAPUV
- av_log(avctx, AV_LOG_DEBUG, "RANGE_MAPUV\n");
- v->range_mapuv = get_bits(gb, 3);
- }
- if (v->panscanflag)
- {
- //NUMPANSCANWIN
- v->numpanscanwin = get_bits(gb, 3);
- av_log(avctx, AV_LOG_DEBUG, "NUMPANSCANWIN: %u\n", v->numpanscanwin);
- }
- return 0;
-}
-#endif
-
-/***********************************************************************/
-/**
- * @defgroup bitplane VC1 Bitplane decoding
- * @see 8.7, p56
- * @{
- */
-
-/** @addtogroup bitplane
- * Imode types
- * @{
- */
-#define IMODE_RAW 0
-#define IMODE_NORM2 1
-#define IMODE_DIFF2 2
-#define IMODE_NORM6 3
-#define IMODE_DIFF6 4
-#define IMODE_ROWSKIP 5
-#define IMODE_COLSKIP 6
-/** @} */ //imode defines
-
-/** Allocate the buffer from a bitplane, given its dimensions
- * @param bp Bitplane which buffer is to allocate
- * @param[in] width Width of the buffer
- * @param[in] height Height of the buffer
- * @return Status
- * @todo TODO: Take into account stride
- * @todo TODO: Allow use of external buffers ?
- */
-static 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;
- bp->height = height;
- return 0;
-}
-
-/** Free the bitplane's buffer
- * @param bp Bitplane which buffer is to free
- */
-static void free_bitplane(BitPlane *bp)
-{
- bp->width = bp->stride = bp->height = 0;
- if (bp->data) av_freep(&bp->data);
-}
-
-/** Decode rows by checking if they are skipped
- * @param plane Buffer to store decoded bits
- * @param[in] width Width of this buffer
- * @param[in] height Height of this buffer
- * @param[in] stride of this buffer
- */
-static void decode_rowskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
- int x, y;
-
- for (y=0; y<height; y++){
- if (!get_bits(gb, 1)) //rowskip
- memset(plane, 0, width);
- else
- for (x=0; x<width; x++)
- plane[x] = get_bits(gb, 1);
- plane += stride;
- }
-}
-
-/** Decode columns by checking if they are skipped
- * @param plane Buffer to store decoded bits
- * @param[in] width Width of this buffer
- * @param[in] height Height of this buffer
- * @param[in] stride of this buffer
- * @fixme FIXME: Optimize
- */
-static void decode_colskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
- int x, y;
-
- for (x=0; x<width; x++){
- if (!get_bits(gb, 1)) //colskip
- for (y=0; y<height; y++)
- plane[y*stride] = 0;
- else
- for (y=0; y<height; y++)
- plane[y*stride] = get_bits(gb, 1);
- plane ++;
- }
-}
-
-/** Decode a bitplane's bits
- * @param bp Bitplane where to store the decode bits
- * @param v VC1 context for bit reading and logging
- * @return Status
- * @fixme FIXME: Optimize
- * @todo TODO: Decide if a struct is needed
- */
-static int bitplane_decoding(BitPlane *bp, VC1Context *v)
-{
- GetBitContext *gb = &v->s.gb;
-
- int imode, x, y, code, use_vertical_tile, tile_w, tile_h, offset;
- uint8_t invert, *planep = bp->data;
-
- invert = get_bits(gb, 1);
- imode = get_vlc2(gb, vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 2);
-
- bp->is_raw = 0;
- switch (imode)
- {
- case IMODE_RAW:
- //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 ((bp->height*bp->width) & 1)
- {
- *(++planep) = get_bits(gb, 1);
- offset = x = 1;
- }
- else offset = x = 0;
-
- for (y=0; y<bp->height; y++)
- {
- for(; x<bp->width; x+=2)
- {
- code = get_vlc2(gb, vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 2);
- *(++planep) = code&1; //lsb => left
- *(++planep) = (code>>1)&1; //msb => right
- }
- planep += bp->stride-bp->width;
- if ((bp->width-offset)&1) //Odd number previously processed
- {
- code = get_vlc2(gb, vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 2);
- *planep = code&1;
- planep += bp->stride-bp->width;
- *planep = (code>>1)&1; //msb => right
- offset = x = 1;
- }
- else
- {
- offset = x = 0;
- planep += bp->stride-bp->width;
- }
- }
- break;
- case IMODE_DIFF6:
- case IMODE_NORM6:
- 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= 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(gb, vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
- if(code<0){
- av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
- return -1;
- }
- //FIXME following is a pure guess and probably wrong
- //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;
- //FIXME Does branch prediction help here?
- if(use_vertical_tile){
- 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*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= bp->width % tile_w;
- decode_colskip(bp->data , x, bp->height , bp->stride, &v->s.gb);
- decode_rowskip(bp->data+x, bp->width - x, bp->height % tile_h, bp->stride, &v->s.gb);
-
- break;
- case IMODE_ROWSKIP:
- decode_rowskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);
- break;
- case IMODE_COLSKIP:
- decode_colskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);
- break;
- default: break;
- }
-
- /* Applying diff operator */
- if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)
- {
- planep = bp->data;
- planep[0] ^= invert;
- for (x=1; x<bp->width; x++)
- planep[x] ^= planep[x-1];
- for (y=1; y<bp->height; y++)
- {
- planep += bp->stride;
- planep[0] ^= planep[-bp->stride];
- for (x=1; x<bp->width; x++)
- {
- if (planep[x-1] != planep[x-bp->stride]) planep[x] ^= invert;
- else planep[x] ^= planep[x-1];
- }
- }
- }
- else if (invert)
- {
- planep = bp->data;
- for (x=0; x<bp->width*bp->height; x++) planep[x] = !planep[x]; //FIXME stride
- }
- return (imode<<1) + invert;
-}
-/** @} */ //Bitplane group
-
-/***********************************************************************/
-/** VOP Dquant decoding
- * @param v VC1 Context
- */
-static int vop_dquant_decoding(VC1Context *v)
-{
- GetBitContext *gb = &v->s.gb;
- int pqdiff;
-
- //variable size
- if (v->dquant == 2)
- {
- 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(gb, 1);
- if ( v->dquantfrm )
- {
- v->dqprofile = get_bits(gb, 2);
- switch (v->dqprofile)
- {
- case DQPROFILE_SINGLE_EDGE:
- case DQPROFILE_DOUBLE_EDGES:
- v->dqsbedge = get_bits(gb, 2);
- break;
- case DQPROFILE_ALL_MBS:
- v->dqbilevel = get_bits(gb, 1);
- default: break; //Forbidden ?
- }
- if (!v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS)
- {
- pqdiff = get_bits(gb, 3);
- if (pqdiff == 7) v->altpq = get_bits(gb, 5);
- else v->altpq = v->pq + pqdiff + 1;
- }
- }
- }
- return 0;
-}
-
-/***********************************************************************/
-/**
- * @defgroup all_frame_hdr All VC1 profiles frame header
- * @brief Part of the frame header decoding from all profiles
- * @warning Only pro/epilog differs between Simple/Main and Advanced => check caller
- * @{
- */
-/** B and BI frame header decoding, primary part
- * @see Tables 11+12, p62-65
- * @param v VC1 context
- * @return Status
- * @warning Also handles BI frames
- */
-static int decode_b_picture_primary_header(VC1Context *v)
-{
- GetBitContext *gb = &v->s.gb;
- int pqindex;
-
- /* Prolog common to all frametypes should be done in caller */
- if (v->profile == PROFILE_SIMPLE)
- {
- av_log(v->s.avctx, AV_LOG_ERROR, "Found a B frame while in Simple Profile!\n");
- return FRAME_SKIPPED;
- }
- v->bfraction = vc1_bfraction_lut[get_vlc2(gb, vc1_bfraction_vlc.table,
- VC1_BFRACTION_VLC_BITS, 2)];
- if (v->bfraction < -1)
- {
- av_log(v->s.avctx, AV_LOG_ERROR, "Invalid BFRaction\n");
- return FRAME_SKIPPED;
- }
- else if (!v->bfraction)
- {
- /* We actually have a BI frame */
- v->s.pict_type = BI_TYPE;
- v->buffer_fullness = get_bits(gb, 7);
- }
-
- /* Read the quantization stuff */
- 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(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)
- v->mvrange = get_prefix(gb, 0, 3);
- }
- /* Read the MV mode */
- if (v->s.pict_type != BI_TYPE)
- {
- v->mv_mode = get_bits(gb, 1);
- if (v->pq < 13)
- {
- if (!v->mv_mode)
- {
- v->mv_mode = get_bits(gb, 2);
- if (v->mv_mode)
- av_log(v->s.avctx, AV_LOG_ERROR,
- "mv_mode for lowquant B frame was %i\n", v->mv_mode);
- }
- }
- else
- {
- if (!v->mv_mode)
- {
- if (get_bits(gb, 1))
- av_log(v->s.avctx, 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;
-}
-
-/** B and BI frame header decoding, secondary part
- * @see Tables 11+12, p62-65
- * @param v VC1 context
- * @return Status
- * @warning Also handles BI frames
- * @warning To call once all MB arrays are allocated
- * @todo Support Advanced Profile headers
- */
-static int decode_b_picture_secondary_header(VC1Context *v)
-{
- GetBitContext *gb = &v->s.gb;
- int status;
-
- 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->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
- "Imode: %i, Invert: %i\n", status>>1, status&1);
-#endif
- }
-
- //bitplane
- status = bitplane_decoding(&v->direct_mb_plane, v);
- if (status < 0) return -1;
-#if TRACE
- av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct plane encoding: "
- "Imode: %i, Invert: %i\n", status>>1, status&1);
-#endif
-
- 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->s.mv_table_index = get_bits(gb, 2); //but using vc1_ tables
- v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)];
-
- if (v->dquant)
- {
- vop_dquant_decoding(v);
- }
-
- if (v->vstransform)
- {
- v->ttmbf = get_bits(gb, 1);
- if (v->ttmbf)
- {
- 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);
- }
- }
- /* Epilog (AC/DC syntax) should be done in caller */
- return 0;
-}
-
-/** I frame header decoding, primary part
- * @see Tables 5+7, p53-54 and 55-57
- * @param v VC1 context
- * @return Status
- * @todo Support Advanced Profile headers
- */
-static int decode_i_picture_primary_header(VC1Context *v)
-{
- GetBitContext *gb = &v->s.gb;
- int pqindex;
-
- /* Prolog common to all frametypes should be done in caller */
- //BF = Buffer Fullness
- if (v->profile < PROFILE_ADVANCED && get_bits(gb, 7))
- {
- av_log(v->s.avctx, AV_LOG_DEBUG, "I BufferFullness not 0\n");
- }
-
- /* Quantizer stuff */
- 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(gb, 1);
- if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
- 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);
- return 0;
-}
-
-/** I frame header decoding, secondary part
- * @param v VC1 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(VC1Context *v)
-{
-#if HAS_ADVANCED_PROFILE
- int status;
- if (v->profile == PROFILE_ADVANCED)
- {
- v->s.ac_pred = get_bits(&v->s.gb, 1);
- if (v->postprocflag) v->postproc = get_bits(&v->s.gb, 1);
- /* 7.1.1.34 + 8.5.2 */
- if (v->overlap && v->pq<9)
- {
- v->condover = get_bits(&v->s.gb, 1);
- if (v->condover)
- {
- v->condover = 2+get_bits(&v->s.gb, 1);
- if (v->condover == 3)
- {
- status = bitplane_decoding(&v->over_flags_plane, v);
- if (status < 0) return -1;
-# if TRACE
- av_log(v->s.avctx, AV_LOG_DEBUG, "Overflags plane encoding: "
- "Imode: %i, Invert: %i\n", status>>1, status&1);
-# endif
- }
- }
- }
- }
-#endif
-
- /* Epilog (AC/DC syntax) should be done in caller */
- return 0;
-}
-
-/** P frame header decoding, primary part
- * @see Tables 5+7, p53-54 and 55-57
- * @param v VC1 context
- * @todo Support Advanced Profile headers
- * @return Status
- */
-static int decode_p_picture_primary_header(VC1Context *v)
-{
- /* INTERFRM, FRMCNT, RANGEREDFRM read in caller */
- GetBitContext *gb = &v->s.gb;
- int lowquant, pqindex;
-
- 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(gb, 1);
- if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
- 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(gb, 0, 3);
-#if HAS_ADVANCED_PROFILE
- if (v->profile == PROFILE_ADVANCED)
- {
- if (v->postprocflag) v->postproc = get_bits(gb, 1);
- }
- else
-#endif
- if (v->multires) v->respic = get_bits(gb, 2);
- lowquant = (v->pquantizer>12) ? 0 : 1;
- 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(gb, 1, 3)];
- v->lumscale = get_bits(gb, 6);
- v->lumshift = get_bits(gb, 6);
- }
- return 0;
-}
-
-/** P frame header decoding, secondary part
- * @see Tables 5+7, p53-54 and 55-57
- * @param v VC1 context
- * @warning To call once all MB arrays are allocated
- * @return Status
- */
-static int decode_p_picture_secondary_header(VC1Context *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)
- {
- status = bitplane_decoding(&v->mv_type_mb_plane, v);
- if (status < 0) return -1;
-#if TRACE
- av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
- "Imode: %i, Invert: %i\n", status>>1, status&1);
-#endif
- }
-
- status = bitplane_decoding(&v->skip_mb_plane, v);
- if (status < 0) return -1;
-#if TRACE
- 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->s.mv_table_index =get_bits(gb, 2); //but using vc1_ tables
- v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)];
-
- if (v->dquant)
- {
- av_log(v->s.avctx, AV_LOG_INFO, "VOP DQuant info\n");
- vop_dquant_decoding(v);
- }
-
- v->ttfrm = 0; //FIXME Is that so ?
- if (v->vstransform)
- {
- v->ttmbf = get_bits(gb, 1);
- if (v->ttmbf)
- {
- 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);
- }
+ v->rangered, v->vstransform, v->overlap, v->s.resync_marker,
+ v->dquant, v->quantizer_mode, avctx->max_b_frames
+ );
+ return 0;
}
- /* Epilog (AC/DC syntax) should be done in caller */
- return 0;
+ return -1;
}
-/** @} */ //End of group all_frm_hdr
-/***********************************************************************/
-/**
- * @defgroup std_frame_hdr VC1 Simple/Main Profiles header decoding
- * @brief Part of the frame header decoding belonging to Simple/Main Profiles
- * @warning Only pro/epilog differs between Simple/Main and Advanced =>
- * check caller
- * @{
- */
-
-/** Frame header decoding, first part, in Simple and Main profiles
- * @see Tables 5+7, p53-54 and 55-57
- * @param v VC1 context
- * @todo FIXME: RANGEREDFRM element not read if BI frame from Table6, P54
- * However, 7.1.1.8 says "all frame types, for main profiles"
- * @return Status
- */
-static int standard_decode_picture_primary_header(VC1Context *v)
+static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
{
- GetBitContext *gb = &v->s.gb;
- int status = 0;
+ int pqindex, lowquant, status;
- if (v->finterpflag) v->interpfrm = get_bits(gb, 1);
+ if(v->finterpflag) v->interpfrm = get_bits(gb, 1);
skip_bits(gb, 2); //framecnt unused
+ v->rangeredfrm = 0;
if (v->rangered) v->rangeredfrm = get_bits(gb, 1);
v->s.pict_type = get_bits(gb, 1);
- if (v->s.avctx->max_b_frames)
- {
- if (!v->s.pict_type)
- {
+ if (v->s.avctx->max_b_frames) {
+ if (!v->s.pict_type) {
if (get_bits(gb, 1)) v->s.pict_type = I_TYPE;
else v->s.pict_type = B_TYPE;
- }
- else v->s.pict_type = P_TYPE;
- }
- else v->s.pict_type++;
+ } else v->s.pict_type = P_TYPE;
+ } else v->s.pict_type = v->s.pict_type ? P_TYPE : I_TYPE;
- switch (v->s.pict_type)
- {
- case I_TYPE: status = decode_i_picture_primary_header(v); break;
- case P_TYPE: status = decode_p_picture_primary_header(v); break;
- case BI_TYPE: //Same as B
- case B_TYPE: status = decode_b_picture_primary_header(v); break;
- }
+ if(v->s.pict_type == I_TYPE)
+ get_bits(gb, 7); // skip buffer fullness
- if (status == FRAME_SKIPPED)
- {
- av_log(v->s.avctx, AV_LOG_INFO, "Skipping frame...\n");
- return status;
- }
- return 0;
-}
+ /* Quantizer stuff */
+ 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];
-/** Frame header decoding, secondary part
- * @param v VC1 context
- * @warning To call once all MB arrays are allocated
- * @return Status
- */
-static int standard_decode_picture_secondary_header(VC1Context *v)
-{
- GetBitContext *gb = &v->s.gb;
- int status = 0;
+ if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
+ v->pquantizer = pqindex < 9;
+ if (v->quantizer_mode == QUANT_UNIFORM || v->quantizer_mode == QUANT_NON_UNIFORM)
+ v->pquantizer = v->quantizer_mode == QUANT_UNIFORM;
+ v->pqindex = pqindex;
+ if (pqindex < 9) v->halfpq = get_bits(gb, 1);
+ else v->halfpq = 0;
+ if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
+ v->pquantizer = get_bits(gb, 1);
+ v->dquantfrm = 0;
- 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;
- case BI_TYPE:
- case I_TYPE: break; //Nothing needed as it's done in the epilog
- }
- if (status < 0) return FRAME_SKIPPED;
+//av_log(v->s.avctx, AV_LOG_INFO, "%c Frame: QP=[%i]%i (+%i/2) %i\n",
+// (v->s.pict_type == P_TYPE) ? 'P' : ((v->s.pict_type == I_TYPE) ? 'I' : 'B'), pqindex, v->pq, v->halfpq, v->rangeredfrm);
- /* AC Syntax */
- v->c_ac_table_index = decode012(gb);
- if (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE)
- {
- v->y_ac_table_index = decode012(gb);
- }
- /* DC Syntax */
- v->s.dc_table_index = decode012(gb);
+ //TODO: complete parsing for P/B/BI frames
+ switch(v->s.pict_type) {
+ case P_TYPE:
+ if (v->pq < 5) v->tt_index = 0;
+ else if(v->pq < 13) v->tt_index = 1;
+ else v->tt_index = 2;
+
+ if (v->extended_mv == 1) v->mvrange = get_prefix(gb, 0, 3);
+ v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
+ v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
+ v->range_x = 1 << (v->k_x - 1);
+ v->range_y = 1 << (v->k_y - 1);
+ if (v->profile == PROFILE_ADVANCED)
+ {
+ if (v->postprocflag) v->postproc = get_bits(gb, 1);
+ }
+ else
+ if (v->multires) v->respic = get_bits(gb, 2);
+ lowquant = (v->pq > 12) ? 0 : 1;
+ 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(gb, 1, 3)];
+ v->lumscale = get_bits(gb, 6);
+ v->lumshift = get_bits(gb, 6);
+ }
+ if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
+ v->s.mspel = 1;
+ else
+ v->s.mspel = 0;
- return 0;
+if(v->mv_mode != MV_PMODE_1MV && v->mv_mode != MV_PMODE_1MV_HPEL && v->mv_mode != MV_PMODE_1MV_HPEL_BILIN) {
+ av_log(v->s.avctx, AV_LOG_ERROR, "Only 1MV P-frames are supported by now\n");
+ return -1;
}
-/** @} */ //End for group std_frame_hdr
-
-#if HAS_ADVANCED_PROFILE
-/***********************************************************************/
-/**
- * @defgroup adv_frame_hdr VC1 Advanced Profile header decoding
- * @brief Part of the frame header decoding belonging to Advanced Profiles
- * @warning Only pro/epilog differs between Simple/Main and Advanced =>
- * check caller
- * @{
- */
-/** Frame header decoding, primary part
- * @param v VC1 context
- * @return Status
- */
-static int advanced_decode_picture_primary_header(VC1Context *v)
-{
- GetBitContext *gb = &v->s.gb;
- static const int type_table[4] = { P_TYPE, B_TYPE, I_TYPE, BI_TYPE };
- int type;
-
- if (v->interlace)
- {
- v->fcm = get_bits(gb, 1);
- if (v->fcm) v->fcm = 2+get_bits(gb, 1);
- }
+ if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
+ v->mv_mode2 == MV_PMODE_MIXED_MV)
+ || v->mv_mode == MV_PMODE_MIXED_MV)
+ {
+ status = bitplane_decoding(&v->mv_type_mb_plane, v);
+ if (status < 0) return -1;
+ av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
+ }
+ status = bitplane_decoding(&v->skip_mb_plane, v);
+ if (status < 0) return -1;
+ av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
- type = get_prefix(gb, 0, 4);
- if (type > 4 || type < 0) return FRAME_SKIPPED;
- v->s.pict_type = type_table[type];
- av_log(v->s.avctx, AV_LOG_INFO, "AP Frame Type: %i\n", v->s.pict_type);
+ /* Hopefully this is correct for P frames */
+ v->s.mv_table_index = get_bits(gb, 2); //but using vc1_ tables
+ v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)];
- if (v->tfcntrflag) v->tfcntr = get_bits(gb, 8);
- if (v->broadcast)
- {
- if (!v->interlace) v->rptfrm = get_bits(gb, 2);
- else
+ if (v->dquant)
{
- v->tff = get_bits(gb, 1);
- v->rff = get_bits(gb, 1);
+ av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
+ vop_dquant_decoding(v);
}
- }
- if (v->panscanflag)
- {
-#if 0
- for (i=0; i<v->numpanscanwin; i++)
+ v->ttfrm = 0; //FIXME Is that so ?
+ if (v->vstransform)
{
- 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);
+ v->ttmbf = get_bits(gb, 1);
+ if (v->ttmbf)
+ {
+ v->ttfrm = get_bits(gb, 2);
+ }
}
-#else
- skip_bits(gb, 16*4*v->numpanscanwin);
-#endif
- }
- 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->s.pict_type)
- {
- case I_TYPE: if (decode_i_picture_primary_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_primary_header(v) < 0) return FRAME_SKIPPED;
- default: return -1;
- }
-}
-
-/** Frame header decoding, secondary part
- * @param v VC1 context
- * @return Status
- */
-static int advanced_decode_picture_secondary_header(VC1Context *v)
-{
- GetBitContext *gb = &v->s.gb;
- int status = 0;
-
- 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;
- case BI_TYPE:
- case I_TYPE: status = decode_i_picture_secondary_header(v); break;
+ break;
+ case B_TYPE:
+ break;
}
- if (status<0) return FRAME_SKIPPED;
/* AC Syntax */
v->c_ac_table_index = decode012(gb);
@@ -1665,16 +1267,14 @@
v->y_ac_table_index = decode012(gb);
}
/* DC Syntax */
- v->s.dc_table_index = decode012(gb);
+ v->s.dc_table_index = get_bits(gb, 1);
return 0;
}
-#endif
-/** @} */ //End for adv_frame_hdr
/***********************************************************************/
/**
- * @defgroup block VC1 Block-level functions
+ * @defgroup block VC-1 Block-level functions
* @see 7.1.4, p91 and 8.1.1.7, p(1)04
* @todo TODO: Integrate to MpegEncContext facilities
* @{
@@ -1726,8 +1326,13 @@
if (!index) { _dmv_x = _dmv_y = 0; } \
else if (index == 35) \
{ \
- _dmv_x = get_bits(gb, v->k_x); \
- _dmv_y = get_bits(gb, v->k_y); \
+ _dmv_x = get_bits(gb, v->k_x - s->mspel); \
+ _dmv_y = get_bits(gb, v->k_y - s->mspel); \
+ } \
+ else if (index == 36) \
+ { \
+ _dmv_x = 0; \
+ _dmv_y = 0; \
s->mb_intra = 1; \
} \
else \
@@ -1747,22 +1352,110 @@
_dmv_y = (sign ^ ((val>>1) + offset_table[index1])) - sign; \
}
-/** Get predicted DC value
+/** Predict and set motion vector
+ */
+static inline void vc1_pred_mv(MpegEncContext *s, int dmv_x, int dmv_y, int mv1, int r_x, int r_y)
+{
+ int xy, wrap, off;
+ int16_t *A, *B, *C;
+ int px, py;
+ int sum;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+
+ /* scale MV difference to be quad-pel */
+ dmv_x <<= s->mspel;
+ dmv_y <<= s->mspel;
+
+ wrap = s->b8_stride;
+ xy = s->block_index[0];
+
+ C = s->current_picture.motion_val[0][xy - (1 << mv1)];
+ A = s->current_picture.motion_val[0][xy - (wrap << mv1)];
+ off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1;
+ B = s->current_picture.motion_val[0][xy + ((off - wrap) << mv1)];
+
+ if(!s->first_slice_line) { // predictor A is not out of bounds
+ if(s->mb_width == 1) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = mid_pred(A[0], B[0], C[0]);
+ py = mid_pred(A[1], B[1], C[1]);
+ }
+ } else if(s->mb_x) { // predictor C is not out of bounds
+ px = C[0];
+ py = C[1];
+ } else {
+ px = py = 0;
+ }
+ if(s->mb_intra) px = py = 0;
+
+ /* Pullback MV as specified in 8.3.5.3.4 */
+ {
+ int qx, qy, X, Y;
+ qx = s->mb_x << 6; //FIXME: add real block coords for 4MV mode
+ qy = s->mb_y << 6;
+ X = (s->mb_width << 6) - 4;
+ Y = (s->mb_height << 6) - 4;
+ if(mv1) {
+ if(qx + px < -60) px = -60 - qx;
+ if(qy + py < -60) py = -60 - qy;
+ } else {
+ if(qx + px < -28) px = -28 - qx;
+ if(qy + py < -28) py = -28 - qy;
+ }
+ if(qx + px > X) px = X - qx;
+ if(qy + py > Y) py = Y - qy;
+ }
+ /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
+ if(!s->mb_intra && !s->first_slice_line && s->mb_x) {
+ if(IS_INTRA(s->current_picture.mb_type[mb_pos - s->mb_stride]))
+ sum = ABS(px) + ABS(py);
+ else
+ sum = ABS(px - A[0]) + ABS(py - A[1]);
+ if(sum > 32) {
+ if(get_bits1(&s->gb)) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = C[0];
+ py = C[1];
+ }
+ } else {
+ if(IS_INTRA(s->current_picture.mb_type[mb_pos - 1]))
+ sum = ABS(px) + ABS(py);
+ else
+ sum = ABS(px - C[0]) + ABS(py - C[1]);
+ if(sum > 32) {
+ if(get_bits1(&s->gb)) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = C[0];
+ py = C[1];
+ }
+ }
+ }
+ }
+ /* store MV using signed modulus of MV range defined in 4.11 */
+ s->mv[0][0][0] = s->current_picture.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[0][0][1] = s->current_picture.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
+}
+
+/** Get predicted DC value for I-frames only
* 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 VC1 way
- * @todo TODO: Handle properly edges
*/
-static inline int vc1_pred_dc(MpegEncContext *s, int n,
- uint16_t **dc_val_ptr, int *dir_ptr)
+static inline int vc1_i_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
+ int16_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,
+ static const uint16_t dcpred[32] = {
+ -1, 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
@@ -1775,45 +1468,97 @@
wrap = s->block_wrap[n];
dc_val= s->dc_val[0] + s->block_index[n];
- /* B C
- * A X
+ /* B A
+ * C X
*/
- a = dc_val[ - 1];
+ c = dc_val[ - 1];
b = dc_val[ - 1 - wrap];
- c = dc_val[ - wrap];
+ a = dc_val[ - wrap];
- /* XXX: Rule B is used only for I and BI frames in S/M/C profile
- * with overlap filtering off
- */
- if ((s->pict_type == I_TYPE || s->pict_type == BI_TYPE) &&
- 1 /* XXX: overlap filtering off */)
+ if (pq < 9 || !overlap)
{
/* Set outer values */
- if (s->first_slice_line && n!=2) b=c=dcpred[scale];
- if (s->mb_x == 0) b=a=dcpred[scale];
+ if (!s->mb_y && (n!=2 && n!=3)) b=a=dcpred[scale];
+ if (s->mb_x == 0 && (n!=1 && n!=3)) b=c=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;
- }
+ if (!s->mb_y && (n!=2 && n!=3)) b=a=0;
+ if (s->mb_x == 0 && (n!=1 && n!=3)) b=c=0;
}
if (abs(a - b) <= abs(b - c)) {
pred = c;
- *dir_ptr = 1;
+ *dir_ptr = 1;//left
} else {
pred = a;
- *dir_ptr = 0;
+ *dir_ptr = 0;//top
+ }
+
+ /* update predictor */
+ *dc_val_ptr = &dc_val[0];
+ return pred;
+}
+
+
+/** 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
+ */
+static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
+ int a_avail, int c_avail,
+ int16_t **dc_val_ptr, int *dir_ptr)
+{
+ int a, b, c, wrap, pred, scale;
+ int16_t *dc_val;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int mb_pos2, q1, q2;
+
+ /* 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];
+
+ /* B A
+ * C X
+ */
+ c = dc_val[ - 1];
+ b = dc_val[ - 1 - wrap];
+ a = dc_val[ - wrap];
+
+ if(a_avail && c_avail) {
+ if(abs(a - b) <= abs(b - c)) {
+ pred = c;
+ *dir_ptr = 1;//left
+ } else {
+ pred = a;
+ *dir_ptr = 0;//top
+ }
+ } else if(a_avail) {
+ pred = a;
+ *dir_ptr = 0;//top
+ } else if(c_avail) {
+ pred = c;
+ *dir_ptr = 1;//left
+ } else {
+ pred = 0;
+ *dir_ptr = 1;//left
+ }
+
+ /* scale coeffs if needed */
+ mb_pos2 = mb_pos - *dir_ptr - (1 - *dir_ptr) * s->mb_stride;
+ q1 = s->current_picture.qscale_table[mb_pos];
+ q2 = s->current_picture.qscale_table[mb_pos2];
+ if(0 && q1 && q2 && q1 != q2) {
+ q1 = s->y_dc_scale_table[q1];
+ q2 = s->y_dc_scale_table[q2];
+ pred = (pred * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
}
/* update predictor */
@@ -1821,25 +1566,294 @@
return pred;
}
-/** Decode one block, inter or intra
+
+/**
+ * @defgroup std_mb VC1 Macroblock-level functions in Simple/Main Profiles
+ * @see 7.1.4, p91 and 8.1.1.7, p(1)04
+ * @todo TODO: Integrate to MpegEncContext facilities
+ * @{
+ */
+
+static inline int vc1_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
+{
+ int xy, wrap, pred, a, b, c;
+
+ xy = s->block_index[n];
+ wrap = s->b8_stride;
+
+ /* B C
+ * A X
+ */
+ a = s->coded_block[xy - 1 ];
+ b = s->coded_block[xy - 1 - wrap];
+ c = s->coded_block[xy - wrap];
+
+ if (b == c) {
+ pred = a;
+ } else {
+ pred = c;
+ }
+
+ /* store value */
+ *coded_block_ptr = &s->coded_block[xy];
+
+ return pred;
+}
+
+/**
+ * Decode one AC coefficient
* @param v The VC1 context
- * @param block 8x8 DCT block
- * @param n Block index in the current MB (<4=>luma)
- * @param coded If the block is coded
- * @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
- * @todo TODO: Use M$ MPEG-4 cbp prediction
+ * @param last Last coefficient
+ * @param skip How much zero coefficients to skip
+ * @param value Decoded AC coefficient value
+ * @see 8.1.3.4
+ */
+static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, int *value, int codingset)
+{
+ GetBitContext *gb = &v->s.gb;
+ int index, escape, run = 0, level = 0, lst = 0;
+
+ index = get_vlc2(gb, vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
+ if (index != vc1_ac_sizes[codingset] - 1) {
+ run = vc1_index_decode_table[codingset][index][0];
+ level = vc1_index_decode_table[codingset][index][1];
+ lst = index >= vc1_last_decode_table[codingset];
+ if(get_bits(gb, 1))
+ level = -level;
+ } else {
+ escape = decode210(gb);
+ if (escape == 0) {
+ index = get_vlc2(gb, vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
+ run = vc1_index_decode_table[codingset][index][0];
+ level = vc1_index_decode_table[codingset][index][1];
+ lst = index >= vc1_last_decode_table[codingset];
+ if(lst)
+ level += vc1_last_delta_level_table[codingset][run];
+ else
+ level += vc1_delta_level_table[codingset][run];
+ if(get_bits(gb, 1))
+ level = -level;
+ } else if (escape == 1) {
+ index = get_vlc2(gb, vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
+ run = vc1_index_decode_table[codingset][index][0];
+ level = vc1_index_decode_table[codingset][index][1];
+ lst = index >= vc1_last_decode_table[codingset];
+ if(lst)
+ run += vc1_last_delta_run_table[codingset][level] + 1;
+ else
+ run += vc1_delta_run_table[codingset][level] + 1;
+ if(get_bits(gb, 1))
+ level = -level;
+ } else {
+ int sign;
+ lst = get_bits(gb, 1);
+ if(v->s.esc3_level_length == 0) {
+ if(v->pq < 8 || v->dquantfrm) { // table 59
+ v->s.esc3_level_length = get_bits(gb, 3);
+ if(!v->s.esc3_level_length)
+ v->s.esc3_level_length = get_bits(gb, 2) + 8;
+ } else { //table 60
+ v->s.esc3_level_length = get_prefix(gb, 1, 6) + 2;
+ }
+ v->s.esc3_run_length = 3 + get_bits(gb, 2);
+ }
+ run = get_bits(gb, v->s.esc3_run_length);
+ sign = get_bits(gb, 1);
+ level = get_bits(gb, v->s.esc3_level_length);
+ if(sign)
+ level = -level;
+ }
+ }
+
+ *last = lst;
+ *skip = run;
+ *value = level;
+}
+
+/** Decode intra block in intra frames - should be faster than decode_intra_block
+ * @param v VC1Context
+ * @param block block to decode
+ * @param coded are AC coeffs present or not
+ * @param codingset set of VLC to decode data
+ */
+static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, int coded, int codingset)
+{
+ GetBitContext *gb = &v->s.gb;
+ MpegEncContext *s = &v->s;
+ int dc_pred_dir = 0; /* Direction of the DC prediction used */
+ int run_diff, i;
+ int16_t *dc_val;
+ int16_t *ac_val, *ac_val2;
+ int dcdiff;
+
+ /* Get DC differential */
+ if (n < 4) {
+ dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+ } else {
+ 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");
+ return -1;
+ }
+ if (dcdiff)
+ {
+ if (dcdiff == 119 /* ESC index value */)
+ {
+ /* TODO: Optimize */
+ if (v->pq == 1) dcdiff = get_bits(gb, 10);
+ else if (v->pq == 2) dcdiff = get_bits(gb, 9);
+ else dcdiff = get_bits(gb, 8);
+ }
+ else
+ {
+ if (v->pq == 1)
+ dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;
+ else if (v->pq == 2)
+ dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1;
+ }
+ if (get_bits(gb, 1))
+ dcdiff = -dcdiff;
+ }
+
+ /* Prediction */
+ dcdiff += vc1_i_pred_dc(&v->s, v->overlap, v->pq, n, &dc_val, &dc_pred_dir);
+ *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;
+ }
+ /* Skip ? */
+ run_diff = 0;
+ i = 0;
+ if (!coded) {
+ goto not_coded;
+ }
+
+ //AC Decoding
+ i = 1;
+
+ {
+ int last = 0, skip, value;
+ const int8_t *zz_table;
+ int scale;
+ int k;
+
+ scale = v->pq * 2 + v->halfpq;
+
+ if(v->s.ac_pred) {
+ if(!dc_pred_dir)
+ zz_table = vc1_horizontal_zz;
+ else
+ zz_table = vc1_vertical_zz;
+ } else
+ zz_table = vc1_normal_zz;
+
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val2 = ac_val;
+ if(dc_pred_dir) //left
+ ac_val -= 16;
+ else //top
+ ac_val -= 16 * s->block_wrap[n];
+
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
+ i += skip;
+ if(i > 63)
+ break;
+ block[zz_table[i++]] = value;
+ }
+
+ /* apply AC prediction if needed */
+ if(s->ac_pred) {
+ if(dc_pred_dir) { //left
+ for(k = 1; k < 8; k++)
+ block[k << 3] += ac_val[k];
+ } else { //top
+ for(k = 1; k < 8; k++)
+ block[k] += ac_val[k + 8];
+ }
+ }
+ /* save AC coeffs for further prediction */
+ for(k = 1; k < 8; k++) {
+ ac_val2[k] = block[k << 3];
+ ac_val2[k + 8] = block[k];
+ }
+
+ /* scale AC coeffs */
+ for(k = 1; k < 64; k++)
+ if(block[k]) {
+ block[k] *= scale;
+ if(!v->pquantizer)
+ block[k] += (block[k] < 0) ? -v->pq : v->pq;
+ }
+
+ if(s->ac_pred) i = 63;
+ }
+
+not_coded:
+ if(!coded) {
+ int k, scale;
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val2 = ac_val;
+
+ scale = v->pq * 2 + v->halfpq;
+ memset(ac_val2, 0, 16 * 2);
+ if(dc_pred_dir) {//left
+ ac_val -= 16;
+ if(s->ac_pred)
+ memcpy(ac_val2, ac_val, 8 * 2);
+ } else {//top
+ ac_val -= 16 * s->block_wrap[n];
+ if(s->ac_pred)
+ memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
+ }
+
+ /* apply AC prediction if needed */
+ if(s->ac_pred) {
+ if(dc_pred_dir) { //left
+ for(k = 1; k < 8; k++) {
+ block[k << 3] = ac_val[k] * scale;
+ if(!v->pquantizer)
+ block[k << 3] += (block[k << 3] < 0) ? -v->pq : v->pq;
+ }
+ } else { //top
+ for(k = 1; k < 8; k++) {
+ block[k] = ac_val[k + 8] * scale;
+ if(!v->pquantizer)
+ block[k] += (block[k] < 0) ? -v->pq : v->pq;
+ }
+ }
+ i = 63;
+ }
+ }
+ s->block_last_index[n] = i;
+
+ return 0;
+}
+
+/** Decode intra block in inter frames - more generic version than vc1_decode_i_block
+ * @param v VC1Context
+ * @param block block to decode
+ * @param coded are AC coeffs present or not
+ * @param mquant block quantizer
+ * @param codingset set of VLC to decode data
*/
-static int vc1_decode_block(VC1Context *v, DCTELEM block[64], int n, int coded, int mquant)
+static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int coded, int mquant, int codingset)
{
GetBitContext *gb = &v->s.gb;
MpegEncContext *s = &v->s;
- int ttblk; /* Transform Type per Block */
- int subblkpat; /* Sub-block Transform Type Pattern */
- int dc_pred_dir; /* Direction of the DC prediction used */
+ int dc_pred_dir = 0; /* Direction of the DC prediction used */
int run_diff, i;
+ int16_t *dc_val;
+ int16_t *ac_val, *ac_val2;
+ int dcdiff;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int a_avail, c_avail;
/* XXX: Guard against dumb values of mquant */
mquant = (mquant < 1) ? 0 : ( (mquant>31) ? 31 : mquant );
@@ -1848,167 +1862,300 @@
s->y_dc_scale = s->y_dc_scale_table[mquant];
s->c_dc_scale = s->c_dc_scale_table[mquant];
- if (s->mb_intra)
+ /* check if prediction blocks A and C are available */
+ a_avail = c_avail = 0;
+ if((n == 2 || n == 3) || (s->mb_y && IS_INTRA(s->current_picture.mb_type[mb_pos - s->mb_stride])))
+ a_avail = 1;
+ if((n == 1 || n == 3) || (s->mb_x && IS_INTRA(s->current_picture.mb_type[mb_pos - 1])))
+ c_avail = 1;
+ /* Get DC differential */
+ if (n < 4) {
+ dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+ } else {
+ 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");
+ return -1;
+ }
+ if (dcdiff)
{
- int dcdiff;
- uint16_t *dc_val;
-
- /* Get DC differential */
- if (n < 4) {
- dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
- } else {
- 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");
- return -1;
- }
- if (dcdiff)
+ if (dcdiff == 119 /* ESC index value */)
{
- if (dcdiff == 119 /* ESC index value */)
- {
- /* TODO: Optimize */
- 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(gb, 2) - 3;
- else if (mquant == 2)
- dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1;
- }
- if (get_bits(gb, 1))
- dcdiff = -dcdiff;
- }
-
- /* Prediction */
- dcdiff += vc1_pred_dc(s, n, &dc_val, &dc_pred_dir);
- *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;
+ /* TODO: Optimize */
+ if (mquant == 1) dcdiff = get_bits(gb, 10);
+ else if (mquant == 2) dcdiff = get_bits(gb, 9);
+ else dcdiff = get_bits(gb, 8);
}
- /* Skip ? */
- run_diff = 0;
- i = 0;
- if (!coded) {
- goto not_coded;
+ else
+ {
+ if (mquant == 1)
+ dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;
+ else if (mquant == 2)
+ dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1;
}
+ if (get_bits(gb, 1))
+ dcdiff = -dcdiff;
}
- else
- {
- mquant = v->pq;
- /* Get TTBLK */
- if (v->ttmb < 8) /* per block */
- ttblk = get_vlc2(gb, vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 2);
- else /* Per frame */
- ttblk = 0; //FIXME, depends on ttfrm
+ /* Prediction */
+ dcdiff += vc1_pred_dc(&v->s, v->overlap, mquant, n, a_avail, c_avail, &dc_val, &dc_pred_dir);
+ *dc_val = dcdiff;
- /* Get SUBBLKPAT */
- if (ttblk == v->ttblk4x4) /* 4x4 transform for that qp value */
- subblkpat = 1+get_vlc2(gb, vc1_subblkpat_vlc[v->tt_index].table,
- VC1_SUBBLKPAT_VLC_BITS, 2);
- else /* All others: 8x8, 4x8, 8x4 */
- subblkpat = decode012(gb);
+ /* 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;
}
+ /* Skip ? */
+ run_diff = 0;
+ i = 0;
+ if (!coded) {
+ goto not_coded;
+ }
+
+ //AC Decoding
+ i = 1;
+
+ {
+ int last = 0, skip, value;
+ const int8_t *zz_table;
+ int scale;
+ int k;
- //TODO AC Decoding
- i = 63; //XXX: nothing done yet
+ scale = mquant * 2 + v->halfpq;
+ if(v->s.ac_pred) {
+ if(!dc_pred_dir)
+ zz_table = vc1_horizontal_zz;
+ else
+ zz_table = vc1_vertical_zz;
+ } else
+ zz_table = vc1_normal_zz;
+
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val2 = ac_val;
+ if(dc_pred_dir) //left
+ ac_val -= 16;
+ else //top
+ ac_val -= 16 * s->block_wrap[n];
+
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
+ i += skip;
+ if(i > 63)
+ break;
+ block[zz_table[i++]] = value;
+ }
- not_coded:
- if (s->mb_intra) {
- mpeg4_pred_ac(s, block, n, dc_pred_dir);
- if (s->ac_pred) {
- i = 63; /* XXX: not optimal */
+ /* apply AC prediction if needed */
+ if(s->ac_pred) {
+ /* scale predictors if needed*/
+ int mb_pos2, q1, q2;
+
+ mb_pos2 = mb_pos - dc_pred_dir - (1 - dc_pred_dir) * s->mb_stride;
+ q1 = s->current_picture.qscale_table[mb_pos];
+ q2 = s->current_picture.qscale_table[mb_pos2];
+
+ if(!c_avail) {
+ memset(ac_val, 0, 8 * sizeof(ac_val[0]));
+ dc_pred_dir = 0;
+ }
+ if(!a_avail) {
+ memset(ac_val + 8, 0, 8 * sizeof(ac_val[0]));
+ dc_pred_dir = 1;
+ }
+ if(!q1 && q1 && q2 && q1 != q2) {
+ q1 = q1 * 2 - 1;
+ q2 = q2 * 2 - 1;
+
+ if(dc_pred_dir) { //left
+ for(k = 1; k < 8; k++)
+ block[k << 3] += (ac_val[k] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+ } else { //top
+ for(k = 1; k < 8; k++)
+ block[k] += (ac_val[k + 8] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+ }
+ } else {
+ if(dc_pred_dir) { //left
+ for(k = 1; k < 8; k++)
+ block[k << 3] += ac_val[k];
+ } else { //top
+ for(k = 1; k < 8; k++)
+ block[k] += ac_val[k + 8];
+ }
+ }
+ }
+ /* save AC coeffs for further prediction */
+ for(k = 1; k < 8; k++) {
+ ac_val2[k] = block[k << 3];
+ ac_val2[k + 8] = block[k];
+ }
+
+ /* scale AC coeffs */
+ for(k = 1; k < 64; k++)
+ if(block[k]) {
+ block[k] *= scale;
+ if(!v->pquantizer)
+ block[k] += (block[k] < 0) ? -mquant : mquant;
+ }
+
+ if(s->ac_pred) i = 63;
+ }
+
+not_coded:
+ if(!coded) {
+ int k, scale;
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val2 = ac_val;
+
+ if(!c_avail) {
+ memset(ac_val, 0, 8 * sizeof(ac_val[0]));
+ dc_pred_dir = 0;
+ }
+ if(!a_avail) {
+ memset(ac_val + 8, 0, 8 * sizeof(ac_val[0]));
+ dc_pred_dir = 1;
+ }
+
+ scale = mquant * 2 + v->halfpq;
+ memset(ac_val2, 0, 16 * 2);
+ if(dc_pred_dir) {//left
+ ac_val -= 16;
+ if(s->ac_pred)
+ memcpy(ac_val2, ac_val, 8 * 2);
+ } else {//top
+ ac_val -= 16 * s->block_wrap[n];
+ if(s->ac_pred)
+ memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
+ }
+
+ /* apply AC prediction if needed */
+ if(s->ac_pred) {
+ if(dc_pred_dir) { //left
+ for(k = 1; k < 8; k++) {
+ block[k << 3] = ac_val[k] * scale;
+ if(!v->pquantizer)
+ block[k << 3] += (block[k << 3] < 0) ? -mquant : mquant;
+ }
+ } else { //top
+ for(k = 1; k < 8; k++) {
+ block[k] = ac_val[k + 8] * scale;
+ if(!v->pquantizer)
+ block[k] += (block[k] < 0) ? -mquant : mquant;
+ }
+ }
+ i = 63;
}
}
- if(i>0) i=63; //FIXME/XXX optimize
s->block_last_index[n] = i;
+
return 0;
}
-/** @} */ //End for group block
-
-/***********************************************************************/
-/**
- * @defgroup std_mb VC1 Macroblock-level functions in Simple/Main Profiles
- * @see 7.1.4, p91 and 8.1.1.7, p(1)04
- * @todo TODO: Integrate to MpegEncContext facilities
- * @{
+/** Decode P block
*/
-
-static inline int vc1_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
+static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquant, int ttmb, int first_block)
{
- int xy, wrap, pred, a, b, c;
-
- xy = s->block_index[n];
- wrap = s->b8_stride;
-
- /* B C
- * A X
- */
- a = s->coded_block[xy - 1 ];
- b = s->coded_block[xy - 1 - wrap];
- c = s->coded_block[xy - wrap];
+ MpegEncContext *s = &v->s;
+ GetBitContext *gb = &s->gb;
+ int i, j;
+ int subblkpat = 0;
+ int scale, off, idx, last, skip, value;
+ int ttblk = ttmb & 7;
- if (b == c) {
- pred = a;
- } else {
- pred = c;
+ if(ttmb == -1) {
+ ttblk = ttblk_to_tt[v->tt_index][get_vlc2(gb, vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)];
}
+ if(ttblk == TT_4X4) {
+ subblkpat = ~(get_vlc2(gb, vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1);
+ }
+ if((ttblk != TT_8X8 && ttblk != TT_4X4) && (v->ttmbf || (ttmb != -1 && (ttmb & 8) && !first_block))) {
+ subblkpat = decode012(gb);
+ if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) ttblk = TT_8X4;
+ if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) ttblk = TT_4X8;
+ }
+ scale = 2 * mquant;
- /* store value */
- *coded_block_ptr = &s->coded_block[xy];
-
- return pred;
-}
-
-/** Decode one I-frame MB (in Simple/Main profile)
- * @todo TODO: Extend to AP
- */
-static int vc1_decode_i_mb(VC1Context *v, DCTELEM block[6][64])
-{
- int i, cbp, val;
- uint8_t *coded_val;
-// uint32_t * const mb_type_ptr= &v->s.current_picture.mb_type[ v->s.mb_x + v->s.mb_y*v->s.mb_stride ];
+ // convert transforms like 8X4_TOP to generic TT and SUBBLKPAT
+ if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) {
+ ttblk = TT_8X4;
+ subblkpat = 2 - (ttblk == TT_8X4_TOP);
+ }
+ if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) {
+ ttblk = TT_4X8;
+ subblkpat = 2 - (ttblk == TT_4X8_LEFT);
+ }
- v->s.mb_intra = 1;
- cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
- if (cbp < 0) return -1;
- v->s.ac_pred = get_bits(&v->s.gb, 1);
-
- for (i=0; i<6; i++)
- {
- val = ((cbp >> (5 - i)) & 1);
- if (i < 4) {
- int pred = vc1_coded_block_pred(&v->s, i, &coded_val);
- val = val ^ pred;
- *coded_val = val;
+ switch(ttblk) {
+ case TT_8X8:
+ i = 0;
+ last = 0;
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+ i += skip;
+ if(i > 63)
+ break;
+ idx = vc1_simple_progressive_8x8_zz[i++];
+ block[idx] = value * scale;
}
- cbp |= val << (5 - i);
- if (vc1_decode_block(v, block[i], i, val, v->pq) < 0) //FIXME Should be mquant
- {
- 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;
+ vc1_inv_trans(block, 8, 8);
+ break;
+ case TT_4X4:
+ for(j = 0; j < 4; j++) {
+ last = subblkpat & (1 << (3 - j));
+ i = 0;
+ off = (j & 1) * 4 + (j & 2) * 32;
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+ i += skip;
+ if(i > 15)
+ break;
+ idx = vc1_simple_progressive_4x4_zz[i++];
+ block[idx + off] = value * scale;
+ }
+ vc1_inv_trans(block + off, 4, 4);
+ }
+ break;
+ case TT_8X4:
+ for(j = 0; j < 2; j++) {
+ last = subblkpat & (1 << (1 - j));
+ i = 0;
+ off = j * 32;
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+ i += skip;
+ if(i > 31)
+ break;
+ idx = vc1_simple_progressive_8x4_zz[i++];
+ block[idx + off] = value * scale;
+ }
+ if(!(subblkpat & (1 << (1 - j)))) vc1_inv_trans(block + off, 8, 4);
}
+ break;
+ case TT_4X8:
+ for(j = 0; j < 2; j++) {
+ last = subblkpat & (1 << (1 - j));
+ i = 0;
+ off = j * 4;
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+ i += skip;
+ if(i > 31)
+ break;
+ idx = vc1_simple_progressive_8x4_zz[i++];
+ block[idx + off] = value * scale;
+ }
+ vc1_inv_trans(block + off, 4, 8);
+ }
+ break;
}
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
@@ -2017,14 +2164,13 @@
{
MpegEncContext *s = &v->s;
GetBitContext *gb = &s->gb;
- int i, mb_offset = s->mb_x + s->mb_y*s->mb_width; /* XXX: mb_stride */
+ int i, j, mb_offset = s->mb_x + s->mb_y*s->mb_width; /* XXX: mb_stride */
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
int cbp; /* cbp decoding stuff */
int hybrid_pred; /* Prediction types */
- int mv_mode_bit = 0;
int mqdiff, mquant; /* MB quantization */
- int ttmb; /* MB Transform type */
+ int ttmb = v->ttmb; /* MB Transform type */
int status;
- uint8_t *coded_val;
static const int size_table[6] = { 0, 2, 3, 4, 5, 8 },
offset_table[6] = { 0, 1, 3, 7, 15, 31 };
@@ -2032,6 +2178,8 @@
int dmv_x, dmv_y; /* Differential MV components */
int index, index1; /* LUT indices */
int val, sign; /* temp values */
+ int first_block = 1;
+ int dst_idx, off;
mquant = v->pq; /* Loosy initialization */
@@ -2039,29 +2187,22 @@
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 */
+ s->current_picture.mbskip_table[mb_pos] = v->skip_mb_plane.data[mb_offset];
+ if (!v->mv_type_mb_plane.data[mb_offset]) /* 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);
+ s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
+ vc1_pred_mv(s, dmv_x, dmv_y, 1, v->range_x, v->range_y);
+
/* 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;
- vc1_decode_block(v, block[i], i, 0, mquant);
- }
- return 0;
}
else if (mb_has_coeffs)
{
@@ -2072,66 +2213,82 @@
else
{
mquant = v->pq;
- /* XXX: how to handle cbp ? */
- /* XXX: how to set values for following predictions ? */
cbp = 0;
}
+ s->current_picture.qscale_table[mb_pos] = mquant;
- if (!v->ttmbf)
+ if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table,
- VC1_TTMB_VLC_BITS, 12);
-
+ VC1_TTMB_VLC_BITS, 2);
+ s->dsp.clear_blocks(block[0]);
+ vc1_mc_1mv(v);
+ dst_idx = 0;
for (i=0; i<6; i++)
{
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
val = ((cbp >> (5 - i)) & 1);
- if (i < 4) {
- int pred = vc1_coded_block_pred(&v->s, i, &coded_val);
- val = val ^ pred;
- *coded_val = val;
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ if(s->mb_intra) {
+ vc1_decode_intra_block(v, block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);
+ vc1_inv_trans(s->block[i], 8, 8);
+ for(j = 0; j < 64; j++) s->block[i][j] += 128;
+ s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
+ } else if(val) {
+ vc1_decode_p_block(v, block[i], i, mquant, ttmb, first_block);
+ if(!v->ttmbf && ttmb < 8) ttmb = -1;
+ first_block = 0;
+ s->dsp.add_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
}
- vc1_decode_block(v, block[i], i, val, mquant); //FIXME
}
}
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);
-
- /* TODO: blah */
+ s->mb_intra = 0;
+ s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
+ vc1_pred_mv(s, 0, 0, 1, v->range_x, v->range_y);
+ vc1_mc_1mv(v);
return 0;
}
} //1MV mode
else //4MV mode
- {
+ {//FIXME: looks not conforming to standard and is not even theoretically complete
if (!v->skip_mb_plane.data[mb_offset] /* unskipped MB */)
{
+ int blk_intra[4], blk_coded[4];
/* Get CBPCY */
cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- for (i=0; i<6; i++)
+ for (i=0; i<4; i++)
{
val = ((cbp >> (5 - i)) & 1);
- if (i < 4) {
- int pred = vc1_coded_block_pred(&v->s, i, &coded_val);
- val = val ^ pred;
- *coded_val = val;
- }
- if (i<4 && val)
- {
+ blk_intra[i] = 0;
+ blk_coded[i] = val;
+ if(val) {
GET_MVDATA(dmv_x, dmv_y);
+ blk_intra[i] = s->mb_intra;
}
if (v->mv_mode == MV_PMODE_MIXED_MV /* Hybrid pred */)
hybrid_pred = get_bits(gb, 1);
+ }
+ if((blk_intra[0] | blk_intra[1] | blk_intra[2] | blk_intra[3]) ||
+ (blk_coded[0] | blk_coded[1] | blk_coded[2] | blk_coded[3])) {
GET_MQUANT();
- if (s->mb_intra /* One of the 4 blocks is intra */ &&
- index /* non-zero pred for that block */)
+ if (s->mb_intra /* One of the 4 blocks is intra */
+ /* non-zero pred for that block */)
s->ac_pred = get_bits(gb, 1);
if (!v->ttmbf)
ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table,
VC1_TTMB_VLC_BITS, 12);
- status = vc1_decode_block(v, block[i], i, val, mquant);
+ for(i = 0; i < 6; i++) {
+ val = ((cbp >> (5 - i)) & 1);
+ if(i & 4 || blk_intra[i] || val) {
+ if(i < 4 && blk_intra[i])
+ status = vc1_decode_intra_block(v, block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);
+ else
+ status = vc1_decode_p_block(v, block[i], i, mquant, ttmb, 0);
+ }
+ }
}
return status;
}
@@ -2142,10 +2299,7 @@
{
if (v->mv_mode == MV_PMODE_MIXED_MV /* Hybrid pred */)
hybrid_pred = get_bits(gb, 1);
- vc1_decode_block(v, block[i], i, 0, v->pq); //FIXME
}
- vc1_decode_block(v, block[4], 4, 0, v->pq); //FIXME
- vc1_decode_block(v, block[5], 5, 0, v->pq); //FIXME
/* TODO: blah */
return 0;
}
@@ -2155,187 +2309,153 @@
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
+/** Decode blocks of I-frame
*/
-static int vc1_decode_b_mb(VC1Context *v, DCTELEM block[6][64])
+static void vc1_decode_i_blocks(VC1Context *v)
{
+ int k;
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 */
+ int cbp, val;
+ uint8_t *coded_val;
+ int mb_pos;
- 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 */
+ /* select codingmode used for VLC tables selection */
+ switch(v->y_ac_table_index){
+ case 0:
+ v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
+ break;
+ case 1:
+ v->codingset = CS_HIGH_MOT_INTRA;
+ break;
+ case 2:
+ v->codingset = CS_MID_RATE_INTRA;
+ break;
+ }
- mb_offset = s->mb_width*s->mb_y + s->mb_x; //FIXME: arrays aren't using stride
+ switch(v->c_ac_table_index){
+ case 0:
+ v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
+ break;
+ case 1:
+ v->codingset2 = CS_HIGH_MOT_INTER;
+ break;
+ case 2:
+ v->codingset2 = CS_MID_RATE_INTER;
+ break;
+ }
- 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);
+ /* Set DC scale - y and c use the same */
+ s->y_dc_scale = s->y_dc_scale_table[v->pq];
+ s->c_dc_scale = s->c_dc_scale_table[v->pq];
- 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();
+ //do frame decode
+ s->mb_x = s->mb_y = 0;
+ s->mb_intra = 1;
+ ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
+ 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++) {
+ ff_init_block_index(s);
+ ff_update_block_index(s);
+ s->dsp.clear_blocks(s->block[0]);
+ mb_pos = s->mb_x + s->mb_y * s->mb_width;
+ s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
+ s->current_picture.qscale_table[mb_pos] = v->pq;
+
+ // do actual MB decoding and displaying
+ cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
+ v->s.ac_pred = get_bits(&v->s.gb, 1);
+
+ for(k = 0; k < 6; k++) {
+ val = ((cbp >> (5 - k)) & 1);
+ if (k < 4) {
+ int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
+ val = val ^ pred;
+ *coded_val = val;
+ }
+ cbp |= val << (5 - k);
+
+ vc1_decode_i_block(v, s->block[k], k, val, (k<4)? v->codingset : v->codingset2);
+
+ vc1_inv_trans(s->block[k], 8, 8);
+ if(v->pq >= 9 && v->overlap) {
+ vc1_overlap_block(s, s->block[k], k, (s->mb_y || k>1), (s->mb_x || (k != 0 && k != 2)));
+ }
}
- }
- }
- //End1
- if (v->ttmbf)
- ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table,
- VC1_TTMB_VLC_BITS, 12);
+ vc1_put_block(v, s->block);
- //End2
- for (i=0; i<6; i++)
- {
- vc1_decode_block(v, block[i], i, 0 /*cbp[i]*/, mquant); //FIXME
+ if(get_bits_count(&s->gb) > v->bits) {
+ av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits);
+ return;
+ }
+ }
+ ff_draw_horiz_band(s, s->mb_y * 16, 16);
}
- 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(VC1Context *v)
+static void vc1_decode_p_blocks(VC1Context *v)
{
MpegEncContext *s = &v->s;
- /* Set transform type info 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 codingmode used for VLC tables selection */
+ switch(v->c_ac_table_index){
+ case 0:
+ v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
+ break;
+ case 1:
+ v->codingset = CS_HIGH_MOT_INTRA;
+ break;
+ case 2:
+ v->codingset = CS_MID_RATE_INTRA;
+ break;
}
- if (s->pict_type != I_TYPE)
- {
- /* 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;
+ switch(v->c_ac_table_index){
+ case 0:
+ v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
+ break;
+ case 1:
+ v->codingset2 = CS_HIGH_MOT_INTER;
+ break;
+ case 2:
+ v->codingset2 = CS_MID_RATE_INTER;
+ break;
}
- 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++)
- {
- //FIXME Get proper MB DCTELEM
- //TODO Move out of the loop
- switch (s->pict_type)
- {
- case I_TYPE: vc1_decode_i_mb(v, s->block); break;
- case P_TYPE: vc1_decode_p_mb(v, s->block); break;
- case BI_TYPE:
- case B_TYPE: vc1_decode_b_mb(v, s->block); break;
+ ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
+ s->first_slice_line = 1;
+ 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++) {
+ ff_init_block_index(s);
+ ff_update_block_index(s);
+ s->dsp.clear_blocks(s->block[0]);
+
+ vc1_decode_p_mb(v, s->block);
+ if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y);
+ return;
}
}
- //Add a check for overconsumption ?
+ ff_draw_horiz_band(s, s->mb_y * 16, 16);
+ s->first_slice_line = 0;
}
- return 0;
}
-/** @} */ //End for group std_mb
-#if HAS_ADVANCED_PROFILE
-/***********************************************************************/
-/**
- * @defgroup adv_mb VC1 Macroblock-level functions in Advanced Profile
- * @todo TODO: Integrate to MpegEncContext facilities
- * @todo TODO: Code P, B and BI
- * @{
- */
-static int advanced_decode_i_mbs(VC1Context *v)
+static void vc1_decode_blocks(VC1Context *v)
{
- MpegEncContext *s = &v->s;
- GetBitContext *gb = &v->s.gb;
- int mqdiff, mquant, mb_offset = 0, over_flags_mb = 0;
- 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->ac_pred_plane.is_raw)
- s->ac_pred = get_bits(gb, 1);
- else
- s->ac_pred = v->ac_pred_plane.data[mb_offset];
- if (v->condover == 3 && v->over_flags_plane.is_raw)
- over_flags_mb = get_bits(gb, 1);
- GET_MQUANT();
+ v->s.esc3_level_length = 0;
- /* TODO: lots */
- }
- mb_offset++;
+ switch(v->s.pict_type) {
+ case I_TYPE:
+ vc1_decode_i_blocks(v);
+ break;
+ case P_TYPE:
+ vc1_decode_p_blocks(v);
+ break;
}
- return 0;
}
-/** @} */ //End for group adv_mb
-#endif
+
/** Initialize a VC1/WMV3 decoder
* @todo TODO: Handle VC-1 IDUs (Transport level?)
@@ -2356,7 +2476,9 @@
if (vc1_init_common(v) < 0) return -1;
av_log(avctx, AV_LOG_INFO, "This decoder is not supposed to produce picture. Dont report this as a bug!\n");
+ av_log(avctx, AV_LOG_INFO, "If you see a picture, don't believe your eyes.\n");
+ avctx->flags |= CODEC_FLAG_EMU_EDGE;
avctx->coded_width = avctx->width;
avctx->coded_height = avctx->height;
if (avctx->codec_id == CODEC_ID_WMV3)
@@ -2403,7 +2525,7 @@
v->previous_line_cbpcy = (uint8_t *)av_malloc(s->mb_stride*4);
if (!v->previous_line_cbpcy) return -1;
-#if HAS_ADVANCED_PROFILE
+ /* Init coded blocks info */
if (v->profile == PROFILE_ADVANCED)
{
if (alloc_bitplane(&v->over_flags_plane, s->mb_width, s->mb_height) < 0)
@@ -2411,10 +2533,10 @@
if (alloc_bitplane(&v->ac_pred_plane, s->mb_width, s->mb_height) < 0)
return -1;
}
-#endif
return 0;
- }
+}
+
/** Decode a VC1/WMV3 frame
* @todo TODO: Handle VC-1 IDUs (Transport level?)
@@ -2426,77 +2548,7 @@
{
VC1Context *v = avctx->priv_data;
MpegEncContext *s = &v->s;
- int ret = FRAME_SKIPPED, len;
AVFrame *pict = data;
- uint8_t *tmp_buf;
- v->s.avctx = avctx;
-
- //buf_size = 0 -> last frame
- if (!buf_size) return 0;
-
- len = avpicture_get_size(avctx->pix_fmt, avctx->width,
- avctx->height);
- tmp_buf = (uint8_t *)av_mallocz(len);
- avpicture_fill((AVPicture *)pict, tmp_buf, avctx->pix_fmt,
- avctx->width, avctx->height);
-
- if (avctx->codec_id == CODEC_ID_VC1)
- {
-#if 0
- // search for IDU's
- // FIXME
- uint32_t scp = 0;
- int scs = 0, i = 0;
-
- while (i < buf_size)
- {
- for (; i < buf_size && scp != 0x000001; i++)
- scp = ((scp<<8)|buf[i])&0xffffff;
-
- if (scp != 0x000001)
- break; // eof ?
-
- scs = buf[i++];
-
- init_get_bits(gb, buf+i, (buf_size-i)*8);
-
- switch(scs)
- {
- 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 < PROFILE_ADVANCED)
- av_log(avctx, AV_LOG_ERROR,
- "Found an entry point in profile %i\n", v->profile);
- advanced_entry_point_process(avctx, gb);
- break;
- case 0x0F: //Sequence header Start Code
- decode_sequence_header(avctx, gb);
- break;
- default:
- av_log(avctx, AV_LOG_ERROR,
- "Unsupported IDU suffix %lX\n", scs);
- }
-
- 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) {
@@ -2511,56 +2563,39 @@
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_ADVANCED)
- ret= advanced_decode_picture_primary_header(v);
- else
-#endif
- ret= standard_decode_picture_primary_header(v);
- if (ret == FRAME_SKIPPED) return buf_size;
- /* skip if the header was thrashed */
- if (ret < 0){
- av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
- return -1;
+ int i= ff_find_unused_picture(s, 0);
+ s->current_picture_ptr= &s->picture[i];
}
- //No bug workaround yet, no DCT conformance
+ avctx->has_b_frames= !s->low_delay;
- //WMV9 does have resized images
- if (v->profile < PROFILE_ADVANCED && v->multires){
- //Parse context stuff in here, don't know how appliable it is
- }
- //Not sure about context initialization
+ init_get_bits(&s->gb, buf, buf_size*8);
+ // do parse frame header
+ if(vc1_parse_frame_header(v, &s->gb) == -1)
+ return -1;
+
+ if(s->pict_type != I_TYPE && s->pict_type != P_TYPE)return -1;
// 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 don't have reference frames */
+ if(s->last_picture_ptr==NULL && (s->pict_type==B_TYPE || s->dropable)) return -1;//buf_size;
/* 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
+ if(avctx->hurry_up && s->pict_type==B_TYPE) return -1;//buf_size;
+ if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE)
+ || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE)
+ || avctx->skip_frame >= AVDISCARD_ALL)
+ return buf_size;
/* skip everything if we are in a hurry>=5 */
- if(avctx->hurry_up>=5)
- return buf_size; //FIXME simulating all buffer consumed
+ if(avctx->hurry_up>=5) return -1;//buf_size;
if(s->next_p_frame_damaged){
if(s->pict_type==B_TYPE)
- return buf_size; //FIXME simulating all buffer consumed
+ return buf_size;
else
s->next_p_frame_damaged=0;
}
@@ -2570,43 +2605,17 @@
ff_er_frame_start(s);
- //wmv9 may or may not have skip bits
-#if HAS_ADVANCED_PROFILE
- if (v->profile == PROFILE_ADVANCED)
- ret= advanced_decode_picture_secondary_header(v);
- else
-#endif
- ret = standard_decode_picture_secondary_header(v);
- if (ret<0) return FRAME_SKIPPED; //FIXME Non fatal for now
-
- //We consider the image coded in only one slice
-#if HAS_ADVANCED_PROFILE
- if (v->profile == PROFILE_ADVANCED)
- {
- 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_SKIPPED;
- }
- if (ret == FRAME_SKIPPED) return buf_size; //We ignore for now failures
- }
- else
-#endif
- {
- ret = standard_decode_mbs(v);
- if (ret == FRAME_SKIPPED) return buf_size;
- }
-
+ v->bits = buf_size * 8;
+ vc1_decode_blocks(v);
+//av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), buf_size*8);
+// if(get_bits_count(&s->gb) > buf_size * 8)
+// return -1;
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);
-
+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_ptr;
} else if (s->last_picture_ptr != NULL) {
@@ -2622,14 +2631,10 @@
/* we substract 1 because it is added on utils.c */
avctx->frame_number = s->picture_number - 1;
- av_log(avctx, AV_LOG_DEBUG, "Consumed %i/%i bits\n",
- get_bits_count(&s->gb), buf_size*8);
-
- /* Fake consumption of all data */
- *data_size = len;
- return buf_size; //Number of bytes consumed
+ return buf_size;
}
+
/** Close a VC1/WMV3 decoder
* @warning Initial try at using MpegEncContext stuff
*/
@@ -2637,10 +2642,8 @@
{
VC1Context *v = avctx->priv_data;
-#if HAS_ADVANCED_PROFILE
av_freep(&v->hrd_rate);
av_freep(&v->hrd_buffer);
-#endif
MPV_common_end(&v->s);
free_bitplane(&v->mv_type_mb_plane);
free_bitplane(&v->skip_mb_plane);
@@ -2648,6 +2651,7 @@
return 0;
}
+
AVCodec vc1_decoder = {
"vc1",
CODEC_TYPE_VIDEO,
Added: trunk/libavcodec/vc1acdata.h
==============================================================================
--- (empty file)
+++ trunk/libavcodec/vc1acdata.h Tue Jun 27 05:11:51 2006
@@ -0,0 +1,564 @@
+#define AC_MODES 8
+
+static const int vc1_ac_sizes[AC_MODES] = {
+ 186, 169, 133, 149, 103, 103, 163, 175
+};
+
+static const uint32_t vc1_ac_tables[AC_MODES][186][2] = {
+{
+{ 0x0001, 2}, { 0x0005, 3}, { 0x000D, 4}, { 0x0012, 5}, { 0x000E, 6}, { 0x0015, 7},
+{ 0x0013, 8}, { 0x003F, 8}, { 0x004B, 9}, { 0x011F, 9}, { 0x00B8, 10}, { 0x03E3, 10},
+{ 0x0172, 11}, { 0x024D, 12}, { 0x03DA, 12}, { 0x02DD, 13}, { 0x1F55, 13}, { 0x05B9, 14},
+{ 0x3EAE, 14}, { 0x0000, 4}, { 0x0010, 5}, { 0x0008, 7}, { 0x0020, 8}, { 0x0029, 9},
+{ 0x01F4, 9}, { 0x0233, 10}, { 0x01E0, 11}, { 0x012A, 12}, { 0x03DD, 12}, { 0x050A, 13},
+{ 0x1F29, 13}, { 0x0A42, 14}, { 0x1272, 15}, { 0x1737, 15}, { 0x0003, 5}, { 0x0011, 7},
+{ 0x00C4, 8}, { 0x004B, 10}, { 0x00B4, 11}, { 0x07D4, 11}, { 0x0345, 12}, { 0x02D7, 13},
+{ 0x07BF, 13}, { 0x0938, 14}, { 0x0BBB, 14}, { 0x095E, 15}, { 0x0013, 5}, { 0x0078, 7},
+{ 0x0069, 9}, { 0x0232, 10}, { 0x0461, 11}, { 0x03EC, 12}, { 0x0520, 13}, { 0x1F2A, 13},
+{ 0x3E50, 14}, { 0x3E51, 14}, { 0x1486, 15}, { 0x000C, 6}, { 0x0024, 9}, { 0x0094, 11},
+{ 0x08C0, 12}, { 0x0F09, 14}, { 0x1EF0, 15}, { 0x003D, 6}, { 0x0053, 9}, { 0x01A0, 11},
+{ 0x02D6, 13}, { 0x0F08, 14}, { 0x0013, 7}, { 0x007C, 9}, { 0x07C1, 11}, { 0x04AC, 14},
+{ 0x001B, 7}, { 0x00A0, 10}, { 0x0344, 12}, { 0x0F79, 14}, { 0x0079, 7}, { 0x03E1, 10},
+{ 0x02D4, 13}, { 0x2306, 14}, { 0x0021, 8}, { 0x023C, 10}, { 0x0FAE, 12}, { 0x23DE, 14},
+{ 0x0035, 8}, { 0x0175, 11}, { 0x07B3, 13}, { 0x00C5, 8}, { 0x0174, 11}, { 0x0785, 13},
+{ 0x0048, 9}, { 0x01A3, 11}, { 0x049E, 13}, { 0x002C, 9}, { 0x00FA, 10}, { 0x07D6, 11},
+{ 0x0092, 10}, { 0x05CC, 13}, { 0x1EF1, 15}, { 0x00A3, 10}, { 0x03ED, 12}, { 0x093E, 14},
+{ 0x01E2, 11}, { 0x1273, 15}, { 0x07C4, 11}, { 0x1487, 15}, { 0x0291, 12}, { 0x0293, 12},
+{ 0x0F8A, 12}, { 0x0509, 13}, { 0x0508, 13}, { 0x078D, 13}, { 0x07BE, 13}, { 0x078C, 13},
+{ 0x04AE, 14}, { 0x0BBA, 14}, { 0x2307, 14}, { 0x0B9A, 14}, { 0x1736, 15}, { 0x000E, 4},
+{ 0x0045, 7}, { 0x01F3, 9}, { 0x047A, 11}, { 0x05DC, 13}, { 0x23DF, 14}, { 0x0019, 5},
+{ 0x0028, 9}, { 0x0176, 11}, { 0x049D, 13}, { 0x23DD, 14}, { 0x0030, 6}, { 0x00A2, 10},
+{ 0x02EF, 12}, { 0x05B8, 14}, { 0x003F, 6}, { 0x00A5, 10}, { 0x03DB, 12}, { 0x093F, 14},
+{ 0x0044, 7}, { 0x07CB, 11}, { 0x095F, 15}, { 0x0063, 7}, { 0x03C3, 12}, { 0x0015, 8},
+{ 0x08F6, 12}, { 0x0017, 8}, { 0x0498, 13}, { 0x002C, 8}, { 0x07B2, 13}, { 0x002F, 8},
+{ 0x1F54, 13}, { 0x008D, 8}, { 0x07BD, 13}, { 0x008E, 8}, { 0x1182, 13}, { 0x00FB, 8},
+{ 0x050B, 13}, { 0x002D, 8}, { 0x07C0, 11}, { 0x0079, 9}, { 0x1F5F, 13}, { 0x007A, 9},
+{ 0x1F56, 13}, { 0x0231, 10}, { 0x03E4, 10}, { 0x01A1, 11}, { 0x0143, 11}, { 0x01F7, 11},
+{ 0x016F, 12}, { 0x0292, 12}, { 0x02E7, 12}, { 0x016C, 12}, { 0x016D, 12}, { 0x03DC, 12},
+{ 0x0F8B, 12}, { 0x0499, 13}, { 0x03D8, 12}, { 0x078E, 13}, { 0x02D5, 13}, { 0x1F5E, 13},
+{ 0x1F2B, 13}, { 0x078F, 13}, { 0x04AD, 14}, { 0x3EAF, 14}, { 0x23DC, 14}, { 0x004A, 9}
+},
+{
+{ 0x0000, 3}, { 0x0003, 4}, { 0x000B, 5}, { 0x0014, 6}, { 0x003F, 6}, { 0x005D, 7},
+{ 0x00A2, 8}, { 0x00AC, 9}, { 0x016E, 9}, { 0x020A, 10}, { 0x02E2, 10}, { 0x0432, 11},
+{ 0x05C9, 11}, { 0x0827, 12}, { 0x0B54, 12}, { 0x04E6, 13}, { 0x105F, 13}, { 0x172A, 13},
+{ 0x20B2, 14}, { 0x2D4E, 14}, { 0x39F0, 14}, { 0x4175, 15}, { 0x5A9E, 15}, { 0x0004, 4},
+{ 0x001E, 5}, { 0x0042, 7}, { 0x00B6, 8}, { 0x0173, 9}, { 0x0395, 10}, { 0x072E, 11},
+{ 0x0B94, 12}, { 0x16A4, 13}, { 0x20B3, 14}, { 0x2E45, 14}, { 0x0005, 5}, { 0x0040, 7},
+{ 0x0049, 9}, { 0x028F, 10}, { 0x05CB, 11}, { 0x048A, 13}, { 0x09DD, 14}, { 0x73E2, 15},
+{ 0x0018, 5}, { 0x0025, 8}, { 0x008A, 10}, { 0x051B, 11}, { 0x0E5F, 12}, { 0x09C9, 14},
+{ 0x139C, 15}, { 0x0029, 6}, { 0x004F, 9}, { 0x0412, 11}, { 0x048D, 13}, { 0x2E41, 14},
+{ 0x0038, 6}, { 0x010E, 9}, { 0x05A8, 11}, { 0x105C, 13}, { 0x39F2, 14}, { 0x0058, 7},
+{ 0x021F, 10}, { 0x0E7E, 12}, { 0x39FF, 14}, { 0x0023, 8}, { 0x02E3, 10}, { 0x04E5, 13},
+{ 0x2E40, 14}, { 0x00A1, 8}, { 0x05BE, 11}, { 0x09C8, 14}, { 0x0083, 8}, { 0x013A, 11},
+{ 0x1721, 13}, { 0x0044, 9}, { 0x0276, 12}, { 0x39F6, 14}, { 0x008B, 10}, { 0x04EF, 13},
+{ 0x5A9B, 15}, { 0x0208, 10}, { 0x1CFE, 13}, { 0x0399, 10}, { 0x1CB4, 13}, { 0x039E, 10},
+{ 0x39F3, 14}, { 0x05AB, 11}, { 0x73E3, 15}, { 0x0737, 11}, { 0x5A9F, 15}, { 0x082D, 12},
+{ 0x0E69, 12}, { 0x0E68, 12}, { 0x0433, 11}, { 0x0B7B, 12}, { 0x2DF8, 14}, { 0x2E56, 14},
+{ 0x2E57, 14}, { 0x39F7, 14}, { 0x51A5, 15}, { 0x0003, 3}, { 0x002A, 6}, { 0x00E4, 8},
+{ 0x028E, 10}, { 0x0735, 11}, { 0x1058, 13}, { 0x1CFA, 13}, { 0x2DF9, 14}, { 0x4174, 15},
+{ 0x0009, 4}, { 0x0054, 8}, { 0x0398, 10}, { 0x048B, 13}, { 0x139D, 15}, { 0x000D, 4},
+{ 0x00AD, 9}, { 0x0826, 12}, { 0x2D4C, 14}, { 0x0011, 5}, { 0x016B, 9}, { 0x0B7F, 12},
+{ 0x51A4, 15}, { 0x0019, 5}, { 0x021B, 10}, { 0x16FD, 13}, { 0x001D, 5}, { 0x0394, 10},
+{ 0x28D3, 14}, { 0x002B, 6}, { 0x05BC, 11}, { 0x5A9A, 15}, { 0x002F, 6}, { 0x0247, 12},
+{ 0x0010, 7}, { 0x0A35, 12}, { 0x003E, 6}, { 0x0B7A, 12}, { 0x0059, 7}, { 0x105E, 13},
+{ 0x0026, 8}, { 0x09CF, 14}, { 0x0055, 8}, { 0x1CB5, 13}, { 0x0057, 8}, { 0x0E5B, 12},
+{ 0x00A0, 8}, { 0x1468, 13}, { 0x0170, 9}, { 0x0090, 10}, { 0x01CE, 9}, { 0x021A, 10},
+{ 0x0218, 10}, { 0x0168, 9}, { 0x021E, 10}, { 0x0244, 12}, { 0x0736, 11}, { 0x0138, 11},
+{ 0x0519, 11}, { 0x0E5E, 12}, { 0x072C, 11}, { 0x0B55, 12}, { 0x09DC, 14}, { 0x20BB, 14},
+{ 0x048C, 13}, { 0x1723, 13}, { 0x2E44, 14}, { 0x16A5, 13}, { 0x0518, 11}, { 0x39FE, 14},
+{ 0x0169, 9}
+},
+{
+{ 0x0001, 2}, { 0x0006, 3}, { 0x000F, 4}, { 0x0016, 5}, { 0x0020, 6}, { 0x0018, 7},
+{ 0x0008, 8}, { 0x009A, 8}, { 0x0056, 9}, { 0x013E, 9}, { 0x00F0, 10}, { 0x03A5, 10},
+{ 0x0077, 11}, { 0x01EF, 11}, { 0x009A, 12}, { 0x005D, 13}, { 0x0001, 4}, { 0x0011, 5},
+{ 0x0002, 7}, { 0x000B, 8}, { 0x0012, 9}, { 0x01D6, 9}, { 0x027E, 10}, { 0x0191, 11},
+{ 0x00EA, 12}, { 0x03DC, 12}, { 0x013B, 13}, { 0x0004, 5}, { 0x0014, 7}, { 0x009E, 8},
+{ 0x0009, 10}, { 0x01AC, 11}, { 0x01E2, 11}, { 0x03CA, 12}, { 0x005F, 13}, { 0x0017, 5},
+{ 0x004E, 7}, { 0x005E, 9}, { 0x00F3, 10}, { 0x01AD, 11}, { 0x00EC, 12}, { 0x05F0, 13},
+{ 0x000E, 6}, { 0x00E1, 8}, { 0x03A4, 10}, { 0x009C, 12}, { 0x013D, 13}, { 0x003B, 6},
+{ 0x001C, 9}, { 0x0014, 11}, { 0x09BE, 12}, { 0x0006, 7}, { 0x007A, 9}, { 0x0190, 11},
+{ 0x0137, 13}, { 0x001B, 7}, { 0x0008, 10}, { 0x075C, 11}, { 0x0071, 7}, { 0x00D7, 10},
+{ 0x09BF, 12}, { 0x0007, 8}, { 0x00AF, 10}, { 0x04CC, 11}, { 0x0034, 8}, { 0x0265, 10},
+{ 0x009F, 12}, { 0x00E0, 8}, { 0x0016, 11}, { 0x0327, 12}, { 0x0015, 9}, { 0x017D, 11},
+{ 0x0EBB, 12}, { 0x0014, 9}, { 0x00F6, 10}, { 0x01E4, 11}, { 0x00CB, 10}, { 0x099D, 12},
+{ 0x00CA, 10}, { 0x02FC, 12}, { 0x017F, 11}, { 0x04CD, 11}, { 0x02FD, 12}, { 0x04FE, 11},
+{ 0x013A, 13}, { 0x000A, 4}, { 0x0042, 7}, { 0x01D3, 9}, { 0x04DD, 11}, { 0x0012, 5},
+{ 0x00E8, 8}, { 0x004C, 11}, { 0x0136, 13}, { 0x0039, 6}, { 0x0264, 10}, { 0x0EBA, 12},
+{ 0x0000, 7}, { 0x00AE, 10}, { 0x099C, 12}, { 0x001F, 7}, { 0x04DE, 11}, { 0x0043, 7},
+{ 0x04DC, 11}, { 0x0003, 8}, { 0x03CB, 12}, { 0x0006, 8}, { 0x099E, 12}, { 0x002A, 8},
+{ 0x05F1, 13}, { 0x000F, 8}, { 0x09FE, 12}, { 0x0033, 8}, { 0x09FF, 12}, { 0x0098, 8},
+{ 0x099F, 12}, { 0x00EA, 8}, { 0x013C, 13}, { 0x002E, 8}, { 0x0192, 11}, { 0x0136, 9},
+{ 0x006A, 9}, { 0x0015, 11}, { 0x03AF, 10}, { 0x01E3, 11}, { 0x0074, 11}, { 0x00EB, 12},
+{ 0x02F9, 12}, { 0x005C, 13}, { 0x00ED, 12}, { 0x03DD, 12}, { 0x0326, 12}, { 0x005E, 13},
+{ 0x0016, 7}
+},
+{
+{ 0x0004, 3}, { 0x0014, 5}, { 0x0017, 7}, { 0x007F, 8}, { 0x0154, 9}, { 0x01F2, 10},
+{ 0x00BF, 11}, { 0x0065, 12}, { 0x0AAA, 12}, { 0x0630, 13}, { 0x1597, 13}, { 0x03B7, 14},
+{ 0x2B22, 14}, { 0x0BE6, 15}, { 0x000B, 4}, { 0x0037, 7}, { 0x0062, 9}, { 0x0007, 11},
+{ 0x0166, 12}, { 0x00CE, 13}, { 0x1590, 13}, { 0x05F6, 14}, { 0x0BE7, 15}, { 0x0007, 5},
+{ 0x006D, 8}, { 0x0003, 11}, { 0x031F, 12}, { 0x05F2, 14}, { 0x0002, 6}, { 0x0061, 9},
+{ 0x0055, 12}, { 0x01DF, 14}, { 0x001A, 6}, { 0x001E, 10}, { 0x0AC9, 12}, { 0x2B23, 14},
+{ 0x001E, 6}, { 0x001F, 10}, { 0x0AC3, 12}, { 0x2B2B, 14}, { 0x0006, 7}, { 0x0004, 11},
+{ 0x02F8, 13}, { 0x0019, 7}, { 0x0006, 11}, { 0x063D, 13}, { 0x0057, 7}, { 0x0182, 11},
+{ 0x2AA2, 14}, { 0x0004, 8}, { 0x0180, 11}, { 0x059C, 14}, { 0x007D, 8}, { 0x0164, 12},
+{ 0x076D, 15}, { 0x0002, 9}, { 0x018D, 11}, { 0x1581, 13}, { 0x00AD, 8}, { 0x0060, 12},
+{ 0x0C67, 14}, { 0x001C, 9}, { 0x00EE, 13}, { 0x0003, 9}, { 0x02CF, 13}, { 0x00D9, 9},
+{ 0x1580, 13}, { 0x0002, 11}, { 0x0183, 11}, { 0x0057, 12}, { 0x0061, 12}, { 0x0031, 11},
+{ 0x0066, 12}, { 0x0631, 13}, { 0x0632, 13}, { 0x00AC, 13}, { 0x031D, 12}, { 0x0076, 12},
+{ 0x003A, 11}, { 0x0165, 12}, { 0x0C66, 14}, { 0x0003, 2}, { 0x0054, 7}, { 0x02AB, 10},
+{ 0x0016, 13}, { 0x05F7, 14}, { 0x0005, 4}, { 0x00F8, 9}, { 0x0AA9, 12}, { 0x005F, 15},
+{ 0x0004, 4}, { 0x001C, 10}, { 0x1550, 13}, { 0x0004, 5}, { 0x0077, 11}, { 0x076C, 15},
+{ 0x000E, 5}, { 0x000A, 12}, { 0x000C, 5}, { 0x0562, 11}, { 0x0004, 6}, { 0x031C, 12},
+{ 0x0006, 6}, { 0x00C8, 13}, { 0x000D, 6}, { 0x01DA, 13}, { 0x0007, 6}, { 0x00C9, 13},
+{ 0x0001, 7}, { 0x002E, 14}, { 0x0014, 7}, { 0x1596, 13}, { 0x000A, 7}, { 0x0AC2, 12},
+{ 0x0016, 7}, { 0x015B, 14}, { 0x0015, 7}, { 0x015A, 14}, { 0x000F, 8}, { 0x005E, 15},
+{ 0x007E, 8}, { 0x00AB, 8}, { 0x002D, 9}, { 0x00D8, 9}, { 0x000B, 9}, { 0x0014, 10},
+{ 0x02B3, 10}, { 0x01F3, 10}, { 0x003A, 10}, { 0x0000, 10}, { 0x0058, 10}, { 0x002E, 9},
+{ 0x005E, 10}, { 0x0563, 11}, { 0x00EC, 12}, { 0x0054, 12}, { 0x0AC1, 12}, { 0x1556, 13},
+{ 0x02FA, 13}, { 0x0181, 11}, { 0x1557, 13}, { 0x059D, 14}, { 0x2AA3, 14}, { 0x2B2A, 14},
+{ 0x01DE, 14}, { 0x063C, 13}, { 0x00CF, 13}, { 0x1594, 13}, { 0x000D, 9}
+},
+{
+{ 0x0002, 2}, { 0x0006, 3}, { 0x000F, 4}, { 0x000D, 5}, { 0x000C, 5}, { 0x0015, 6},
+{ 0x0013, 6}, { 0x0012, 6}, { 0x0017, 7}, { 0x001F, 8}, { 0x001E, 8}, { 0x001D, 8},
+{ 0x0025, 9}, { 0x0024, 9}, { 0x0023, 9}, { 0x0021, 9}, { 0x0021, 10}, { 0x0020, 10},
+{ 0x000F, 10}, { 0x000E, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11}, { 0x0021, 11},
+{ 0x0050, 12}, { 0x0051, 12}, { 0x0052, 12}, { 0x000E, 4}, { 0x0014, 6}, { 0x0016, 7},
+{ 0x001C, 8}, { 0x0020, 9}, { 0x001F, 9}, { 0x000D, 10}, { 0x0022, 11}, { 0x0053, 12},
+{ 0x0055, 12}, { 0x000B, 5}, { 0x0015, 7}, { 0x001E, 9}, { 0x000C, 10}, { 0x0056, 12},
+{ 0x0011, 6}, { 0x001B, 8}, { 0x001D, 9}, { 0x000B, 10}, { 0x0010, 6}, { 0x0022, 9},
+{ 0x000A, 10}, { 0x000D, 6}, { 0x001C, 9}, { 0x0008, 10}, { 0x0012, 7}, { 0x001B, 9},
+{ 0x0054, 12}, { 0x0014, 7}, { 0x001A, 9}, { 0x0057, 12}, { 0x0019, 8}, { 0x0009, 10},
+{ 0x0018, 8}, { 0x0023, 11}, { 0x0017, 8}, { 0x0019, 9}, { 0x0018, 9}, { 0x0007, 10},
+{ 0x0058, 12}, { 0x0007, 4}, { 0x000C, 6}, { 0x0016, 8}, { 0x0017, 9}, { 0x0006, 10},
+{ 0x0005, 11}, { 0x0004, 11}, { 0x0059, 12}, { 0x000F, 6}, { 0x0016, 9}, { 0x0005, 10},
+{ 0x000E, 6}, { 0x0004, 10}, { 0x0011, 7}, { 0x0024, 11}, { 0x0010, 7}, { 0x0025, 11},
+{ 0x0013, 7}, { 0x005A, 12}, { 0x0015, 8}, { 0x005B, 12}, { 0x0014, 8}, { 0x0013, 8},
+{ 0x001A, 8}, { 0x0015, 9}, { 0x0014, 9}, { 0x0013, 9}, { 0x0012, 9}, { 0x0011, 9},
+{ 0x0026, 11}, { 0x0027, 11}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12},
+{ 0x0003, 7}
+},
+{
+{ 0x0002, 2}, { 0x000F, 4}, { 0x0015, 6}, { 0x0017, 7}, { 0x001F, 8}, { 0x0025, 9},
+{ 0x0024, 9}, { 0x0021, 10}, { 0x0020, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11},
+{ 0x0006, 3}, { 0x0014, 6}, { 0x001E, 8}, { 0x000F, 10}, { 0x0021, 11}, { 0x0050, 12},
+{ 0x000E, 4}, { 0x001D, 8}, { 0x000E, 10}, { 0x0051, 12}, { 0x000D, 5}, { 0x0023, 9},
+{ 0x000D, 10}, { 0x000C, 5}, { 0x0022, 9}, { 0x0052, 12}, { 0x000B, 5}, { 0x000C, 10},
+{ 0x0053, 12}, { 0x0013, 6}, { 0x000B, 10}, { 0x0054, 12}, { 0x0012, 6}, { 0x000A, 10},
+{ 0x0011, 6}, { 0x0009, 10}, { 0x0010, 6}, { 0x0008, 10}, { 0x0016, 7}, { 0x0055, 12},
+{ 0x0015, 7}, { 0x0014, 7}, { 0x001C, 8}, { 0x001B, 8}, { 0x0021, 9}, { 0x0020, 9},
+{ 0x001F, 9}, { 0x001E, 9}, { 0x001D, 9}, { 0x001C, 9}, { 0x001B, 9}, { 0x001A, 9},
+{ 0x0022, 11}, { 0x0023, 11}, { 0x0056, 12}, { 0x0057, 12}, { 0x0007, 4}, { 0x0019, 9},
+{ 0x0005, 11}, { 0x000F, 6}, { 0x0004, 11}, { 0x000E, 6}, { 0x000D, 6}, { 0x000C, 6},
+{ 0x0013, 7}, { 0x0012, 7}, { 0x0011, 7}, { 0x0010, 7}, { 0x001A, 8}, { 0x0019, 8},
+{ 0x0018, 8}, { 0x0017, 8}, { 0x0016, 8}, { 0x0015, 8}, { 0x0014, 8}, { 0x0013, 8},
+{ 0x0018, 9}, { 0x0017, 9}, { 0x0016, 9}, { 0x0015, 9}, { 0x0014, 9}, { 0x0013, 9},
+{ 0x0012, 9}, { 0x0011, 9}, { 0x0007, 10}, { 0x0006, 10}, { 0x0005, 10}, { 0x0004, 10},
+{ 0x0024, 11}, { 0x0025, 11}, { 0x0026, 11}, { 0x0027, 11}, { 0x0058, 12}, { 0x0059, 12},
+{ 0x005A, 12}, { 0x005B, 12}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12},
+{ 0x0003, 7}
+},
+{
+{ 0x0000, 2}, { 0x0003, 3}, { 0x000D, 4}, { 0x0005, 4}, { 0x001C, 5}, { 0x0016, 5},
+{ 0x003F, 6}, { 0x003A, 6}, { 0x002E, 6}, { 0x0022, 6}, { 0x007B, 7}, { 0x0067, 7},
+{ 0x005F, 7}, { 0x0047, 7}, { 0x0026, 7}, { 0x00EF, 8}, { 0x00CD, 8}, { 0x00C1, 8},
+{ 0x00A9, 8}, { 0x004F, 8}, { 0x01F2, 9}, { 0x01DD, 9}, { 0x0199, 9}, { 0x0185, 9},
+{ 0x015D, 9}, { 0x011B, 9}, { 0x03EF, 10}, { 0x03E1, 10}, { 0x03C8, 10}, { 0x0331, 10},
+{ 0x0303, 10}, { 0x02F1, 10}, { 0x02A0, 10}, { 0x0233, 10}, { 0x0126, 10}, { 0x07C0, 11},
+{ 0x076F, 11}, { 0x076C, 11}, { 0x0661, 11}, { 0x0604, 11}, { 0x0572, 11}, { 0x0551, 11},
+{ 0x046A, 11}, { 0x0274, 11}, { 0x0F27, 12}, { 0x0F24, 12}, { 0x0EDB, 12}, { 0x0C8E, 12},
+{ 0x0C0B, 12}, { 0x0C0A, 12}, { 0x0AE3, 12}, { 0x08D6, 12}, { 0x0490, 12}, { 0x0495, 12},
+{ 0x1F19, 13}, { 0x1DB5, 13}, { 0x0009, 4}, { 0x0010, 5}, { 0x0029, 6}, { 0x0062, 7},
+{ 0x00F3, 8}, { 0x00AD, 8}, { 0x01E5, 9}, { 0x0179, 9}, { 0x009C, 9}, { 0x03B1, 10},
+{ 0x02AE, 10}, { 0x0127, 10}, { 0x076E, 11}, { 0x0570, 11}, { 0x0275, 11}, { 0x0F25, 12},
+{ 0x0EC0, 12}, { 0x0AA0, 12}, { 0x08D7, 12}, { 0x1E4C, 13}, { 0x0008, 5}, { 0x0063, 7},
+{ 0x00AF, 8}, { 0x017B, 9}, { 0x03B3, 10}, { 0x07DD, 11}, { 0x0640, 11}, { 0x0F8D, 12},
+{ 0x0BC1, 12}, { 0x0491, 12}, { 0x0028, 6}, { 0x00C3, 8}, { 0x0151, 9}, { 0x02A1, 10},
+{ 0x0573, 11}, { 0x0EC3, 12}, { 0x1F35, 13}, { 0x0065, 7}, { 0x01DA, 9}, { 0x02AF, 10},
+{ 0x0277, 11}, { 0x08C9, 12}, { 0x1781, 13}, { 0x0025, 7}, { 0x0118, 9}, { 0x0646, 11},
+{ 0x0AA6, 12}, { 0x1780, 13}, { 0x00C9, 8}, { 0x0321, 10}, { 0x0F9B, 12}, { 0x191E, 13},
+{ 0x0048, 8}, { 0x07CC, 11}, { 0x0AA1, 12}, { 0x0180, 9}, { 0x0465, 11}, { 0x1905, 13},
+{ 0x03E2, 10}, { 0x0EC1, 12}, { 0x3C9B, 14}, { 0x02F4, 10}, { 0x08C8, 12}, { 0x07C1, 11},
+{ 0x0928, 13}, { 0x05E1, 11}, { 0x320D, 14}, { 0x0EC2, 12}, { 0x6418, 15}, { 0x1F34, 13},
+{ 0x0078, 7}, { 0x0155, 9}, { 0x0552, 11}, { 0x191F, 13}, { 0x00FA, 8}, { 0x07DC, 11},
+{ 0x1907, 13}, { 0x00AC, 8}, { 0x0249, 11}, { 0x13B1, 14}, { 0x01F6, 9}, { 0x0AE2, 12},
+{ 0x01DC, 9}, { 0x04ED, 12}, { 0x0184, 9}, { 0x1904, 13}, { 0x0156, 9}, { 0x09D9, 13},
+{ 0x03E7, 10}, { 0x0929, 13}, { 0x03B2, 10}, { 0x3B68, 14}, { 0x02F5, 10}, { 0x13B0, 14},
+{ 0x0322, 10}, { 0x3B69, 14}, { 0x0234, 10}, { 0x7935, 15}, { 0x07C7, 11}, { 0xC833, 16},
+{ 0x0660, 11}, { 0x7934, 15}, { 0x024B, 11}, { 0xC832, 16}, { 0x0AA7, 12}, { 0x1F18, 13},
+{ 0x007A, 7}
+},
+{
+{ 0x0002, 2}, { 0x0000, 3}, { 0x001E, 5}, { 0x0004, 5}, { 0x0012, 6}, { 0x0070, 7},
+{ 0x001A, 7}, { 0x005F, 8}, { 0x0047, 8}, { 0x01D3, 9}, { 0x00B5, 9}, { 0x0057, 9},
+{ 0x03B5, 10}, { 0x016D, 10}, { 0x0162, 10}, { 0x07CE, 11}, { 0x0719, 11}, { 0x0691, 11},
+{ 0x02C6, 11}, { 0x0156, 11}, { 0x0F92, 12}, { 0x0D2E, 12}, { 0x0D20, 12}, { 0x059E, 12},
+{ 0x0468, 12}, { 0x02A6, 12}, { 0x1DA2, 13}, { 0x1C60, 13}, { 0x1A43, 13}, { 0x0B1D, 13},
+{ 0x08C0, 13}, { 0x055D, 13}, { 0x0003, 3}, { 0x000A, 5}, { 0x0077, 7}, { 0x00E5, 8},
+{ 0x01D9, 9}, { 0x03E5, 10}, { 0x0166, 10}, { 0x0694, 11}, { 0x0152, 11}, { 0x059F, 12},
+{ 0x1F3C, 13}, { 0x1A4B, 13}, { 0x055E, 13}, { 0x000C, 4}, { 0x007D, 7}, { 0x0044, 8},
+{ 0x03E0, 10}, { 0x0769, 11}, { 0x0E31, 12}, { 0x1F26, 13}, { 0x055C, 13}, { 0x001B, 5},
+{ 0x00E2, 8}, { 0x03A5, 10}, { 0x02C9, 11}, { 0x1F23, 13}, { 0x3B47, 14}, { 0x0007, 5},
+{ 0x01D8, 9}, { 0x02D8, 11}, { 0x1F27, 13}, { 0x3494, 14}, { 0x0035, 6}, { 0x03E1, 10},
+{ 0x059C, 12}, { 0x38C3, 14}, { 0x000C, 6}, { 0x0165, 10}, { 0x1D23, 13}, { 0x1638, 14},
+{ 0x0068, 7}, { 0x0693, 11}, { 0x3A45, 14}, { 0x0020, 7}, { 0x0F90, 12}, { 0x7CF6, 15},
+{ 0x00E8, 8}, { 0x058F, 12}, { 0x2CEF, 15}, { 0x0045, 8}, { 0x0B3A, 13}, { 0x01F1, 9},
+{ 0x3B46, 14}, { 0x01A7, 9}, { 0x1676, 14}, { 0x0056, 9}, { 0x692A, 15}, { 0x038D, 10},
+{ 0xE309, 16}, { 0x00AA, 10}, { 0x1C611, 17}, { 0x02DF, 11}, { 0xB3B9, 17}, { 0x02C8, 11},
+{ 0x38C20, 18}, { 0x01B0, 11}, { 0x16390, 18}, { 0x0F9F, 12}, { 0x16771, 18}, { 0x0ED0, 12},
+{ 0x71843, 19}, { 0x0D2A, 12}, { 0xF9E8C, 20}, { 0x0461, 12}, { 0xF9E8E, 20}, { 0x0B67, 13},
+{ 0x055F, 13}, { 0x003F, 6}, { 0x006D, 9}, { 0x0E90, 12}, { 0x054E, 13}, { 0x0013, 6},
+{ 0x0119, 10}, { 0x0B66, 13}, { 0x000B, 6}, { 0x0235, 11}, { 0x7CF5, 15}, { 0x0075, 7},
+{ 0x0D24, 12}, { 0xF9E9, 16}, { 0x002E, 7}, { 0x1F22, 13}, { 0x0021, 7}, { 0x054F, 13},
+{ 0x0014, 7}, { 0x3A44, 14}, { 0x00E4, 8}, { 0x7CF7, 15}, { 0x005E, 8}, { 0x7185, 15},
+{ 0x0037, 8}, { 0x2C73, 15}, { 0x01DB, 9}, { 0x59DD, 16}, { 0x01C7, 9}, { 0x692B, 15},
+{ 0x01A6, 9}, { 0x58E5, 16}, { 0x00B4, 9}, { 0x1F3D0, 17}, { 0x00B0, 9}, { 0xB1C9, 17},
+{ 0x03E6, 10}, { 0x16770, 18}, { 0x016E, 10}, { 0x3E7A2, 18}, { 0x011B, 10}, { 0xF9E8D, 20},
+{ 0x00D9, 10}, { 0xF9E8F, 20}, { 0x00A8, 10}, { 0x2C723, 19}, { 0x0749, 11}, { 0xE3084, 20},
+{ 0x0696, 11}, { 0x58E45, 20}, { 0x02DE, 11}, { 0xB1C88, 21}, { 0x0231, 11}, { 0x1C610A, 21},
+{ 0x01B1, 11}, { 0x71842D, 23}, { 0x0D2B, 12}, { 0x38C217, 22}, { 0x0D2F, 12}, { 0x163913, 22},
+{ 0x05B2, 12}, { 0x163912, 22}, { 0x0469, 12}, { 0x71842C, 23}, { 0x1A42, 13}, { 0x08C1, 13},
+{ 0x0073, 7}
+}
+};
+
+/* which indexes point to last=1 entries in tables */
+static const int vc1_last_decode_table[AC_MODES] = {
+ 119, 99, 85, 81, 67, 58, 126, 109
+};
+
+static const uint8_t vc1_index_decode_table[AC_MODES][185][2] = {
+{
+{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
+{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
+{ 0, 17}, { 0, 18}, { 0, 19}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5},
+{ 1, 6}, { 1, 7}, { 1, 8}, { 1, 9}, { 1, 10}, { 1, 11}, { 1, 12}, { 1, 13},
+{ 1, 14}, { 1, 15}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 2, 5}, { 2, 6},
+{ 2, 7}, { 2, 8}, { 2, 9}, { 2, 10}, { 2, 11}, { 2, 12}, { 3, 1}, { 3, 2},
+{ 3, 3}, { 3, 4}, { 3, 5}, { 3, 6}, { 3, 7}, { 3, 8}, { 3, 9}, { 3, 10},
+{ 3, 11}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5}, { 4, 6}, { 5, 1},
+{ 5, 2}, { 5, 3}, { 5, 4}, { 5, 5}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4},
+{ 7, 1}, { 7, 2}, { 7, 3}, { 7, 4}, { 8, 1}, { 8, 2}, { 8, 3}, { 8, 4},
+{ 9, 1}, { 9, 2}, { 9, 3}, { 9, 4}, { 10, 1}, { 10, 2}, { 10, 3}, { 11, 1},
+{ 11, 2}, { 11, 3}, { 12, 1}, { 12, 2}, { 12, 3}, { 13, 1}, { 13, 2}, { 13, 3},
+{ 14, 1}, { 14, 2}, { 14, 3}, { 15, 1}, { 15, 2}, { 15, 3}, { 16, 1}, { 16, 2},
+{ 17, 1}, { 17, 2}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1},
+{ 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1}, { 29, 1}, { 30, 1}, { 0, 1},
+{ 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 1, 1}, { 1, 2}, { 1, 3},
+{ 1, 4}, { 1, 5}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 3, 1}, { 3, 2},
+{ 3, 3}, { 3, 4}, { 4, 1}, { 4, 2}, { 4, 3}, { 5, 1}, { 5, 2}, { 6, 1},
+{ 6, 2}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1},
+{ 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1},
+{ 14, 2}, { 15, 1}, { 15, 2}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1},
+{ 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1},
+{ 29, 1}, { 30, 1}, { 31, 1}, { 32, 1}, { 33, 1}, { 34, 1}, { 35, 1}, { 36, 1},
+{ 37, 1}
+},
+{
+{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
+{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
+{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 1, 1},
+{ 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8}, { 1, 9},
+{ 1, 10}, { 1, 11}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 2, 5}, { 2, 6},
+{ 2, 7}, { 2, 8}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, { 3, 5}, { 3, 6},
+{ 3, 7}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5}, { 5, 1}, { 5, 2},
+{ 5, 3}, { 5, 4}, { 5, 5}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, { 7, 1},
+{ 7, 2}, { 7, 3}, { 7, 4}, { 8, 1}, { 8, 2}, { 8, 3}, { 9, 1}, { 9, 2},
+{ 9, 3}, { 10, 1}, { 10, 2}, { 10, 3}, { 11, 1}, { 11, 2}, { 11, 3}, { 12, 1},
+{ 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2}, { 16, 1},
+{ 16, 2}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1},
+{ 24, 1}, { 25, 1}, { 26, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5},
+{ 0, 6}, { 0, 7}, { 0, 8}, { 0, 9}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4},
+{ 1, 5}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 3, 1}, { 3, 2}, { 3, 3},
+{ 3, 4}, { 4, 1}, { 4, 2}, { 4, 3}, { 5, 1}, { 5, 2}, { 5, 3}, { 6, 1},
+{ 6, 2}, { 6, 3}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2},
+{ 10, 1}, { 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2},
+{ 14, 1}, { 14, 2}, { 15, 1}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1},
+{ 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1},
+{ 29, 1}, { 30, 1}, { 31, 1}, { 32, 1}, { 33, 1}, { 34, 1}, { 35, 1}, { 36, 1}
+},
+{
+{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
+{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
+{ 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8},
+{ 1, 9}, { 1, 10}, { 1, 11}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 2, 5},
+{ 2, 6}, { 2, 7}, { 2, 8}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, { 3, 5},
+{ 3, 6}, { 3, 7}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5}, { 5, 1},
+{ 5, 2}, { 5, 3}, { 5, 4}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, { 7, 1},
+{ 7, 2}, { 7, 3}, { 8, 1}, { 8, 2}, { 8, 3}, { 9, 1}, { 9, 2}, { 9, 3},
+{ 10, 1}, { 10, 2}, { 10, 3}, { 11, 1}, { 11, 2}, { 11, 3}, { 12, 1}, { 12, 2},
+{ 12, 3}, { 13, 1}, { 13, 2}, { 13, 3}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2},
+{ 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 0, 1}, { 0, 2}, { 0, 3},
+{ 0, 4}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 2, 1}, { 2, 2}, { 2, 3},
+{ 3, 1}, { 3, 2}, { 3, 3}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1},
+{ 6, 2}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1},
+{ 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1},
+{ 15, 1}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1},
+{ 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}
+},
+{
+{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
+{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 1, 1}, { 1, 2},
+{ 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8}, { 1, 9}, { 2, 1},
+{ 2, 2}, { 2, 3}, { 2, 4}, { 2, 5}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4},
+{ 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 5, 1}, { 5, 2}, { 5, 3}, { 5, 4},
+{ 6, 1}, { 6, 2}, { 6, 3}, { 7, 1}, { 7, 2}, { 7, 3}, { 8, 1}, { 8, 2},
+{ 8, 3}, { 9, 1}, { 9, 2}, { 9, 3}, { 10, 1}, { 10, 2}, { 10, 3}, { 11, 1},
+{ 11, 2}, { 11, 3}, { 12, 1}, { 12, 2}, { 12, 3}, { 13, 1}, { 13, 2}, { 14, 1},
+{ 14, 2}, { 15, 1}, { 15, 2}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1},
+{ 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1},
+{ 29, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 1, 1}, { 1, 2},
+{ 1, 3}, { 1, 4}, { 2, 1}, { 2, 2}, { 2, 3}, { 3, 1}, { 3, 2}, { 3, 3},
+{ 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2}, { 7, 1}, { 7, 2},
+{ 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 10, 2}, { 11, 1}, { 11, 2},
+{ 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2},
+{ 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1},
+{ 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1}, { 29, 1}, { 30, 1}, { 31, 1},
+{ 32, 1}, { 33, 1}, { 34, 1}, { 35, 1}, { 36, 1}, { 37, 1}, { 38, 1}, { 39, 1},
+{ 40, 1}, { 41, 1}, { 42, 1}, { 43, 1}
+},
+{
+{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
+{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
+{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 0, 24},
+{ 0, 25}, { 0, 26}, { 0, 27}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5},
+{ 1, 6}, { 1, 7}, { 1, 8}, { 1, 9}, { 1, 10}, { 2, 1}, { 2, 2}, { 2, 3},
+{ 2, 4}, { 2, 5}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, { 4, 1}, { 4, 2},
+{ 4, 3}, { 5, 1}, { 5, 2}, { 5, 3}, { 6, 1}, { 6, 2}, { 6, 3}, { 7, 1},
+{ 7, 2}, { 7, 3}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 11, 1},
+{ 12, 1}, { 13, 1}, { 14, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5},
+{ 0, 6}, { 0, 7}, { 0, 8}, { 1, 1}, { 1, 2}, { 1, 3}, { 2, 1}, { 2, 2},
+{ 3, 1}, { 3, 2}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2},
+{ 7, 1}, { 8, 1}, { 9, 1}, { 10, 1}, { 11, 1}, { 12, 1}, { 13, 1}, { 14, 1},
+{ 15, 1}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}
+},
+{
+{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
+{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4},
+{ 1, 5}, { 1, 6}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 3, 1}, { 3, 2},
+{ 3, 3}, { 4, 1}, { 4, 2}, { 4, 3}, { 5, 1}, { 5, 2}, { 5, 3}, { 6, 1},
+{ 6, 2}, { 6, 3}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2},
+{ 10, 1}, { 10, 2}, { 11, 1}, { 12, 1}, { 13, 1}, { 14, 1}, { 15, 1}, { 16, 1},
+{ 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1}, { 24, 1},
+{ 25, 1}, { 26, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 1, 1}, { 1, 2}, { 2, 1},
+{ 3, 1}, { 4, 1}, { 5, 1}, { 6, 1}, { 7, 1}, { 8, 1}, { 9, 1}, { 10, 1},
+{ 11, 1}, { 12, 1}, { 13, 1}, { 14, 1}, { 15, 1}, { 16, 1}, { 17, 1}, { 18, 1},
+{ 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1},
+{ 27, 1}, { 28, 1}, { 29, 1}, { 30, 1}, { 31, 1}, { 32, 1}, { 33, 1}, { 34, 1},
+{ 35, 1}, { 36, 1}, { 37, 1}, { 38, 1}, { 39, 1}, { 40, 1}
+},
+{
+{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
+{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
+{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 0, 24},
+{ 0, 25}, { 0, 26}, { 0, 27}, { 0, 28}, { 0, 29}, { 0, 30}, { 0, 31}, { 0, 32},
+{ 0, 33}, { 0, 34}, { 0, 35}, { 0, 36}, { 0, 37}, { 0, 38}, { 0, 39}, { 0, 40},
+{ 0, 41}, { 0, 42}, { 0, 43}, { 0, 44}, { 0, 45}, { 0, 46}, { 0, 47}, { 0, 48},
+{ 0, 49}, { 0, 50}, { 0, 51}, { 0, 52}, { 0, 53}, { 0, 54}, { 0, 55}, { 0, 56},
+{ 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8},
+{ 1, 9}, { 1, 10}, { 1, 11}, { 1, 12}, { 1, 13}, { 1, 14}, { 1, 15}, { 1, 16},
+{ 1, 17}, { 1, 18}, { 1, 19}, { 1, 20}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4},
+{ 2, 5}, { 2, 6}, { 2, 7}, { 2, 8}, { 2, 9}, { 2, 10}, { 3, 1}, { 3, 2},
+{ 3, 3}, { 3, 4}, { 3, 5}, { 3, 6}, { 3, 7}, { 4, 1}, { 4, 2}, { 4, 3},
+{ 4, 4}, { 4, 5}, { 4, 6}, { 5, 1}, { 5, 2}, { 5, 3}, { 5, 4}, { 5, 5},
+{ 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, { 7, 1}, { 7, 2}, { 7, 3}, { 8, 1},
+{ 8, 2}, { 8, 3}, { 9, 1}, { 9, 2}, { 9, 3}, { 10, 1}, { 10, 2}, { 11, 1},
+{ 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 0, 1}, { 0, 2},
+{ 0, 3}, { 0, 4}, { 1, 1}, { 1, 2}, { 1, 3}, { 2, 1}, { 2, 2}, { 2, 3},
+{ 3, 1}, { 3, 2}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2},
+{ 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 10, 2},
+{ 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2},
+{ 15, 1}, { 16, 1}
+},
+{
+{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
+{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
+{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 0, 24},
+{ 0, 25}, { 0, 26}, { 0, 27}, { 0, 28}, { 0, 29}, { 0, 30}, { 0, 31}, { 0, 32},
+{ 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8},
+{ 1, 9}, { 1, 10}, { 1, 11}, { 1, 12}, { 1, 13}, { 2, 1}, { 2, 2}, { 2, 3},
+{ 2, 4}, { 2, 5}, { 2, 6}, { 2, 7}, { 2, 8}, { 3, 1}, { 3, 2}, { 3, 3},
+{ 3, 4}, { 3, 5}, { 3, 6}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5},
+{ 5, 1}, { 5, 2}, { 5, 3}, { 5, 4}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4},
+{ 7, 1}, { 7, 2}, { 7, 3}, { 8, 1}, { 8, 2}, { 8, 3}, { 9, 1}, { 9, 2},
+{ 9, 3}, { 10, 1}, { 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1},
+{ 13, 2}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2}, { 16, 1}, { 16, 2}, { 17, 1},
+{ 17, 2}, { 18, 1}, { 18, 2}, { 19, 1}, { 19, 2}, { 20, 1}, { 20, 2}, { 21, 1},
+{ 21, 2}, { 22, 1}, { 22, 2}, { 23, 1}, { 24, 1}, { 0, 1}, { 0, 2}, { 0, 3},
+{ 0, 4}, { 1, 1}, { 1, 2}, { 1, 3}, { 2, 1}, { 2, 2}, { 2, 3}, { 3, 1},
+{ 3, 2}, { 3, 3}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2},
+{ 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 10, 2},
+{ 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2},
+{ 15, 1}, { 15, 2}, { 16, 1}, { 16, 2}, { 17, 1}, { 17, 2}, { 18, 1}, { 18, 2},
+{ 19, 1}, { 19, 2}, { 20, 1}, { 20, 2}, { 21, 1}, { 21, 2}, { 22, 1}, { 22, 2},
+{ 23, 1}, { 23, 2}, { 24, 1}, { 24, 2}, { 25, 1}, { 25, 2}, { 26, 1}, { 26, 2},
+{ 27, 1}, { 27, 2}, { 28, 1}, { 28, 2}, { 29, 1}, { 30, 1}
+}
+};
+
+static const uint8_t vc1_delta_level_table[AC_MODES][31] = {
+{
+ 19, 15, 12, 11, 6, 5, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 2, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1
+},
+{
+ 23, 11, 8, 7, 5, 5, 4, 4, 3, 3,
+ 3, 3, 2, 2, 2, 2, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1
+},
+{
+ 16, 11, 8, 7, 5, 4, 4, 3, 3, 3,
+ 3, 3, 3, 3, 2, 2, 1, 1, 1, 1,
+ 1
+},
+{
+ 14, 9, 5, 4, 4, 4, 3, 3, 3, 3,
+ 3, 3, 3, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1
+},
+{
+ 27, 10, 5, 4, 3, 3, 3, 3, 2, 2,
+ 1, 1, 1, 1, 1
+},
+{
+ 12, 6, 4, 3, 3, 3, 3, 2, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1
+},
+{
+ 56, 20, 10, 7, 6, 5, 4, 3, 3, 3,
+ 2, 2, 2, 2, 1
+},
+{
+ 32, 13, 8, 6, 5, 4, 4, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 1, 1
+}
+};
+
+static const uint8_t vc1_last_delta_level_table[AC_MODES][44] = {
+{
+ 6, 5, 4, 4, 3, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1
+},
+{
+ 9, 5, 4, 4, 3, 3, 3, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1
+},
+{
+ 4, 4, 3, 3, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1
+},
+{
+ 5, 4, 3, 3, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1
+},
+{
+ 8, 3, 2, 2, 2, 2, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1
+},
+{
+ 3, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1
+},
+{
+ 4, 3, 3, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 1
+},
+{
+ 4, 3, 3, 3, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1
+}
+};
+
+static const uint8_t vc1_delta_run_table[AC_MODES][57] = {
+{
+ -1, 30, 17, 15, 9, 5, 4, 3, 3, 3,
+ 3, 3, 2, 1, 1, 1, 0, 0, 0,
+ 0
+},
+{
+ -1, 26, 16, 11, 7, 5, 3, 3, 2, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+},
+{
+ -1, 20, 15, 13, 6, 4, 3, 3, 2, 1,
+ 1, 1, 0, 0, 0, 0, 0
+},
+{
+ -1, 29, 15, 12, 5, 2, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0
+},
+{
+ -1, 14, 9, 7, 3, 2, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+},
+{
+ -1, 26, 10, 6, 2, 1, 1, 0, 0, 0,
+ 0, 0, 0
+},
+{
+ -1, 14, 13, 9, 6, 5, 4, 3, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0
+},
+{
+ -1, 24, 22, 9, 6, 4, 3, 2, 2, 1,
+ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
+}
+};
+
+static const uint8_t vc1_last_delta_run_table[AC_MODES][10] = {
+{
+ -1, 37, 15, 4, 3, 1, 0
+},
+{
+ -1, 36, 14, 6, 3, 1, 0, 0, 0,
+ 0
+},
+{
+ -1, 26, 13, 3, 1
+},
+{
+ -1, 43, 15, 3, 1, 0
+},
+{
+ -1, 20, 6, 1, 0, 0, 0, 0, 0
+},
+{
+ -1, 40, 1, 0
+},
+{
+ -1, 16, 14, 2, 0
+},
+{
+ -1, 30, 28, 3, 0
+}
+};
Modified: trunk/libavcodec/vc1data.h
==============================================================================
--- trunk/libavcodec/vc1data.h (original)
+++ trunk/libavcodec/vc1data.h Tue Jun 27 05:11:51 2006
@@ -1,6 +1,6 @@
/**
* @file vc1data.h
- * VC1 tables.
+ * VC-1 tables.
*/
#ifndef VC1DATA_H
@@ -167,10 +167,65 @@
};
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
+ 0, 2, 4, 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 */
+#if 1 // Looks like original tables are not conforming to standard at all. Are they used for old WMV?
+static const uint16_t vc1_cbpcy_p_codes[4][64] = {
+ {
+ 0, 6, 15, 13, 13, 11, 3, 13, 5, 8, 49, 10, 12, 114, 102, 119,
+ 1, 54, 96, 8, 10, 111, 5, 15, 12, 10, 2, 12, 13, 115, 53, 63,
+ 1, 7, 1, 7, 14, 12, 4, 14, 1, 9, 97, 11, 7, 58, 52, 62,
+ 4, 103, 1, 9, 11, 56, 101, 118, 4, 110, 100, 30, 2, 5, 4, 3
+ },
+ {
+ 0, 9, 1, 18, 5, 14, 237, 26, 3, 121, 3, 22, 13, 16, 6, 30,
+ 2, 10, 1, 20, 12, 241, 5, 28, 16, 12, 3, 24, 28, 124, 239, 247,
+ 1, 240, 1, 19, 18, 15, 4, 27, 1, 122, 2, 23, 1, 17, 7, 31,
+ 1, 11, 2, 21, 19, 246, 238, 29, 17, 13, 236, 25, 58, 63, 8, 125
+ },
+ {
+ 0, 201, 25, 231, 5, 221, 1, 3, 2, 414, 2, 241, 16, 225, 195, 492,
+ 2, 412, 1, 240, 7, 224, 98, 245, 1, 220, 96, 5, 9, 230, 101, 247,
+ 1, 102, 1, 415, 24, 3, 2, 244, 3, 54, 3, 484, 17, 114, 200, 493,
+ 3, 413, 1, 4, 13, 113, 99, 485, 4, 111, 194, 243, 5, 29, 26, 31
+ },
+ {
+ 0, 28, 12, 44, 3, 36, 20, 52, 2, 32, 16, 48, 8, 40, 24, 28,
+ 1, 30, 14, 46, 6, 38, 22, 54, 3, 34, 18, 50, 10, 42, 26, 30,
+ 1, 29, 13, 45, 5, 37, 21, 53, 2, 33, 17, 49, 9, 41, 25, 29,
+ 1, 31, 15, 47, 7, 39, 23, 55, 4, 35, 19, 51, 11, 43, 27, 31
+ }
+};
+
+static const uint8_t vc1_cbpcy_p_bits[4][64] = {
+ {
+ 13, 13, 7, 13, 7, 13, 13, 12, 6, 13, 7, 12, 6, 8, 8, 8,
+ 5, 7, 8, 12, 6, 8, 13, 12, 7, 13, 13, 12, 6, 8, 7, 7,
+ 6, 13, 8, 12, 7, 13, 13, 12, 7, 13, 8, 12, 5, 7, 7, 7,
+ 6, 8, 13, 12, 6, 7, 8, 8, 5, 8, 8, 6, 3, 3, 3, 2
+ },
+ {
+ 14, 13, 8, 13, 3, 13, 8, 13, 3, 7, 8, 13, 4, 13, 13, 13,
+ 3, 13, 13, 13, 4, 8, 13, 13, 5, 13, 13, 13, 5, 7, 8, 8,
+ 3, 8, 14, 13, 5, 13, 13, 13, 4, 7, 13, 13, 6, 13, 13, 13,
+ 5, 13, 8, 13, 5, 8, 8, 13, 5, 13, 8, 13, 6, 6, 13, 7
+ },
+ {
+ 13, 8, 6, 8, 4, 8, 13, 12, 4, 9, 8, 8, 5, 8, 8, 9,
+ 5, 9, 10, 8, 4, 8, 7, 8, 6, 8, 7, 13, 4, 8, 7, 8,
+ 5, 7, 8, 9, 6, 13, 13, 8, 4, 6, 8, 9, 5, 7, 8, 9,
+ 5, 9, 9, 13, 5, 7, 7, 9, 4, 7, 8, 8, 3, 5, 5, 5
+ },
+ {
+ 9, 9, 9, 9, 2, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 8,
+ 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
+ 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8
+ }
+};
+#else
static const uint16_t vc1_cbpcy_p_codes[4][64] = {
{
0, 1, 1, 4, 5, 1, 12, 4, 13, 14, 10, 11, 12, 7, 13, 2,
@@ -223,6 +278,7 @@
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8
}
};
+#endif
/* MacroBlock Transform Type: 7.1.3.11, p89
* 8x8:B
@@ -402,5 +458,153 @@
/* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */
/* Scantables/ZZ scan are at 11.9 (p262) and 8.1.1.12 (p10) */
-
+static const int8_t vc1_normal_zz[64] = {
+ 0, 8, 1, 2, 9, 16, 24, 17,
+ 10, 3, 4, 11, 18, 25, 32, 40,
+ 33, 48, 26, 19, 12, 5, 6, 13,
+ 20, 27, 34, 41, 56, 49, 57, 42,
+ 35, 28, 21, 14, 7, 15, 22, 29,
+ 36, 43, 50, 58, 51, 59, 44, 37,
+ 30, 23, 31, 38, 45, 52, 60, 53,
+ 61, 46, 39, 47, 54, 62, 55, 63
+};
+
+static const int8_t vc1_horizontal_zz [64] = /* Table 227 */
+{
+ 0, 1, 8, 2, 3, 9, 16, 24,
+ 17, 10, 4, 5, 11, 18, 25, 32,
+ 40, 48, 33, 26, 19, 12, 6, 7,
+ 13, 20, 27, 34, 41, 56, 49, 57,
+ 42, 35, 28, 21, 14, 15, 22, 29,
+ 36, 43, 50, 58, 51, 44, 37, 30,
+ 23, 31, 38, 45, 52, 59, 60, 53,
+ 46, 39, 47, 54, 61, 62, 55, 63
+};
+
+static const int8_t vc1_vertical_zz [64] = /* Table 228 */
+{
+ 0, 8, 16, 1, 24, 32, 40, 9,
+ 2, 3, 10, 17, 25, 48, 56, 41,
+ 33, 26, 18, 11, 4, 5, 12, 19,
+ 27, 34, 49, 57, 50, 42, 35, 28,
+ 20, 13, 6, 7, 14, 21, 29, 36,
+ 43, 51, 58, 59, 52, 44, 37, 30,
+ 22, 15, 23, 31, 38, 45, 60, 53,
+ 46, 39, 47, 54, 61, 62, 55, 63
+};
+
+static const int8_t vc1_simple_progressive_8x8_zz [64] =
+/* Table 229 */
+{
+ 0, 8, 1, 2, 9, 16, 24, 17,
+ 10, 3, 4, 11, 18, 25, 32, 40,
+ 48, 56, 41, 33, 26, 19, 12, 5,
+ 6, 13, 20, 27, 34, 49, 57, 58,
+ 50, 42, 35, 28, 21, 14, 7, 15,
+ 22, 29, 36, 43, 51, 59, 60, 52,
+ 44, 37, 30, 23, 31, 38, 45, 53,
+ 61, 62, 54, 46, 39, 47, 55, 63
+};
+
+static const int8_t vc1_simple_progressive_8x4_zz [32] = /* Table 230 */
+{
+ 0, 1, 2, 8, 3, 9, 10, 16,
+ 4, 11, 17, 24, 18, 12, 5, 19,
+ 25, 13, 20, 26, 27, 6, 21, 28,
+ 14, 22, 29, 7, 30, 15, 23, 31
+};
+
+static const int8_t vc1_simple_progressive_4x8_zz [32] = /* Table 231 */
+{
+ 0, 8, 1, 16,
+ 9, 24, 17, 2,
+ 32, 10, 25, 40,
+ 18, 48, 33, 26,
+ 56, 41, 34, 3,
+ 49, 57, 11, 42,
+ 19, 50, 27, 58,
+ 35, 43, 51, 59
+};
+
+/* Table 232 */
+static const int8_t vc1_simple_progressive_4x4_zz [16] =
+{
+ 0, 8, 16, 1,
+ 9, 24, 17, 2,
+ 10, 18, 25, 3,
+ 11, 26, 19, 27
+};
+
+static const int8_t vc1_adv_progressive_8x4_zz [32] = /* Table 233 */
+{
+ 0, 8, 1, 16, 2, 9, 10, 3,
+ 24, 17, 4, 11, 18, 12, 5, 19,
+ 25, 13, 20, 26, 27, 6, 21, 28,
+ 14, 22, 29, 7, 30, 15, 23, 31
+};
+
+static const int8_t vc1_adv_progressive_4x8_zz [32] = /* Table 234 */
+{
+ 0, 1, 8, 2,
+ 9, 16, 17, 24,
+ 10, 32, 25, 18,
+ 40, 3, 33, 26,
+ 48, 11, 56, 41,
+ 34, 49, 57, 42,
+ 19, 50, 27, 58,
+ 35, 43, 51, 59
+};
+
+static const int8_t vc1_adv_interlaced_8x8_zz [64] = /* Table 235 */
+{
+ 0, 8, 1, 16, 24, 9, 2, 32,
+ 40, 48, 56, 17, 10, 3, 25, 18,
+ 11, 4, 33, 41, 49, 57, 26, 34,
+ 42, 50, 58, 19, 12, 5, 27, 20,
+ 13, 6, 35, 28, 21, 14, 7, 15,
+ 22, 29, 36, 43, 51, 59, 60, 52,
+ 44, 37, 30, 23, 31, 38, 45, 53,
+ 61, 62, 54, 46, 39, 47, 55, 63
+};
+
+static const int8_t vc1_adv_interlaced_8x4_zz [32] = /* Table 236 */
+{
+ 0, 8, 16, 24, 1, 9, 2, 17,
+ 25, 10, 3, 18, 26, 4, 11, 19,
+ 12, 5, 13, 20, 27, 6, 21, 28,
+ 14, 22, 29, 7, 30, 15, 23, 31
+};
+
+static const int8_t vc1_adv_interlaced_4x8_zz [32] = /* Table 237 */
+{
+ 0, 1, 2, 8,
+ 16, 9, 24, 17,
+ 10, 3, 32, 40,
+ 48, 56, 25, 18,
+ 33, 26, 41, 34,
+ 49, 57, 11, 42,
+ 19, 50, 27, 58,
+ 35, 43, 51, 59
+};
+
+static const int8_t vc1_adv_interlaced_4x4_zz [16] = /* Table 238 */
+{
+ 0, 8, 16, 24,
+ 1, 9, 17, 2,
+ 25, 10, 18, 3,
+ 26, 11, 19, 27
+};
+
+
+/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */
+static const int32_t vc1_dqscale[63] = {
+0x40000, 0x20000, 0x15555, 0x10000, 0xCCCD, 0xAAAB, 0x9249, 0x8000,
+ 0x71C7, 0x6666, 0x5D17, 0x5555, 0x4EC5, 0x4925, 0x4444, 0x4000,
+ 0x3C3C, 0x38E4, 0x35E5, 0x3333, 0x30C3, 0x2E8C, 0x2C86, 0x2AAB,
+ 0x28F6, 0x2762, 0x25ED, 0x2492, 0x234F, 0x2222, 0x2108, 0x2000,
+ 0x1F08, 0x1E1E, 0x1D42, 0x1C72, 0x1BAD, 0x1AF3, 0x1A42, 0x199A,
+ 0x18FA, 0x1862, 0x17D0, 0x1746, 0x16C1, 0x1643, 0x15CA, 0x1555,
+ 0x14E6, 0x147B, 0x1414, 0x13B1, 0x1352, 0x12F7, 0x129E, 0x1249,
+ 0x11F7, 0x11A8, 0x115B, 0x1111, 0x10C9, 0x1084, 0x1000
+};
#endif /* VC1DATA_H */
More information about the ffmpeg-cvslog
mailing list