📄 decoder.cpp
字号:
/***************************************************************************** * * XVID MPEG-4 VIDEO CODEC * - Decoder Module - * * Copyright(C) 2002 MinChen <chenm001@163.com> * 2002-2003 Peter Ross <pross@xvid.org> * * This program is free software ; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation ; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: decoder.cpp,v 1.3 2006/12/13 15:12:25 jeanlf Exp $ * ****************************************************************************/#include "quant.h"#include "quant_matrix.h"#include "interpolate8x8.h"#include "reduced.h"#include "mbprediction.h"#include "gmc.h"#include "mem_align.h"#ifdef __SYMBIAN32__#include <e32base.h>#endif//----------------------------# define DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) \ type name##_storage[(sizex)*(sizey)+(alignment)-1]; \ type * name = (type *) (((int) name##_storage+(alignment - 1)) & ~((int)(alignment)-1))//----------------------------//----------------------------/* K = 4 */static const dword roundtab_76[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1 };/* K = 1 */const dword roundtab_79[4] = { 0, 1, 0, 0 };//----------------------------int S_decoder::Resize(){ //free existing image_destroy(&cur, edged_width, edged_height); image_destroy(&refn[0], edged_width, edged_height); image_destroy(&refn[1], edged_width, edged_height); image_destroy(&tmp, edged_width, edged_height); image_destroy(&qtmp, edged_width, edged_height); image_destroy(&gmc, edged_width, edged_height); if(last_mbs) xvid_free(last_mbs); if(mbs) xvid_free(mbs); //realloc mb_width = (width + 15) / 16; mb_height = (height + 15) / 16; edged_width = 16 * mb_width + 2 * EDGE_SIZE; edged_height = 16 * mb_height + 2 * EDGE_SIZE; if(image_create(&cur, edged_width, edged_height)){ xvid_free(this); return XVID_ERR_MEMORY; } if(image_create(&refn[0], edged_width, edged_height)){ image_destroy(&cur, edged_width, edged_height); xvid_free(this); return XVID_ERR_MEMORY; } //support B-frame to reference last 2 frame if(image_create(&refn[1], edged_width, edged_height)){ image_destroy(&cur, edged_width, edged_height); image_destroy(&refn[0], edged_width, edged_height); xvid_free(this); return XVID_ERR_MEMORY; } if(image_create(&tmp, edged_width, edged_height)){ image_destroy(&cur, edged_width, edged_height); image_destroy(&refn[0], edged_width, edged_height); image_destroy(&refn[1], edged_width, edged_height); xvid_free(this); return XVID_ERR_MEMORY; } if(image_create(&qtmp, edged_width, edged_height)){ image_destroy(&cur, edged_width, edged_height); image_destroy(&refn[0], edged_width, edged_height); image_destroy(&refn[1], edged_width, edged_height); image_destroy(&tmp, edged_width, edged_height); xvid_free(this); return XVID_ERR_MEMORY; } if(image_create(&gmc, edged_width, edged_height)){ image_destroy(&qtmp, edged_width, edged_height); image_destroy(&cur, edged_width, edged_height); image_destroy(&refn[0], edged_width, edged_height); image_destroy(&refn[1], edged_width, edged_height); image_destroy(&tmp, edged_width, edged_height); xvid_free(this); return XVID_ERR_MEMORY; } mbs = (MACROBLOCK*)xvid_malloc(sizeof(MACROBLOCK) * mb_width * mb_height, CACHE_LINE); if(mbs == NULL){ image_destroy(&cur, edged_width, edged_height); image_destroy(&refn[0], edged_width, edged_height); image_destroy(&refn[1], edged_width, edged_height); image_destroy(&tmp, edged_width, edged_height); image_destroy(&qtmp, edged_width, edged_height); xvid_free(this); return XVID_ERR_MEMORY; } MemSet(mbs, 0, sizeof(MACROBLOCK) * mb_width * mb_height); //for skip MB flag last_mbs = (MACROBLOCK*)xvid_malloc(sizeof(MACROBLOCK) * mb_width * mb_height, CACHE_LINE); if(!last_mbs){ xvid_free(mbs); image_destroy(&cur, edged_width, edged_height); image_destroy(&refn[0], edged_width, edged_height); image_destroy(&refn[1], edged_width, edged_height); image_destroy(&tmp, edged_width, edged_height); image_destroy(&qtmp, edged_width, edged_height); xvid_free(this); return XVID_ERR_MEMORY; } MemSet(last_mbs, 0, sizeof(MACROBLOCK) * mb_width * mb_height); return 0;}//----------------------------int decoder_create(xvid_dec_create_t *create){ if(XVID_VERSION_MAJOR(create->version) != 1) /* v1.x.x */ return XVID_ERR_VERSION; //S_decoder *dec = (S_decoder*)xvid_malloc(sizeof(S_decoder), CACHE_LINE); S_decoder *dec = new(ELeave) S_decoder(create); if(!dec) return XVID_ERR_MEMORY; return dec->Init(create);}//----------------------------S_decoder::S_decoder(xvid_dec_create_t *create):#ifdef PROFILE prof(*create->prof),#endif time_inc_resolution(0), fixed_time_inc(0), time_inc_bits(0), shape(0), quant_bits(0), quant_type(0), mpeg_quant_matrices(0), quarterpel(0), complexity_estimation_disable(0), interlacing(false), top_field_first(0), alternate_vertical_scan(0), aspect_ratio(0), par_width(0), par_height(0), sprite_enable(0), sprite_warping_points(0), sprite_warping_accuracy(0), sprite_brightness_change(0), newpred_enable(0), reduced_resolution_enable(false), bs_version(0), width(0), height(0), edged_width(0), edged_height(0), mb_width(0), mb_height(0), mbs(0), last_mbs(0), last_coding_type(0), frames(0), time(0), time_base(0), last_time_base(0), last_non_b_time(0), time_pp(0), time_bp(0), fixed_dimensions(false), scalability(false), low_delay(false), low_delay_default(false), last_reduced_resolution(false), packed_mode(false){ MemSet(&p_fmv, 0, sizeof(p_fmv)); MemSet(&p_bmv, 0, sizeof(p_bmv));}//----------------------------S_decoder::~S_decoder(){ xvid_free(last_mbs); xvid_free(mbs); //image based GMC image_destroy(&gmc, edged_width, edged_height); image_destroy(&refn[0], edged_width, edged_height); image_destroy(&refn[1], edged_width, edged_height); image_destroy(&tmp, edged_width, edged_height); image_destroy(&qtmp, edged_width, edged_height); image_destroy(&cur, edged_width, edged_height); xvid_free(mpeg_quant_matrices);}//----------------------------int S_decoder::Init(xvid_dec_create_t *create){ mpeg_quant_matrices = (dword*)xvid_malloc(sizeof(dword) * 64 * 8, CACHE_LINE); if(!mpeg_quant_matrices){ delete this; return XVID_ERR_MEMORY; } create->handle = this; width = create->width; height = create->height; cur.Null(); refn[0].Null(); refn[1].Null(); tmp.Null(); qtmp.Null(); //image based GMC gmc.Null(); mbs = NULL; last_mbs = NULL; init_mpeg_matrix(mpeg_quant_matrices); //For B-frame support (used to save reference frame's time frames = 0; time = time_base = last_time_base = 0; low_delay = false; packed_mode = false; fixed_dimensions = (width > 0 && height > 0); init_vlc_tables(); idct_int32_init(); if(fixed_dimensions) return Resize(); return 0;}//----------------------------static const int dquant_table[4] = { -1, -2, 1, 2};//----------------------------static dword get_dc_scaler(dword quant, dword lum){ if(quant < 5) return 8; if(quant < 25 && !lum) return (quant + 13) / 2; if(quant < 9) return 2 * quant; if(quant < 25) return quant + 8; if(lum) return 2 * quant - 16; return quant - 6;}//---------------------------#ifdef _ARM_extern"C"void XVID_ClearMatrix(void *dst);#elsevoid XVID_ClearMatrix(void *dst);#ifndef USE_ARM_ASMinline void XVID_ClearMatrix(void *dst){ MemSet(dst, 0, 64 * sizeof(int)); }#endif#endif//--------------------------/* decode an intra macroblock */void S_decoder::MBIntra(MACROBLOCK *pMB, dword x_pos, dword y_pos, dword acpred_flag, dword cbp, Bitstream *bs, dword quant, dword intra_dc_threshold, dword bound, bool reduced_resolution){ DECLARE_ALIGNED_MATRIX(block, 6, 64, int, CACHE_LINE); DECLARE_ALIGNED_MATRIX(data, 6, 64, int, CACHE_LINE); int i; dword stride = edged_width; const dword stride2 = stride / 2; byte *pY_Cur, *pU_Cur, *pV_Cur; if(reduced_resolution) { pY_Cur = cur.y + (y_pos << 5) * stride + (x_pos << 5); pU_Cur = cur.u + (y_pos << 4) * stride2 + (x_pos << 4); pV_Cur = cur.v + (y_pos << 4) * stride2 + (x_pos << 4); }else{ pY_Cur = cur.y + (y_pos << 4) * stride + (x_pos << 4); pU_Cur = cur.u + (y_pos << 3) * stride2 + (x_pos << 3); pV_Cur = cur.v + (y_pos << 3) * stride2 + (x_pos << 3); } MemSet(block, 0, 6 * 64 * sizeof(int)); //clear const dword iQuant = pMB->quant; for(i = 0; i < 6; i++){ dword iDcScaler = get_dc_scaler(iQuant, i < 4); int predictors[8]; int start_coeff; predict_acdc(mbs, x_pos, y_pos, mb_width, i, &block[i * 64], iQuant, iDcScaler, predictors, bound); if(!acpred_flag) pMB->acpred_directions[i] = 0; if(quant < intra_dc_threshold){ PROF_S(PROF_1); int dc_size; int dc_dif; dc_size = i < 4 ? bs->get_dc_size_lum() : bs->get_dc_size_chrom(); dc_dif = dc_size ? bs->get_dc_dif(dc_size) : 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -