예제 #1
0
void CComplexityAnalysis::AnalyzeGomComplexityViaVar (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {
  int32_t iWidth     = pSrcPixMap->sRect.iRectWidth;
  int32_t iHeight    = pSrcPixMap->sRect.iRectHeight;
  int32_t iMbWidth  = iWidth  >> 4;
  int32_t iMbHeight = iHeight >> 4;
  int32_t iMbNum    = iMbWidth * iMbHeight;

  int32_t iMbNumInGom = m_sComplexityAnalysisParam.iMbNumInGom;
  int32_t iGomMbNum = (iMbNum + iMbNumInGom - 1) / iMbNumInGom;
  int32_t iGomSampleNum = 0;

  int32_t iGomMbStartIndex = 0, iGomMbEndIndex = 0, iGomMbRowNum = 0;
  int32_t iMbStartIndex = 0, iMbEndIndex = 0;
  int32_t iStartSampleIndex = 0;

  SVAACalcResult* pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult;
  int32_t*  pGomComplexity = (int32_t*)m_sComplexityAnalysisParam.pGomComplexity;

  uint8_t* pSrcY = NULL;
  int32_t iCurStride = 0;

  uint8_t* pCurTmp = NULL;
  uint32_t uiSampleSum = 0, uiSquareSum = 0;

  pSrcY = (uint8_t*)pSrcPixMap->pPixel[0];
  iCurStride  = pSrcPixMap->iStride[0];

  for (int32_t j = 0; j < iGomMbNum; j ++) {
    uiSampleSum = 0;
    uiSquareSum = 0;

    iGomMbStartIndex = j * iMbNumInGom;
    iGomMbEndIndex = WELS_MIN ((j + 1) * iMbNumInGom, iMbNum);
    iGomMbRowNum = (iGomMbEndIndex + iMbWidth - 1) / iMbWidth  - iGomMbStartIndex / iMbWidth;

    iMbStartIndex = iGomMbStartIndex;
    iMbEndIndex = WELS_MIN ((iMbStartIndex / iMbWidth + 1) * iMbWidth, iGomMbEndIndex);

    iStartSampleIndex  = (iMbStartIndex / iMbWidth) * MB_WIDTH_LUMA * iCurStride + (iMbStartIndex % iMbWidth) *
                         MB_WIDTH_LUMA;
    iGomSampleNum = (iMbEndIndex - iMbStartIndex) * MB_WIDTH_LUMA * MB_WIDTH_LUMA;

    do {
      pCurTmp = pSrcY + iStartSampleIndex;

      for (int32_t i = iMbStartIndex; i < iMbEndIndex; i ++) {
        uiSampleSum += pVaaCalcResults->pSum16x16[i];
        uiSquareSum += pVaaCalcResults->pSumOfSquare16x16[i];
      }

      iMbStartIndex = iMbEndIndex;
      iMbEndIndex = WELS_MIN (iMbEndIndex + iMbWidth, iGomMbEndIndex);

      iStartSampleIndex  = (iMbStartIndex / iMbWidth) * MB_WIDTH_LUMA * iCurStride + (iMbStartIndex % iMbWidth) *
                           MB_WIDTH_LUMA;
    } while (--iGomMbRowNum);

    pGomComplexity[j] = uiSquareSum - (uiSampleSum * uiSampleSum / iGomSampleNum);
  }
}
예제 #2
0
void CComplexityAnalysis::AnalyzeGomComplexityViaSad (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {
  int32_t iWidth     = pSrcPixMap->sRect.iRectWidth;
  int32_t iHeight    = pSrcPixMap->sRect.iRectHeight;
  int32_t iMbWidth  = iWidth  >> 4;
  int32_t iMbHeight = iHeight >> 4;
  int32_t iMbNum    = iMbWidth * iMbHeight;

  int32_t iMbNumInGom = m_sComplexityAnalysisParam.iMbNumInGom;
  int32_t iGomMbNum = (iMbNum + iMbNumInGom - 1) / iMbNumInGom;

  int32_t iGomMbStartIndex = 0, iGomMbEndIndex = 0, iGomMbRowNum = 0;
  int32_t iMbStartIndex = 0, iMbEndIndex = 0;

  uint8_t* pBackgroundMbFlag = (uint8_t*)m_sComplexityAnalysisParam.pBackgroundMbFlag;
  uint32_t* uiRefMbType = (uint32_t*)m_sComplexityAnalysisParam.uiRefMbType;
  SVAACalcResult* pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult;
  int32_t*  pGomForegroundBlockNum = (int32_t*)m_sComplexityAnalysisParam.pGomForegroundBlockNum;
  int32_t*  pGomComplexity = (int32_t*)m_sComplexityAnalysisParam.pGomComplexity;


  uint32_t uiGomSad = 0, uiFrameSad = 0;

  InitGomSadFunc (m_pfGomSad, m_sComplexityAnalysisParam.iCalcBgd);

  for (int32_t j = 0; j < iGomMbNum; j ++) {
    uiGomSad = 0;

    iGomMbStartIndex = j * iMbNumInGom;
    iGomMbEndIndex = WELS_MIN ((j + 1) * iMbNumInGom, iMbNum);
    iGomMbRowNum = (iGomMbEndIndex + iMbWidth - 1) / iMbWidth  - iGomMbStartIndex / iMbWidth;

    iMbStartIndex = iGomMbStartIndex;
    iMbEndIndex = WELS_MIN ((iMbStartIndex / iMbWidth + 1) * iMbWidth, iGomMbEndIndex);

    do {
      for (int32_t i = iMbStartIndex; i < iMbEndIndex; i ++) {
        m_pfGomSad (&uiGomSad, pGomForegroundBlockNum + j, pVaaCalcResults->pSad8x8[i], pBackgroundMbFlag[i]
                    && !IS_INTRA (uiRefMbType[i]));
      }

      iMbStartIndex = iMbEndIndex;
      iMbEndIndex = WELS_MIN (iMbEndIndex + iMbWidth , iGomMbEndIndex);

    } while (--iGomMbRowNum);

    pGomComplexity[j] = uiGomSad;
    uiFrameSad += pGomComplexity[j];
  }

  m_sComplexityAnalysisParam.iFrameComplexity = uiFrameSad;
}
예제 #3
0
void CComplexityAnalysis::AnalyzeGomComplexityViaVar (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {
    int32_t iWidth     = pSrcPixMap->sRect.iRectWidth;
    int32_t iHeight    = pSrcPixMap->sRect.iRectHeight;
    int32_t iMbWidth  = iWidth  >> 4;
    int32_t iMbHeight = iHeight >> 4;
    int32_t iMbNum    = iMbWidth * iMbHeight;

    int32_t iMbNumInGom = m_sComplexityAnalysisParam.iMbNumInGom;
    int32_t iGomMbNum = (iMbNum + iMbNumInGom - 1) / iMbNumInGom;
    int32_t iGomSampleNum = 0;

    int32_t iGomMbStartIndex = 0, iGomMbEndIndex = 0, iGomMbRowNum = 0;
    int32_t iMbStartIndex = 0, iMbEndIndex = 0;

    SVAACalcResult* pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult;
    int32_t*  pGomComplexity = (int32_t*)m_sComplexityAnalysisParam.pGomComplexity;
    uint32_t  uiFrameSad = 0;

    uint32_t uiSampleSum = 0, uiSquareSum = 0;

    for (int32_t j = 0; j < iGomMbNum; j ++) {
        uiSampleSum = 0;
        uiSquareSum = 0;

        iGomMbStartIndex = j * iMbNumInGom;
        iGomMbEndIndex = WELS_MIN ((j + 1) * iMbNumInGom, iMbNum);
        iGomMbRowNum = (iGomMbEndIndex + iMbWidth - 1) / iMbWidth  - iGomMbStartIndex / iMbWidth;

        iMbStartIndex = iGomMbStartIndex;
        iMbEndIndex = WELS_MIN ((iMbStartIndex / iMbWidth + 1) * iMbWidth, iGomMbEndIndex);

        iGomSampleNum = (iMbEndIndex - iMbStartIndex) * MB_WIDTH_LUMA * MB_WIDTH_LUMA;

        do {
            for (int32_t i = iMbStartIndex; i < iMbEndIndex; i ++) {
                uiSampleSum += pVaaCalcResults->pSum16x16[i];
                uiSquareSum += pVaaCalcResults->pSumOfSquare16x16[i];
            }

            iMbStartIndex = iMbEndIndex;
            iMbEndIndex = WELS_MIN (iMbEndIndex + iMbWidth, iGomMbEndIndex);

        } while (--iGomMbRowNum);

        pGomComplexity[j] = uiSquareSum - (uiSampleSum * uiSampleSum / iGomSampleNum);
        uiFrameSad += pGomComplexity[j];
    }
    m_sComplexityAnalysisParam.iFrameComplexity = uiFrameSad;
}
예제 #4
0
int32_t CComplexityAnalysis::GetFrameSadExcludeBackground (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {
  int32_t iWidth     = pSrcPixMap->sRect.iRectWidth;
  int32_t iHeight    = pSrcPixMap->sRect.iRectHeight;
  int32_t iMbWidth  = iWidth  >> 4;
  int32_t iMbHeight = iHeight >> 4;
  int32_t iMbNum    = iMbWidth * iMbHeight;

  int32_t iMbNumInGom = m_sComplexityAnalysisParam.iMbNumInGom;
  int32_t iGomMbNum = (iMbNum + iMbNumInGom - 1) / iMbNumInGom;
  int32_t iGomMbStartIndex = 0, iGomMbEndIndex = 0;

  uint8_t* pBackgroundMbFlag = (uint8_t*)m_sComplexityAnalysisParam.pBackgroundMbFlag;
  uint32_t* uiRefMbType = (uint32_t*)m_sComplexityAnalysisParam.uiRefMbType;
  SVAACalcResult* pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult;
  int32_t*  pGomForegroundBlockNum = m_sComplexityAnalysisParam.pGomForegroundBlockNum;

  uint32_t uiFrameSad = 0;
  for (int32_t j = 0; j < iGomMbNum; j ++) {
    iGomMbStartIndex = j * iMbNumInGom;
    iGomMbEndIndex = WELS_MIN ((j + 1) * iMbNumInGom, iMbNum);

    for (int32_t i = iGomMbStartIndex; i < iGomMbEndIndex; i ++) {
      if (pBackgroundMbFlag[i] == 0 || IS_INTRA (uiRefMbType[i])) {
        pGomForegroundBlockNum[j]++;
        uiFrameSad += pVaaCalcResults->pSad8x8[i][0];
        uiFrameSad += pVaaCalcResults->pSad8x8[i][1];
        uiFrameSad += pVaaCalcResults->pSad8x8[i][2];
        uiFrameSad += pVaaCalcResults->pSad8x8[i][3];
      }
    }
  }

  return (uiFrameSad);
}
예제 #5
0
void CComplexityAnalysisScreen::GomComplexityAnalysisIntra (SPixMap* pSrc) {
    int32_t iWidth                  = pSrc->sRect.iRectWidth;
    int32_t iHeight                 = pSrc->sRect.iRectHeight;
    int32_t iBlockWidth             = iWidth  >> 4;
    int32_t iBlockHeight            = iHeight >> 4;

    int32_t iBlockSadH, iBlockSadV, iGomSad = 0;
    int32_t iIdx = 0;

    uint8_t* pPtrY = NULL;
    int32_t iStrideY = 0;
    int32_t iRowStrideY = 0;

    uint8_t* pTmpCur = NULL;

    ENFORCE_STACK_ALIGN_1D (uint8_t, iMemPredMb, 256, 16)

    pPtrY = (uint8_t*)pSrc->pPixel[0];

    iStrideY  = pSrc->iStride[0];
    iRowStrideY = iStrideY << 4;

    m_ComplexityAnalysisParam.iFrameComplexity = 0;

    for (int32_t j = 0; j < iBlockHeight; j ++) {
        pTmpCur = pPtrY;

        for (int32_t i = 0; i < iBlockWidth; i++) {
            iBlockSadH = iBlockSadV = 0x7fffffff; // INT_MAX
            if (j > 0) {
                m_pIntraFunc[0] (iMemPredMb, pTmpCur, iStrideY);
                iBlockSadH = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
            }
            if (i > 0) {
                m_pIntraFunc[1] (iMemPredMb, pTmpCur, iStrideY);
                iBlockSadV = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
            }
            if (i || j)
                iGomSad += WELS_MIN (iBlockSadH, iBlockSadV);

            pTmpCur += 16;

            if (i == iBlockWidth - 1 && ((j + 1) % m_ComplexityAnalysisParam.iMbRowInGom == 0 || j == iBlockHeight - 1)) {
                m_ComplexityAnalysisParam.pGomComplexity[iIdx] = iGomSad;
                m_ComplexityAnalysisParam.iFrameComplexity += iGomSad;
                iIdx++;
                iGomSad = 0;
            }
        }

        pPtrY += iRowStrideY;
    }
    m_ComplexityAnalysisParam.iGomNumInFrame = iIdx;
}
예제 #6
0
int32_t PredIntra4x4Mode (int8_t* pIntraPredMode, int32_t iIdx4) {
  int8_t iTopMode  = pIntraPredMode[g_kuiScan8[iIdx4] - 8];
  int8_t iLeftMode = pIntraPredMode[g_kuiScan8[iIdx4] - 1];
  int8_t iBestMode;

  if (-1 == iLeftMode || -1 == iTopMode) {
    iBestMode = 2;
  } else {
    iBestMode = WELS_MIN (iLeftMode, iTopMode);
  }
  return iBestMode;
}
void ScrollDetectionCore (SPixMap* pSrcPixMap, SPixMap* pRefPixMap, int32_t iWidth, int32_t iHeight,
                          int32_t iOffsetX, int32_t iOffsetY, SScrollDetectionParam& sScrollDetectionParam) {
  bool bScrollDetected = 0;
  uint8_t* pYLine;
  uint8_t* pYTmp;
  int32_t iTestPos, iSearchPos = 0, iOffsetAbs, iMaxAbs;
  int32_t iPicHeight = pRefPixMap->sRect.iRectHeight;
  int32_t iMinHeight = WELS_MAX (iOffsetY, 0);
  int32_t iMaxHeight = WELS_MIN (iOffsetY + iHeight - 1, iPicHeight - 1) ; //offset_y + height - 1;//
  uint8_t* pYRef, *pYSrc;
  int32_t iYStride;

  pYRef = (uint8_t*)pRefPixMap->pPixel[0];
  pYSrc = (uint8_t*)pSrcPixMap->pPixel[0];
  iYStride = pRefPixMap->iStride[0];

  iTestPos = SelectTestLine (pYSrc, iWidth, iHeight, iPicHeight, iYStride, iOffsetX, iOffsetY);

  if (iTestPos == -1) {
    sScrollDetectionParam.bScrollDetectFlag = 0;
    return;
  }
  pYLine = pYSrc + iYStride * iTestPos + iOffsetX;
  iMaxAbs = WELS_MIN (WELS_MAX (iTestPos - iMinHeight - 1, iMaxHeight - iTestPos), MAX_SCROLL_MV_Y);
  iSearchPos = iTestPos;
  for (iOffsetAbs = 0; iOffsetAbs <= iMaxAbs; iOffsetAbs++) {
    iSearchPos = iTestPos + iOffsetAbs;
    if (iSearchPos <= iMaxHeight) {
      pYTmp = pYRef + iSearchPos * iYStride + iOffsetX;
      if (!CompareLine (pYLine, pYTmp, iWidth)) {
        uint8_t* pYUpper, *pYLineUpper;
        int32_t iCheckedLines;
        int32_t iLowOffset = WELS_MIN (iMaxHeight - iSearchPos, CHECK_OFFSET);
        int32_t i;

        iCheckedLines = WELS_MIN (iTestPos - iMinHeight + iLowOffset, 2 * CHECK_OFFSET);
        pYUpper = pYTmp - (iCheckedLines - iLowOffset) * iYStride;
        pYLineUpper = pYLine - (iCheckedLines - iLowOffset) * iYStride;

        for (i = 0; i < iCheckedLines; i ++) {
          if (CompareLine (pYLineUpper, pYUpper, iWidth)) {
            break;
          }
          pYUpper += iYStride;
          pYLineUpper += iYStride;
        }
        if (i == iCheckedLines) {
          bScrollDetected = 1;
          break;
        }
      }
    }

    iSearchPos = iTestPos - iOffsetAbs - 1;
    if (iSearchPos >= iMinHeight) {
      pYTmp = pYRef + iSearchPos * iYStride + iOffsetX;
      if (!CompareLine (pYLine, pYTmp, iWidth)) {
        uint8_t* pYUpper, *pYLineUpper;
        int32_t iCheckedLines;
        int32_t iUpOffset = WELS_MIN (iSearchPos - iMinHeight, CHECK_OFFSET);
        int32_t i;

        pYUpper = pYTmp - iUpOffset * iYStride;
        pYLineUpper = pYLine - iUpOffset * iYStride;
        iCheckedLines = WELS_MIN (iMaxHeight - iTestPos + iUpOffset, 2 * CHECK_OFFSET);

        for (i = 0; i < iCheckedLines; i ++) {
          if (CompareLine (pYLineUpper, pYUpper, iWidth)) {
            break;
          }
          pYUpper += iYStride;
          pYLineUpper += iYStride;
        }
        if (i == iCheckedLines) {
          bScrollDetected = 1;
          break;
        }
      }
    }
  }

  if (!bScrollDetected) {
    sScrollDetectionParam.bScrollDetectFlag = 0;
  } else {
    sScrollDetectionParam.bScrollDetectFlag = 1;
    sScrollDetectionParam.iScrollMvY = iSearchPos - iTestPos; // pre_pos - cur_pos, change to mv
    sScrollDetectionParam.iScrollMvX = 0;
  }
}
예제 #8
0
void CComplexityAnalysisScreen::GomComplexityAnalysisInter (SPixMap* pSrc, SPixMap* pRef, bool bScrollFlag) {
    int32_t iWidth                  = pSrc->sRect.iRectWidth;
    int32_t iHeight                 = pSrc->sRect.iRectHeight;
    int32_t iBlockWidth             = iWidth  >> 4;
    int32_t iBlockHeight            = iHeight >> 4;

    int32_t iInterSad, iScrollSad, iBlockSadH, iBlockSadV, iGomSad = 0;
    int32_t iIdx = 0;

    int32_t iScrollMvX = m_ComplexityAnalysisParam.sScrollResult.iScrollMvX;
    int32_t iScrollMvY = m_ComplexityAnalysisParam.sScrollResult.iScrollMvY;

    uint8_t* pPtrX = NULL, *pPtrY = NULL;
    int32_t iStrideX = 0, iStrideY = 0;
    int32_t iRowStrideX = 0, iRowStrideY = 0;

    uint8_t* pTmpRef = NULL, *pTmpCur = NULL, *pTmpRefScroll = NULL;

    ENFORCE_STACK_ALIGN_1D (uint8_t, iMemPredMb, 256, 16)

    pPtrX = (uint8_t*)pRef->pPixel[0];
    pPtrY = (uint8_t*)pSrc->pPixel[0];

    iStrideX  = pRef->iStride[0];
    iStrideY  = pSrc->iStride[0];

    iRowStrideX  = pRef->iStride[0] << 4;
    iRowStrideY  = pSrc->iStride[0] << 4;

    m_ComplexityAnalysisParam.iFrameComplexity = 0;

    for (int32_t j = 0; j < iBlockHeight; j ++) {
        pTmpRef  = pPtrX;
        pTmpCur  = pPtrY;

        for (int32_t i = 0; i < iBlockWidth; i++) {
            int32_t iBlockPointX = i << 4;
            int32_t iBlockPointY = j << 4;

            iInterSad = m_pSadFunc (pTmpCur, iStrideY, pTmpRef, iStrideX);
            if (bScrollFlag) {
                if ((iInterSad != 0) &&
                        (iBlockPointX + iScrollMvX >= 0) && (iBlockPointX + iScrollMvX <= iWidth - 8) &&
                        (iBlockPointY + iScrollMvY >= 0) && (iBlockPointY + iScrollMvY <= iHeight - 8)) {
                    pTmpRefScroll = pTmpRef - iScrollMvY * iStrideX + iScrollMvX;
                    iScrollSad = m_pSadFunc (pTmpCur, iStrideY, pTmpRefScroll, iStrideX);

                    if (iScrollSad < iInterSad) {
                        iInterSad = iScrollSad;
                    }
                }

            }

            iBlockSadH = iBlockSadV = 0x7fffffff; // INT_MAX

            if (j > 0) {
                m_pIntraFunc[0] (iMemPredMb, pTmpCur, iStrideY);
                iBlockSadH = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
            }
            if (i > 0) {
                m_pIntraFunc[1] (iMemPredMb, pTmpCur, iStrideY);
                iBlockSadV = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
            }

            iGomSad += WELS_MIN (WELS_MIN (iBlockSadH, iBlockSadV), iInterSad);

            if (i == iBlockWidth - 1 && ((j + 1) % m_ComplexityAnalysisParam.iMbRowInGom == 0 || j == iBlockHeight - 1)) {
                m_ComplexityAnalysisParam.pGomComplexity[iIdx] = iGomSad;
                m_ComplexityAnalysisParam.iFrameComplexity += iGomSad;
                iIdx++;
                iGomSad = 0;
            }

            pTmpRef += 16;
            pTmpCur += 16;
        }
        pPtrX += iRowStrideX;
        pPtrY += iRowStrideY;
    }
    m_ComplexityAnalysisParam.iGomNumInFrame = iIdx;
}