⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 errorconcealment.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 3 页
字号:
/*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.*/#ifdef ERROR_CONCEALMENT#include <string.h>#include "nccglob.h"#include "globals.h"#include "framebuffer.h"#include "motcomp.h"#include "parameterset.h"#include "dpb.h"#include "slice.h"#include "errorconcealment.h"#define mabs(a) ( (a) < 0 ? -(a) : (a) )#define MVPERMB_THR 8#define DIR_ZERO 0#define DIR_TOP  1#define DIR_BOTTOM 2#define DIR_LEFT 3#define DIR_RIGHT 4#define DIR_UPPERLEFT 5#define DIR_UPPERRIGHT 6#define DIR_BOTTOMLEFT 7#define DIR_BOTTOMRIGHT 8#define NUM_OF_CANDIDATES 9#define MASK_TOP    1#define MASK_BOTTOM 2#define MASK_LEFT   4#define MASK_RIGHT  8/* * * fillMotionVectors: * * Parameters: *      mbIdxX                MB horizontal location *      mbIdxY                MB vertical location *      picWidth              Picture width in pixel *      picHeight             Picture height in pixel *      refTab                Reference index buffer *      motVecs               Motion vector buffer *      from                  Where are the candidate MVs from? * * Function: *      Fill the MVs of a lost MB. *       * Returns: *      0:                    If all MVs in the MB is set to be zero MV *      1:                    Otherwise */static int fillMotionVectors(int mbIdxX, int mbIdxY, int picWidth, int picHeight, int8 *refTab,                              motVec_s *motVecs, int from){  int blks   = picWidth/BLK_SIZE;  int blkX   = mbIdxX*BLK_PER_MB;  int blkY   = mbIdxY*BLK_PER_MB;  motVec_s vec;  int blkIdx;  motVec_s *vecPtr;  motVec_s *adjVecPtr;  int8 *refPtr;  int8 *adjRefPtr;  int zeroMvFlag;  int blkAddr;  int widthMBs = picWidth/MBK_SIZE;  int heightMBs = picHeight/MBK_SIZE;  blkAddr = blkY*blks+blkX;  adjVecPtr = vecPtr = &motVecs[blkAddr];  adjRefPtr = refPtr = &refTab[blkAddr];  vec.x = 0;  vec.y = 0;  zeroMvFlag = 1;  switch (from) {  case DIR_TOP: // Top    adjVecPtr -= (blks);    adjRefPtr -= (blks);    /* If upper MB is not available */    if (( mbIdxY == 0) ||        (adjRefPtr[0] == -1 && adjVecPtr[0].x == 0 && adjVecPtr[0].y == 0)) {      zeroMvFlag = 1;    }    /* Otherwise, skip mode vec is predicted */    else {      zeroMvFlag = 0;    }    break;  case DIR_BOTTOM: // Bottom    adjVecPtr += (4*blks);    adjRefPtr += (4*blks);    /* If bottom MB is not available */    if (( mbIdxY == (heightMBs - 1) ) ||        (adjRefPtr[0] == -1 && adjVecPtr[0].x == 0 && adjVecPtr[0].y == 0)) {      zeroMvFlag = 1;    }    /* Otherwise, skip mode vec is predicted */    else {      zeroMvFlag = 0;    }    break;  case DIR_LEFT: // Left    adjVecPtr -= 1;    adjRefPtr -= 1;    /* If left MB is not available */    if (( mbIdxX == 0 ) ||        (adjRefPtr[0] == -1 && adjVecPtr[0].x == 0 && adjVecPtr[0].y == 0)) {      zeroMvFlag = 1;    }    /* Otherwise, skip mode vec is predicted */    else {      zeroMvFlag = 0;    }    break;  case DIR_RIGHT: // right    adjVecPtr += 4;    adjRefPtr += 4;    /* If right MB is not available */    if (( mbIdxX == (widthMBs - 1) ) ||        (adjRefPtr[0] == -1 && adjVecPtr[0].x == 0 && adjVecPtr[0].y == 0)) {      zeroMvFlag = 1;    }    /* Otherwise, skip mode vec is predicted */    else {      zeroMvFlag = 0;    }    break;  case DIR_UPPERLEFT:    adjVecPtr -= (1*blks+1);    adjRefPtr -= (1*blks+1);    /* if the upper left MB is not available */    if ( mbIdxY == 0 || // the first line      mbIdxX == 0 || // the first column      adjRefPtr[0] == -1 // Intra coded      ) {      zeroMvFlag = 1;    }    else      zeroMvFlag = 0;    break;  case DIR_UPPERRIGHT:    adjVecPtr -= (1*blks-4);    adjRefPtr -= (1*blks-4);    /* if the upper right MB is not available */    if ( mbIdxY == 0 || // the first line      mbIdxX == widthMBs-1 || // the last column      adjRefPtr[0] == -1 // intra coded      ) {      zeroMvFlag = 1;    }    else      zeroMvFlag = 0;    break;  case DIR_BOTTOMLEFT:    adjVecPtr += (4*blks-1);    adjRefPtr += (4*blks-1);    if (mbIdxY == heightMBs-1 || // the last line      mbIdxX == 0 || // the first column      adjRefPtr[0] == -1 // intra coded      ) {      zeroMvFlag = 1;    }    else      zeroMvFlag = 0;    break;        case DIR_BOTTOMRIGHT:    adjVecPtr += (4*blks+4);    adjRefPtr += (4*blks+4);    if (mbIdxY == heightMBs-1 || // the last line      mbIdxX == widthMBs-1 || // the last column      adjRefPtr[0] == -1 // intra coded      ) {      zeroMvFlag = 1;    }    else      zeroMvFlag = 0;    break;  case DIR_ZERO:  default:    zeroMvFlag = 1;    break;  }  if (zeroMvFlag) {    for (blkIdx = 0; blkIdx < BLK_PER_MB; blkIdx++) {      vecPtr[0] = vec;      vecPtr[1] = vec;      vecPtr[2] = vec;      vecPtr[3] = vec;      refPtr[0] = 0;      refPtr[1] = 0;      refPtr[2] = 0;      refPtr[3] = 0;      vecPtr += blks;      refPtr += blks;    }  }  else { // non zero MVs    if (from == DIR_TOP || from == DIR_BOTTOM) {      for (blkIdx = 0; blkIdx < BLK_PER_MB; blkIdx++) {        vecPtr[0] = adjVecPtr[0];        vecPtr[1] = adjVecPtr[1];        vecPtr[2] = adjVecPtr[2];        vecPtr[3] = adjVecPtr[3];        refPtr[0] = adjRefPtr[0];        refPtr[1] = adjRefPtr[1];        refPtr[2] = adjRefPtr[2];        refPtr[3] = adjRefPtr[3];        vecPtr += blks;        refPtr += blks;      }    }    else if (from == DIR_LEFT || from == DIR_RIGHT) {      for (blkIdx = 0; blkIdx < BLK_PER_MB; blkIdx++) {        vecPtr[  0   ] = adjVecPtr[  0   ];        vecPtr[  blks] = adjVecPtr[  blks];        vecPtr[2*blks] = adjVecPtr[2*blks];        vecPtr[3*blks] = adjVecPtr[3*blks];        refPtr[  0   ] = adjRefPtr[  0   ];        refPtr[  blks] = adjRefPtr[  blks];        refPtr[2*blks] = adjRefPtr[2*blks];        refPtr[3*blks] = adjRefPtr[3*blks];        vecPtr += 1;        refPtr += 1;      }    }    else if (from == DIR_UPPERLEFT || from == DIR_UPPERRIGHT || from == DIR_BOTTOMLEFT || from == DIR_BOTTOMRIGHT) {      for (blkIdx = 0; blkIdx < BLK_PER_MB; blkIdx++) {        vecPtr[0] = adjVecPtr[0];        vecPtr[1] = adjVecPtr[0];        vecPtr[2] = adjVecPtr[0];        vecPtr[3] = adjVecPtr[0];        refPtr[0] = adjRefPtr[0];        refPtr[1] = adjRefPtr[0];        refPtr[2] = adjRefPtr[0];        refPtr[3] = adjRefPtr[0];        vecPtr += blks;        refPtr += blks;      }    }  }  return zeroMvFlag;}/* * * getMismatch: * * Parameters: *      pEc                   EC object   *      currPic               The picture to be concealed *      mbIdxX                MB horizontal location *      mbIdxY                MB vertical location *      mbData                Table of MB attributes *      refPicList            Reference picture list * * Function: *      Calculate the mismatch *       * Returns: *      Mismatch */static u_int32 selectDir(errorConcealment_s* pEc, int isUpOrDown, int mbIdxX, int mbIdxY){  if (isUpOrDown == 0) // if going downwards  // check if correctly received neighbours exist  {    // when the top mb is available    if ( mbIdxY > 0 && pEc->decodedMbs[mbIdxY-1][mbIdxX] == 1 ) {      return DIR_TOP;    }    // when the left mb is available    if ( mbIdxX > 0 && pEc->decodedMbs[mbIdxY][mbIdxX-1] == 1 ) {      return DIR_LEFT;    }    // when the right mb is available    if ( mbIdxX < (pEc->widthMbs-1) && pEc->decodedMbs[mbIdxY][mbIdxX+1] == 1 ) {        return DIR_RIGHT;    }    // when the bottom mb is available    if ( mbIdxY < (pEc->heightMbs-1) && pEc->decodedMbs[mbIdxY+1][mbIdxX] == 1 ) {      return DIR_BOTTOM;    }    // when the top mb is available    if ( mbIdxY > 0 && pEc->decodedMbs[mbIdxY-1][mbIdxX] == 2 ) {      return DIR_TOP;    }    // when the left mb is available    if ( mbIdxX > 0 && pEc->decodedMbs[mbIdxY][mbIdxX-1] == 2 ) {      return DIR_LEFT;    }    // when the right mb is available    if ( mbIdxX < (pEc->widthMbs-1) && pEc->decodedMbs[mbIdxY][mbIdxX+1] == 2 ) {        return DIR_RIGHT;    }    // when the bottom mb is available    if ( mbIdxY < (pEc->heightMbs-1) && pEc->decodedMbs[mbIdxY+1][mbIdxX] == 2 ) {      return DIR_BOTTOM;    }  }  else // going upwards  {    // when the bottom mb is available    if ( mbIdxY < (pEc->heightMbs-1) && pEc->decodedMbs[mbIdxY+1][mbIdxX] == 1 ) {      return DIR_BOTTOM;    }    // when the right mb is available    if ( mbIdxX < (pEc->widthMbs-1) && pEc->decodedMbs[mbIdxY][mbIdxX+1] == 1 ) {        return DIR_RIGHT;    }    // when the left mb is available    if ( mbIdxX > 0 && pEc->decodedMbs[mbIdxY][mbIdxX-1] == 1 ) {      return DIR_LEFT;    }    // when the top mb is available    if ( mbIdxY > 0 && pEc->decodedMbs[mbIdxY-1][mbIdxX] == 1 ) {      return DIR_TOP;    }    // when the bottom mb is available    if ( mbIdxY < (pEc->heightMbs-1) && pEc->decodedMbs[mbIdxY+1][mbIdxX] == 2 ) {      return DIR_BOTTOM;    }    // when the right mb is available    if ( mbIdxX < (pEc->widthMbs-1) && pEc->decodedMbs[mbIdxY][mbIdxX+1] == 2 ) {        return DIR_RIGHT;    }    // when the left mb is available    if ( mbIdxX > 0 && pEc->decodedMbs[mbIdxY][mbIdxX-1] == 2 ) {      return DIR_LEFT;    }    // when the top mb is available    if ( mbIdxY > 0 && pEc->decodedMbs[mbIdxY-1][mbIdxX] == 2 ) {      return DIR_TOP;    }  }  return DIR_ZERO;}/* * * initDir: * * Parameters: *      pEc                   EC object   *      refTab                Reference index buffer * * Function: *      Init the rank array (pEc->rank) before starting the concealment of current picture * * Returns: *      - */static void initDir(errorConcealment_s* pEc){  int start;  int i, j;  if (pEc->decodedMbs[0][0] != 0) {    pEc->dirDown = 1;    pEc->posDown = 1;  }  else {    pEc->dirDown = 0;  }  if (pEc->decodedMbs[pEc->heightMbs-1][pEc->widthMbs-1] != 0) {    pEc->dirUp = 1;    pEc->posUp = pEc->widthMbs*pEc->heightMbs - 1;  }  else {    pEc->dirUp = 0;  }  if (pEc->dirDown == 0 && pEc->dirUp == 0) {    start = -1;    for (j = 0; j < pEc->heightMbs && start < 0; j++) {      for (i = 0; i < pEc->widthMbs; i++) {        if (pEc->decodedMbs[j][i] != 0) {          start = j*pEc->widthMbs+i;          break;        }      }    }    if (start != -1) {      pEc->dirDown = 1;      pEc->posDown = start+1;      pEc->dirUp = 1;      pEc->posUp = start-1;    }  }  if (pEc->dirDown == 0 && pEc->dirUp == 0) {    pEc->dirDown = 1;    pEc->posDown = 0;  }  if (pEc->dirDown != 0)    pEc->dir = 0;   // going down  else    pEc->dir = 1;   // going up}static int selectDownwards(errorConcealment_s* pEc){  int i;  int found = -1;  if (pEc->dirDown == 0)    return found;  for (i=pEc->posDown; i<pEc->widthMbs*pEc->heightMbs; i++) {    if (pEc->decodedMbs[0][i] == 0) {      found = i;      pEc->posDown = i+1;      break;    }  }  if (found == -1)     pEc->dirDown = 0;  return found;}static int selectUpwards(errorConcealment_s* pEc){  int i;  int found = -1;  if (pEc->dirUp == 0)    return found;  for (i=pEc->posUp; i>=0; i--) {    if (pEc->decodedMbs[0][i] == 0) {      found = i;      pEc->posUp = i-1;      break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -