Showing the changes to codec/processing/src/scenechangedetection/SceneChangeDetection.cpp (1 of 124 files). Show all
Unified · Split
| @@ -0,0 +1,136 @@ | ||
| 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 | + | |
| 33 | +#include "SceneChangeDetection.h" | |
| 34 | +#include "../common/cpu.h" | |
| 35 | + | |
| 36 | +WELSVP_NAMESPACE_BEGIN | |
| 37 | + | |
| 38 | +#define HIGH_MOTION_BLOCK_THRESHOLD 320 | |
| 39 | +#define SCENE_CHANGE_MOTION_RATIO 0.85f | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 44 | + | |
| 45 | +CSceneChangeDetection::CSceneChangeDetection (int32_t iCpuFlag) { | |
| 46 | + m_iCpuFlag = iCpuFlag; | |
| 47 | + m_eMethod = METHOD_SCENE_CHANGE_DETECTION; | |
| 48 | + m_pfSad = NULL; | |
| 49 | + WelsMemset (&m_sSceneChangeParam, 0, sizeof (m_sSceneChangeParam)); | |
| 50 | + InitSadFuncs (m_pfSad, m_iCpuFlag); | |
| 51 | +} | |
| 52 | + | |
| 53 | +CSceneChangeDetection::~CSceneChangeDetection() { | |
| 54 | +} | |
| 55 | + | |
| 56 | +EResult CSceneChangeDetection::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { | |
| 57 | + EResult eReturn = RET_INVALIDPARAM; | |
| 58 | + | |
| 59 | + int32_t iWidth = pSrcPixMap->sRect.iRectWidth; | |
| 60 | + int32_t iHeight = pSrcPixMap->sRect.iRectHeight; | |
| 61 | + int32_t iBlock8x8Width = iWidth >> 3; | |
| 62 | + int32_t iBlock8x8Height = iHeight >> 3; | |
| 63 | + int32_t iBlock8x8Num = iBlock8x8Width * iBlock8x8Height; | |
| 64 | + int32_t iSceneChangeThreshold = WelsStaticCast (int32_t, SCENE_CHANGE_MOTION_RATIO * iBlock8x8Num + 0.5f + PESN); | |
| 65 | + | |
| 66 | + int32_t iBlockSad = 0; | |
| 67 | + int32_t iMotionBlockNum = 0; | |
| 68 | + | |
| 69 | + uint8_t* pRefY = NULL, *pCurY = NULL; | |
| 70 | + int32_t iRefStride = 0, iCurStride = 0; | |
| 71 | + int32_t iRefRowStride = 0, iCurRowStride = 0; | |
| 72 | + | |
| 73 | + uint8_t* pRefTmp = NULL, *pCurTmp = NULL; | |
| 74 | + | |
| 75 | + pRefY = (uint8_t*)pRefPixMap->pPixel[0]; | |
| 76 | + pCurY = (uint8_t*)pSrcPixMap->pPixel[0]; | |
| 77 | + | |
| 78 | + iRefStride = pRefPixMap->iStride[0]; | |
| 79 | + iCurStride = pSrcPixMap->iStride[0]; | |
| 80 | + | |
| 81 | + iRefRowStride = pRefPixMap->iStride[0] << 3; | |
| 82 | + iCurRowStride = pSrcPixMap->iStride[0] << 3; | |
| 83 | + | |
| 84 | + m_sSceneChangeParam.bSceneChangeFlag = 0; | |
| 85 | + | |
| 86 | + for (int32_t j = 0; j < iBlock8x8Height; j ++) { | |
| 87 | + pRefTmp = pRefY; | |
| 88 | + pCurTmp = pCurY; | |
| 89 | + | |
| 90 | + for (int32_t i = 0; i < iBlock8x8Width; i++) { | |
| 91 | + iBlockSad = m_pfSad (pRefTmp, iRefStride, pCurTmp, iCurStride); | |
| 92 | + | |
| 93 | + iMotionBlockNum += (iBlockSad > HIGH_MOTION_BLOCK_THRESHOLD); | |
| 94 | + | |
| 95 | + pRefTmp += 8; | |
| 96 | + pCurTmp += 8; | |
| 97 | + } | |
| 98 | + | |
| 99 | + pRefY += iRefRowStride; | |
| 100 | + pCurY += iCurRowStride; | |
| 101 | + } | |
| 102 | + | |
| 103 | + if (iMotionBlockNum >= iSceneChangeThreshold) { | |
| 104 | + m_sSceneChangeParam.bSceneChangeFlag = 1; | |
| 105 | + } | |
| 106 | + | |
| 107 | + eReturn = RET_SUCCESS; | |
| 108 | + | |
| 109 | + return eReturn; | |
| 110 | +} | |
| 111 | + | |
| 112 | + | |
| 113 | +EResult CSceneChangeDetection::Get (int32_t iType, void* pParam) { | |
| 114 | + if (pParam == NULL) { | |
| 115 | + return RET_INVALIDPARAM; | |
| 116 | + } | |
| 117 | + | |
| 118 | + * (SSceneChangeResult*)pParam = m_sSceneChangeParam; | |
| 119 | + | |
| 120 | + return RET_SUCCESS; | |
| 121 | +} | |
| 122 | + | |
| 123 | +/////////////////////////////////////////////////////////////////////////////////////////////// | |
| 124 | + | |
| 125 | +void CSceneChangeDetection::InitSadFuncs (SadFuncPtr& pfSad, int32_t iCpuFlag) { | |
| 126 | + pfSad = WelsSampleSad8x8_c; | |
| 127 | + | |
| 128 | +#ifdef X86_ASM | |
| 129 | + if (iCpuFlag & WELS_CPU_SSE2) { | |
| 130 | + pfSad = WelsSampleSad8x8_sse21; | |
| 131 | + } | |
| 132 | +#endif | |
| 133 | +} | |
| 134 | + | |
| 135 | + | |
| 136 | +WELSVP_NAMESPACE_END | |