📄 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 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, int mb_type, int mvdb, int trd, int trb, int fourMV){ h263_Status status = H263_STATUS_OK; h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture; int mvdx = 0, mvdy = 0; int i, numMV = fourMV ? 4 : 1; int leftlim = VPic->modes.UMV ? -63 : -32; int 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); int quant, quant_c, bquant, bquant_c, i, dx, dy; int stepYr, stepYc, stepCbr, stepCbc, stepCrr, stepCrc, mbPerRow, mbPerCol; int colNum, rowNum, stepF[6]; Ipp8u *pYc, *pCbc, *pCrc, *pYr, *pCbr, *pCrr, *pF[6]; Ipp8u *pYn, *pCbn, *pCrn; int stepYn, stepCbn, stepCrn; int mb_not_coded, mb_type = 0, cbpc = 0, cbpy = 0, cbpyPrev = 0; int 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; int gob_header_present = 1; int cbpb = 0, mvdb, bmb_type = 0, cbpbPrev = 0, bmb_typePrev = 0; int predMode = 0; h263_Status status; int num_rows_per_gob, num_gobs, row; int k; int fourMVmode = VPic->modes.advPred | VPic->oppmodes.advPred | VPic->oppmodes.deblockFilt; int obmcFlag = VPic->modes.advPred | VPic->oppmodes.advPred; int pbFlag = VPic->picture_coding_type == H263_PIC_TYPE_PB || VPic->picture_coding_type == H263_PIC_TYPE_iPB; int trd = VPic->temporal_reference - VPic->prev_temporal_reference; int trb = VPic->temporal_reference_B; int fourMVmb; 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; { int 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; if (i) { gob_header_present = h263_ParseGOBHeader(pInfo); if (gob_header_present < 0) { h263_Error("Error: Invalid GOB header"); return H263_STATUS_PARSE_ERROR; } if (VPic->gob_number > 30) return H263_STATUS_OK; /* EOS or EOSBS */ if (VPic->gob_number - i > 0) { pYc += (stepYc << 4) * num_rows_per_gob * (VPic->gob_number - i); pCbc += (stepCbc << 3) * num_rows_per_gob * (VPic->gob_number - i); pCrc += (stepCrc << 3) * num_rows_per_gob * (VPic->gob_number - i); pYr += (stepYr << 4) * num_rows_per_gob * (VPic->gob_number - i); pCbr += (stepCbr << 3) * num_rows_per_gob * (VPic->gob_number - i); pCrr += (stepCrr << 3) * num_rows_per_gob * (VPic->gob_number - i); pYn += (stepYn << 4) * num_rows_per_gob * (VPic->gob_number - i); pCbn += (stepCbn << 3) * num_rows_per_gob * (VPic->gob_number - i); pCrn += (stepCrn << 3) * num_rows_per_gob * (VPic->gob_number - i); pMBinfo += (VPic->gob_number - i) * num_rows_per_gob * mbPerRow; 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) return H263_STATUS_ERROR; } 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) return H263_STATUS_ERROR; } else { if (h263_DecodeCBPY_P(pInfo, &cbpy, mb_type) != H263_STATUS_OK) return H263_STATUS_ERROR; } 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"); return H263_STATUS_ERROR; } if (fourMVmode) { pMBinfo->mv[1] = pMBinfo->mv[2] = pMBinfo->mv[3] = pMBinfo->mv[0]; } } else { if (!fourMVmode) pMBinfo->mv[0].dx = pMBinfo->mv[0].dy = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -