⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vlc.cpp

📁 avs decoder sources, added a command line sample
💻 CPP
字号:
/** * Copyright (c) 2006 *      OpenAVS Developers. All Rights Reserved. * * Copyright (c) 2005-2006 *      NSCC. All Rights Reserved. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *//**      * ! \file "vlc.c" *   \brief Functions related to VLC decoding process. */#include "vlc.h"#include "define.h"#include "global.h"#include "assert.h"#include "memory.h"static AVS_I8 AVS_2DVLC_INTRA_dec[7][64][2] = { { {-1, -1} } };static AVS_I8 AVS_2DVLC_INTER_dec[7][64][2] = { { {-1, -1} } };static AVS_I8 AVS_2DVLC_CHROMA_dec[5][64][2] = { { {-1, -1} } };static const AVS_INT EOB_Pos_intra[7] = {-1, 8, 8, 8, 6, 0, 0};static const AVS_INT EOB_Pos_inter[7] = {-1, 2, 2, 2, 2, 0, 0};static void  linfo_ue(AVS_INT len, AVS_INT info, AVS_INT *value1);static void  linfo_se(AVS_INT len, AVS_INT info, AVS_INT *value1);static void  linfo_cbp_intra(AVS_INT len,AVS_INT info,AVS_INT *cbp);static void  linfo_cbp_inter(AVS_INT len,AVS_INT info,AVS_INT *cbp);/** * Function: Count the leading zero bits in data stream. * Used in decoding Exponential-Golomb(Exp-Golomb). */static AVS_INT PassLeadingZeroBits(const AVS_BYTE * buffer, AVS_DWORD * totbitoffset){	AVS_LONG byteoffset;	/* byte from start of buffer */	AVS_INT bitLeft;	/* bit from start of byte */	AVS_INT findtag;	AVS_INT oldbitoffset = *totbitoffset;	findtag = 0;	byteoffset = (*totbitoffset) / 8;	bitLeft= 31 - ((*totbitoffset) & 7);	AVS_INT data = DWORD_SWAP(*(AVS_DWORD*)(buffer + byteoffset));		while (! findtag) {		findtag = (data & (0x01 << bitLeft));		bitLeft--;		(*totbitoffset)++;	}		return *totbitoffset - oldbitoffset - 1;}/** * Function: Read numbits from current position. * Used in decoding fixed-/variable-length coding. */AVS_INT read_bits(const AVS_BYTE * buffer, AVS_DWORD * totbitoffset, AVS_INT numbits){	if (numbits == 0)		return 0;	AVS_INT inf;	AVS_INT byteoffset = (*totbitoffset) >> 3;	AVS_INT bitoffset = (*totbitoffset) & 7;	AVS_INT bitleft = 31 - bitoffset;	AVS_UINT data = DWORD_SWAP(*(AVS_DWORD*)(buffer + byteoffset));		*totbitoffset += numbits;	AVS_UINT tmp = data << bitoffset;	inf = tmp >> (32 - numbits);	return inf;}AVS_INT se(const AVS_BYTE * buffer,AVS_DWORD * totbitoffset, AVS_INT bytecount){	AVS_INT info = 0;	AVS_INT value1= 0;	AVS_INT len = PassLeadingZeroBits(buffer, totbitoffset);	info = read_bits(buffer, totbitoffset, len);	linfo_se(len, info, &value1);		return value1;}AVS_INT ue(const AVS_BYTE * buffer,AVS_DWORD * totbitoffset, AVS_INT bytecount){	AVS_INT info = 0;	AVS_INT value1;		AVS_INT len = PassLeadingZeroBits(buffer, totbitoffset);	info = read_bits(buffer, totbitoffset, len); 	linfo_ue(len * 2 + 1, info, &value1);		return value1;  }static void linfo_ue(AVS_INT len, AVS_INT info, AVS_INT *value1){	AVS_INT n = 1 << (len / 2);	info --;	*value1 = n + info;}static void linfo_se(AVS_INT len, AVS_INT info, AVS_INT * value1){	AVS_INT n;	n = 1<< len;	n += info;	if (n & 1)		*value1 = -(n >> 1);	else		*value1 = (n >> 1);}static void linfo_cbp_intra(AVS_INT len, AVS_INT info, AVS_INT * cbp){	AVS_INT cbp_idx;	linfo_ue(len, info, &cbp_idx);	*cbp = NCBP[cbp_idx][0];}static void linfo_cbp_inter(AVS_INT len, AVS_INT info, AVS_INT * cbp){	AVS_INT cbp_idx;	linfo_ue(len, info, &cbp_idx);	*cbp = NCBP[cbp_idx][1];}static void linfo_cbp_intra422(AVS_INT len, AVS_INT info, AVS_INT * cbp){	AVS_INT cbp_idx;	linfo_ue(len, info, &cbp_idx);	*cbp = NCBP422[cbp_idx][0];}static void linfo_cbp_inter422(AVS_INT len, AVS_INT info, AVS_INT *cbp){	AVS_INT cbp_idx;	linfo_ue(len, info, &cbp_idx);	*cbp = NCBP422[cbp_idx][1];}AVS_INT me(const AVS_BYTE* buffer,AVS_DWORD* totbitoffset, AVS_INT bytecount, AVS_DWORD dwMbType){		AVS_INT cbp = 0;	AVS_INT len = PassLeadingZeroBits(buffer, totbitoffset);	AVS_INT info = read_bits(buffer, totbitoffset, len); 	if (dwMbType == I_8x8) {		/* Infra */		linfo_cbp_intra(len * 2 + 1, info, &cbp);	}	else {		/* Inter */		linfo_cbp_inter(len * 2 + 1, info, &cbp);	}	return cbp;}AVS_INT me_chroma422(		const AVS_BYTE * buffer, 		AVS_DWORD * totbitoffset, 		AVS_INT bytecount, 		AVS_DWORD dwMbType){	AVS_INT cbp = 0;	AVS_INT len = PassLeadingZeroBits(buffer, totbitoffset);	AVS_INT info = read_bits(buffer, totbitoffset, len); 	if (dwMbType == I_8x8)		linfo_cbp_intra422(len * 2 + 1, info, &cbp);	else		linfo_cbp_inter422(len * 2 + 1, info, &cbp);	return cbp;}/** * Function: Initialize VLC table. */void MakeVlcTable(){	AVS_INT level, run, ipos;	AVS_INT i;	/* make decoder table for 2DVLC_INTRA code */	/* Don't need to set this every time. rewrite later. */	if (AVS_2DVLC_INTRA_dec[0][0][1] < 0) {    		memset(AVS_2DVLC_INTRA_dec, -1, sizeof(AVS_2DVLC_INTRA_dec));		for (i=0; i < 7; i++) {			for (run = 0; run < 26; run++)				for (level = 0; level < 27; level++) {					ipos = AVS_2DVLC_INTRA[i][run][level];					assert(ipos < 64);					if (ipos >= 0) {						if(i == 0) {							AVS_2DVLC_INTRA_dec[i][ipos][0] = 								level + 1;							AVS_2DVLC_INTRA_dec[i][ipos][1] = 								run;							AVS_2DVLC_INTRA_dec[i][ipos + 1][0] = 								-(level + 1);							AVS_2DVLC_INTRA_dec[i][ipos + 1][1] = 								run;						}						else {							AVS_2DVLC_INTRA_dec[i][ipos][0]=level;							AVS_2DVLC_INTRA_dec[i][ipos][1]=run;													if (level == 0)								continue;							AVS_2DVLC_INTRA_dec[i][ipos + 1][0] =									-(level);							AVS_2DVLC_INTRA_dec[i][ipos + 1][1] =									run;						}					}				}		}		/* otherwise, tables are bad. */		assert(AVS_2DVLC_INTRA_dec[0][0][1] >= 0);	}		/* make decoder table for 2DVLC_INTER code */	/* Don't need to set this every time. rewrite later. */	if (AVS_2DVLC_INTER_dec[0][0][1] < 0) {		memset(AVS_2DVLC_INTER_dec, -1, sizeof(AVS_2DVLC_INTER_dec));		for (i = 0; i < 7; i++) {			for (run = 0; run < 26; run++)				for (level = 0; level < 27;level++) {					ipos = AVS_2DVLC_INTER[i][run][level];					assert(ipos < 64);					if (ipos < 0)						continue;					if (i == 0) {						AVS_2DVLC_INTER_dec[i][ipos][0] = 							level + 1;						AVS_2DVLC_INTER_dec[i][ipos][1] = 							run;													AVS_2DVLC_INTER_dec[i][ipos+1][0] = 							-(level + 1);						AVS_2DVLC_INTER_dec[i][ipos+1][1] = 							run;					}					else {						AVS_2DVLC_INTER_dec[i][ipos][0] = 							level;						AVS_2DVLC_INTER_dec[i][ipos][1] = 							run;						if (level == 0)							continue;													AVS_2DVLC_INTER_dec[i][ipos+1][0] = 							-(level);						AVS_2DVLC_INTER_dec[i][ipos+1][1] = 							run;					}				}		}		/* otherwise, tables are bad. */		assert(AVS_2DVLC_INTER_dec[0][0][1] >= 0);	}		/* make decoder table for 2DVLC_CHROMA code */	/* Don't need to set this every time. rewrite later. */	if (AVS_2DVLC_CHROMA_dec[0][0][1] < 0) {		memset(AVS_2DVLC_CHROMA_dec, -1, sizeof(AVS_2DVLC_CHROMA_dec));		for (i = 0; i < 5; i++) {			for (run = 0; run < 26; run++)				for (level = 0; level < 27; level++) {					ipos = AVS_2DVLC_CHROMA[i][run][level];					assert(ipos < 64);					if (ipos < 0)						continue;					if (i == 0) {						AVS_2DVLC_CHROMA_dec[i][ipos][0] = 							level + 1;						AVS_2DVLC_CHROMA_dec[i][ipos][1] = 							run;						AVS_2DVLC_CHROMA_dec[i][ipos + 1][0] = 							-(level + 1);						AVS_2DVLC_CHROMA_dec[i][ipos + 1][1] = 							run;					}					else {						AVS_2DVLC_CHROMA_dec[i][ipos][0] = 							level;						AVS_2DVLC_CHROMA_dec[i][ipos][1] = 							run;						if (level == 0)							continue;						AVS_2DVLC_CHROMA_dec[i][ipos + 1][0] = -(level);						AVS_2DVLC_CHROMA_dec[i][ipos + 1][1] = run;					}				}		}		/* otherwise, tables are bad. */		assert(AVS_2DVLC_CHROMA_dec[0][0][1] >= 0);	}}void  ReadLumaCoeff(		const AVS_BYTE * pbCurrent,		AVS_DWORD dwDataLen, 		AVS_DWORD * pdwBitOffset, 		MBINFO * pCurrMb, 		AVS_DWORD dwPictureStructure, 		AVS_SHORT* pResidual){	static const AVS_INT incVlc_intra[7] = { 0, 1, 2, 4, 7, 10, 3000 };  	static const AVS_INT incVlc_inter[7] = { 0, 1, 2, 3, 6,  9, 3000 };   		AVS_INT i;	AVS_INT ii, jj;	AVS_DWORD tabNo = 0;	AVS_INT symbol2D; 	AVS_INT vlc_numcoef = 0;	AVS_INT run = 0, level = 0;	AVS_INT buffer_level[65];	AVS_INT buffer_run[65];		AVS_INT* TABNO = TabNoBuf + 512;	AVS_INT* TABNO2 = TabNoBuf2 + 512;		AVS_INT qp, shift;	qp = pCurrMb->dwMbQp;		AVS_INT QPI, sum;	AVS_INT ipos = -1;	AVS_INT Golomb_se_type = SE_LUM_AC_INTER;		AVS_INT leadingZeroBits;	AVS_INT grad;	AVS_INT val, val2;		memset(buffer_run, 0, 65 * sizeof(AVS_INT));	memset(buffer_level, 0, 65 * sizeof(AVS_INT));	if (pCurrMb->dwMbType == I_8x8) {		for (i = 0; i < 65; i++) {			leadingZeroBits = PassLeadingZeroBits(pbCurrent, pdwBitOffset);			grad = VLC_Golomb_Order[0][tabNo][0]; 			val = read_bits(pbCurrent, pdwBitOffset, leadingZeroBits + grad);			symbol2D = (1 << (leadingZeroBits + grad)) - (1 << grad) + val; 						if (symbol2D == EOB_Pos_intra[tabNo]) {				vlc_numcoef = i;				break;			}        			else if (symbol2D < CODE2D_ESCAPE_SYMBOL) {				level = AVS_2DVLC_INTRA_dec[tabNo][symbol2D][0]; 				run = AVS_2DVLC_INTRA_dec[tabNo][symbol2D][1]; 			}			else {				run = (symbol2D - CODE2D_ESCAPE_SYMBOL) >> 1;				leadingZeroBits = PassLeadingZeroBits(pbCurrent, pdwBitOffset);				grad = 1;				val = read_bits(pbCurrent, pdwBitOffset, leadingZeroBits+grad);				val2 = (1 << (leadingZeroBits+grad)) - (1 << grad) + val; 				level = val2 + ((run>MaxRun[0][tabNo])?1:RefAbsLevel[tabNo][run]);				if (symbol2D & 1)    					level = -level;					}			buffer_level[i] = level;			buffer_run[i] = run;			if (abs(level) > incVlc_intra[tabNo]) {				tabNo = TABNO[level];			}  		}				for (i = (vlc_numcoef - 1); i>=0; i--) {			ipos += (buffer_run[i] + 1);						ii = SCAN[dwPictureStructure][ipos][0];			jj = SCAN[dwPictureStructure][ipos][1];						shift = IQ_SHIFT[qp];			QPI = IQ_TAB[qp]; 			val = buffer_level[i];			sum = (val * QPI + (1 << (shift - 2))) >> (shift - 1);						*(pResidual + jj * 8 + ii) =  sum;		}	}	else {		tabNo = 0;		for (i = 0; i < 65; i++) {			leadingZeroBits = PassLeadingZeroBits(pbCurrent, pdwBitOffset);			grad = VLC_Golomb_Order[1][tabNo][0]; 			val = read_bits(pbCurrent, pdwBitOffset, leadingZeroBits + grad);			symbol2D = (1 << (leadingZeroBits + grad)) - (1 << grad) + val; 						if (symbol2D == EOB_Pos_inter[tabNo]) {				vlc_numcoef = i;				break;			}			else if (symbol2D < CODE2D_ESCAPE_SYMBOL) {				level = AVS_2DVLC_INTER_dec[tabNo][symbol2D][0];   				run = AVS_2DVLC_INTER_dec[tabNo][symbol2D][1];   			}			else {				run = (symbol2D - CODE2D_ESCAPE_SYMBOL) >> 1;				leadingZeroBits = PassLeadingZeroBits(pbCurrent, pdwBitOffset);				grad = 0;				val = read_bits(pbCurrent, pdwBitOffset, leadingZeroBits + grad);				val2 = (1 << (leadingZeroBits+grad)) - (1 << grad) + val; 				level = val2 + 				        ((run > MaxRun[1][tabNo]) ? 					  1 : RefAbsLevel[tabNo+7][run]);								if (symbol2D & 1)					level=-level;					}			buffer_level[i] = level;			buffer_run[i] = run;			if (abs(level) > incVlc_inter[tabNo]) {				tabNo = TABNO2[level];			}		}		/* store encoded level,run to LumaCoeff[][] */		for (i = (vlc_numcoef - 1); i >= 0; i--) {			ipos += (buffer_run[i] + 1);						ii = SCAN[dwPictureStructure][ipos][0];			jj = SCAN[dwPictureStructure][ipos][1];						shift = IQ_SHIFT[qp];			QPI = IQ_TAB[qp];			val = buffer_level[i];			sum = (val * QPI + (1 << (shift - 2))) >> (shift - 1);			*(pResidual + jj * 8 + ii) = sum;		}	}}void  ReadChromaCoeff(		const AVS_BYTE * pbCurrent,		AVS_DWORD dwDataLen, 		AVS_DWORD * pdwBitOffset, 		MBINFO * pCurrMb, 		AVS_DWORD dwPictureStructure, 		AVS_SHORT * pResidual){	AVS_INT tabNo = 0;	AVS_INT symbol2D = 0;	AVS_INT vlc_numcoef = 0;	AVS_INT run, level;	AVS_INT buffer_level[65];	AVS_INT buffer_run[65];	static const AVS_INT EOB_Pos_chroma[2][5] = { 		{-1, 4, 8, 6, 4}, 		{-1, 0, 2, 0, 0} 	};  	static const AVS_INT incVlc_chroma[5] = {0, 1, 2, 4, 3000};   	AVS_INT leadingZeroBits;	AVS_INT grad;	AVS_INT val, val2;		/* using old style qp */	AVS_INT qp_chroma = QP_SCALE_CR[pCurrMb->dwMbQp];	AVS_INT temp;	AVS_INT ii, jj;	AVS_INT shift, QPI;	AVS_INT ipos = -1;		for (AVS_INT i = 0; i < 65; i++) {		leadingZeroBits = PassLeadingZeroBits(pbCurrent, pdwBitOffset);		grad = VLC_Golomb_Order[2][tabNo][0];		val = read_bits(pbCurrent, pdwBitOffset, leadingZeroBits+grad);		symbol2D = (1 << (leadingZeroBits + grad)) - (1 << grad) + val;				if (symbol2D == EOB_Pos_chroma[1][tabNo]) {			vlc_numcoef = i;			break;		}		if (symbol2D < CODE2D_ESCAPE_SYMBOL) {			level = AVS_2DVLC_CHROMA_dec[tabNo][symbol2D][0];    			run = AVS_2DVLC_CHROMA_dec[tabNo][symbol2D][1];    		}		else {			run = (symbol2D-CODE2D_ESCAPE_SYMBOL) >> 1;				leadingZeroBits = PassLeadingZeroBits(pbCurrent, pdwBitOffset);			grad = 0;			val = read_bits(pbCurrent, pdwBitOffset, leadingZeroBits+grad);			val2 = (1 << (leadingZeroBits + grad)) - (1 << grad) + val; 			level = val2 + ((run>MaxRun[2][tabNo])?1:RefAbsLevel[tabNo+14][run]);			if (symbol2D & 1)				level = -level;				}		buffer_level[i] = level;		buffer_run[i] = run;		if (abs(level) > incVlc_chroma[tabNo]) {			if (abs(level) <= 2)				tabNo = abs(level);			else if (abs(level) <= 4)				tabNo = 3;			else				tabNo = 4;		}	}	for (AVS_INT i = (vlc_numcoef - 1); i >= 0; i--) {		ipos += (buffer_run[i] + 1);				ii = SCAN[dwPictureStructure][ipos][0];		jj = SCAN[dwPictureStructure][ipos][1];		shift = IQ_SHIFT[qp_chroma];		QPI = IQ_TAB[qp_chroma]; 		val = buffer_level[i];		temp = (val * QPI + (1 << (shift - 2))) >> (shift - 1);				*(pResidual + jj * 8 + ii) = temp;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -