📄 h263decframep.c
字号:
/* ///////////////////////////////////////////////////////////////////////
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2005-2007 Intel Corporation. All Rights Reserved.
//
// Description: Decodes P-Frames
//
*/
#include "h263.h"
#include "h263dec.h"
static h263_Status h263_PredictDecode4MV_PB(h263_Info *pInfo, IppMotionVector *mv,
IppMotionVector *mvF, IppMotionVector *mvB, IppMotionVector *mvFPrev,
Ipp32s mb_type, Ipp32s mvdb, Ipp32s trd, Ipp32s trb, Ipp32s fourMV)
{
h263_Status status = H263_STATUS_OK;
h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
Ipp32s mvdx = 0, mvdy = 0;
Ipp32s i, numMV = fourMV ? 4 : 1;
Ipp32s leftlim = VPic->modes.UMV ? -63 : -32;
Ipp32s rightlim = VPic->modes.UMV ? 63 : 31;
if (mvdb) {
if (!VPic->oppmodes.UMV) {
status = h263_DecodeMVD(pInfo, &mvdx, &mvdy, 1);
} else {
status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy);
}
}
if (mb_type != IPPVC_MBTYPE_FORWARD) {
for (i = 0; i < numMV; i++) {
mvF[i].dx = (Ipp16s)(mv[i].dx * trb / trd);
mvF[i].dy = (Ipp16s)(mv[i].dy * trb / trd);
}
} else
mvF[0] = *mvFPrev;
if (mb_type == -1) { /* PB-frame */
if (!VPic->oppmodes.UMV) {
for (i = 0; i < numMV; i++) {
reconstructMV(&mvF[i], mvdx, mvdy, leftlim, rightlim);
mvB[i].dx = (Ipp16s)(mvdx ? (mvF[i].dx - mv[i].dx) : ((trb - trd) * mv[i].dx / trd));
mvB[i].dy = (Ipp16s)(mvdy ? (mvF[i].dy - mv[i].dy) : ((trb - trd) * mv[i].dy / trd));
}
} else {
for (i = 0; i < numMV; i++) {
mvF[i].dx = mvF[i].dx + (Ipp16s)mvdx;
mvF[i].dy = mvF[i].dy + (Ipp16s)mvdy;
mvB[i].dx = (Ipp16s)(mvdx ? (mvF[i].dx - mv[i].dx) : ((trb - trd) * mv[i].dx / trd));
mvB[i].dy = (Ipp16s)(mvdy ? (mvF[i].dy - mv[i].dy) : ((trb - trd) * mv[i].dy / trd));
}
}
} else if (mb_type == IPPVC_MBTYPE_INTERPOLATE) {
for (i = 0; i < numMV; i++) {
mvB[i].dx = (Ipp16s)((trb - trd) * mv[i].dx / trd);
mvB[i].dy = (Ipp16s)((trb - trd) * mv[i].dy / trd);
}
} else { /* IPPVC_MBTYPE_FORWARD */
if (!VPic->oppmodes.UMV) {
reconstructMV(&mvF[0], mvdx, mvdy, leftlim, rightlim);
} else {
mvF[0].dx = mvF[0].dx + (Ipp16s)mvdx;
mvF[0].dy = mvF[0].dy + (Ipp16s)mvdy;
}
*mvFPrev = mvF[0];
}
return status;
}
/*
// decode H.263++ P-Picture
*/
h263_Status h263_DecodeFrame_P(h263_Info* pInfo, h263_Frame *rFrame)
{
__ALIGN16(Ipp16s, coeffMB, 64*6);
__ALIGN16(Ipp16s, coeffMB_b, 64*6);
__ALIGN16(Ipp16s, coeffMB_bI, 64*2);
__ALIGN16(Ipp8u, predMB, 64*6);
Ipp32s quant, quant_c, bquant, bquant_c, i, dx, dy;
Ipp32s stepYr, stepYc, stepCbr, stepCbc, stepCrr, stepCrc, mbPerRow, mbPerCol;
Ipp32s colNum, rowNum, stepF[6];
Ipp8u *pYc, *pCbc, *pCrc, *pYr, *pCbr, *pCrr, *pF[6];
Ipp8u *pYn, *pCbn, *pCrn;
Ipp32s stepYn, stepCbn, stepCrn;
Ipp32s mb_not_coded, mb_type = 0, cbpc = 0, cbpy = 0, cbpyPrev = 0;
Ipp32s rt;
IppiRect limitRectL, limitRectC;
IppMotionVector mvCur[4], mvCbCr, mvPrev[4];
IppMotionVector mvBack[4], mvForw[4], mvBackPrev[4], mvForwPrev[4], mvFCbCr, mvBCbCr, mvFCbCrPrev, mvBCbCrPrev, mvForwPred;
h263_MacroBlock *pMBinfo;
h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
Ipp32s gob_header_present = 1;
Ipp32s cbpb = 0, mvdb, bmb_type = 0, cbpbPrev = 0, bmb_typePrev = 0;
Ipp32s predMode = 0;
h263_Status status;
Ipp32s num_rows_per_gob, num_gobs, row;
Ipp32s k;
Ipp32s fourMVmode = VPic->modes.advPred | VPic->oppmodes.advPred | VPic->oppmodes.deblockFilt;
Ipp32s obmcFlag = VPic->modes.advPred | VPic->oppmodes.advPred;
Ipp32s pbFlag = VPic->picture_coding_type == H263_PIC_TYPE_PB || VPic->picture_coding_type == H263_PIC_TYPE_iPB;
Ipp32s trd = VPic->temporal_reference - VPic->prev_temporal_reference;
Ipp32s trb = VPic->temporal_reference_B;
Ipp32s fourMVmb;
h263_Status sts;
if (trd < 0)
trd += VPic->PCF ? 1024 : 256;
stepYc = pInfo->VideoSequence.cFrame.stepY;
stepYr = rFrame->stepY;
stepCbc = pInfo->VideoSequence.cFrame.stepCb;
stepCbr = rFrame->stepCb;
stepCrc = pInfo->VideoSequence.cFrame.stepCr;
stepCrr = rFrame->stepCr;
pYc = pInfo->VideoSequence.cFrame.pY;
pCbc = pInfo->VideoSequence.cFrame.pCb;
pCrc = pInfo->VideoSequence.cFrame.pCr;
pYr = rFrame->pY;
pCbr = rFrame->pCb;
pCrr = rFrame->pCr;
stepF[0] = stepF[1] = stepF[2] = stepF[3] = stepYc; stepF[4] = stepCbc; stepF[5] = stepCrc;
if (pbFlag) {
stepYn = pInfo->VideoSequence.nFrame.stepY;
stepCbn = pInfo->VideoSequence.nFrame.stepCb;
stepCrn = pInfo->VideoSequence.nFrame.stepCr;
pYn = pInfo->VideoSequence.nFrame.pY;
pCbn = pInfo->VideoSequence.nFrame.pCb;
pCrn = pInfo->VideoSequence.nFrame.pCr;
}
mbPerRow = pInfo->VideoSequence.VideoPicture.MacroBlockPerRow;
mbPerCol = pInfo->VideoSequence.VideoPicture.MacroBlockPerCol;
num_gobs = pInfo->VideoSequence.VideoPicture.num_gobs_in_pic;
num_rows_per_gob = pInfo->VideoSequence.VideoPicture.RowsPerGOB;
/* Bounding rectangle for MV limitation */
limitRectL.x = -16;
limitRectL.y = -16;
limitRectL.width = pInfo->VideoSequence.VideoPicture.MacroBlockPerRow * 16 + 32;
limitRectL.height = pInfo->VideoSequence.VideoPicture.MacroBlockPerCol * 16 + 32;
limitRectC.x = -8;
limitRectC.y = -8;
limitRectC.width = pInfo->VideoSequence.VideoPicture.MacroBlockPerRow * 8 + 16;
limitRectC.height = pInfo->VideoSequence.VideoPicture.MacroBlockPerCol * 8 + 16;
rt = VPic->rtype;
pMBinfo = pInfo->VideoSequence.MBinfo;
{
Ipp32s frGOB;
h263_IntraPredBlock *b = pInfo->VideoSequence.IntraPredBuff.block;
quant = VPic->pic_quant;
pInfo->VideoSequence.VideoPicture.gob_number = 0;
dy = 0;
frGOB = 0;
if (VPic->oppmodes.deblockFilt)
ippsZero_8u(pInfo->VideoSequence.GOBboundary, mbPerCol);
for (i = 0; i < num_gobs; i++) {
VPic->gob_number = i;
rowNum = i*num_rows_per_gob;
colNum = 0;
if (i) {
ErrRet_1:
gob_header_present = h263_ParseGOBHeader(pInfo);
if (gob_header_present < 0) {
h263_Error("Error: Invalid GOB header");
goto Err_1;
// return H263_STATUS_PARSE_ERROR;
}
if (VPic->gob_number > 30)
return H263_STATUS_OK; /* EOS or EOSBS */
if (gob_header_present) {
Ipp32s nummbs2copy = (VPic->gob_number * num_rows_per_gob - rowNum) * mbPerRow - colNum;
h263_CopyMacroBlocks(&pInfo->VideoSequence.rFrame, &pInfo->VideoSequence.cFrame, mbPerRow, rowNum, colNum, nummbs2copy);
if (pbFlag)
h263_CopyMacroBlocks(&pInfo->VideoSequence.rFrame, &pInfo->VideoSequence.nFrame, mbPerRow, rowNum, colNum, nummbs2copy);
rowNum = num_rows_per_gob * VPic->gob_number;
colNum = 0;
pYc = pInfo->VideoSequence.cFrame.pY + (stepYc << 4) * rowNum;
pCbc = pInfo->VideoSequence.cFrame.pCb + (stepCbc << 3) * rowNum;
pCrc = pInfo->VideoSequence.cFrame.pCr + (stepCrc << 3) * rowNum;
pYr = pInfo->VideoSequence.rFrame.pY + (stepYr << 4) * rowNum;
pCbr = pInfo->VideoSequence.rFrame.pCb + (stepCbr << 3) * rowNum;
pCrr = pInfo->VideoSequence.rFrame.pCr + (stepCrr << 3) * rowNum;
if (pbFlag) {
pYn = pInfo->VideoSequence.nFrame.pY + (stepYn << 4) * rowNum;
pCbn = pInfo->VideoSequence.nFrame.pCb + (stepCbn << 3) * rowNum;
pCrn = pInfo->VideoSequence.nFrame.pCr + (stepCrn << 3) * rowNum;
}
pMBinfo = pInfo->VideoSequence.MBinfo + rowNum * mbPerRow;
if (VPic->gob_number > i)
ippsSet_8u(127, pInfo->VideoSequence.GOBboundary + i*num_rows_per_gob, (VPic->gob_number - i) * num_rows_per_gob);
i = VPic->gob_number;
}
if (gob_header_present) {
frGOB = i*num_rows_per_gob;
pInfo->VideoSequence.GOBboundary[frGOB] = 1;
}
}
quant = quant_c = VPic->pic_quant;
if (VPic->oppmodes.modQuant)
quant_c = h263_quant_c[quant];
if (VPic->picture_coding_type == H263_PIC_TYPE_PB || VPic->picture_coding_type == H263_PIC_TYPE_iPB) {
bquant_c = bquant = (VPic->dbquant + 5)*quant >> 2;
h263_CLIPR(bquant, 31);
if (VPic->oppmodes.modQuant)
bquant_c = h263_quant_c[bquant];
}
h263_CLIPR(num_rows_per_gob, (mbPerCol - i*num_rows_per_gob));
if (gob_header_present && VPic->oppmodes.advIntra) {
for (k = 0; k <= mbPerRow; k++) {
b[k*6+0].dct_dc = b[k*6+1].dct_dc = b[k*6+2].dct_dc = b[k*6+3].dct_dc = b[k*6+4].dct_dc = b[k*6+5].dct_dc = -1;
}
}
for (row = 0; row < num_rows_per_gob; row++) {
rowNum = i*num_rows_per_gob + row;
dy = rowNum * 16;
for (colNum = 0; colNum < mbPerRow; colNum++) {
dx = colNum * 16;
do {
mb_not_coded = h263_GetBit(pInfo);
if (mb_not_coded)
break;
if (h263_DecodeMCBPC_P(pInfo, &mb_type, &cbpc, 1) != H263_STATUS_OK)
goto Err_1;
} while (mb_type == IPPVC_MB_STUFFING);
if (mb_not_coded) {
if (!obmcFlag) {
ippiCopy16x16_8u_C1R(pYr, stepYr, pYc, stepYc);
ippiCopy8x8_8u_C1R(pCbr, stepCbr, pCbc, stepCbc);
ippiCopy8x8_8u_C1R(pCrr, stepCrr, pCrc, stepCrc);
if (pbFlag) {
ippiCopy16x16_8u_C1R(pYr, stepYr, pYn, stepYn);
ippiCopy8x8_8u_C1R(pCbr, stepCbr, pCbn, stepCbn);
ippiCopy8x8_8u_C1R(pCrr, stepCrr, pCrn, stepCrn);
}
}
mb_type = pMBinfo->type = IPPVC_MB_STUFFING; /* to indicate mb_not_coded */
h263_Zero4MV(pMBinfo->mv);
mvForwPred.dx = mvForwPred.dy = 0;
if (VPic->oppmodes.advIntra) {
for (k = 0; k < 6; k++)
b[(colNum + 1)*6 + k].dct_dc = -1;
}
h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_NOTCODED);
} else {
pMBinfo->type = (Ipp8u)mb_type;
if (VPic->oppmodes.advIntra && (mb_type == IPPVC_MBTYPE_INTRA || mb_type == IPPVC_MBTYPE_INTRA_Q))
h263_AdvI_PredMode(pInfo, predMode);
mvdb = cbpb = 0;
if (VPic->picture_coding_type == H263_PIC_TYPE_PB) {
if (h263_GetBit(pInfo)) {
mvdb = 1;
cbpb = h263_GetBit(pInfo);
} else {
mvForw[0].dx = mvForw[0].dy = mvBack[0].dx = mvBack[0].dy = 0;
}
bmb_type = -1;
h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTERPOLATE_PB);
} else if (VPic->picture_coding_type == H263_PIC_TYPE_iPB) {
h263_DecodeMODB_iPB(pInfo, &bmb_type, &cbpb, &mvdb);
if (!mvdb || colNum == 0)
mvForwPred.dx = mvForwPred.dy = 0;
}
if (cbpb)
cbpb = h263_GetBits9(pInfo, 6);
if (VPic->oppmodes.altInterVLC && cbpc == 3) {
if (h263_DecodeCBPY_I(pInfo, &cbpy) != H263_STATUS_OK)
goto Err_1;
} else {
if (h263_DecodeCBPY_P(pInfo, &cbpy, mb_type) != H263_STATUS_OK)
goto Err_1;
}
if (mb_type == IPPVC_MBTYPE_INTRA_Q || mb_type == IPPVC_MBTYPE_INTER_Q || mb_type == IPPVC_MBTYPE_INTER4V_Q) {
if (!VPic->oppmodes.modQuant) {
h263_UpdateQuant(pInfo, VPic->pic_quant);
quant_c = VPic->pic_quant;
} else {
quant_c = h263_UpdateQuant_Mod(pInfo);
}
quant = VPic->pic_quant;
if (VPic->picture_coding_type == H263_PIC_TYPE_PB || VPic->picture_coding_type == H263_PIC_TYPE_iPB) {
bquant_c = bquant = (VPic->dbquant + 5)*quant >> 2;
h263_CLIPR(bquant, 31);
if (VPic->oppmodes.modQuant)
bquant_c = h263_quant_c[bquant];
}
}
pMBinfo->quant = (Ipp8u)quant;
if (mb_type == IPPVC_MBTYPE_INTRA || mb_type == IPPVC_MBTYPE_INTRA_Q) {
pF[0] = pYc; pF[1] = pYc + 8; pF[2] = pYc + 8 * stepYc; pF[3] = pYc + 8 * stepYc + 8; pF[4] = pCbc; pF[5] = pCrc;
if (VPic->picture_coding_type == H263_PIC_TYPE_PB || (VPic->picture_coding_type == H263_PIC_TYPE_iPB && bmb_type == IPPVC_MBTYPE_INTERPOLATE)) {
if (h263_PredictDecodeMV(pInfo, pMBinfo, frGOB, rowNum, colNum, fourMVmode) != H263_STATUS_OK) {
h263_Error("Error when decoding motion vector");
goto Err_1;
}
if (fourMVmode) {
pMBinfo->mv[1] = pMBinfo->mv[2] = pMBinfo->mv[3] = pMBinfo->mv[0];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -