• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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