261 lines · 9.3 KB · C++
RawDownload
/*! * \copy *     Copyright (c)  2013, Cisco Systems *     All rights reserved. * *     Redistribution and use in source and binary forms, with or without *     modification, are permitted provided that the following conditions *     are met: * *        * Redistributions of source code must retain the above copyright *          notice, this list of conditions and the following disclaimer. * *        * Redistributions in binary form must reproduce the above copyright *          notice, this list of conditions and the following disclaimer in *          the documentation and/or other materials provided with the *          distribution. * *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *     POSSIBILITY OF SUCH DAMAGE. * */#include "AdaptiveQuantization.h" WELSVP_NAMESPACE_BEGIN   #define AVERAGE_TIME_MOTION                   (0.3) //0.3046875 // 1/4 + 1/16 - 1/128 ~ 0.3#define AVERAGE_TIME_TEXTURE_QUALITYMODE  (1.0) //0.5 // 1/2#define AVERAGE_TIME_TEXTURE_BITRATEMODE  (0.875) //0.5 // 1/2#define MODEL_ALPHA                           (0.9910) //1.5 //1.1102#define MODEL_TIME                            (5.8185) //9.0 //5.9842 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// CAdaptiveQuantization::CAdaptiveQuantization (int32_t iCpuFlag) {  m_CPUFlag = iCpuFlag;  m_eMethod   = METHOD_ADAPTIVE_QUANT;  m_pfVar   = NULL;  WelsMemset (&m_sAdaptiveQuantParam, 0, sizeof (m_sAdaptiveQuantParam));  WelsInitVarFunc (m_pfVar, m_CPUFlag);  XMMREG_PROTECT_INIT(AdaptiveQuantization);} CAdaptiveQuantization::~CAdaptiveQuantization() {  XMMREG_PROTECT_UNINIT(AdaptiveQuantization);} EResult CAdaptiveQuantization::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {  EResult eReturn = RET_INVALIDPARAM;   int32_t iWidth     = pSrcPixMap->sRect.iRectWidth;  int32_t iHeight    = pSrcPixMap->sRect.iRectHeight;  int32_t iMbWidth  = iWidth  >> 4;  int32_t iMbHeight = iHeight >> 4;  int32_t iMbTotalNum    = iMbWidth * iMbHeight;   SMotionTextureUnit* pMotionTexture = NULL;  SVAACalcResult*     pVaaCalcResults = NULL;  int8_t   iMotionTextureIndexToDeltaQp = 0;  int32_t	 iAverMotionTextureIndexToDeltaQp = 0;	// double to uint32  double_t dAverageMotionIndex = 0.0;	// double to float  double_t dAverageTextureIndex = 0.0;   double_t dQStep = 0.0;  double_t dLumaMotionDeltaQp = 0;  double_t dLumaTextureDeltaQp = 0;   uint8_t* pRefFrameY = NULL, *pCurFrameY = NULL;  int32_t iRefStride = 0, iCurStride = 0;   uint8_t* pRefFrameTmp = NULL, *pCurFrameTmp = NULL;  int32_t i = 0, j = 0;   pRefFrameY = (uint8_t*)pRefPixMap->pPixel[0];  pCurFrameY = (uint8_t*)pSrcPixMap->pPixel[0];   iRefStride  = pRefPixMap->iStride[0];  iCurStride  = pSrcPixMap->iStride[0];   /////////////////////////////////////// motion //////////////////////////////////  //  motion MB residual variance  dAverageMotionIndex = 0.0;  dAverageTextureIndex = 0.0;  pMotionTexture = m_sAdaptiveQuantParam.pMotionTextureUnit;  pVaaCalcResults = m_sAdaptiveQuantParam.pCalcResult;   if (pVaaCalcResults->pRefY == pRefFrameY && pVaaCalcResults->pCurY == pCurFrameY) {    int32_t iMbIndex = 0;    int32_t iSumDiff, iSQDiff, uiSum, iSQSum;    for (j = 0; j < iMbHeight; j ++) {      pRefFrameTmp  = pRefFrameY;      pCurFrameTmp  = pCurFrameY;      for (i = 0; i < iMbWidth; i++) {        XMMREG_PROTECT_STORE(AdaptiveQuantization);        iSumDiff =  pVaaCalcResults->pSad8x8[iMbIndex][0];        iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][1];        iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][2];        iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][3];         iSQDiff = pVaaCalcResults->pSsd16x16[iMbIndex];        uiSum = pVaaCalcResults->pSum16x16[iMbIndex];        iSQSum = pVaaCalcResults->pSumOfSquare16x16[iMbIndex];        XMMREG_PROTECT_LOAD(AdaptiveQuantization);         iSumDiff = iSumDiff >> 8;        pMotionTexture->uiMotionIndex = (iSQDiff >> 8) - (iSumDiff * iSumDiff);         uiSum = uiSum >> 8;        pMotionTexture->uiTextureIndex = (iSQSum >> 8) - (uiSum * uiSum);         dAverageMotionIndex += pMotionTexture->uiMotionIndex;        dAverageTextureIndex += pMotionTexture->uiTextureIndex;        pMotionTexture++;        ++iMbIndex;        pRefFrameTmp += MB_WIDTH_LUMA;        pCurFrameTmp += MB_WIDTH_LUMA;      }      pRefFrameY += (iRefStride) << 4;      pCurFrameY += (iCurStride) << 4;    }  } else {    for (j = 0; j < iMbHeight; j ++) {      pRefFrameTmp  = pRefFrameY;      pCurFrameTmp  = pCurFrameY;      for (i = 0; i < iMbWidth; i++) {        XMMREG_PROTECT_STORE(AdaptiveQuantization);        m_pfVar (pRefFrameTmp, iRefStride, pCurFrameTmp, iCurStride, pMotionTexture);        XMMREG_PROTECT_LOAD(AdaptiveQuantization);        dAverageMotionIndex += pMotionTexture->uiMotionIndex;        dAverageTextureIndex += pMotionTexture->uiTextureIndex;        pMotionTexture++;        pRefFrameTmp += MB_WIDTH_LUMA;        pCurFrameTmp += MB_WIDTH_LUMA;       }      pRefFrameY += (iRefStride) << 4;      pCurFrameY += (iCurStride) << 4;    }  }  dAverageMotionIndex = dAverageMotionIndex / iMbTotalNum;  dAverageTextureIndex = dAverageTextureIndex / iMbTotalNum;  if ((dAverageMotionIndex <= PESN) && (dAverageMotionIndex >= -PESN)) {    dAverageMotionIndex = 1.0;  }  if ((dAverageTextureIndex <= PESN) && (dAverageTextureIndex >= -PESN)) {    dAverageTextureIndex = 1.0;  }  //  motion mb residual map to QP  //  texture mb original map to QP  iAverMotionTextureIndexToDeltaQp = 0;  dAverageMotionIndex = AVERAGE_TIME_MOTION * dAverageMotionIndex;   if (m_sAdaptiveQuantParam.iAdaptiveQuantMode == AQ_QUALITY_MODE) {    dAverageTextureIndex = AVERAGE_TIME_TEXTURE_QUALITYMODE * dAverageTextureIndex;  } else {    dAverageTextureIndex = AVERAGE_TIME_TEXTURE_BITRATEMODE * dAverageTextureIndex;  }   pMotionTexture = m_sAdaptiveQuantParam.pMotionTextureUnit;  for (j = 0; j < iMbHeight; j ++) {    for (i = 0; i < iMbWidth; i++) {      double_t a = pMotionTexture->uiTextureIndex / dAverageTextureIndex;      dQStep = (a - 1) / (a + MODEL_ALPHA);      dLumaTextureDeltaQp = MODEL_TIME * dQStep;// range +- 6       iMotionTextureIndexToDeltaQp = (int8_t)dLumaTextureDeltaQp;       a = pMotionTexture->uiMotionIndex / dAverageMotionIndex;      dQStep = (a - 1) / (a + MODEL_ALPHA);      dLumaMotionDeltaQp = MODEL_TIME * dQStep;// range +- 6       if ((m_sAdaptiveQuantParam.iAdaptiveQuantMode == AQ_QUALITY_MODE && dLumaMotionDeltaQp < -PESN)          || (m_sAdaptiveQuantParam.iAdaptiveQuantMode == AQ_BITRATE_MODE)) {        iMotionTextureIndexToDeltaQp += (int8_t)dLumaMotionDeltaQp;      }       m_sAdaptiveQuantParam.pMotionTextureIndexToDeltaQp[j * iMbWidth + i] = iMotionTextureIndexToDeltaQp;      iAverMotionTextureIndexToDeltaQp += iMotionTextureIndexToDeltaQp;      pMotionTexture++;    }  }  m_sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp = (1.0 * iAverMotionTextureIndexToDeltaQp) / iMbTotalNum;   eReturn = RET_SUCCESS;   return eReturn;}   EResult CAdaptiveQuantization::Set (int32_t iType, void* pParam) {  if (pParam == NULL) {    return RET_INVALIDPARAM;  }   m_sAdaptiveQuantParam = * (SAdaptiveQuantizationParam*)pParam;   return RET_SUCCESS;} EResult CAdaptiveQuantization::Get (int32_t iType, void* pParam) {  if (pParam == NULL) {    return RET_INVALIDPARAM;  }   SAdaptiveQuantizationParam* sAdaptiveQuantParam = (SAdaptiveQuantizationParam*)pParam;   sAdaptiveQuantParam->dAverMotionTextureIndexToDeltaQp = m_sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp;   return RET_SUCCESS;} /////////////////////////////////////////////////////////////////////////////////////////////// void CAdaptiveQuantization::WelsInitVarFunc (PVarFunc& pfVar,  int32_t iCpuFlag) {  pfVar = SampleVariance16x16_c; #ifdef X86_ASM  if (iCpuFlag & WELS_CPU_SSE2) {    pfVar = SampleVariance16x16_sse2;  }#endif} void SampleVariance16x16_c (uint8_t* pRefY, int32_t iRefStride, uint8_t* pSrcY, int32_t iSrcStride,                            SMotionTextureUnit* pMotionTexture) {  uint32_t uiCurSquare = 0,  uiSquare = 0;  uint16_t uiCurSum = 0,  uiSum = 0;   for (int32_t y = 0; y < MB_WIDTH_LUMA; y++) {    for (int32_t x = 0; x < MB_WIDTH_LUMA; x++) {      uint32_t uiDiff = WELS_ABS (pRefY[x] - pSrcY[x]);      uiSum += uiDiff;      uiSquare += uiDiff * uiDiff;       uiCurSum += pSrcY[x];      uiCurSquare += pSrcY[x] * pSrcY[x];    }    pRefY += iRefStride;    pSrcY += iSrcStride;  }   uiSum = uiSum >> 8;  pMotionTexture->uiMotionIndex = (uiSquare >> 8) - (uiSum * uiSum);   uiCurSum = uiCurSum >> 8;  pMotionTexture->uiTextureIndex = (uiCurSquare >> 8) - (uiCurSum * uiCurSum);} WELSVP_NAMESPACE_END

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t