📄 encode_b.cpp
字号:
/*////////////////////////////////////////////////////////////////////////////////// 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) 2002-2005 Intel Corporation. All Rights Reserved.//*/#include "ippi.h"#include "ipps.h"#include "mpeg2_defs.h"/////////////////////////////////////////////////////////////////////////////////////////////////////////////// Coding B picture ///////////////////////////////////////////////////////////////////////////////////////////////////////////////void ippMPEG2VideoEncoder::encodeB(int numTh){ Ipp8u *pRef; int i, j, ic, jc, k, pred_ind; Ipp32s macroblock_address_increment; Ipp32s dc_dct_pred[3]; Ipp16s *pMBlock, *pDiff; int Y_width = YFrameHSize; Ipp32s Count[12], CodedBlockPattern; IppMotionVector2 vectorF, vectorF_top, vectorF_bottom; IppMotionVector2 vectorB, vectorB_top, vectorB_bottom; MB_prediction_info pred_info[2]; MB_prediction_info *best = pred_info; MB_prediction_info *curr = pred_info + 1; Ipp32s meF_bound_left, meF_bound_top; Ipp32s meB_bound_left, meB_bound_top; Ipp32s meF_bound_right, meF_bound_bottom; Ipp32s meB_bound_right, meB_bound_bottom; Ipp32s cur_offset; Ipp8u *YBlock; Ipp8u *UBlock; Ipp8u *VBlock; int nYPitch = Y_pitch; int nUPitch = U_pitch; int nVPitch = V_pitch; Ipp32s mean_frm[4], mean_fld[4]; int slice_past_intra_address; int slice_macroblock_address; int start_y; int start_uv; int stop_y; CALC_START_STOP_ROWS best->pDiff = threadSpec[numTh].pDiff_; curr->pDiff = threadSpec[numTh].pDiff1_; for (j = start_y, jc = start_uv; j < stop_y; j += 16, jc += BlkHeight_c) { PutSliceHeader(j >> 4, numTh); macroblock_address_increment = 1; slice_macroblock_address = 0; slice_past_intra_address = 0; // reset predictors at the start of slice dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = ResetTbl[encodeInfo.intra_dc_precision]; ippsZero_8u((Ipp8u*)threadSpec[numTh].PMV, sizeof(threadSpec[0].PMV)); for(i=ic=0; i < YFrameHSize; i += 16, ic += BlkWidth_c) { cur_offset = i + j * YFrameHSize; YBlock = Y_src + i + j * nYPitch; UBlock = U_src + ic + jc * nUPitch; VBlock = V_src + ic + jc * nVPitch; threadSpec[numTh].YBlock = YBlock; threadSpec[numTh].UBlock = UBlock; threadSpec[numTh].VBlock = VBlock; pMBInfo[k].mb_type = 0; slice_macroblock_address = i >> 4; threadSpec[numTh].var_min = quantiser_scale_value; pMBInfo[k].dct_type = DCT_FRAME; pMBInfo[k].prediction_type = MC_FRAME; // try skip MB if (i != 0 && i != YFrameHSize-16 && !(pMBInfo[k-1].mb_type & MB_INTRA)) { int skip_flag = 1; int blk; Ipp32s var, mean; int mb_type; mb_type = pMBInfo[k - 1].mb_type & (MB_FORWARD | MB_BACKWARD); pMBInfo[k].mb_type = mb_type; pDiff = threadSpec[numTh].pDiff_; SET_MOTION_VECTOR((&vectorF), threadSpec[numTh].PMV[0][0].x, threadSpec[numTh].PMV[0][0].y); SET_MOTION_VECTOR((&vectorB), threadSpec[numTh].PMV[0][1].x, threadSpec[numTh].PMV[0][1].y); if (mb_type == (MB_FORWARD|MB_BACKWARD)) { GETDIFF_FRAME_FB(Y, l, pDiff); } else if (mb_type & MB_FORWARD) { GETDIFF_FRAME(Y, l, pDiff, F); } else // if(mb_type & MB_BACKWARD) { GETDIFF_FRAME(Y, l, pDiff, B); } for (blk = 0; blk < 4; blk++) { ippiVarMean8x8_16s32s_C1R(pDiff + frm_diff_off[blk], 32, &var, &mean); if(var > threadSpec[numTh].var_min) { skip_flag = 0; break; } mean /= 8; if(mean >= quantiser_scale_value || mean <= -quantiser_scale_value) { skip_flag = 0; break; } } if (skip_flag) { pMBInfo[k].cbp = -1; macroblock_address_increment++; k++; ippsCopy_8u((Ipp8u*)threadSpec[numTh].PMV, (Ipp8u*)pMBInfo[k].MV, sizeof(threadSpec[0].PMV)); continue; } } // try skip pMBInfo[k].mb_type = 0; best->var_sum = (1 << 30); VARMEAN_FRAME_Y(curr->var, mean_frm, curr->var_sum); if(curr->var_sum < best->var_sum) { curr->mb_type = MB_INTRA; curr->dct_type = DCT_FRAME; SWAP_PTR(best, curr); } ME_FRAME(F, curr->var_sum, curr->pDiff, curr->dct_type); if(curr->var_sum < best->var_sum) { curr->mb_type = MB_FORWARD; curr->pred_type = MC_FRAME; SWAP_PTR(best, curr); } IF_GOOD_PRED(best->var, best->mean) { goto encodeMB; } if (!curr_frame_dct) { VARMEAN_FIELD_Y(curr->var, mean_fld, curr->var_sum); if(curr->var_sum < best->var_sum) { curr->mb_type = MB_INTRA; curr->dct_type = DCT_FIELD; SWAP_PTR(best, curr); } } if (!curr_frame_pred) { ME_FIELD(F, curr->var_sum, curr->pDiff, curr->dct_type); if(curr->var_sum < best->var_sum) { curr->mb_type = MB_FORWARD; curr->pred_type = MC_FIELD; SWAP_PTR(best, curr); } } // Backward vector search ME_FRAME(B, curr->var_sum, curr->pDiff, curr->dct_type); if(curr->var_sum < best->var_sum) { curr->mb_type = MB_BACKWARD; curr->pred_type = MC_FRAME; SWAP_PTR(best, curr); } IF_GOOD_PRED(best->var, best->mean) { goto encodeMB; } if (!curr_frame_pred) { ME_FIELD(B, curr->var_sum, curr->pDiff, curr->dct_type); if(curr->var_sum < best->var_sum) { curr->mb_type = MB_BACKWARD; curr->pred_type = MC_FIELD; SWAP_PTR(best, curr); } } // Bi-directional for (pred_ind = 0; pred_ind <= ((curr_frame_pred) ? 0 : 1); pred_ind++) { int pred_type; pDiff = curr->pDiff; if (!pred_ind) { pred_type = MC_FRAME; GETDIFF_FRAME_FB(Y, l, pDiff); } else { pred_type = MC_FIELD; GETDIFF_FIELD_FB(Y, l, pDiff); } VARMEAN_FRAME(pDiff, curr->var, curr->mean, curr->var_sum); if(curr->var_sum < best->var_sum) { curr->mb_type = MB_FORWARD | MB_BACKWARD; curr->pred_type = pred_type; curr->dct_type = DCT_FRAME; SWAP_PTR(best, curr); } if (!curr_frame_dct) { VARMEAN_FIELD(pDiff, curr->var, curr->mean, curr->var_sum); if(curr->var_sum < best->var_sum) { curr->mb_type = MB_FORWARD | MB_BACKWARD; curr->pred_type = pred_type; curr->dct_type = DCT_FIELD; if (pDiff != curr->pDiff) { Ipp16s *tmp = curr->pDiff; curr->pDiff = best->pDiff; best->pDiff = tmp; } SWAP_PTR(best, curr); } } }encodeMB: pMBInfo[k].prediction_type = best->pred_type; pMBInfo[k].dct_type = best->dct_type; pMBInfo[k].mb_type = best->mb_type; pMBInfo[k].act = best->var_sum + 1; pDiff = best->pDiff; if (pMBInfo[k].mb_type & MB_INTRA) { ippsZero_8u((Ipp8u*)threadSpec[numTh].PMV, sizeof(threadSpec[0].PMV)); ippsZero_8u((Ipp8u*)pMBInfo[k].MV, sizeof(pMBInfo[k].MV)); PutAddrIncrement(macroblock_address_increment, numTh); macroblock_address_increment = 1; if(slice_macroblock_address - slice_past_intra_address > 1) dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = ResetTbl[encodeInfo.intra_dc_precision]; slice_past_intra_address = (i >> 4); Ipp8u *BlockSrc[3] = {YBlock, UBlock, VBlock}; PutIntraMacroBlock(numTh, k, BlockSrc, NULL, dc_dct_pred, B_TYPE); k++; continue; } //Intra macroblock ippsZero_8u((Ipp8u*)Count, sizeof(Count)); CodedBlockPattern = 0; // Non-intra macroblock if(pMBInfo[k].prediction_type == MC_FRAME) { if((pMBInfo[k].mb_type&MB_FORWARD)&& (pMBInfo[k].mb_type&MB_BACKWARD)) { GETDIFF_FRAME_FB(U, c, pDiff); GETDIFF_FRAME_FB(V, c, pDiff); EncodeMacroBlock(numTh, pMBInfo[k].dct_type, pDiff, Count, &CodedBlockPattern); PutAddrIncrement(macroblock_address_increment, numTh); macroblock_address_increment = 1; PUT_MB_TYPE(B_TYPE, MB_FORWARD | MB_BACKWARD, FRAME); PutMV_FRAME(numTh, k, &vectorF, MB_FORWARD); PutMV_FRAME(numTh, k, &vectorB, MB_BACKWARD); } else if(pMBInfo[k].mb_type&MB_FORWARD) { if (curr_frame_dct) { GETDIFF_FRAME(Y, l, pDiff, F); } GETDIFF_FRAME(U, c, pDiff, F); GETDIFF_FRAME(V, c, pDiff, F); EncodeMacroBlock(numTh, pMBInfo[k].dct_type, pDiff, Count, &CodedBlockPattern); PutAddrIncrement(macroblock_address_increment, numTh); macroblock_address_increment = 1; PUT_MB_TYPE(B_TYPE, MB_FORWARD, FRAME); PutMV_FRAME(numTh, k, &vectorF, MB_FORWARD); } else //pMBInfo.mb_type&MB_BACKWARD { if (curr_frame_dct) { GETDIFF_FRAME(Y, l, pDiff, B); } GETDIFF_FRAME(U, c, pDiff, B); GETDIFF_FRAME(V, c, pDiff, B); EncodeMacroBlock(numTh, pMBInfo[k].dct_type, pDiff, Count, &CodedBlockPattern); PutAddrIncrement(macroblock_address_increment, numTh); macroblock_address_increment = 1; PUT_MB_TYPE(B_TYPE, MB_BACKWARD, FRAME); PutMV_FRAME(numTh, k, &vectorB, MB_BACKWARD); } } else //pMBInfo[k].prediction_type == MC_FIELD { if((pMBInfo[k].mb_type&MB_FORWARD)&& (pMBInfo[k].mb_type&MB_BACKWARD)) { GETDIFF_FIELD_FB(U, c, pDiff); GETDIFF_FIELD_FB(V, c, pDiff); EncodeMacroBlock(numTh, pMBInfo[k].dct_type, pDiff, Count, &CodedBlockPattern); PutAddrIncrement(macroblock_address_increment, numTh); macroblock_address_increment = 1; PUT_MB_TYPE(B_TYPE, MB_FORWARD | MB_BACKWARD, FIELD); PutMV_FIELD(numTh, k, &vectorF_top, &vectorF_bottom, MB_FORWARD); PutMV_FIELD(numTh, k, &vectorB_top, &vectorB_bottom, MB_BACKWARD); } else if(pMBInfo[k].mb_type&MB_FORWARD) { GETDIFF_FIELD(U, c, pDiff, F); GETDIFF_FIELD(V, c, pDiff, F); EncodeMacroBlock(numTh, pMBInfo[k].dct_type, pDiff, Count, &CodedBlockPattern); PutAddrIncrement(macroblock_address_increment, numTh); macroblock_address_increment = 1; PUT_MB_TYPE(B_TYPE, MB_FORWARD, FIELD); PutMV_FIELD(numTh, k, &vectorF_top, &vectorF_bottom, MB_FORWARD); } else //pMBInfo.mb_type&MB_BACKWARD { GETDIFF_FIELD(U, c, pDiff, B); GETDIFF_FIELD(V, c, pDiff, B); EncodeMacroBlock(numTh, pMBInfo[k].dct_type, pDiff, Count, &CodedBlockPattern); PutAddrIncrement(macroblock_address_increment, numTh); macroblock_address_increment = 1; PUT_MB_TYPE(B_TYPE, MB_BACKWARD, FIELD); PutMV_FIELD(numTh, k, &vectorB_top, &vectorB_bottom, MB_BACKWARD); } } //FIELD_PREDICTION PUT_BLOCK_PATTERN(CodedBlockPattern); pMBlock = threadSpec[numTh].pMBlock_; for (int loop = 0; loop < block_count; loop++) { if (Count[loop]) { PutNonIntraBlock(pMBlock, Count[loop], numTh); } pMBlock += 64; } pMBInfo[k].cbp = CodedBlockPattern; ippsCopy_8u((Ipp8u*)threadSpec[numTh].PMV, (Ipp8u*)pMBInfo[k].MV, sizeof(threadSpec[0].PMV)); k++; } // for(i) } // for(j)}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -