📄 vp3.c
字号:
/* * * Copyright (C) 2003 the ffmpeg project * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * VP3 Video Decoder by Mike Melanson (melanson@pcisys.net) * For more information about the VP3 coding process, visit: * http://www.pcisys.net/~melanson/codecs/ * * Theora decoder by Alex Beregszaszi * *//** * @file vp3.c * On2 VP3 Video Decoder */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "common.h"#include "avcodec.h"#include "dsputil.h"#include "mpegvideo.h"#include "dsputil.h"#include "vp3data.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 printf#elsestatic inline void debug_vp3(const char *format, ...) { }#endif#if DEBUG_INIT#define debug_init printf#elsestatic inline void debug_init(const char *format, ...) { }#endif#if DEBUG_DEQUANTIZERS#define debug_dequantizers printf #elsestatic inline void debug_dequantizers(const char *format, ...) { } #endif#if DEBUG_BLOCK_CODING#define debug_block_coding printf #elsestatic inline void debug_block_coding(const char *format, ...) { } #endif#if DEBUG_MODES#define debug_modes printf #elsestatic inline void debug_modes(const char *format, ...) { } #endif#if DEBUG_VECTORS#define debug_vectors printf #elsestatic inline void debug_vectors(const char *format, ...) { } #endif#if DEBUG_TOKEN #define debug_token printf #elsestatic inline void debug_token(const char *format, ...) { } #endif#if DEBUG_VLC#define debug_vlc printf #elsestatic inline void debug_vlc(const char *format, ...) { } #endif#if DEBUG_DC_PRED#define debug_dc_pred printf #elsestatic inline void debug_dc_pred(const char *format, ...) { } #endif#if DEBUG_IDCT#define debug_idct printf #elsestatic inline void debug_idct(const char *format, ...) { } #endiftypedef struct Vp3Fragment { DCTELEM coeffs[64]; int coding_method; int coeff_count; int last_coeff; int motion_x; int motion_y; /* 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 */ int macroblock;} 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 int ModeAlphabet[7][CODING_MODE_COUNT] ={ /* this is the custom scheme */ { 0, 0, 0, 0, 0, 0, 0, 0 }, /* 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 width, height; AVFrame golden_frame; AVFrame last_frame; AVFrame current_frame; int keyframe; DSPContext dsp; 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; int u_fragment_start; int v_fragment_start; /* tables */ uint16_t coded_dc_scale_factor[64]; uint32_t coded_quality_threshold[64]; uint16_t coded_intra_y_dequant[64]; uint16_t coded_intra_c_dequant[64]; uint16_t coded_inter_dequant[64]; /* this is a list of indices into the all_fragments array indicating * which of the fragments are coded */ int *coded_fragment_list; int coded_fragment_list_index; int pixel_addresses_inited; VLC dc_vlc[16]; VLC ac_vlc_1[16]; VLC ac_vlc_2[16]; VLC ac_vlc_3[16]; VLC ac_vlc_4[16]; int16_t intra_y_dequant[64]; int16_t intra_c_dequant[64]; int16_t inter_dequant[64]; /* This table contains superblock_count * 16 entries. Each set of 16 * numbers corresponds to the fragment indices 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 indices 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 indices 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 uint8_t qscale_table[2048]; //FIXME dynamic alloc (width+15)/16} Vp3DecodeContext;/************************************************************************ * VP3 I/DCT ************************************************************************/#define IdctAdjustBeforeShift 8#define xC1S7 64277#define xC2S6 60547#define xC3S5 54491#define xC4S4 46341#define xC5S3 36410#define xC6S2 25080#define xC7S1 12785void vp3_idct_c(int16_t *input_data, int16_t *dequant_matrix, int16_t *output_data){ int32_t intermediate_data[64]; int32_t *ip = intermediate_data; int16_t *op = output_data; int32_t A_, B_, C_, D_, _Ad, _Bd, _Cd, _Dd, E_, F_, G_, H_; int32_t _Ed, _Gd, _Add, _Bdd, _Fd, _Hd; int32_t t1, t2; int i, j; debug_idct("raw coefficient block:\n"); for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { debug_idct(" %5d", input_data[i * 8 + j]); } debug_idct("\n"); } debug_idct("\n"); for (i = 0; i < 64; i++) { j = dezigzag_index[i]; intermediate_data[j] = dequant_matrix[i] * input_data[i]; } debug_idct("dequantized block:\n"); for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { debug_idct(" %5d", intermediate_data[i * 8 + j]); } debug_idct("\n"); } debug_idct("\n"); /* Inverse DCT on the rows now */ for (i = 0; i < 8; i++) { /* Check for non-zero values */ if ( ip[0] | ip[1] | ip[2] | ip[3] | ip[4] | ip[5] | ip[6] | ip[7] ) { t1 = (int32_t)(xC1S7 * ip[1]); t2 = (int32_t)(xC7S1 * ip[7]); t1 >>= 16; t2 >>= 16; A_ = t1 + t2; t1 = (int32_t)(xC7S1 * ip[1]); t2 = (int32_t)(xC1S7 * ip[7]); t1 >>= 16; t2 >>= 16; B_ = t1 - t2; t1 = (int32_t)(xC3S5 * ip[3]); t2 = (int32_t)(xC5S3 * ip[5]); t1 >>= 16; t2 >>= 16; C_ = t1 + t2; t1 = (int32_t)(xC3S5 * ip[5]); t2 = (int32_t)(xC5S3 * ip[3]); t1 >>= 16; t2 >>= 16; D_ = t1 - t2; t1 = (int32_t)(xC4S4 * (A_ - C_)); t1 >>= 16; _Ad = t1; t1 = (int32_t)(xC4S4 * (B_ - D_)); t1 >>= 16; _Bd = t1; _Cd = A_ + C_; _Dd = B_ + D_; t1 = (int32_t)(xC4S4 * (ip[0] + ip[4])); t1 >>= 16; E_ = t1; t1 = (int32_t)(xC4S4 * (ip[0] - ip[4])); t1 >>= 16; F_ = t1; t1 = (int32_t)(xC2S6 * ip[2]); t2 = (int32_t)(xC6S2 * ip[6]); t1 >>= 16; t2 >>= 16; G_ = t1 + t2; t1 = (int32_t)(xC6S2 * ip[2]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -