📄 vc9.c
字号:
/* * VC-9 and WMV3 decoder * Copyright (c) 2005 Anonymous * Copyright (c) 2005 Alex Beregszaszi * Copyright (c) 2005 Michael Niedermayer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * *//** * @file vc9.c * VC-9 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 "vc9data.h"#undef NDEBUG#include <assert.h>extern const uint32_t ff_table0_dc_lum[120][2], ff_table1_dc_lum[120][2];extern const uint32_t ff_table0_dc_chroma[120][2], ff_table1_dc_chroma[120][2];extern VLC ff_msmp4_dc_luma_vlc[2], ff_msmp4_dc_chroma_vlc[2];#define MB_INTRA_VLC_BITS 9extern VLC ff_msmp4_mb_i_vlc;#define DC_VLC_BITS 9static 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//@}/** 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//@}/** 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//@}/** @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//@}/** 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//@}/** 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//@}/** @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//@}/** 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 }};/** One more frame type */#define BI_TYPE 7static const int fps_nr[5] = { 24, 25, 30, 50, 60 }, fps_dr[2] = { 1000, 1001 };static const uint8_t pquant_table[3][32] = { { /* Implicit quantizer */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31 }, { /* Explicit quantizer, pquantizer uniform */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }, { /* Explicit quantizer, pquantizer non-uniform */ 0, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 31 }};/** @name VC-9 VLC tables and defines * @todo TODO move this into the context *///@{#define VC9_BFRACTION_VLC_BITS 7static VLC vc9_bfraction_vlc;#define VC9_IMODE_VLC_BITS 4static VLC vc9_imode_vlc;#define VC9_NORM2_VLC_BITS 3static VLC vc9_norm2_vlc;#define VC9_NORM6_VLC_BITS 9static VLC vc9_norm6_vlc;/* Could be optimized, one table only needs 8 bits */#define VC9_TTMB_VLC_BITS 9 //12static VLC vc9_ttmb_vlc[3];#define VC9_MV_DIFF_VLC_BITS 9 //15static VLC vc9_mv_diff_vlc[4];#define VC9_CBPCY_P_VLC_BITS 9 //14static VLC vc9_cbpcy_p_vlc[4];#define VC9_4MV_BLOCK_PATTERN_VLC_BITS 6static VLC vc9_4mv_block_pattern_vlc[4];#define VC9_TTBLK_VLC_BITS 5static VLC vc9_ttblk_vlc[3];#define VC9_SUBBLKPAT_VLC_BITS 6static VLC vc9_subblkpat_vlc[3];//@}/** 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 * @fixme For now, stride=width * @warning Data are bits, either 1 or 0 */typedef struct BitPlane { uint8_t *data; ///< Data buffer int width; ///< Width of the buffer int stride; ///< Stride of the buffer int height; ///< Plane height uint8_t is_raw; ///< Bit values must be read at MB level} BitPlane;/** The VC9 Context * @fixme Change size wherever another size is more efficient * Many members are only used for Advanced Profile */typedef struct VC9Context{ MpegEncContext s; /** Simple/Main Profile sequence header */ //@{ int res_sm; ///< reserved, 2b int res_x8; ///< reserved int multires; ///< frame-level RESPIC syntax element present int res_fasttx; ///< reserved, always 1 int res_transtab; ///< reserved, always 0 int rangered; ///< RANGEREDFRM (range reduction) syntax element present ///< at frame level int res_rtm_flag; ///< reserved, set to 1 int reserved; ///< reserved //@}#if HAS_ADVANCED_PROFILE /** Advanced Profile */ //@{ int level; ///< 3bits, for Advanced/Simple Profile, provided by TS layer int chromaformat; ///< 2bits, 2=4:2:0, only defined int postprocflag; ///< Per-frame processing suggestion flag present int broadcast; ///< TFF/RFF present int interlace; ///< Progressive/interlaced (RPTFTM syntax element) int tfcntrflag; ///< TFCNTR present int panscanflag; ///< NUMPANSCANWIN, TOPLEFT{X,Y}, BOTRIGHT{X,Y} present int extended_dmv; ///< Additional extended dmv range at P/B frame-level int color_prim; ///< 8bits, chroma coordinates of the color primaries int transfer_char; ///< 8bits, Opto-electronic transfer characteristics int matrix_coef; ///< 8bits, Color primaries->YCbCr transform matrix 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 */ //@{ int profile; ///< 2bits, Profile int frmrtq_postproc; ///< 3bits, int bitrtq_postproc; ///< 5bits, quantized framerate-based postprocessing strength int fastuvmc; ///< Rounding of qpel vector to hpel ? (not in Simple) int extended_mv; ///< Ext MV in P/B (not in Simple) int dquant; ///< How qscale varies with MBs, 2bits (not in Simple) int vstransform; ///< variable-size [48]x[48] transform type + info int overlap; ///< overlapped transforms in use int quantizer_mode; ///< 2bits, quantizer mode used for sequence, see QUANT_* int finterpflag; ///< INTERPFRM present //@} /** Frame decoding info for all profiles */ //@{ uint8_t mv_mode; ///< MV coding monde 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) uint8_t pq, altpq; ///< Current/alternate frame quantizer scale /** pquant parameters */ //@{ uint8_t dquantfrm; uint8_t dqprofile; uint8_t dqsbedge; uint8_t dqbilevel; //@} /** AC coding set indexes * @see 8.1.1.10, p(1)10 */ //@{ int c_ac_table_index; ///< Chroma index from ACFRM element int y_ac_table_index; ///< Luma index from AC2FRM element //@} int ttfrm; ///< Transform type info present at frame level uint8_t ttmbf; ///< Transform type flag int ttmb; ///< Transform type uint8_t ttblk4x4; ///< Value of ttblk which indicates a 4x4 transform /** Luma compensation parameters */ //@{ uint8_t lumscale; uint8_t lumshift; //@} int16_t bfraction; ///< Relative position % anchors=> how to scale MVs uint8_t halfpq; ///< Uniform quant over image and qp+.5 uint8_t respic; ///< Frame-level flag for resized images int buffer_fullness; ///< HRD info /** Ranges: * -# 0 -> [-64n 63.f] x [-32, 31.f] * -# 1 -> [-128, 127.f] x [-64, 63.f] * -# 2 -> [-512, 511.f] x [-128, 127.f] * -# 3 -> [-1024, 1023.f] x [-256, 255.f] */ uint8_t mvrange; uint8_t pquantizer; ///< Uniform (over sequence) quantizer in use uint8_t *previous_line_cbpcy; ///< To use for predicted CBPCY VLC *cbpcy_vlc; ///< CBPCY VLC table int tt_index; ///< Index for Transform Type tables BitPlane mv_type_mb_plane; ///< bitplane for mv_type == (4MV) BitPlane skip_mb_plane; ///< bitplane for skipped MBs BitPlane direct_mb_plane; ///< bitplane for "direct" MBs /** Frame decoding info for S/M profiles only */ //@{ uint8_t rangeredfrm; ///< out_sample = CLIP((in_sample-128)*2+128) uint8_t interpfrm; //@}#if HAS_ADVANCED_PROFILE /** Frame decoding info for Advanced profile */ //@{ uint8_t fcm; ///< 0->Progressive, 2->Frame-Interlace, 3->Field-Interlace uint8_t numpanscanwin; uint8_t tfcntr; uint8_t rptfrm, tff, rff; uint16_t topleftx; uint16_t toplefty; uint16_t bottomrightx; uint16_t bottomrighty; uint8_t uvsamp; uint8_t postproc; int hrd_num_leaky_buckets; uint8_t bit_rate_exponent; uint8_t buffer_size_exponent; BitPlane ac_pred_plane; ///< AC prediction flags bitplane BitPlane over_flags_plane; ///< Overflags bitplane uint8_t condover; uint16_t *hrd_rate, *hrd_buffer; uint8_t *hrd_fullness; uint8_t range_mapy_flag; uint8_t range_mapuv_flag; uint8_t range_mapy; uint8_t range_mapuv; //@}#endif} VC9Context;/** * Get unary code of limited length * @fixme FIXME Slow and ugly * @param gb GetBitContext * @param[in] stop The bitstop value (unary code of 1's or 0's) * @param[in] len Maximum length * @return Unary length/index */static int get_prefix(GetBitContext *gb, int stop, int len){#if 1 int i = 0, tmp = !stop; while (i != len && tmp != stop) { tmp = get_bits(gb, 1); i++; } if (i == len && tmp != stop) return len+1; return i;#else unsigned int buf; int log; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); buf=GET_CACHE(re, gb); //Still not sure if (stop) buf = ~buf; log= av_log2(-buf); //FIXME: -? if (log < limit){ LAST_SKIP_BITS(re, gb, log+1); CLOSE_READER(re, gb); return log; } LAST_SKIP_BITS(re, gb, limit); CLOSE_READER(re, gb); return limit;#endif}/** * Init VC-9 specific tables and VC9Context members * @param v The VC9Context to initialize * @return Status */static int vc9_init_common(VC9Context *v){ static int done = 0; int i = 0; /* Set the bit planes */ 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= (vc9_norm6_spec[i][1] << vc9_norm6_spec[i][4]) + vc9_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= vc9_norm6_spec[i][2] + vc9_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(&vc9_bfraction_vlc, VC9_BFRACTION_VLC_BITS, 23, vc9_bfraction_bits, 1, 1, vc9_bfraction_codes, 1, 1, 1); INIT_VLC(&vc9_norm2_vlc, VC9_NORM2_VLC_BITS, 4,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -