📄 vp3.c
字号:
/* * Copyright (C) 2003-2004 the ffmpeg project * * This file is part of FFmpeg. * * FFmpeg 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.1 of the License, or (at your option) any later version. * * FFmpeg 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 FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//** * @file vp3.c * On2 VP3 Video Decoder * * VP3 Video Decoder by Mike Melanson (mike at multimedia.cx) * For more information about the VP3 coding process, visit: * http://wiki.multimedia.cx/index.php?title=On2_VP3 * * Theora decoder by Alex Beregszaszi */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "avcodec.h"#include "dsputil.h"#include "bitstream.h"#include "vp3data.h"#include "xiph.h"#define FRAGMENT_PIXELS 8/* * Debugging Variables * * Define one or more of the following compile-time variables to 1 to obtain * elaborate information about certain aspects of the decoding process. * * KEYFRAMES_ONLY: set this to 1 to only see keyframes (VP3 slideshow mode) * DEBUG_VP3: high-level decoding flow * DEBUG_INIT: initialization parameters * DEBUG_DEQUANTIZERS: display how the dequanization tables are built * DEBUG_BLOCK_CODING: unpacking the superblock/macroblock/fragment coding * DEBUG_MODES: unpacking the coding modes for individual fragments * DEBUG_VECTORS: display the motion vectors * DEBUG_TOKEN: display exhaustive information about each DCT token * DEBUG_VLC: display the VLCs as they are extracted from the stream * DEBUG_DC_PRED: display the process of reversing DC prediction * DEBUG_IDCT: show every detail of the IDCT process */#define KEYFRAMES_ONLY 0#define DEBUG_VP3 0#define DEBUG_INIT 0#define DEBUG_DEQUANTIZERS 0#define DEBUG_BLOCK_CODING 0#define DEBUG_MODES 0#define DEBUG_VECTORS 0#define DEBUG_TOKEN 0#define DEBUG_VLC 0#define DEBUG_DC_PRED 0#define DEBUG_IDCT 0#if DEBUG_VP3#define debug_vp3(args...) av_log(NULL, AV_LOG_DEBUG, ## args)#elsestatic inline void debug_vp3(const char *format, ...) { }#endif#if DEBUG_INIT#define debug_init(args...) av_log(NULL, AV_LOG_DEBUG, ## args)#elsestatic inline void debug_init(const char *format, ...) { }#endif#if DEBUG_DEQUANTIZERS#define debug_dequantizers(args...) av_log(NULL, AV_LOG_DEBUG, ## args)#elsestatic inline void debug_dequantizers(const char *format, ...) { }#endif#if DEBUG_BLOCK_CODING#define debug_block_coding(args...) av_log(NULL, AV_LOG_DEBUG, ## args)#elsestatic inline void debug_block_coding(const char *format, ...) { }#endif#if DEBUG_MODES#define debug_modes(args...) av_log(NULL, AV_LOG_DEBUG, ## args)#elsestatic inline void debug_modes(const char *format, ...) { }#endif#if DEBUG_VECTORS#define debug_vectors(args...) av_log(NULL, AV_LOG_DEBUG, ## args)#elsestatic inline void debug_vectors(const char *format, ...) { }#endif#if DEBUG_TOKEN#define debug_token(args...) av_log(NULL, AV_LOG_DEBUG, ## args)#elsestatic inline void debug_token(const char *format, ...) { }#endif#if DEBUG_VLC#define debug_vlc(args...) av_log(NULL, AV_LOG_DEBUG, ## args)#elsestatic inline void debug_vlc(const char *format, ...) { }#endif#if DEBUG_DC_PRED#define debug_dc_pred(args...) av_log(NULL, AV_LOG_DEBUG, ## args)#elsestatic inline void debug_dc_pred(const char *format, ...) { }#endif#if DEBUG_IDCT#define debug_idct(args...) av_log(NULL, AV_LOG_DEBUG, ## args)#elsestatic inline void debug_idct(const char *format, ...) { }#endiftypedef struct Coeff { struct Coeff *next; DCTELEM coeff; uint8_t index;} Coeff;//FIXME split things out into their own arraystypedef struct Vp3Fragment { Coeff *next_coeff; /* address of first pixel taking into account which plane the fragment * lives on as well as the plane stride */ int first_pixel; /* this is the macroblock that the fragment belongs to */ uint16_t macroblock; uint8_t coding_method; int8_t motion_x; int8_t motion_y;} Vp3Fragment;#define SB_NOT_CODED 0#define SB_PARTIALLY_CODED 1#define SB_FULLY_CODED 2#define MODE_INTER_NO_MV 0#define MODE_INTRA 1#define MODE_INTER_PLUS_MV 2#define MODE_INTER_LAST_MV 3#define MODE_INTER_PRIOR_LAST 4#define MODE_USING_GOLDEN 5#define MODE_GOLDEN_MV 6#define MODE_INTER_FOURMV 7#define CODING_MODE_COUNT 8/* special internal mode */#define MODE_COPY 8/* There are 6 preset schemes, plus a free-form scheme */static const int ModeAlphabet[6][CODING_MODE_COUNT] ={ /* scheme 1: Last motion vector dominates */ { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, MODE_INTER_PLUS_MV, MODE_INTER_NO_MV, MODE_INTRA, MODE_USING_GOLDEN, MODE_GOLDEN_MV, MODE_INTER_FOURMV }, /* scheme 2 */ { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, MODE_INTER_NO_MV, MODE_INTER_PLUS_MV, MODE_INTRA, MODE_USING_GOLDEN, MODE_GOLDEN_MV, MODE_INTER_FOURMV }, /* scheme 3 */ { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV, MODE_INTER_PRIOR_LAST, MODE_INTER_NO_MV, MODE_INTRA, MODE_USING_GOLDEN, MODE_GOLDEN_MV, MODE_INTER_FOURMV }, /* scheme 4 */ { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV, MODE_INTER_NO_MV, MODE_INTER_PRIOR_LAST, MODE_INTRA, MODE_USING_GOLDEN, MODE_GOLDEN_MV, MODE_INTER_FOURMV }, /* scheme 5: No motion vector dominates */ { MODE_INTER_NO_MV, MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, MODE_INTER_PLUS_MV, MODE_INTRA, MODE_USING_GOLDEN, MODE_GOLDEN_MV, MODE_INTER_FOURMV }, /* scheme 6 */ { MODE_INTER_NO_MV, MODE_USING_GOLDEN, MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, MODE_INTER_PLUS_MV, MODE_INTRA, MODE_GOLDEN_MV, MODE_INTER_FOURMV },};#define MIN_DEQUANT_VAL 2typedef struct Vp3DecodeContext { AVCodecContext *avctx; int theora, theora_tables; int version; int width, height; AVFrame golden_frame; AVFrame last_frame; AVFrame current_frame; int keyframe; DSPContext dsp; int flipped_image; int qis[3]; int nqis; int quality_index; int last_quality_index; int superblock_count; int superblock_width; int superblock_height; int y_superblock_width; int y_superblock_height; int c_superblock_width; int c_superblock_height; int u_superblock_start; int v_superblock_start; unsigned char *superblock_coding; int macroblock_count; int macroblock_width; int macroblock_height; int fragment_count; int fragment_width; int fragment_height; Vp3Fragment *all_fragments; uint8_t *coeff_counts; Coeff *coeffs; Coeff *next_coeff; int fragment_start[3]; ScanTable scantable; /* tables */ uint16_t coded_dc_scale_factor[64]; uint32_t coded_ac_scale_factor[64]; uint8_t base_matrix[384][64]; uint8_t qr_count[2][3]; uint8_t qr_size [2][3][64]; uint16_t qr_base[2][3][64]; /* this is a list of indexes into the all_fragments array indicating * which of the fragments are coded */ int *coded_fragment_list; int coded_fragment_list_index; int pixel_addresses_initialized; VLC dc_vlc[16]; VLC ac_vlc_1[16]; VLC ac_vlc_2[16]; VLC ac_vlc_3[16]; VLC ac_vlc_4[16]; VLC superblock_run_length_vlc; VLC fragment_run_length_vlc; VLC mode_code_vlc; VLC motion_vector_vlc; /* these arrays need to be on 16-byte boundaries since SSE2 operations * index into them */ DECLARE_ALIGNED_16(int16_t, qmat[2][4][64]); //<qmat[is_inter][plane] /* This table contains superblock_count * 16 entries. Each set of 16 * numbers corresponds to the fragment indexes 0..15 of the superblock. * An entry will be -1 to indicate that no entry corresponds to that * index. */ int *superblock_fragments; /* This table contains superblock_count * 4 entries. Each set of 4 * numbers corresponds to the macroblock indexes 0..3 of the superblock. * An entry will be -1 to indicate that no entry corresponds to that * index. */ int *superblock_macroblocks; /* This table contains macroblock_count * 6 entries. Each set of 6 * numbers corresponds to the fragment indexes 0..5 which comprise * the macroblock (4 Y fragments and 2 C fragments). */ int *macroblock_fragments; /* This is an array that indicates how a particular macroblock * is coded. */ unsigned char *macroblock_coding; int first_coded_y_fragment; int first_coded_c_fragment; int last_coded_y_fragment; int last_coded_c_fragment; uint8_t edge_emu_buffer[9*2048]; //FIXME dynamic alloc int8_t qscale_table[2048]; //FIXME dynamic alloc (width+15)/16 /* Huffman decode */ int hti; unsigned int hbits; int entries; int huff_code_size; uint16_t huffman_table[80][32][2]; uint32_t filter_limit_values[64]; int bounding_values_array[256];} Vp3DecodeContext;/************************************************************************ * VP3 specific functions ************************************************************************//* * This function sets up all of the various blocks mappings: * superblocks <-> fragments, macroblocks <-> fragments, * superblocks <-> macroblocks * * Returns 0 is successful; returns 1 if *anything* went wrong. */static int init_block_mapping(Vp3DecodeContext *s){ int i, j;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -