History

Merge pull request #535 from volvet/add-scene-change-detector

Add scene change detector

ruil2 committed 12 years ago

Commit 3238c912 parents 37e1c29 af522895 files · +112 −113Browse files

Showing the changes to codec/processing/src (3 of 5 files). Show all

Unified · Split

3 files
  1. codec/processing/src/common/WelsFrameWork.cpp +3 −2
  2. codec/processing/src/scenechangedetection/SceneChangeDetection.cpp +10 −101
  3. codec/processing/src/scenechangedetection/SceneChangeDetection.h +96 −8
codec/processing/src/common/WelsFrameWork.cpp+3−2
@@ -265,8 +265,9 @@ IStrategy* CVpFrameWork::CreateStrategy (EMethods m_eMethod, int32_t iCpuFlag) { · 264 unmodified lines
265265 case METHOD_DENOISE:
266266 pStrategy = WelsDynamicCast (IStrategy*, new CDenoiser (iCpuFlag));
267267 break;
268− case METHOD_SCENE_CHANGE_DETECTION:
269− pStrategy = WelsDynamicCast (IStrategy*, new CSceneChangeDetection (iCpuFlag));
268+ case METHOD_SCENE_CHANGE_DETECTION_VIDEO:
269+ case METHOD_SCENE_CHANGE_DETECTION_SCREEN:
270+ pStrategy = BuildSceneChangeDetection(m_eMethod, iCpuFlag);
270271 break;
271272 case METHOD_DOWNSAMPLE:
272273 pStrategy = WelsDynamicCast (IStrategy*, new CDownsampling (iCpuFlag));
codec/processing/src/scenechangedetection/SceneChangeDetection.cpp+10−101
@@ -35,108 +35,17 @@ · 34 unmodified lines
3535
3636 WELSVP_NAMESPACE_BEGIN
3737
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.eSceneChangeIdc = SIMILAR_SCENE;
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.eSceneChangeIdc = LARGE_CHANGED_SCENE;
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−#ifdef HAVE_NEON
135− if (iCpuFlag & WELS_CPU_NEON) {
136− pfSad = WelsProcessingSampleSad8x8_neon;
38+IStrategy * BuildSceneChangeDetection(EMethods eMethod, int32_t iCpuFlag){
39+ switch(eMethod){
40+ case METHOD_SCENE_CHANGE_DETECTION_VIDEO:
41+ return new CSceneChangeDetection<CSceneChangeDetectorVideo>(eMethod, iCpuFlag);
42+ break;
43+ case METHOD_SCENE_CHANGE_DETECTION_SCREEN:
44+ default:
45+ // not support yet
46+ return NULL;
13747 }
138−#endif
13948 }
14049
141−
14250 WELSVP_NAMESPACE_END
51+
codec/processing/src/scenechangedetection/SceneChangeDetection.h+96−8
@@ -44,29 +44,117 @@ · 43 unmodified lines
4444
4545 #include "util.h"
4646 #include "memory.h"
47+#include "cpu.h"
4748 #include "WelsFrameWork.h"
4849 #include "IWelsVP.h"
4950 #include "SceneChangeDetectionCommon.h"
5051
52+#define HIGH_MOTION_BLOCK_THRESHOLD 320
53+#define SCENE_CHANGE_MOTION_RATIO 0.85f
54+
5155 WELSVP_NAMESPACE_BEGIN
5256
57+class CSceneChangeDetectorVideo {
58+public:
59+ CSceneChangeDetectorVideo(int32_t iCpuFlag) {
60+ m_pfSad = WelsSampleSad8x8_c;
61+#ifdef X86_ASM
62+ if (iCpuFlag & WELS_CPU_SSE2){
63+ m_pfSad = WelsSampleSad8x8_sse21;
64+ }
65+#endif
66+#ifdef HAVE_NEON
67+ if (iCpuFlag & WELS_CPU_NEON){
68+ m_pfSad = WelsProcessingSampleSad8x8_neon;
69+ }
70+#endif
71+ }
72+ virtual ~CSceneChangeDetectorVideo() {
73+ }
74+ virtual int32_t operator () (uint8_t* pSrcY, int32_t iSrcStrideY, uint8_t* pRefY, int32_t iRefStrideY) {
75+ return m_pfSad(pSrcY, iSrcStrideY, pRefY, iSrcStrideY);
76+ }
77+protected:
78+ SadFuncPtr m_pfSad;
79+};
80+
81+template<typename T>
5382 class CSceneChangeDetection : public IStrategy {
5483 public:
55− CSceneChangeDetection (int32_t iCpuFlag);
56− ~CSceneChangeDetection();
84+ CSceneChangeDetection (EMethods eMethod, int32_t iCpuFlag): m_cDetector(iCpuFlag) {
85+ m_eMethod = eMethod;
86+ WelsMemset (&m_sSceneChangeParam, 0, sizeof (m_sSceneChangeParam));
87+ }
5788
58− EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* pRef);
59− EResult Get (int32_t iType, void* pParam);
89+ ~CSceneChangeDetection(){
90+ }
6091
61− private:
62− void InitSadFuncs (SadFuncPtr& pfSadFunc, int32_t iCpuFlag);
92+ EResult Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap){
93+ EResult eReturn = RET_INVALIDPARAM;
94+ int32_t iWidth = pSrcPixMap->sRect.iRectWidth;
95+ int32_t iHeight = pSrcPixMap->sRect.iRectHeight;
96+ int32_t iBlock8x8Width = iWidth >> 3;
97+ int32_t iBlock8x8Height = iHeight >> 3;
98+ int32_t iBlock8x8Num = iBlock8x8Width * iBlock8x8Height;
99+ int32_t iSceneChangeThreshold = WelsStaticCast (int32_t, SCENE_CHANGE_MOTION_RATIO * iBlock8x8Num + 0.5f + PESN);
100+ int32_t iBlockSad = 0;
101+ int32_t iMotionBlockNum = 0;
102+ uint8_t* pRefY = NULL, *pCurY = NULL;
103+ int32_t iRefStride = 0, iCurStride = 0;
104+ int32_t iRefRowStride = 0, iCurRowStride = 0;
105+ uint8_t* pRefTmp = NULL, *pCurTmp = NULL;
106+
107+ pRefY = (uint8_t*)pRefPixMap->pPixel[0];
108+ pCurY = (uint8_t*)pSrcPixMap->pPixel[0];
109+
110+ iRefStride = pRefPixMap->iStride[0];
111+ iCurStride = pSrcPixMap->iStride[0];
112+
113+ iRefRowStride = pRefPixMap->iStride[0] << 3;
114+ iCurRowStride = pSrcPixMap->iStride[0] << 3;
115+
116+ m_sSceneChangeParam.eSceneChangeIdc = SIMILAR_SCENE;
117+
118+ for (int32_t j = 0; j < iBlock8x8Height; j ++) {
119+ pRefTmp = pRefY;
120+ pCurTmp = pCurY;
121+
122+ for (int32_t i = 0; i < iBlock8x8Width; i++) {
123+ iBlockSad = m_cDetector(pRefTmp, iRefStride, pCurTmp, iCurStride);
124+ iMotionBlockNum += (iBlockSad > HIGH_MOTION_BLOCK_THRESHOLD);
125+
126+ pRefTmp += 8;
127+ pCurTmp += 8;
128+ }
129+
130+ pRefY += iRefRowStride;
131+ pCurY += iCurRowStride;
132+ }
133+
134+ if (iMotionBlockNum >= iSceneChangeThreshold) {
135+ m_sSceneChangeParam.eSceneChangeIdc = LARGE_CHANGED_SCENE;
136+ }
137+
138+ eReturn = RET_SUCCESS;
139+
140+ return eReturn;
141+ }
142+
143+ EResult Get (int32_t iType, void* pParam) {
144+ if (pParam == NULL) {
145+ return RET_INVALIDPARAM;
146+ }
147+ * (SSceneChangeResult*)pParam = m_sSceneChangeParam;
148+ return RET_SUCCESS;
149+ }
63150
64151 private:
65− SadFuncPtr m_pfSad;
66− int32_t m_iCpuFlag;
67152 SSceneChangeResult m_sSceneChangeParam;
153+ T m_cDetector;
68154 };
69155
156+IStrategy * BuildSceneChangeDetection(EMethods eMethod, int32_t iCpuFlag);
157+
70158 WELSVP_NAMESPACE_END
71159
72160 #endif

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