📄 macroblock.c
字号:
/*COPYRIGHT, LICENSE AND WARRANTY INFORMATIONThis software module has been originally developed by Nokia Corporation. Provided that a person, entity or a company willing to use the Software (hereinafter Licensee) comply with all the terms and conditions of this Statement and subject to the limitations set forth in this Statement Nokia grants to such Licensee a non-exclusive, sub-licensable, worldwide, limited license under copyrights owned by Nokia to use the Software for the sole purpose of creating, manufacturing, selling, marketing, or distributing (including the right to make modifications to the Software) a fully compliant decoder implementation (hereinafter "Decoder") of ITU-T Recommendation H.264 / ISO/IEC International Standard 14496-10 and an encoder implementation producing output that is decodable with the Decoder.Nokia retains the ownership of copyrights to the Software. There is no patent nor other intellectual property right of Nokia licensed under this Statement (except the copyright license above). Licensee hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if patent licenses are required, it is their responsibility to acquire the license before utilizing the Software.The license by Nokia is subject to that the Licensee grants to Nokia the non-exclusive, worldwide, royalty-free, perpetual and irrevocable covenant that the Licensee(s) shall not bring a suit before any court or administrative agency or otherwise assert a claim for infringement under the Licensee intellectual property rights that, but for a license, would be infringed by the Software against (a) Nokia or Nokia's Affiliate; or (b) other recipient of a license and covenant not to sue with respect to the Software from Nokia; or (c) contractor, customer or distributor of a party listed above in a or b, which suit or claim is related to the Software or use thereof.The Licensee(s) further agrees to grant a reciprocal license to Nokia (as granted by Nokia to the Licensee(s) on the modifications made by Licensee(s) to the Software. THE SOFTWARE IS PROVIDED "AS IS" AND THE ORIGINAL DEVELOPER DISCLAIMS ANY AND ALL WARRANTIES WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. THOSE INTENDING TO USE THE SOFTWARE ARE EXPRESSLY ADVISED THAT ITS USE MAY INFRINGE EXISTING PATENTS AND BE SUBJECT TO ROYALTY PAYMENTS TO PATENT OWNERS. ANYONE USING THE SOFTWARE ON THE BASIS OF THIS LICENSE AGREES TO OBTAIN THE NECESSARY PERMISSIONS FROM ANY AND ALL APPLICABLE PATENT OWNERS FOR SUCH USE.IN NO EVENT SHALL THE ORIGINAL DEVELOPER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.This copyright, license and warranty information notice must be retained in all copies and derivative works of the Software or substantial portions thereof.*/#include <limits.h>#include "nccglob.h"#include "globals.h"#include "debug.h"#include "bitbuffer.h"#include "macroblock.h"#include "intrapred.h"#include "motest.h"#include "motcomp.h"#include "prederrorcod.h"#include "prederrordec.h"#include "stream.h"#include "vlcutility.h"#include "modedecision.h"#include "ratecontrol.h"#include <math.h>static int qp2RdoLambda[52];/* * Prototypes for static functions */static void getOrigMB(macroblock_s *mb, frmBuf_s *orig, int width);/* * mbkLoad * * Parameters: * - * * Function: * Initialize macroblock constants * * Returns: * - */void mbkLoad(){ int qp; for (qp = 0; qp < 52; qp ++) // scaled by 1024 qp2RdoLambda[qp] = (int) (0.85 * 256 * pow (2, (qp - 12)/3.0) + 0.5); //qp2RdoLambda[qp] = (lambda * lambda * 85)/100;}/* * getOrigMB: * * Parameters: * mb Macroblock object * orig Pointer to original frame * width Frame width * * Function: * Copies original blocks from original frame * * Returns: * - */static void getOrigMB(macroblock_s *mb, frmBuf_s *orig, int width){ int i, j, k; int widthC = width>>1; int pixX, pixY; u_int8 *yPtr; int partSum; /* * Get luma blocks */ pixX = mb->idxX * MBK_SIZE; pixY = mb->idxY * MBK_SIZE; yPtr = orig->y + pixY * width + pixX; // get MB pixels and calculate partial sums for (j = 0; j < MBK_SIZE; j += 4) { for (i = 0; i < MBK_SIZE; i += 4) { for (partSum = 0, k = 0; k < 4; k ++) { mb->origY[j+k][i+0] = yPtr[k * width + i + 0]; partSum += mb->origY[j+k][i+0] ; mb->origY[j+k][i+1] = yPtr[k * width + i + 1]; partSum += mb->origY[j+k][i+1]; mb->origY[j+k][i+2] = yPtr[k * width + i + 2]; partSum += mb->origY[j+k][i+2]; mb->origY[j+k][i+3] = yPtr[k * width + i + 3]; partSum += mb->origY[j+k][i+3]; } mb->partSums4x4[j >> 2][i >> 2] = partSum; } yPtr += 4*width; } // 8x8 partial sums for (i = 0; i < 4; i += 2) for (j = 0; j < 4; j += 2) { mb->partSums[i][j] = mb->partSums4x4[i][j] + mb->partSums4x4[i][j + 1] + mb->partSums4x4[i + 1][j] + mb->partSums4x4[i + 1][j + 1]; } /* * Get chroma blocks */ pixX >>= 1; pixY >>= 1; for (j = 0; j < MBK_SIZE/2; j++) { for (i = 0; i < MBK_SIZE/2; i++) { mb->origC[j][ i] = orig->u[(pixY+j) * widthC + pixX+i]; mb->origC[j][MBK_SIZE/2+i] = orig->v[(pixY+j) * widthC + pixX+i]; } }}/* * mbkSetupNeighbors: * * Parameters: * pMb Information related to motion estimation * * Function: * Set up the pointers to the neighbors for all the blocks in all modes. * Because we use the local buffers, most of the relationships are fixed. * Relationships that could change will be modified in other function. * * Each macroblock need to access up to 10 motion vectors from 4 * neighboring macroblocks. Those vectors will be stored in array * "surround" in ME profile. They are stored in the following order: * 0 - 3, 4 right-most vectors of left macroblock * 4 - 7, 4 bottom vectors of top macroblock * 8, vector at lower-left corner of up-right macroblock * 9, vector at lower-right corner of up-left macroblock * Vectors of the current macroblock will be stored in array "current" * in ME profile, in raster order, instead of coding order. * * Returns: * - */static void mbkSetupNeighbors(macroblock_s *mb){ int i, blkX, blkY; blkState_s *s; blkState_s *c; s = mb->surround; c = & mb->current[0][0]; // all the mode has the same left and top neighbor relationship for (i = 0; i < 16; i ++) { blkX = i % 4; blkY = i / 4; mb->blkLeft[i] = (blkX == 0) ? & s[blkY] : & c[i - 1]; mb->blkUp[i] = (blkY == 0) ? & s[blkX + 4] : & c[i - 4]; } // 16x16 and 16 x 8 can share the same up-right pointer arrays mb->blkUpRight[0][0] = & s[8]; mb->blkUpRight[0][8] = & s[1]; // 8 x 16 and 8 x 8, and 8 x 4 can share the same up-right pointer arrays mb->blkUpRight[1][0] = & s[6]; mb->blkUpRight[1][2] = & s[8]; mb->blkUpRight[1][4] = & s[0]; mb->blkUpRight[1][6] = & c[1]; mb->blkUpRight[1][8] = & c[6]; mb->blkUpRight[1][10] = & c[5]; mb->blkUpRight[1][12] = & s[2]; mb->blkUpRight[1][14] = & c[9]; // 4 x 8 and 4x4 can share the same pointer arrays for (i = 0; i < 16; i ++) { blkX = i % 4; blkY = i / 4; // assign the up-right neighboring block if (blkY == 0) mb->blkUpRight[2][i] = & s[blkX + 5]; else if ((blkX & 1) != 0 && (blkY & 1) != 0) mb->blkUpRight[2][i] = & c[i - 5]; else mb->blkUpRight[2][i] = & c[i - 3]; } // exception mb->blkUpRight[2][11] = & c [6]; mb->coeffElim = USE_COEF_ELIM; mb->coeffElimThLuma = COEF_ELIM_TH_MB; // threshold for 16x16 luma mb->coeffElimTh8x8 = COEF_ELIM_TH_BLK8x8; // threshold for 8x8 luma mb->coeffElimThChroma = COEF_ELIM_TH_CHROMA; // threshold for 8x8 chroma}/* * mbkInit: * * Parameters: * mb Macroblock object * * Function: * Set structure for intra mode and motion vector prediction. * * Returns: * - */void mbkInit(macroblock_s *mb, int plr){ mb->i4x4CornersAvail[1][1] = 0 | 1; // 0, up-right, 1, up-left mb->i4x4CornersAvail[1][2] = 2 | 1; // 1, up-right, 1, up-left mb->i4x4CornersAvail[1][3] = 0 | 1; // 0, up-right, 1, up-left mb->i4x4CornersAvail[2][1] = 2 | 1; // 1, up-right, 1, up-left mb->i4x4CornersAvail[2][2] = 2 | 1; // 1, up-right, 1, up-left mb->i4x4CornersAvail[2][3] = 0 | 1; // 0, up-right, 1, up-left mb->i4x4CornersAvail[3][1] = 0 | 1; // 0, up-right, 1, up-left mb->i4x4CornersAvail[3][2] = 2 | 1; // 1, up-right, 1, up-left mb->i4x4CornersAvail[3][3] = 0 | 1; // 0, up-right, 1, up-left mbkSetupNeighbors(mb); // need a temporary buffer for doing test encoding, to count the bits bibOpen(& mb->mbBs, 256); mb->plr = plr;}/* * mbkRelease: * * Parameters: * mb Macroblock object * * Function: * Release any dynamic structures in macroblock. * * Returns: * - */void mbkRelease(macroblock_s *mb){ bibClose(& mb->mbBs);}/* * mbkStartEnc: * * Parameters: * mb Macroblock object * mbStateArr Array of objects that store MB coding information * orig Frame buffer of original frame * reco Frame buffer of reconstructed frame * encPar Encoding parameters * qp Quantization parameter * tuneFactor Factor for tuning rdoLambda based on user input * * Function: * Setup macroblock object for encoding the current macroblock. * * Returns: * - */void mbkStartEnc(macroblock_s *mb, mbState_s *mbStateArr, frmBuf_s *orig, frmBuf_s *reco, encParams_s *encPar, int qp, int tuneFactor){ int pixX, pixY; int mbsPerLine; mbsPerLine = encPar->picWidth/MBK_SIZE; mb->blkAddr = (mb->idxY * BLK_PER_MB) * (encPar->picWidth/BLK_SIZE) + mb->idxX * BLK_PER_MB; mb->mbThis = mbStateArr + mb->mbAddr; mb->mbLeft = mb->mbThis - 1; mb->mbUp = mb->mbThis - mbsPerLine; mb->mbUpLeft = mb->mbUp - 1; mb->mbUpRight = mb->mbUp + 1; pixX = mb->idxX * MBK_SIZE; pixY = mb->idxY * MBK_SIZE; // setup the pointers to the reconstructed frame buffer mb->recoY = reco->y + pixY * encPar->picWidth + pixX; mb->recoU = reco->u + (pixY >> 1) * (encPar->picWidth >> 1) + (pixX >> 1); mb->recoV = reco->v + (pixY >> 1) * (encPar->picWidth >> 1) + (pixX >> 1); // DT: check. The following two lines and mb->qp = qp; mb->qpC = qpChroma[clip(MIN_QP, MAX_QP, qp + encPar->chromaQpIdx)]; mb->lambda = QP2QUANT[mb->qp];#ifndef DISABLE_RDO // play with rdoLambda for inter and intra, if intra RDO is not enabled, smaller lambda is preferred!!! mb->rdoLambda = mb->rdoLambdaIntra = (qp2RdoLambda[mb->qp] * tuneFactor + (1 << 15)) >> 16; if (mb->rdoLambda == 0) mb->rdoLambda = mb->rdoLambdaIntra = 1;#endif getOrigMB(mb, orig, encPar->picWidth);}/* * getMbAvailability: * * Parameters: * mb Macroblock object * picWidth Picture width * constrainedIntra Constrained intra prediction flag *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -