📄 macroblock.cpp
字号:
/*************************************************************************
AVS1-P2视频解码器源码
版权所有:联合信源数字音视频技术(北京)有限公司, (c) 2005-2006
AVS1-P2 Video Decoder Source Code
(c) Copyright, NSCC All Rights Reserved, 2005-2006
*************************************************************************
Distributed 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
*************************************************************************/
/*************************************************************************
文件名称: macroblock.cpp
描 述: 包含三个函数:ParseOnMacroBlock完成宏块码流Parse
McIdctRecOneMarcroBlock完成运动补偿和重构
InitOneMacroBlock完成在求预测mv之前的一些准备工作
详细情况见函数具体实现
*************************************************************************/
/*************************************************************************
Revision History
data Modification Author
2005-2-21 Created jthou
*************************************************************************/
#include "macroblock.h"
#include "vlc.h"
#include "global.h"
#include "pred.h"
#include "block.h"
#include "define.h"
/************************************************************************/
/* 函数功能:解码过程,从压缩码流中解出宏块信息及亮度色度系数 */
/* - Parse码流 */
/* - VLD */
/* - 反量化 */
/************************************************************************/
AVS_HRESULT ParseOneMacroBlock(AVS_BYTE** ppData,
AVS_DWORD dwDataLen,
AVS_DWORD* pdwBitOffset,
STREAMINFO* StrmInfo,
MBINFO* pMbInfo,
AVS_DWORD dwMbIndex,
AVS_INT* pCodCounter,
AVS_SHORT* pLumaResidual,
AVS_SHORT* pChromaResidual)
{
const AVS_BYTE* pbCurrent = *ppData;
AVS_DWORD MbWidth = StrmInfo->SeqInfo.dwMbWidth;
AVS_DWORD MbHeight = StrmInfo->SeqInfo.dwHeight;
AVS_DWORD PictureType = StrmInfo->ImgInfo.dwImageType;
AVS_BOOL PictureStructure = StrmInfo->ImgInfo.bPictureStructure;
AVS_BOOL SkipModeFlag = StrmInfo->ImgInfo.bSkipModeFlag;
AVS_DWORD MbTypeIndex = 0;
MBINFO* pCurrMb = &pMbInfo[dwMbIndex];
AVS_INT mb_type = 0;
AVS_INT i;
AVS_INT cod_counter = *pCodCounter;
//应该初始化宏块信息
pCurrMb->bHasCbp = FALSE;
pCurrMb->dwMbQp = StrmInfo->ImgInfo.dwPictureQp;
if(PictureType == I_IMG) //这部分与标准不符,从参考软件52b中摘出来的
{
mb_type = 0;
}
else if(StrmInfo->ImgInfo.bSkipModeFlag)
{
if(cod_counter == -1)
{
cod_counter = ue(pbCurrent, pdwBitOffset, dwDataLen);
}
if(cod_counter == 0)
{
mb_type = ue(pbCurrent, pdwBitOffset, dwDataLen);
if(PictureType == P_IMG)
mb_type ++;
cod_counter --;
}
else
{
cod_counter --;
mb_type = 0;
}
}
else
{
//好像运行不到
}
*pCodCounter = cod_counter;
if(mb_type==0 && PictureType != I_IMG && cod_counter >=0) //跳过模式 skip mode
{
if(PictureType == P_IMG)
pCurrMb->dwMbType = P_Skip;
else
pCurrMb->dwMbType = B_Skip;
return AVS_NOERROR;
}
if(PictureType == I_IMG)
//if(StrmInfo->ImgInfo.dwImageType1 == I_IMG)
{
if(PictureStructure == 1)
{
MbTypeIndex = 0;
pCurrMb->dwMbType = I_8x8;
pCurrMb->dwMvNum = 0;
}
if(PictureStructure == 0)
{
MbTypeIndex = 0;
pCurrMb->dwMbType = I_8x8;
pCurrMb->dwMvNum = 0;
}
}
if(PictureType == P_IMG)
{
MbTypeIndex = mb_type;
if(MbTypeIndex >= 5) //含CBP
{
pCurrMb->bHasCbp = TRUE;
pCurrMb->dwCBPCodeNum = MbTypeIndex - 5;
MbTypeIndex = 5;
}
if(MbTypeIndex == 5)
pCurrMb->dwMbType = I_8x8;
else
pCurrMb->dwMbType = MbTypeIndex + 1;
}
if(PictureType == B_IMG)
{
if(SkipModeFlag)
MbTypeIndex = mb_type + 1;
else
MbTypeIndex = mb_type;
if(MbTypeIndex >= 24)
{
pCurrMb->bHasCbp = TRUE;
pCurrMb->dwCBPCodeNum = MbTypeIndex - 24;
MbTypeIndex = 24;
}
if(MbTypeIndex == 24)
pCurrMb->dwMbType = I_8x8;
else if(MbTypeIndex == 23) //B_8x8
{
pCurrMb->dwMbType = B_8x8;
}
else
pCurrMb->dwMbType = MbTypeIndex + 6;
}
if(pCurrMb->dwMbType != P_Skip && pCurrMb->dwMbType != B_Skip)
{
if(pCurrMb->dwMbType == B_8x8)
{
for(i=0; i<4; i++)
{
AVS_INT mb_part_type = read_bits(pbCurrent, pdwBitOffset, 2);//u(pbCurrent, pdwBitOffset, dwDataLen, 2);
pCurrMb->dwMbPartType[i] = mb_part_type + 30;
}
}
if(pCurrMb->dwMbType == I_8x8)
{
for(i=0; i<4; i++)
{
pCurrMb->bPredModeFlag[i] = read_bits(pbCurrent, pdwBitOffset, 1);//u(pbCurrent, pdwBitOffset, dwDataLen, 1);
if(!pCurrMb->bPredModeFlag[i])
pCurrMb->iIntraLumaPredMode[i] = read_bits(pbCurrent, pdwBitOffset, 2);//u(pbCurrent, pdwBitOffset, dwDataLen, 2);
else
pCurrMb->iIntraLumaPredMode[i] = -1;
}
pCurrMb->dwintraChromaPredMode = ue(pbCurrent, pdwBitOffset, dwDataLen);
if(StrmInfo->SeqInfo.dwChromaFormat == CHROMA422)
pCurrMb->dwintraChromaPredMode422 = ue(pbCurrent, pdwBitOffset, dwDataLen);
}
if(pCurrMb->dwMbType == B_8x8)
{
for(i=0; i<4; i++)
pCurrMb->dwMvNum += MvNum[pCurrMb->dwMbPartType[i]];
}
else
pCurrMb->dwMvNum = MvNum[pCurrMb->dwMbType];
AVS_INT mvBwNum = 0;
if(pCurrMb->dwMbType == B_8x8)
{
for(i=0; i<4; i++)
{
if(pCurrMb->dwMbPartType[i] == SB_Bck_8x8)
{
mvBwNum ++;
}
}
}
AVS_INT mvFwNum = pCurrMb->dwMvNum - mvBwNum;
AVS_INT tmpRefIdxFw[4], tmpRefIdxBw[4];
AVS_INT x = 0;
AVS_INT y = 0;
if ((!StrmInfo->ImgInfo.bPictureReferenceFlag && PictureType==P_IMG && StrmInfo->ImgInfo.bPictureStructure) ||
(!StrmInfo->ImgInfo.bPictureReferenceFlag && !StrmInfo->ImgInfo.bPictureStructure && StrmInfo->ImgInfo.dwImageType1 !=I_IMG))
{
for(i=0; i<pCurrMb->dwMvNum; i++)
{
if(pCurrMb->dwMbType == B_8x8)
{
if(i<mvFwNum)
{
if(!PictureStructure && PictureType==P_IMG)
tmpRefIdxFw[x] = read_bits(pbCurrent, pdwBitOffset, 2);
else
tmpRefIdxFw[x] = read_bits(pbCurrent, pdwBitOffset, 1);
x++;
}
else
{
if(!PictureStructure && PictureType==P_IMG)
tmpRefIdxBw[y] = read_bits(pbCurrent, pdwBitOffset, 2);
else
tmpRefIdxBw[y] = read_bits(pbCurrent, pdwBitOffset, 1);
y++;
}
}
else
{
if(!PictureStructure && PictureType==P_IMG)
pCurrMb->dwMbReferenceIndex[i] = read_bits(pbCurrent, pdwBitOffset, 2);
else
pCurrMb->dwMbReferenceIndex[i] = read_bits(pbCurrent, pdwBitOffset, 1);
}
}
x = 0;
y = 0;
if(pCurrMb->dwMbType == B_8x8)
{
for(i=0; i<4; i++)
{
if(pCurrMb->dwMbPartType[i] == SB_Bck_8x8)
{
pCurrMb->dwMbReferenceIndex[i] = tmpRefIdxBw[x];
x++;
}
else if(pCurrMb->dwMbPartType[i] == SB_Direct_8x8)
{
pCurrMb->dwMbReferenceIndex[i] = 0;
}
else
{
pCurrMb->dwMbReferenceIndex[i] = tmpRefIdxFw[y];
y++;
}
}
}
}
AVS_INT tmpmvdFwx[4], tmpmvdFwy[4];
AVS_INT tmpmvdBwx[4], tmpmvdBwy[4];
x=y=0;
for(i=0; i<pCurrMb->dwMvNum; i++)
{
if(pCurrMb->dwMbType == B_8x8)
{
if(i<mvFwNum)
{
tmpmvdFwx[x] = se(pbCurrent, pdwBitOffset, dwDataLen);
tmpmvdFwy[x] = se(pbCurrent, pdwBitOffset, dwDataLen);
x++;
}
else
{
tmpmvdBwx[y] = se(pbCurrent, pdwBitOffset, dwDataLen);
tmpmvdBwy[y] = se(pbCurrent, pdwBitOffset, dwDataLen);
y++;
}
}
else
{
pCurrMb->iMvDiffX[i] = se(pbCurrent, pdwBitOffset, dwDataLen);
pCurrMb->iMvDiffY[i] = se(pbCurrent, pdwBitOffset, dwDataLen);
}
}
x = 0;
y = 0;
if(pCurrMb->dwMbType == B_8x8)
{
for(i=0; i<4; i++)
{
if(pCurrMb->dwMbPartType[i] == SB_Bck_8x8)
{
pCurrMb->iMvDiffX[i] = tmpmvdBwx[x];
pCurrMb->iMvDiffY[i] = tmpmvdBwy[x];
x++;
}
else if(pCurrMb->dwMbPartType[i] == SB_Direct_8x8)
{
pCurrMb->iMvDiffX[i] = 0;
pCurrMb->iMvDiffY[i] = 0;
}
else
{
pCurrMb->iMvDiffX[i] = tmpmvdFwx[y];
pCurrMb->iMvDiffY[i] = tmpmvdFwy[y];
y++;
}
}
}
if(pCurrMb->bHasCbp)
{
pCurrMb->dwCbp = NCBP[pCurrMb->dwCBPCodeNum][0];
}
else
{
pCurrMb->dwCbp = me(pbCurrent, pdwBitOffset, dwDataLen, pCurrMb->dwMbType);
}
if(StrmInfo->SeqInfo.dwChromaFormat == CHROMA422)
{
pCurrMb->dwCbp422 = me_chroma422(pbCurrent, pdwBitOffset, dwDataLen, pCurrMb->dwMbType);
}
if((pCurrMb->dwCbp>0 || (pCurrMb->dwCbp422>0 && StrmInfo->SeqInfo.dwChromaFormat == CHROMA422)) &&
!StrmInfo->ImgInfo.bFixedPictureQp) //??
{
pCurrMb->iMbQpDelta = se(pbCurrent, pdwBitOffset, dwDataLen);
pCurrMb->dwMbQp += pCurrMb->iMbQpDelta; //??
}
for(i=0; i<4; i++)
{
if (pCurrMb->dwCbp&(1<<i))
ReadLumaCoeff(pbCurrent,dwDataLen, pdwBitOffset, pCurrMb, StrmInfo->ImgInfo.bPictureStructure, pLumaResidual+i*64);
}
for(i=0; i<2; i++)
{
if ((pCurrMb->dwCbp>>4)&(i+1))
ReadChromaCoeff(pbCurrent, dwDataLen, pdwBitOffset, pCurrMb, StrmInfo->ImgInfo.bPictureStructure, pChromaResidual+i*64);
}
if(StrmInfo->SeqInfo.dwChromaFormat == CHROMA422)
{
for(i=6; i<8; i++)
{
// ReadChromaCoff422();
}
}
}
return AVS_NOERROR;
}
/************************************************************************/
/* 函数功能:运动补偿、反变换、重构 */
/* - 运动矢量预测 */
/* - 计算预测值 */
/* - 对系数进行反变化得到残差数据 */
/* - 残差数据和预测数据相加,得到重构图像 */
/************************************************************************/
AVS_HRESULT McIdctRecOneMarcroBlock(MBINFO* pMbInfo,
AVS_DWORD dwMbIndex,
STREAMINFO* pStrmInfo,
const VIDEODATA** ppRefFrame,
VIDEODATA* pCurrFrame,
AVS_DWORD dwRefNum,
AVS_DWORD MbWidth,
AVS_DWORD MbHeight,
AVS_DWORD dwCurrDistanceIndex,
BWREFINFO* pBwRefInfo,
AVS_SHORT* pLumaResidual,
AVS_SHORT* pChromaResidual)
{
AVS_INT block;
AVS_INT MbX = dwMbIndex%MbWidth;
AVS_INT MbY = dwMbIndex/MbWidth;
AVS_DWORD imgWidth = pStrmInfo->SeqInfo.dwWidth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -