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 (4 of 5 files). Show all

Unified · Split

4 files
  1. codec/processing/interface/IWelsVP.h +2 −1
  2. codec/processing/src/common/WelsFrameWork.cpp +3 −2
  3. codec/processing/src/scenechangedetection/SceneChangeDetection.cpp +10 −101
  4. codec/processing/src/scenechangedetection/SceneChangeDetection.h +96 −8
codec/processing/interface/IWelsVP.h+2−1
@@ -122,7 +122,8 @@ typedef enum { · 121 unmodified lines
122 METHOD_NULL = 0,122 METHOD_NULL = 0,
123 METHOD_COLORSPACE_CONVERT ,//not support yet123 METHOD_COLORSPACE_CONVERT ,//not support yet
124 METHOD_DENOISE ,124 METHOD_DENOISE ,
125 METHOD_SCENE_CHANGE_DETECTION ,125 METHOD_SCENE_CHANGE_DETECTION_VIDEO ,
126 METHOD_SCENE_CHANGE_DETECTION_SCREEN ,
126 METHOD_DOWNSAMPLE ,127 METHOD_DOWNSAMPLE ,
127 METHOD_VAA_STATISTICS ,128 METHOD_VAA_STATISTICS ,
128 METHOD_BACKGROUND_DETECTION ,129 METHOD_BACKGROUND_DETECTION ,
codec/processing/src/common/WelsFrameWork.cpp+3−2
@@ -265,8 +265,9 @@ IStrategy* CVpFrameWork::CreateStrategy (EMethods m_eMethod, int32_t iCpuFlag) { · 264 unmodified lines
265 case METHOD_DENOISE:265 case METHOD_DENOISE:
266 pStrategy = WelsDynamicCast (IStrategy*, new CDenoiser (iCpuFlag));266 pStrategy = WelsDynamicCast (IStrategy*, new CDenoiser (iCpuFlag));
267 break;267 break;
268 case METHOD_SCENE_CHANGE_DETECTION:268 case METHOD_SCENE_CHANGE_DETECTION_VIDEO:
269 pStrategy = WelsDynamicCast (IStrategy*, new CSceneChangeDetection (iCpuFlag));269 case METHOD_SCENE_CHANGE_DETECTION_SCREEN:
270 pStrategy = BuildSceneChangeDetection(m_eMethod, iCpuFlag);
270 break;271 break;
271 case METHOD_DOWNSAMPLE:272 case METHOD_DOWNSAMPLE:
272 pStrategy = WelsDynamicCast (IStrategy*, new CDownsampling (iCpuFlag));273 pStrategy = WelsDynamicCast (IStrategy*, new CDownsampling (iCpuFlag));
codec/processing/src/scenechangedetection/SceneChangeDetection.cpp+10−101
@@ -35,108 +35,17 @@ · 34 unmodified lines
35 35
36WELSVP_NAMESPACE_BEGIN36WELSVP_NAMESPACE_BEGIN
37 37
38#define HIGH_MOTION_BLOCK_THRESHOLD 32038IStrategy * BuildSceneChangeDetection(EMethods eMethod, int32_t iCpuFlag){
39#define SCENE_CHANGE_MOTION_RATIO 0.85f39 switch(eMethod){
40 40 case METHOD_SCENE_CHANGE_DETECTION_VIDEO:
41 41 return new CSceneChangeDetection<CSceneChangeDetectorVideo>(eMethod, iCpuFlag);
42 42 break;
43///////////////////////////////////////////////////////////////////////////////////////////////////////////////43 case METHOD_SCENE_CHANGE_DETECTION_SCREEN:
44 44 default:
45CSceneChangeDetection::CSceneChangeDetection (int32_t iCpuFlag) {45 // not support yet
46 m_iCpuFlag = iCpuFlag;46 return NULL;
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
53CSceneChangeDetection::~CSceneChangeDetection() {
54}
55
56EResult 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
113EResult 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
125void 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;
137 }47 }
138#endif
139}48}
140 49
141
142WELSVP_NAMESPACE_END50WELSVP_NAMESPACE_END
51
codec/processing/src/scenechangedetection/SceneChangeDetection.h+96−8
@@ -44,29 +44,117 @@ · 43 unmodified lines
44 44
45#include "util.h"45#include "util.h"
46#include "memory.h"46#include "memory.h"
47#include "cpu.h"
47#include "WelsFrameWork.h"48#include "WelsFrameWork.h"
48#include "IWelsVP.h"49#include "IWelsVP.h"
49#include "SceneChangeDetectionCommon.h"50#include "SceneChangeDetectionCommon.h"
50 51
52#define HIGH_MOTION_BLOCK_THRESHOLD 320
53#define SCENE_CHANGE_MOTION_RATIO 0.85f
54
51WELSVP_NAMESPACE_BEGIN55WELSVP_NAMESPACE_BEGIN
52 56
57class CSceneChangeDetectorVideo {
58public:
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 }
77protected:
78 SadFuncPtr m_pfSad;
79};
80
81template<typename T>
53class CSceneChangeDetection : public IStrategy {82class CSceneChangeDetection : public IStrategy {
54 public:83 public:
55 CSceneChangeDetection (int32_t iCpuFlag);84 CSceneChangeDetection (EMethods eMethod, int32_t iCpuFlag): m_cDetector(iCpuFlag) {
56 ~CSceneChangeDetection();85 m_eMethod = eMethod;
86 WelsMemset (&m_sSceneChangeParam, 0, sizeof (m_sSceneChangeParam));
87 }
57 88
58 EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* pRef);89 ~CSceneChangeDetection(){
59 EResult Get (int32_t iType, void* pParam);90 }
60 91
61 private:92 EResult Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap){
62 void InitSadFuncs (SadFuncPtr& pfSadFunc, int32_t iCpuFlag);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 }
63 150
64 private:151 private:
65 SadFuncPtr m_pfSad;
66 int32_t m_iCpuFlag;
67 SSceneChangeResult m_sSceneChangeParam;152 SSceneChangeResult m_sSceneChangeParam;
153 T m_cDetector;
68};154};
69 155
156IStrategy * BuildSceneChangeDetection(EMethods eMethod, int32_t iCpuFlag);
157
70WELSVP_NAMESPACE_END158WELSVP_NAMESPACE_END
71 159
72#endif160#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