1 /*!
2 * \copy
3 * Copyright (c) 2009-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 "ScrollDetection.h"
34 #include "ScrollDetectionFuncs.h"
35 #include "ls_defines.h"
36
37 WELSVP_NAMESPACE_BEGIN
38
CheckLine(uint8_t * pData,int32_t iWidth)39 int32_t CheckLine (uint8_t* pData, int32_t iWidth) {
40 int32_t iQualified = 0;
41 int32_t iColorMap[8] = {0};
42 int32_t iChangedTimes = 0;
43 int32_t iColorCounts = 0;
44
45 RECORD_COLOR (pData[0], iColorMap);
46
47 for (int32_t i = 1; i < iWidth; i++) {
48 RECORD_COLOR (pData[i], iColorMap);
49 iChangedTimes += (pData[i] != pData[i - 1]);
50 }
51 for (int32_t i = 0; i < 8; i++)
52 for (int32_t j = 0; j < 32; j++)
53 iColorCounts += ((iColorMap[i] >> j) & 1);
54
55 switch (iColorCounts) {
56 case 1:
57 iQualified = 0;
58 break;
59 case 2:
60 case 3:
61 iQualified = (iChangedTimes > 3);
62 break;
63 default:
64 iQualified = 1;
65 break;
66 }
67 return iQualified;
68 }
69
SelectTestLine(uint8_t * pY,int32_t iWidth,int32_t iHeight,int32_t iPicHeight,int32_t iStride,int32_t iOffsetX,int32_t iOffsetY)70 int32_t SelectTestLine (uint8_t* pY, int32_t iWidth, int32_t iHeight, int32_t iPicHeight,
71 int32_t iStride, int32_t iOffsetX, int32_t iOffsetY) {
72 const int32_t kiHalfHeight = iHeight >> 1;
73 const int32_t kiMidPos = iOffsetY + kiHalfHeight;
74 int32_t TestPos = kiMidPos;
75 int32_t iOffsetAbs;
76 uint8_t* pTmp;
77
78 for (iOffsetAbs = 0; iOffsetAbs < kiHalfHeight; iOffsetAbs++) {
79 TestPos = kiMidPos + iOffsetAbs;
80 if (TestPos < iPicHeight) {
81 pTmp = pY + TestPos * iStride + iOffsetX;
82 if (CheckLine (pTmp, iWidth)) break;
83 }
84 TestPos = kiMidPos - iOffsetAbs;
85 if (TestPos >= 0) {
86 pTmp = pY + TestPos * iStride + iOffsetX;
87 if (CheckLine (pTmp, iWidth)) break;
88 }
89 }
90 if (iOffsetAbs == kiHalfHeight)
91 TestPos = -1;
92 return TestPos;
93 }
94
95 /*
96 * compare pixel line between previous and current one
97 * return: 0 for totally equal, otherwise 1
98 */
CompareLine(uint8_t * pYSrc,uint8_t * pYRef,const int32_t kiWidth)99 int32_t CompareLine (uint8_t* pYSrc, uint8_t* pYRef, const int32_t kiWidth) {
100 int32_t iCmp = 1;
101
102 if (LD32 (pYSrc) != LD32 (pYRef)) return 1;
103 if (LD32 (pYSrc + 4) != LD32 (pYRef + 4)) return 1;
104 if (LD32 (pYSrc + 8) != LD32 (pYRef + 8)) return 1;
105 if (kiWidth > 12)
106 iCmp = WelsMemcmp (pYSrc + 12, pYRef + 12, kiWidth - 12);
107 return iCmp;
108 }
109
ScrollDetectionCore(SPixMap * pSrcPixMap,SPixMap * pRefPixMap,int32_t iWidth,int32_t iHeight,int32_t iOffsetX,int32_t iOffsetY,SScrollDetectionParam & sScrollDetectionParam)110 void ScrollDetectionCore (SPixMap* pSrcPixMap, SPixMap* pRefPixMap, int32_t iWidth, int32_t iHeight,
111 int32_t iOffsetX, int32_t iOffsetY, SScrollDetectionParam& sScrollDetectionParam) {
112 bool bScrollDetected = 0;
113 uint8_t* pYLine;
114 uint8_t* pYTmp;
115 int32_t iTestPos, iSearchPos = 0, iOffsetAbs, iMaxAbs;
116 int32_t iPicHeight = pRefPixMap->sRect.iRectHeight;
117 int32_t iMinHeight = WELS_MAX (iOffsetY, 0);
118 int32_t iMaxHeight = WELS_MIN (iOffsetY + iHeight - 1, iPicHeight - 1) ; //offset_y + height - 1;//
119 uint8_t* pYRef, *pYSrc;
120 int32_t iYStride;
121
122 pYRef = (uint8_t*)pRefPixMap->pPixel[0];
123 pYSrc = (uint8_t*)pSrcPixMap->pPixel[0];
124 iYStride = pRefPixMap->iStride[0];
125
126 iTestPos = SelectTestLine (pYSrc, iWidth, iHeight, iPicHeight, iYStride, iOffsetX, iOffsetY);
127
128 if (iTestPos == -1) {
129 sScrollDetectionParam.bScrollDetectFlag = 0;
130 return;
131 }
132 pYLine = pYSrc + iYStride * iTestPos + iOffsetX;
133 iMaxAbs = WELS_MIN (WELS_MAX (iTestPos - iMinHeight - 1, iMaxHeight - iTestPos), MAX_SCROLL_MV_Y);
134 iSearchPos = iTestPos;
135 for (iOffsetAbs = 0; iOffsetAbs <= iMaxAbs; iOffsetAbs++) {
136 iSearchPos = iTestPos + iOffsetAbs;
137 if (iSearchPos <= iMaxHeight) {
138 pYTmp = pYRef + iSearchPos * iYStride + iOffsetX;
139 if (!CompareLine (pYLine, pYTmp, iWidth)) {
140 uint8_t* pYUpper, *pYLineUpper;
141 int32_t iCheckedLines;
142 int32_t iLowOffset = WELS_MIN (iMaxHeight - iSearchPos, CHECK_OFFSET);
143 int32_t i;
144
145 iCheckedLines = WELS_MIN (iTestPos - iMinHeight + iLowOffset, 2 * CHECK_OFFSET);
146 pYUpper = pYTmp - (iCheckedLines - iLowOffset) * iYStride;
147 pYLineUpper = pYLine - (iCheckedLines - iLowOffset) * iYStride;
148
149 for (i = 0; i < iCheckedLines; i ++) {
150 if (CompareLine (pYLineUpper, pYUpper, iWidth)) {
151 break;
152 }
153 pYUpper += iYStride;
154 pYLineUpper += iYStride;
155 }
156 if (i == iCheckedLines) {
157 bScrollDetected = 1;
158 break;
159 }
160 }
161 }
162
163 iSearchPos = iTestPos - iOffsetAbs - 1;
164 if (iSearchPos >= iMinHeight) {
165 pYTmp = pYRef + iSearchPos * iYStride + iOffsetX;
166 if (!CompareLine (pYLine, pYTmp, iWidth)) {
167 uint8_t* pYUpper, *pYLineUpper;
168 int32_t iCheckedLines;
169 int32_t iUpOffset = WELS_MIN (iSearchPos - iMinHeight, CHECK_OFFSET);
170 int32_t i;
171
172 pYUpper = pYTmp - iUpOffset * iYStride;
173 pYLineUpper = pYLine - iUpOffset * iYStride;
174 iCheckedLines = WELS_MIN (iMaxHeight - iTestPos + iUpOffset, 2 * CHECK_OFFSET);
175
176 for (i = 0; i < iCheckedLines; i ++) {
177 if (CompareLine (pYLineUpper, pYUpper, iWidth)) {
178 break;
179 }
180 pYUpper += iYStride;
181 pYLineUpper += iYStride;
182 }
183 if (i == iCheckedLines) {
184 bScrollDetected = 1;
185 break;
186 }
187 }
188 }
189 }
190
191 if (!bScrollDetected) {
192 sScrollDetectionParam.bScrollDetectFlag = 0;
193 } else {
194 sScrollDetectionParam.bScrollDetectFlag = 1;
195 sScrollDetectionParam.iScrollMvY = iSearchPos - iTestPos; // pre_pos - cur_pos, change to mv
196 sScrollDetectionParam.iScrollMvX = 0;
197 }
198 }
199
200 WELSVP_NAMESPACE_END
201