📄 h263decframei.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 I-Pictures//*/#include "h263.h"#include "h263dec.h"/*// decode mcbpc and set MBtype and ChromaPattern*/static h263_Status h263_DecodeMCBPC_I(h263_Info* pInfo, int *mbType, int *mbPattern){ Ipp32u code; int type, pattern, fb; code = h263_ShowBits9(pInfo, 9); if (code == 1) { type = IPPVC_MB_STUFFING; pattern = 0; fb = 9; } else if (code >= 64) { type = IPPVC_MBTYPE_INTRA; pattern = code >> 6; if (pattern >= 4) { pattern = 0; fb = 1; } else fb = 3; } else { type = IPPVC_MBTYPE_INTRA_Q; pattern = code >> 3; if (pattern >= 4) { pattern = 0; fb = 4; } else if (code >= 8) { fb = 6; } else { h263_Error("Error when decoding mcbpc of I-Frame macroblock"); return H263_STATUS_ERROR; } } h263_FlushBits(pInfo, fb); *mbType = type; *mbPattern = pattern; if (type == IPPVC_MBTYPE_INTRA) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTRA); else if (type == IPPVC_MBTYPE_INTRA_Q) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTRA_Q); return H263_STATUS_OK;}/*// decode I-Frame*/h263_Status h263_DecodeFrame_I(h263_Info* pInfo){ int quant, quant_c, i, j, mbPerRow, mbPerCol, mb_type, cbpc, cbpy, predMode; int stepYc, stepCbc, stepCrc, stepF[6]; int num_gobs, num_rows_per_gob, row; Ipp8u *pF[6]; h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture; int gob_header_present = 1; int k; h263_MacroBlock *pMBinfo = pInfo->VideoSequence.MBinfo; h263_Status sts; h263_IntraPredBlock *b = pInfo->VideoSequence.IntraPredBuff.block; stepYc = pInfo->VideoSequence.cFrame.stepY; stepCbc = pInfo->VideoSequence.cFrame.stepCb; stepCrc = pInfo->VideoSequence.cFrame.stepCr; stepYc = pInfo->VideoSequence.cFrame.stepY; 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; stepF[0] = stepF[1] = stepF[2] = stepF[3] = stepYc; stepF[4] = stepCbc; stepF[5] = stepCrc; pF[0] = pInfo->VideoSequence.cFrame.pY; pF[1] = pInfo->VideoSequence.cFrame.pY + 8; pF[2] = pInfo->VideoSequence.cFrame.pY + 8 * stepYc; pF[3] = pInfo->VideoSequence.cFrame.pY + 8 * stepYc + 8; pF[4] = pInfo->VideoSequence.cFrame.pCb; pF[5] = pInfo->VideoSequence.cFrame.pCr; VPic->gob_number = 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) { pF[0] += (stepYc << 4) * num_rows_per_gob * (VPic->gob_number - i); pF[1] += (stepYc << 4) * num_rows_per_gob * (VPic->gob_number - i); pF[2] += (stepYc << 4) * num_rows_per_gob * (VPic->gob_number - i); pF[3] += (stepYc << 4) * num_rows_per_gob * (VPic->gob_number - i); pF[4] += (stepCbc << 3) * num_rows_per_gob * (VPic->gob_number - i); pF[5] += (stepCrc << 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) pInfo->VideoSequence.GOBboundary[i*num_rows_per_gob] = 1; } h263_CLIPR(num_rows_per_gob, (mbPerCol - i*num_rows_per_gob)); quant = quant_c = VPic->pic_quant; if (VPic->oppmodes.modQuant) quant_c = h263_quant_c[quant]; 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++) { for (j = 0; j < mbPerRow; j++) { do { if (h263_DecodeMCBPC_I(pInfo, &mb_type, &cbpc) != H263_STATUS_OK) return H263_STATUS_ERROR; } while (mb_type == IPPVC_MB_STUFFING); if (VPic->oppmodes.advIntra) h263_AdvI_PredMode(pInfo, predMode); if (h263_DecodeCBPY_I(pInfo, &cbpy) != H263_STATUS_OK) return H263_STATUS_ERROR; if (mb_type == IPPVC_MBTYPE_INTRA_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->oppmodes.advIntra) sts = h263_DecodeMacroBlockIntra_AdvI(pInfo, j, (cbpy << 2) + cbpc, quant, quant_c, predMode, pF, stepF); else sts = h263_DecodeMacroBlockIntra(pInfo, (cbpy << 2) + cbpc, quant, quant_c, pF, stepF); if (sts != H263_STATUS_OK) { h263_Error("Error when decoding coefficients of Intra block"); return H263_STATUS_ERROR; } if (VPic->oppmodes.deblockFilt) { H263_MB_INTERNAL_HOR_DEBLOCKING_LUM(pF[0], stepF[0], quant); } pF[0] += 16; pF[1] += 16; pF[2] += 16; pF[3] += 16; pF[4] += 8; pF[5] += 8; VPic->pic_quant = quant; pMBinfo->quant = (Ipp8u)quant; pMBinfo++; h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB); } pF[0] += 2 * H263_NUM_EXT_MB * 16 + (stepYc << 4) - stepYc; pF[1] += 2 * H263_NUM_EXT_MB * 16 + (stepYc << 4) - stepYc; pF[2] += 2 * H263_NUM_EXT_MB * 16 + (stepYc << 4) - stepYc; pF[3] += 2 * H263_NUM_EXT_MB * 16 + (stepYc << 4) - stepYc; pF[4] += 2 * H263_NUM_EXT_MB * 8 + (stepCbc << 3) - stepCbc; pF[5] += 2 * H263_NUM_EXT_MB * 8 + (stepCrc << 3) - stepCrc; } } h263_AlignBits(pInfo); /* Deblocking filtering */ if (VPic->oppmodes.deblockFilt) h263_DeblockingFilter_I(pInfo, &pInfo->VideoSequence.cFrame); return H263_STATUS_OK;}#ifdef _OMP_KARABASstatic h263_Status h263_DecodeFrame_I_DecodeSlice(h263_Info* pInfo, int curRow, h263_MacroBlockMT* pMBinfoMT){ int quant, quant_c; int mb_type = 0, cbpc = 0, cbpy = 0; int mbPerRow; h263_MacroBlock *pMBinfo; h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture; int predMode = 0; h263_Status status; int colNum; mbPerRow = VPic->MacroBlockPerRow; pMBinfo = pInfo->VideoSequence.MBinfo + curRow * mbPerRow; quant = quant_c = VPic->pic_quant; if (VPic->oppmodes.modQuant) quant_c = h263_quant_c[quant]; for (colNum = 0; colNum < mbPerRow; colNum++) { do { if (h263_DecodeMCBPC_I(pInfo, &mb_type, &cbpc) != H263_STATUS_OK) return H263_STATUS_ERROR; } while (mb_type == IPPVC_MB_STUFFING); if (VPic->oppmodes.advIntra) h263_AdvI_PredMode(pInfo, predMode); if (h263_DecodeCBPY_I(pInfo, &cbpy) != H263_STATUS_OK) return H263_STATUS_ERROR;// pMBinfo->type = (Ipp8u)mb_type; pMBinfoMT->cbpc = cbpc; pMBinfoMT->cbpy = cbpy; if (mb_type == IPPVC_MBTYPE_INTRA_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; } pMBinfo->quant = (Ipp8u)quant; status = h263_DecodeDequantMacroBlockIntra(pInfo, colNum, (cbpy << 2) + cbpc, quant, quant_c, predMode, pMBinfoMT->dctCoeffs, pMBinfoMT->lnz); if (status != H263_STATUS_OK) { h263_Error("Error when decoding coefficients of Intra block"); return H263_STATUS_ERROR; } h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB); pMBinfo++; pMBinfoMT++; } // skip stuffing while (h263_ShowBits(pInfo, 9) == 1) h263_FlushBits(pInfo, 9); return H263_STATUS_OK;}/*********************************************************************************/static void h263_DecodeFrame_I_ReconSlice(h263_Info* pInfo, int curRow, h263_MacroBlockMT* pMBinfoMT){ int i, j; int stepYc, stepCbc, stepCrc, mbPerRow; int stepF[6]; Ipp8u *pYc, *pCbc, *pCrc, *pF[6]; h263_MacroBlock *pMBinfo; h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture; Ipp16s* coeffMB; stepYc = pInfo->VideoSequence.cFrame.stepY; stepCbc = pInfo->VideoSequence.cFrame.stepCb; stepCrc = pInfo->VideoSequence.cFrame.stepCr; pYc = pInfo->VideoSequence.cFrame.pY + curRow*16*stepYc; pCbc = pInfo->VideoSequence.cFrame.pCb + curRow*8*stepCbc; pCrc = pInfo->VideoSequence.cFrame.pCr + curRow*8*stepCrc; stepF[0] = stepF[1] = stepF[2] = stepF[3] = stepYc; stepF[4] = stepCbc; stepF[5] = stepCrc; mbPerRow = VPic->MacroBlockPerRow; pMBinfo = pInfo->VideoSequence.MBinfo + curRow * mbPerRow; for (j = 0; j < mbPerRow; j++) { coeffMB = pMBinfoMT->dctCoeffs; pF[0] = pYc; pF[1] = pYc + 8; pF[2] = pYc + 8 * stepYc; pF[3] = pYc + 8 * stepYc + 8; pF[4] = pCbc; pF[5] = pCrc; for (i = 0; i < 6; i++) { if (pMBinfoMT->lnz[i] > 0) ippiDCT8x8Inv_16s8u_C1R(&coeffMB[i*64], pF[i], stepF[i]); else h263_Set8x8_8u(pF[i], stepF[i], (Ipp8u)((coeffMB[i*64] + 4) >> 3)); } if (VPic->oppmodes.deblockFilt) { int quant; quant = pMBinfo->quant; H263_MB_INTERNAL_HOR_DEBLOCKING_LUM(pYc, stepYc, quant); } pMBinfo++; pMBinfoMT++; pYc += 16; pCrc += 8; pCbc += 8; }}/*********************************************************************************/h263_Status h263_DecodeFrame_I_MT(h263_Info* pInfo){ int i; h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture; int mbPerCol = VPic->MacroBlockPerCol; int mbPerRow = VPic->MacroBlockPerRow; h263_Status sts = H263_STATUS_OK; int num_rows_per_gob = VPic->RowsPerGOB; h263_IntraPredBlock *b; // reset Intra prediction buffer b = pInfo->VideoSequence.IntraPredBuff.block; for (i = 0; i <= mbPerRow; i ++) { b[i*6+0].dct_dc = b[i*6+1].dct_dc = b[i*6+2].dct_dc = b[i*6+3].dct_dc = b[i*6+4].dct_dc = b[i*6+5].dct_dc = -1; } i = 0; ippsZero_8u(pInfo->VideoSequence.GOBboundary, mbPerCol);#ifdef _OPENMP#pragma omp parallel shared(pInfo, i, mbPerCol, mbPerRow, sts) num_threads(pInfo->number_threads)#endif { int idThread = 0; /* the thread id of the calling thread. */ int curRow; h263_MacroBlockMT* pMBinfoMT;#ifdef _OPENMP idThread = omp_get_thread_num();#endif pMBinfoMT = pInfo->pMBinfoMT + mbPerRow * idThread; curRow = i; while (curRow < mbPerCol) {#ifdef _OPENMP#pragma omp critical(DECODE_SLICE)#endif { int gob_header_present; curRow = i; i++; if (curRow < mbPerCol) { if (curRow) { VPic->gob_number = curRow; gob_header_present = h263_ParseGOBHeader(pInfo); if (gob_header_present < 0) sts = H263_STATUS_PARSE_ERROR; else if (gob_header_present) { if (VPic->gob_number > 30) curRow = mbPerCol; /* EOS or EOSBS */ else { if (VPic->gob_number * num_rows_per_gob - curRow > 0) { ippsSet_8u(127, pInfo->VideoSequence.GOBboundary + curRow, VPic->gob_number * num_rows_per_gob - curRow); curRow = VPic->gob_number * num_rows_per_gob; } pInfo->VideoSequence.GOBboundary[curRow] = 1; } } } if (sts == H263_STATUS_OK) if (h263_DecodeFrame_I_DecodeSlice(pInfo, curRow, pMBinfoMT) != H263_STATUS_OK) sts = H263_STATUS_ERROR; } } if (curRow < mbPerCol) { if (sts == H263_STATUS_OK) { h263_DecodeFrame_I_ReconSlice(pInfo, curRow, pMBinfoMT); } } curRow++; } } if (sts != H263_STATUS_OK) return sts; if (VPic->oppmodes.deblockFilt) { int curRow;#ifdef _OPENMP#pragma omp parallel for shared(pInfo, mbPerCol) /* num_threads(pInfo->number_threads) */#endif for (curRow = 1; curRow < mbPerCol; curRow++) { h263_DeblockingFilterHor_I_MT(pInfo, curRow); }#ifdef _OPENMP#pragma omp parallel for shared(pInfo, mbPerCol) /* num_threads(pInfo->number_threads) */#endif for (curRow = 0; curRow < mbPerCol; curRow++) { h263_DeblockingFilterVer_I_MT(pInfo, curRow); } } return sts;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -