Ethan HuggInitial Commit70e5e6212 years agoHistory
1361 lines · 39.8 KB · C++
RawDownload
/*! * \copy *     Copyright (c)  2008-2013, Cisco Systems *     All rights reserved. * *     Redistribution and use in source and binary forms, with or without *     modification, are permitted provided that the following conditions *     are met: * *        * Redistributions of source code must retain the above copyright *          notice, this list of conditions and the following disclaimer. * *        * Redistributions in binary form must reproduce the above copyright *          notice, this list of conditions and the following disclaimer in *          the documentation and/or other materials provided with the *          distribution. * *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *     POSSIBILITY OF SUCH DAMAGE. * * *  Abstract *      current slice decoding * *  History *      07/10/2008 Created *      08/09/2013 Modified * *****************************************************************************/#include <memory.h> #include "typedefs.h"#include "dec_golomb.h" #include "fmo.h"#include "deblocking.h"#include "utils.h" #include "decode_slice.h" #include "error_code.h"#include "decode_mb_aux.h"#include "parse_mb_syn_cavlc.h"#include "rec_mb.h"#include "mv_pred.h" #include "as264_common.h"#include "cpu_core.h"#include "expand_pic.h" namespace WelsDec { int32_t WelsTargetSliceConstruction( PWelsDecoderContext pCtx ){	int32_t iPreQP = 0; 	PDqLayer pCurLayer = pCtx->pCurDqLayer;	PSlice pCurSlice = &pCurLayer->sLayerInfo.sSliceInLayer;	PSliceHeader pSliceHeader = &pCurSlice->sSliceHeaderExt.sSliceHeader; 	int32_t iTotalMbTargetLayer = pSliceHeader->pSps->uiTotalMbCount; 	int32_t iCurLayerWidth  = pCurLayer->iMbWidth << 4; 	int32_t iCurLayerHeight = pCurLayer->iMbHeight << 4; 	int32_t iNextMbXyIndex = 0;	PFmo pFmo = pCtx->pFmo; 	int32_t iTotalNumMb = pCurSlice->iTotalMbInCurSlice;	int32_t iCountNumMb = 0;	PDeblockingFilterMbFunc pDeblockMb; 	if ( !pCtx->bAvcBasedFlag && iCurLayerWidth != pCtx->iCurSeqIntervalMaxPicWidth ) 	{		return -1;	} 	iNextMbXyIndex   = pSliceHeader->iFirstMbInSlice;	pCurLayer->iMbX  = iNextMbXyIndex % pCurLayer->iMbWidth;	pCurLayer->iMbY  = iNextMbXyIndex / pCurLayer->iMbWidth; 	pCurLayer->iMbXyIndex = iNextMbXyIndex;	 	if ( 0 == iNextMbXyIndex )	{		pCurLayer->pDec->iSpsId = pSliceHeader->iSpsId;		pCurLayer->pDec->iPpsId = pSliceHeader->iPpsId; 		pCurLayer->pDec->uiQualityId = pCurLayer->sLayerInfo.sNalHeaderExt.uiQualityId;	} 	do 	{		iPreQP = pCurLayer->pLumaQp[pCurLayer->iMbXyIndex];				if ( WelsTargetMbConstruction( pCtx ) )		{			WelsLog( pCtx, WELS_LOG_WARNING, "WelsTargetSliceConstruction():::MB(%d, %d) construction error. pCurSlice_type:%d\n",				pCurLayer->iMbX, pCurLayer->iMbY, pCurSlice->eSliceType ); 			return -1;		} 		++iCountNumMb;		++pCurLayer->pDec->iTotalNumMbRec;		if ( iCountNumMb >= iTotalNumMb )		{			break;		}				if ( pCurLayer->pDec->iTotalNumMbRec > iTotalMbTargetLayer )		{			WelsLog( pCtx, WELS_LOG_WARNING, "WelsTargetSliceConstruction():::fdec->iTotalNumMbRec:%d, iTotalMbTargetLayer:%d\n",				pCurLayer->pDec->iTotalNumMbRec, iTotalMbTargetLayer ); 			return -1;		}						if ( pSliceHeader->pPps->uiNumSliceGroups > 1 )		{			iNextMbXyIndex = FmoNextMb( pFmo, iNextMbXyIndex );		}		else		{			++iNextMbXyIndex;		}		if ( -1 == iNextMbXyIndex || iNextMbXyIndex >= iTotalMbTargetLayer )	// slice group boundary or end of a frame		{			break;		}		pCurLayer->iMbX  = iNextMbXyIndex % pCurLayer->iMbWidth;		pCurLayer->iMbY  = iNextMbXyIndex / pCurLayer->iMbWidth;		pCurLayer->iMbXyIndex = iNextMbXyIndex;	} while (1);		pCtx->pDec->iWidthInPixel  = iCurLayerWidth;	pCtx->pDec->iHeightInPixel = iCurLayerHeight; 	if((pCurSlice->eSliceType != I_SLICE)&&(pCurSlice->eSliceType != P_SLICE))		return 0;     pDeblockMb = WelsDeblockingMb;  	if ( 1 == pSliceHeader->uiDisableDeblockingFilterIdc )	{		return 0;//NO_SUPPORTED_FILTER_IDX	}	else	{		WelsDeblockingFilterSlice( pCtx, pDeblockMb ); 	}	// any other filter_idc not supported here, 7/22/2010 	return 0;} int32_t WelsMbInterSampleConstruction( PWelsDecoderContext pCtx, PDqLayer pCurLayer, 											  uint8_t* pDstY, uint8_t* pDstU, uint8_t* pDstV, int32_t iStrideL, int32_t iStrideC ){	int32_t iMbXy = pCurLayer->iMbXyIndex;	int32_t i, iIndex, iOffset; 	WelsChromaDcIdct( pCurLayer->pScaledTCoeff[iMbXy] + 256 );	// 256 = 16*16	WelsChromaDcIdct( pCurLayer->pScaledTCoeff[iMbXy] + 320 );	// 320 = 16*16 + 16*4 	for(i=0; i<16; i++) //luma	{		iIndex = g_kuiMbNonZeroCountIdx[i];		if( pCurLayer->pNzc[iMbXy][iIndex] )		{			iOffset = ((iIndex>>2)<<2) * iStrideL + ((iIndex%4)<<2);						pCtx->pIdctResAddPredFunc( pDstY+iOffset, iStrideL, pCurLayer->pScaledTCoeff[iMbXy]+(i<<4) );		}	} 	for ( i = 0; i < 4; i++ ) //chroma	{		iIndex = g_kuiMbNonZeroCountIdx[i+16]; //Cb		if ( pCurLayer->pNzc[iMbXy][iIndex] || *(pCurLayer->pScaledTCoeff[iMbXy]+((i+16)<<4)) )		{			iOffset = (((iIndex-16)>>2)<<2) * iStrideC + (((iIndex-16)%4)<<2);						pCtx->pIdctResAddPredFunc( pDstU+iOffset, iStrideC, pCurLayer->pScaledTCoeff[iMbXy]+((i+16)<<4) );		} 		iIndex = g_kuiMbNonZeroCountIdx[i+20]; //Cr		if ( pCurLayer->pNzc[iMbXy][iIndex] || *(pCurLayer->pScaledTCoeff[iMbXy]+((i+20)<<4)) )		{			iOffset = (((iIndex-18)>>2)<<2) * iStrideC + (((iIndex-18)%4)<<2);						pCtx->pIdctResAddPredFunc( pDstV+iOffset, iStrideC , pCurLayer->pScaledTCoeff[iMbXy]+((i+20)<<4));		}	} 	return 0;}int32_t WelsMbInterConstruction(PWelsDecoderContext pCtx, PDqLayer pCurLayer){	int32_t iMbX = pCurLayer->iMbX;	int32_t iMbY = pCurLayer->iMbY;	uint8_t  *pDstY, *pDstCb, *pDstCr; 	int32_t iLumaStride   = pCtx->pDec->iLinesize[0];	int32_t iChromaStride = pCtx->pDec->iLinesize[1]; 	pDstY  = pCurLayer->pDec->pData[0] + ((iMbY * iLumaStride + iMbX)<<4);	pDstCb = pCurLayer->pDec->pData[1] + ((iMbY * iChromaStride + iMbX)<<3);	pDstCr = pCurLayer->pDec->pData[2] + ((iMbY * iChromaStride + iMbX)<<3); 	GetInterPred(pDstY, pDstCb, pDstCr, pCtx);	WelsMbInterSampleConstruction( pCtx, pCurLayer, pDstY, pDstCb, pDstCr, iLumaStride, iChromaStride ); 	pCtx->sBlockFunc.pWelsSetNonZeroCountFunc(NULL, pCurLayer->pNzc[pCurLayer->iMbXyIndex]);// set all none-zero nzc to 1; dbk can be opti!	return 0;} void_t WelsLumaDcDequantIdct(int16_t *pBlock, int32_t iQp){    const int32_t kiQMul= g_kuiDequantCoeff[iQp][0];#define STRIDE 16    int32_t i;    int32_t iTemp[16]; //FIXME check if this is a good idea	int16_t* pBlk = pBlock;    static const int32_t kiXOffset[4]={0, STRIDE, STRIDE<<2,  5*STRIDE};    static const int32_t kiYOffset[4]={0, STRIDE<<1, STRIDE<<3, 10*STRIDE};     for(i=0; i<4; i++){        const int32_t kiOffset= kiYOffset[i];		const int32_t kiX1 = kiOffset + kiXOffset[2];		const int32_t kiX2 = STRIDE + kiOffset;		const int32_t kiX3 = kiOffset + kiXOffset[3];		const int32_t kiI4 = i << 2;	// 4*i        const int32_t kiZ0= pBlk[kiOffset] + pBlk[kiX1];        const int32_t kiZ1= pBlk[kiOffset] - pBlk[kiX1];        const int32_t kiZ2= pBlk[kiX2] - pBlk[kiX3];        const int32_t kiZ3= pBlk[kiX2] + pBlk[kiX3];         iTemp[kiI4]  = kiZ0+kiZ3;        iTemp[1+kiI4]= kiZ1+kiZ2;        iTemp[2+kiI4]= kiZ1-kiZ2;        iTemp[3+kiI4]= kiZ0-kiZ3;    }     for(i=0; i<4; i++){        const int32_t kiOffset= kiXOffset[i];		const int32_t kiI4 = 4 + i;        const int32_t kiZ0= iTemp[i] + iTemp[4+kiI4];        const int32_t kiZ1= iTemp[i] - iTemp[4+kiI4];        const int32_t kiZ2= iTemp[kiI4] - iTemp[8+kiI4];        const int32_t kiZ3= iTemp[kiI4] + iTemp[8+kiI4];         pBlk[kiOffset]= ((kiZ0 + kiZ3)*kiQMul + 2)>>2; //FIXME think about merging this into decode_resdual        pBlk[kiYOffset[1] +kiOffset]= ((kiZ1 + kiZ2)*kiQMul + 2)>>2;        pBlk[kiYOffset[2] +kiOffset]= ((kiZ1 - kiZ2)*kiQMul + 2)>>2;        pBlk[kiYOffset[3] +kiOffset]= ((kiZ0 - kiZ3)*kiQMul + 2)>>2;    }	#undef STRIDE} int32_t WelsMbIntraPredictionConstruction(PWelsDecoderContext pCtx, PDqLayer pCurLayer, bool_t bOutput){//seems IPCM should not enter this path	int32_t iMbXy = pCurLayer->iMbXyIndex; 	FORCE_STACK_ALIGN_1D( int16_t, pTempScaledTCoeff, MB_COEFF_LIST_SIZE, 16 ); 	memcpy(pTempScaledTCoeff, pCurLayer->pScaledTCoeff[iMbXy], 384*sizeof(pCurLayer->pScaledTCoeff[iMbXy][0])); 	WelsFillRecNeededMbInfo(pCtx, bOutput, pCurLayer);		if(IS_INTRA16x16(pCurLayer->pMbType[iMbXy]))	{		int32_t i,j;		// really need?		for(i=0; i<16; i++)		{			j = g_kuiLumaDcZigzagScan[i];			pTempScaledTCoeff[j] = pCurLayer->pScaledTCoeff[iMbXy][j];		}		WelsLumaDcDequantIdct(pTempScaledTCoeff, pCurLayer->pLumaQp[iMbXy]);		RecI16x16Mb(iMbXy, pCtx,pTempScaledTCoeff,pCurLayer); 		return 0;	}			if(IS_INTRA4x4(pCurLayer->pMbType[iMbXy]))		RecI4x4Mb(iMbXy, pCtx,pTempScaledTCoeff,pCurLayer);			return 0;} int32_t WelsMbInterPrediction(PWelsDecoderContext pCtx, PDqLayer pCurLayer){	int32_t iMbX = pCurLayer->iMbX;	int32_t iMbY = pCurLayer->iMbY;	uint8_t  *pDstY, *pDstCb, *pDstCr; 	int32_t iLumaStride   = pCtx->pDec->iLinesize[0];	int32_t iChromaStride = pCtx->pDec->iLinesize[1]; 	pDstY  = pCurLayer->pDec->pData[0] + ((iMbY * iLumaStride + iMbX)<<4);	pDstCb = pCurLayer->pDec->pData[1] + ((iMbY * iChromaStride + iMbX)<<3);	pDstCr = pCurLayer->pDec->pData[2] + ((iMbY * iChromaStride + iMbX)<<3); 	GetInterPred(pDstY, pDstCb, pDstCr, pCtx); 	return 0;} void_t WelsMbCopy( uint8_t *pDst, int32_t iStrideDst, uint8_t *pSrc, int32_t iStrideSrc, 				 int32_t iHeight, int32_t iWidth ){	int32_t i;	int32_t iOffsetDst = 0, iOffsetSrc = 0;	for ( i = 0; i < iHeight; i++ )	{		memcpy( pDst+iOffsetDst, pSrc+iOffsetSrc, iWidth );		iOffsetDst += iStrideDst;		iOffsetSrc += iStrideSrc;	}}  int32_t WelsTargetMbConstruction(PWelsDecoderContext pCtx){	PDqLayer pCurLayer = pCtx->pCurDqLayer;		if ( MB_TYPE_INTRA_PCM == pCurLayer->pMbType[pCurLayer->iMbXyIndex] )	{				//copy cs into fdec		int32_t iCsStrideL = pCurLayer->iCsStride[0];		int32_t iCsStrideC = pCurLayer->iCsStride[1]; 		int32_t iDecStrideL = pCurLayer->pDec->iLinesize[0]; 		int32_t iDecStrideC = pCurLayer->pDec->iLinesize[1];  		int32_t iCsOffsetL = ( pCurLayer->iMbX + pCurLayer->iMbY * iCsStrideL ) << 4;		int32_t iCsOffsetC = ( pCurLayer->iMbX + pCurLayer->iMbY * iCsStrideC ) << 3;				int32_t iDecOffsetL = ( pCurLayer->iMbX + pCurLayer->iMbY * iDecStrideL ) << 4;		int32_t iDecOffsetC = ( pCurLayer->iMbX + pCurLayer->iMbY * iDecStrideC ) << 3;				uint8_t* pSrcY = pCurLayer->pCsData[0] + iCsOffsetL;		uint8_t* pSrcU = pCurLayer->pCsData[1] + iCsOffsetC;		uint8_t* pSrcV = pCurLayer->pCsData[2] + iCsOffsetC;				uint8_t* pDecY = pCurLayer->pDec->pData[0] + iDecOffsetL;		uint8_t* pDecU = pCurLayer->pDec->pData[1] + iDecOffsetC;		uint8_t* pDecV = pCurLayer->pDec->pData[2] + iDecOffsetC; 		WelsMbCopy( pDecY, iDecStrideL, pSrcY, iCsStrideL, 16, 16 );		WelsMbCopy( pDecU, iDecStrideC, pSrcU, iCsStrideC, 8, 8 );		WelsMbCopy( pDecV, iDecStrideC, pSrcV, iCsStrideC, 8, 8 );				return 0;	}	else if(IS_INTRA(pCurLayer->pMbType[pCurLayer->iMbXyIndex]))	{		WelsMbIntraPredictionConstruction(pCtx, pCurLayer, 1);	}	else if ( IS_INTER( pCurLayer->pMbType[pCurLayer->iMbXyIndex] ) ) //InterMB	{		if ( 0 == pCurLayer->pCbp[pCurLayer->iMbXyIndex] ) //uiCbp==0 include SKIP		{			WelsMbInterPrediction( pCtx, pCurLayer );		}		else		{			WelsMbInterConstruction( pCtx, pCurLayer );		}				}	else	{		WelsLog( pCtx, WELS_LOG_WARNING, "WelsTargetMbConstruction():::::Unknown MB type: %d\n", pCurLayer->pMbType[pCurLayer->iMbXyIndex] );		return -1;	}		return 0;} void_t WelsChromaDcIdct( int16_t *pBlock ){    int32_t iStride= 32;    int32_t iXStride= 16;	int32_t iStride1 = iXStride + iStride;	int16_t* pBlk = pBlock;    int32_t iA,iB,iC,iD,iE;	    iA= pBlk[0];    iB= pBlk[iXStride];    iC= pBlk[iStride];    iD= pBlk[iStride1];	    iE = iA-iB;    iA += iB;    iB = iC-iD;    iC += iD;		pBlk[0]= (iA+iC) >> 1;    pBlk[iXStride]= (iE+iB) >> 1;    pBlk[iStride]= (iA-iC) >> 1;    pBlk[iStride1]= (iE-iB) >> 1;} int32_t WelsDecodeSlice(PWelsDecoderContext pCtx, bool_t bFirstSliceInLayer, PNalUnit pNalCur){	PDqLayer pCurLayer = pCtx->pCurDqLayer;	PFmo pFmo = pCtx->pFmo;	int32_t i, iRet;	int32_t iNextMbXyIndex, iSliceIdc;  	PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;	PSliceHeaderExt pSliceHeaderExt = &pSlice->sSliceHeaderExt;	PSliceHeader pSliceHeader = &pSliceHeaderExt->sSliceHeader;	int32_t iMbX, iMbY;	const int32_t kiCountNumMb = pSliceHeader->pSps->uiTotalMbCount; //need to be correct when fmo or multi slice	PBitStringAux pBs = pCurLayer->pBitStringAux; 	int32_t iUsedBits  = 0;		PWelsDecMbCavlcFunc pDecMbCavlcFunc;  	pSlice->iTotalMbInCurSlice = 0; //initialize at the starting of slice decoding. 	if ( P_SLICE == pSliceHeader->eSliceType ) 	{		pDecMbCavlcFunc = WelsDecodeMbCavlcPSlice;	}	else //I_SLICE	{		pDecMbCavlcFunc = WelsDecodeMbCavlcISlice;	} 	if ( pSliceHeader->pPps->bConstainedIntraPredFlag )	{		pCtx->pFillInfoCacheIntra4x4Func = WelsFillCacheConstrain1Intra4x4;		pCtx->pParseIntra4x4ModeFunc      = ParseIntra4x4ModeConstrain1;		pCtx->pParseIntra16x16ModeFunc    = ParseIntra16x16ModeConstrain1;	}	else	{		pCtx->pFillInfoCacheIntra4x4Func = WelsFillCacheConstrain0Intra4x4;		pCtx->pParseIntra4x4ModeFunc      = ParseIntra4x4ModeConstrain0;		pCtx->pParseIntra16x16ModeFunc    = ParseIntra16x16ModeConstrain0;	}		pCtx->eSliceType = pSliceHeader->eSliceType; 	if (pCurLayer->sLayerInfo.pPps->bEntropyCodingModeFlag == 1)	{		//CABAC encoding is unsupported yet!		return -1;	}		iNextMbXyIndex = pSliceHeader->iFirstMbInSlice; 	if ( iNextMbXyIndex >= kiCountNumMb )	{		WelsLog(pCtx, WELS_LOG_ERROR, "WelsDecodeSlice()::iFirstMbInSlice(%d) > pSps->kiTotalMb(%d). ERROR!!! resolution change....\n", 			iNextMbXyIndex, kiCountNumMb);		pCtx->iErrorCode |= dsNoParamSets;		return dsNoParamSets;	}	 	iMbX = iNextMbXyIndex % pCurLayer->iMbWidth;	iMbY = iNextMbXyIndex / pCurLayer->iMbWidth; // error is introduced by multiple slices case, 11/23/2009	pSlice->iMbSkipRun = -1;	iSliceIdc = (pSliceHeader->iFirstMbInSlice<<7)+pCurLayer->uiLayerDqId;		pCurLayer->iMbX =  iMbX;	pCurLayer->iMbY = iMbY;	pCurLayer->iMbXyIndex = iNextMbXyIndex; 	if(pSliceHeaderExt->bSliceSkipFlag == 1)	{		for(i=0; i<(int32_t)pSliceHeaderExt->uiNumMbsInSlice; i++)		{			pCurLayer->pSliceIdc[iNextMbXyIndex] = iSliceIdc;								pCurLayer->pResidualPredFlag[iNextMbXyIndex] = 1;								if ( pSliceHeaderExt->sSliceHeader.pPps->uiNumSliceGroups > 1 )			{				iNextMbXyIndex = FmoNextMb( pFmo, iNextMbXyIndex );			}			else			{				++iNextMbXyIndex;			} 			iMbX = iNextMbXyIndex%pCurLayer->iMbWidth;			iMbY = iNextMbXyIndex%pCurLayer->iMbHeight;				pCurLayer->iMbX =  iMbX;			pCurLayer->iMbY = iMbY;

Lines 1–500 of 1361.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t