Showing the changes to codec/processing/src/adaptivequantization (2 of 124 files). Show all
Unified · Split
| @@ -0,0 +1,256 @@ | ||
| 1 | +/*! | |
| 2 | + * \copy | |
| 3 | + * Copyright (c) 2013, Cisco Systems | |
| 4 | + * All rights reserved. | |
| 5 | + * | |
| 6 | + * Redistribution and use in source and binary forms, with or without | |
| 7 | + * modification, are permitted provided that the following conditions | |
| 8 | + * are met: | |
| 9 | + * | |
| 10 | + * * Redistributions of source code must retain the above copyright | |
| 11 | + * notice, this list of conditions and the following disclaimer. | |
| 12 | + * | |
| 13 | + * * Redistributions in binary form must reproduce the above copyright | |
| 14 | + * notice, this list of conditions and the following disclaimer in | |
| 15 | + * the documentation and/or other materials provided with the | |
| 16 | + * distribution. | |
| 17 | + * | |
| 18 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 | + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
| 21 | + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
| 22 | + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
| 23 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
| 24 | + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 25 | + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
| 26 | + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 27 | + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |
| 28 | + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 29 | + * POSSIBILITY OF SUCH DAMAGE. | |
| 30 | + * | |
| 31 | + */ | |
| 32 | +#include "AdaptiveQuantization.h" | |
| 33 | +#include "../common/cpu.h" | |
| 34 | + | |
| 35 | +WELSVP_NAMESPACE_BEGIN | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | +#define AVERAGE_TIME_MOTION (0.3) //0.3046875 // 1/4 + 1/16 - 1/128 ~ 0.3 | |
| 40 | +#define AVERAGE_TIME_TEXTURE_QUALITYMODE (1.0) //0.5 // 1/2 | |
| 41 | +#define AVERAGE_TIME_TEXTURE_BITRATEMODE (0.875) //0.5 // 1/2 | |
| 42 | +#define MODEL_ALPHA (0.9910) //1.5 //1.1102 | |
| 43 | +#define MODEL_TIME (5.8185) //9.0 //5.9842 | |
| 44 | + | |
| 45 | +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 46 | + | |
| 47 | +CAdaptiveQuantization::CAdaptiveQuantization (int32_t iCpuFlag) { | |
| 48 | + m_CPUFlag = iCpuFlag; | |
| 49 | + m_eMethod = METHOD_ADAPTIVE_QUANT; | |
| 50 | + m_pfVar = NULL; | |
| 51 | + WelsMemset (&m_sAdaptiveQuantParam, 0, sizeof (m_sAdaptiveQuantParam)); | |
| 52 | + WelsInitVarFunc (m_pfVar, m_CPUFlag); | |
| 53 | +} | |
| 54 | + | |
| 55 | +CAdaptiveQuantization::~CAdaptiveQuantization() { | |
| 56 | +} | |
| 57 | + | |
| 58 | +EResult CAdaptiveQuantization::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { | |
| 59 | + EResult eReturn = RET_INVALIDPARAM; | |
| 60 | + | |
| 61 | + int32_t iWidth = pSrcPixMap->sRect.iRectWidth; | |
| 62 | + int32_t iHeight = pSrcPixMap->sRect.iRectHeight; | |
| 63 | + int32_t iMbWidth = iWidth >> 4; | |
| 64 | + int32_t iMbHeight = iHeight >> 4; | |
| 65 | + int32_t iMbTotalNum = iMbWidth * iMbHeight; | |
| 66 | + | |
| 67 | + SMotionTextureUnit* pMotionTexture = NULL; | |
| 68 | + SVAACalcResult* pVaaCalcResults = NULL; | |
| 69 | + int8_t iMotionTextureIndexToDeltaQp = 0; | |
| 70 | + int32_t iAverMotionTextureIndexToDeltaQp = 0; // double to uint32 | |
| 71 | + double_t dAverageMotionIndex = 0.0; // double to float | |
| 72 | + double_t dAverageTextureIndex = 0.0; | |
| 73 | + | |
| 74 | + double_t dQStep = 0.0; | |
| 75 | + double_t dLumaMotionDeltaQp = 0; | |
| 76 | + double_t dLumaTextureDeltaQp = 0; | |
| 77 | + | |
| 78 | + uint8_t* pRefFrameY = NULL, *pCurFrameY = NULL; | |
| 79 | + int32_t iRefStride = 0, iCurStride = 0; | |
| 80 | + | |
| 81 | + uint8_t* pRefFrameTmp = NULL, *pCurFrameTmp = NULL; | |
| 82 | + int32_t i = 0, j = 0; | |
| 83 | + | |
| 84 | + pRefFrameY = (uint8_t*)pRefPixMap->pPixel[0]; | |
| 85 | + pCurFrameY = (uint8_t*)pSrcPixMap->pPixel[0]; | |
| 86 | + | |
| 87 | + iRefStride = pRefPixMap->iStride[0]; | |
| 88 | + iCurStride = pSrcPixMap->iStride[0]; | |
| 89 | + | |
| 90 | + /////////////////////////////////////// motion ////////////////////////////////// | |
| 91 | + // motion MB residual variance | |
| 92 | + dAverageMotionIndex = 0.0; | |
| 93 | + dAverageTextureIndex = 0.0; | |
| 94 | + pMotionTexture = m_sAdaptiveQuantParam.pMotionTextureUnit; | |
| 95 | + pVaaCalcResults = m_sAdaptiveQuantParam.pCalcResult; | |
| 96 | + | |
| 97 | + if (pVaaCalcResults->pRefY == pRefFrameY && pVaaCalcResults->pCurY == pCurFrameY) { | |
| 98 | + int32_t iMbIndex = 0; | |
| 99 | + int32_t iSumDiff, iSQDiff, uiSum, iSQSum; | |
| 100 | + for (j = 0; j < iMbHeight; j ++) { | |
| 101 | + pRefFrameTmp = pRefFrameY; | |
| 102 | + pCurFrameTmp = pCurFrameY; | |
| 103 | + for (i = 0; i < iMbWidth; i++) { | |
| 104 | + iSumDiff = pVaaCalcResults->pSad8x8[iMbIndex][0]; | |
| 105 | + iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][1]; | |
| 106 | + iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][2]; | |
| 107 | + iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][3]; | |
| 108 | + | |
| 109 | + iSQDiff = pVaaCalcResults->pSsd16x16[iMbIndex]; | |
| 110 | + uiSum = pVaaCalcResults->pSum16x16[iMbIndex]; | |
| 111 | + iSQSum = pVaaCalcResults->pSumOfSquare16x16[iMbIndex]; | |
| 112 | + | |
| 113 | + iSumDiff = iSumDiff >> 8; | |
| 114 | + pMotionTexture->uiMotionIndex = (iSQDiff >> 8) - (iSumDiff * iSumDiff); | |
| 115 | + | |
| 116 | + uiSum = uiSum >> 8; | |
| 117 | + pMotionTexture->uiTextureIndex = (iSQSum >> 8) - (uiSum * uiSum); | |
| 118 | + | |
| 119 | + dAverageMotionIndex += pMotionTexture->uiMotionIndex; | |
| 120 | + dAverageTextureIndex += pMotionTexture->uiTextureIndex; | |
| 121 | + pMotionTexture++; | |
| 122 | + ++iMbIndex; | |
| 123 | + pRefFrameTmp += MB_WIDTH_LUMA; | |
| 124 | + pCurFrameTmp += MB_WIDTH_LUMA; | |
| 125 | + } | |
| 126 | + pRefFrameY += (iRefStride) << 4; | |
| 127 | + pCurFrameY += (iCurStride) << 4; | |
| 128 | + } | |
| 129 | + } else { | |
| 130 | + for (j = 0; j < iMbHeight; j ++) { | |
| 131 | + pRefFrameTmp = pRefFrameY; | |
| 132 | + pCurFrameTmp = pCurFrameY; | |
| 133 | + for (i = 0; i < iMbWidth; i++) { | |
| 134 | + m_pfVar (pRefFrameTmp, iRefStride, pCurFrameTmp, iCurStride, pMotionTexture); | |
| 135 | + dAverageMotionIndex += pMotionTexture->uiMotionIndex; | |
| 136 | + dAverageTextureIndex += pMotionTexture->uiTextureIndex; | |
| 137 | + pMotionTexture++; | |
| 138 | + pRefFrameTmp += MB_WIDTH_LUMA; | |
| 139 | + pCurFrameTmp += MB_WIDTH_LUMA; | |
| 140 | + | |
| 141 | + } | |
| 142 | + pRefFrameY += (iRefStride) << 4; | |
| 143 | + pCurFrameY += (iCurStride) << 4; | |
| 144 | + } | |
| 145 | + } | |
| 146 | + dAverageMotionIndex = dAverageMotionIndex / iMbTotalNum; | |
| 147 | + dAverageTextureIndex = dAverageTextureIndex / iMbTotalNum; | |
| 148 | + if ((dAverageMotionIndex <= PESN) && (dAverageMotionIndex >= -PESN)) { | |
| 149 | + dAverageMotionIndex = 1.0; | |
| 150 | + } | |
| 151 | + if ((dAverageTextureIndex <= PESN) && (dAverageTextureIndex >= -PESN)) { | |
| 152 | + dAverageTextureIndex = 1.0; | |
| 153 | + } | |
| 154 | + // motion mb residual map to QP | |
| 155 | + // texture mb original map to QP | |
| 156 | + iAverMotionTextureIndexToDeltaQp = 0; | |
| 157 | + dAverageMotionIndex = AVERAGE_TIME_MOTION * dAverageMotionIndex; | |
| 158 | + | |
| 159 | + if (m_sAdaptiveQuantParam.iAdaptiveQuantMode == AQ_QUALITY_MODE) { | |
| 160 | + dAverageTextureIndex = AVERAGE_TIME_TEXTURE_QUALITYMODE * dAverageTextureIndex; | |
| 161 | + } else { | |
| 162 | + dAverageTextureIndex = AVERAGE_TIME_TEXTURE_BITRATEMODE * dAverageTextureIndex; | |
| 163 | + } | |
| 164 | + | |
| 165 | + pMotionTexture = m_sAdaptiveQuantParam.pMotionTextureUnit; | |
| 166 | + for (j = 0; j < iMbHeight; j ++) { | |
| 167 | + for (i = 0; i < iMbWidth; i++) { | |
| 168 | + double_t a = pMotionTexture->uiTextureIndex / dAverageTextureIndex; | |
| 169 | + dQStep = (a - 1) / (a + MODEL_ALPHA); | |
| 170 | + dLumaTextureDeltaQp = MODEL_TIME * dQStep;// range +- 6 | |
| 171 | + | |
| 172 | + iMotionTextureIndexToDeltaQp = (int8_t)dLumaTextureDeltaQp; | |
| 173 | + | |
| 174 | + a = pMotionTexture->uiMotionIndex / dAverageMotionIndex; | |
| 175 | + dQStep = (a - 1) / (a + MODEL_ALPHA); | |
| 176 | + dLumaMotionDeltaQp = MODEL_TIME * dQStep;// range +- 6 | |
| 177 | + | |
| 178 | + if ((m_sAdaptiveQuantParam.iAdaptiveQuantMode == AQ_QUALITY_MODE && dLumaMotionDeltaQp < -PESN) | |
| 179 | + || (m_sAdaptiveQuantParam.iAdaptiveQuantMode == AQ_BITRATE_MODE)) { | |
| 180 | + iMotionTextureIndexToDeltaQp += (int8_t)dLumaMotionDeltaQp; | |
| 181 | + } | |
| 182 | + | |
| 183 | + m_sAdaptiveQuantParam.pMotionTextureIndexToDeltaQp[j * iMbWidth + i] = iMotionTextureIndexToDeltaQp; | |
| 184 | + iAverMotionTextureIndexToDeltaQp += iMotionTextureIndexToDeltaQp; | |
| 185 | + pMotionTexture++; | |
| 186 | + } | |
| 187 | + } | |
| 188 | + m_sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp = (1.0 * iAverMotionTextureIndexToDeltaQp) / iMbTotalNum; | |
| 189 | + | |
| 190 | + eReturn = RET_SUCCESS; | |
| 191 | + | |
| 192 | + return eReturn; | |
| 193 | +} | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | +EResult CAdaptiveQuantization::Set (int32_t iType, void* pParam) { | |
| 198 | + if (pParam == NULL) { | |
| 199 | + return RET_INVALIDPARAM; | |
| 200 | + } | |
| 201 | + | |
| 202 | + m_sAdaptiveQuantParam = * (SAdaptiveQuantizationParam*)pParam; | |
| 203 | + | |
| 204 | + return RET_SUCCESS; | |
| 205 | +} | |
| 206 | + | |
| 207 | +EResult CAdaptiveQuantization::Get (int32_t iType, void* pParam) { | |
| 208 | + if (pParam == NULL) { | |
| 209 | + return RET_INVALIDPARAM; | |
| 210 | + } | |
| 211 | + | |
| 212 | + SAdaptiveQuantizationParam* sAdaptiveQuantParam = (SAdaptiveQuantizationParam*)pParam; | |
| 213 | + | |
| 214 | + sAdaptiveQuantParam->dAverMotionTextureIndexToDeltaQp = m_sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp; | |
| 215 | + | |
| 216 | + return RET_SUCCESS; | |
| 217 | +} | |
| 218 | + | |
| 219 | +/////////////////////////////////////////////////////////////////////////////////////////////// | |
| 220 | + | |
| 221 | +void CAdaptiveQuantization::WelsInitVarFunc (PVarFunc& pfVar, int32_t iCpuFlag) { | |
| 222 | + pfVar = SampleVariance16x16_c; | |
| 223 | + | |
| 224 | +#ifdef X86_ASM | |
| 225 | + if (iCpuFlag & WELS_CPU_SSE2) { | |
| 226 | + // pfVar = SampleVariance16x16_sse2; | |
| 227 | + } | |
| 228 | +#endif | |
| 229 | +} | |
| 230 | + | |
| 231 | +void SampleVariance16x16_c (uint8_t* pRefY, int32_t iRefStride, uint8_t* pSrcY, int32_t iSrcStride, | |
| 232 | + SMotionTextureUnit* pMotionTexture) { | |
| 233 | + uint32_t uiCurSquare = 0, uiSquare = 0; | |
| 234 | + uint16_t uiCurSum = 0, uiSum = 0; | |
| 235 | + | |
| 236 | + for (int32_t y = 0; y < MB_WIDTH_LUMA; y++) { | |
| 237 | + for (int32_t x = 0; x < MB_WIDTH_LUMA; x++) { | |
| 238 | + uint32_t uiDiff = WELS_ABS (pRefY[x] - pSrcY[x]); | |
| 239 | + uiSum += uiDiff; | |
| 240 | + uiSquare += uiDiff * uiDiff; | |
| 241 | + | |
| 242 | + uiCurSum += pSrcY[x]; | |
| 243 | + uiCurSquare += pSrcY[x] * pSrcY[x]; | |
| 244 | + } | |
| 245 | + pRefY += iRefStride; | |
| 246 | + pSrcY += iSrcStride; | |
| 247 | + } | |
| 248 | + | |
| 249 | + uiSum = uiSum >> 8; | |
| 250 | + pMotionTexture->uiMotionIndex = (uiSquare >> 8) - (uiSum * uiSum); | |
| 251 | + | |
| 252 | + uiCurSum = uiCurSum >> 8; | |
| 253 | + pMotionTexture->uiTextureIndex = (uiCurSquare >> 8) - (uiCurSum * uiCurSum); | |
| 254 | +} | |
| 255 | + | |
| 256 | +WELSVP_NAMESPACE_END | |
| @@ -0,0 +1,85 @@ | ||
| 1 | +/*! | |
| 2 | + * \copy | |
| 3 | + * Copyright (c) 2011-2013, Cisco Systems | |
| 4 | + * All rights reserved. | |
| 5 | + * | |
| 6 | + * Redistribution and use in source and binary forms, with or without | |
| 7 | + * modification, are permitted provided that the following conditions | |
| 8 | + * are met: | |
| 9 | + * | |
| 10 | + * * Redistributions of source code must retain the above copyright | |
| 11 | + * notice, this list of conditions and the following disclaimer. | |
| 12 | + * | |
| 13 | + * * Redistributions in binary form must reproduce the above copyright | |
| 14 | + * notice, this list of conditions and the following disclaimer in | |
| 15 | + * the documentation and/or other materials provided with the | |
| 16 | + * distribution. | |
| 17 | + * | |
| 18 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 | + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
| 21 | + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
| 22 | + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
| 23 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
| 24 | + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 25 | + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
| 26 | + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 27 | + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |
| 28 | + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 29 | + * POSSIBILITY OF SUCH DAMAGE. | |
| 30 | + * | |
| 31 | + * \file : AdaptiveQuantization.h | |
| 32 | + * | |
| 33 | + * \brief : adaptive quantization class of wels video processor class | |
| 34 | + * | |
| 35 | + * \date : 2011/03/21 | |
| 36 | + * | |
| 37 | + * \description : 1. rewrite the package code of scene change detection class | |
| 38 | + * | |
| 39 | + */ | |
| 40 | + | |
| 41 | +#ifndef WELSVP_ADAPTIVEQUANTIZATION_H | |
| 42 | +#define WELSVP_ADAPTIVEQUANTIZATION_H | |
| 43 | + | |
| 44 | +#include "../common/util.h" | |
| 45 | +#include "../common/memory.h" | |
| 46 | +#include "../common/WelsFrameWork.h" | |
| 47 | +#include "../../interface/IWelsVP.h" | |
| 48 | + | |
| 49 | +WELSVP_NAMESPACE_BEGIN | |
| 50 | + | |
| 51 | +typedef void (VarFunc) (uint8_t* pRefY, int32_t iRefStrideY, uint8_t* pSrc, int32_t iSrcStrideY, | |
| 52 | + SMotionTextureUnit* pMotionTexture); | |
| 53 | + | |
| 54 | +typedef VarFunc* PVarFunc; | |
| 55 | + | |
| 56 | +VarFunc SampleVariance16x16_c; | |
| 57 | + | |
| 58 | +#ifdef X86_ASM | |
| 59 | +WELSVP_EXTERN_C_BEGIN | |
| 60 | +VarFunc SampleVariance16x16_sse2; | |
| 61 | +WELSVP_EXTERN_C_END | |
| 62 | +#endif | |
| 63 | + | |
| 64 | + | |
| 65 | +class CAdaptiveQuantization : public IStrategy { | |
| 66 | + public: | |
| 67 | + CAdaptiveQuantization (int32_t iCpuFlag); | |
| 68 | + ~CAdaptiveQuantization(); | |
| 69 | + | |
| 70 | + EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* pRef); | |
| 71 | + EResult Set (int32_t iType, void* pParam); | |
| 72 | + EResult Get (int32_t iType, void* pParam); | |
| 73 | + | |
| 74 | + private: | |
| 75 | + void WelsInitVarFunc (PVarFunc& pfVar, int32_t iCpuFlag); | |
| 76 | + | |
| 77 | + private: | |
| 78 | + PVarFunc m_pfVar; | |
| 79 | + int32_t m_CPUFlag; | |
| 80 | + SAdaptiveQuantizationParam m_sAdaptiveQuantParam; | |
| 81 | +}; | |
| 82 | + | |
| 83 | +WELSVP_NAMESPACE_END | |
| 84 | + | |
| 85 | +#endif | |