xref: /utopia/UTPA2-700.0.x/modules/vdec_v3/hal/maserati/vpu_v3/Film.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 #ifndef MSOS_TYPE_LINUX_KERNEL
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #else
6 #include <linux/string.h>
7 #endif
8 
9 #include "Film.h"
10 #include "drvBDMA.h"
11 #define USE_NEON
12 #define REMOVE_T0B0
13 //#define REMOVE_T1B1
14 #define ONLY_Detect_Crop_Region
15 //W  x H                (x_start, x_end) (y_start, y_end)
16 //720x576   -> window = (  0,  720 ) x (  0, 576 )
17 //1920x1080 -> window = (288, 1632 ) x (192, 896 )
18 //#define FILE_DBG
19 
20 #if (!defined(MSOS_TYPE_NUTTX) && !defined(MSOS_TYPE_OPTEE) && !defined(MSOS_TYPE_LINUX_KERNEL) && !defined(ANDROID)) || defined(SUPPORT_X_MODEL_FEATURE)
21 
22 #ifdef USE_NEON
23 #ifdef __arm__
24 #include <arm_neon.h>
25 #else
26 #include "NEON_2_SSE.h"
27 #endif
28 #endif
29 
30 static int g_Height = 0;
31 static int g_Width = 0;
32 static int g_Height_remain = 0;
33 static int g_Width_remain  = 0;
34 static int g_pitch         = 0;
35 static int g_tile_width    = 0;
36 static int g_tile_height   = 0;
37 static int g_tile_w_mod    = 0;
38 static int g_tile_w_shift  = 0;
39 static int g_fod_win_en    = 0;
40 static int g_base_pos      = 0;
41 static int g_sceneChangeTh = 800000;
42 
43 #define X_START 288
44 #define X_END   1632
45 #define Y_START 192
46 #define Y_END   896
47 
48 /*MPEG-2 tile:
49 16x32, stripe align 16bytes
50 32x32, stripe align 32bytes*/
51 /*
52 AVS/AVS+:
53 tile16x32, stripe align 16bytes.
54 */
55 
56 //tile width is 16 or 32
57 #define TILE_Width1 16
58 #define TILE_Width2 32
59 #define W_shift1    4
60 #define W_shift2    5
61 #define W_Mod1      ((1<<W_shift1)- 1)
62 #define W_Mod2      ((1<<W_shift2)- 1)
63 
64 //tile height is 32
65 #define TILE_Height 32
66 #define H_shift     5
67 #define H_Mod       ((1<<H_shift)- 1)
68 
69 
70 #define det_length 4
71 #define lowTh  196
72 #define highTh 320
73 #define MAXFRAME (det_length + 1) /* on purpose */
74 
75 static int g_ary_idx = -1;
76 static int g_bInitPhase = 1;
77 static int ary_frame_motion_ratio[MAXFRAME];
78 static int ary_IsSceneChangeTh[MAXFRAME];
79 
80 static int frame_motion_T1B0 = 0;
81 static int frame_motion_T0B1 = 0;
82 static int frame_motion_T0B0 = 0;
83 static int frame_motion_T1B1 = 0;
84 
85 static int reg_fod_mot_diff_th = 0;
86 static int reg_fod_med_filter_th = 0;
87 static int reg_fod_mot_diff_fm_th = 0;
88 static int reg_fod_med_filter_fm_th = 0;
89 #define OneFrameStep 96
90 #define minmax(v,a,b)       (((v)<(a))? (a) : ((v)>(b)) ? (b) : (v))
91 //#define DEBUG_INFO
92 #ifdef DEBUG_INFO
93 static unsigned long g_checksum = 0;
94 #define BASE 65521      /* largest prime smaller than 65536 */
95 #define NMAX 5552
96 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
97 
98 #define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
99 #define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
100 #define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
101 #define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
102 #define DO16(buf)   DO8(buf,0); DO8(buf,8);
103 
104 #  define MOD(a) a %= BASE
105 #  define MOD28(a) a %= BASE
106 #  define MOD63(a) a %= BASE
107 
108 
109 /* ========================================================================= */
adler32(unsigned long adler,const unsigned char * buf,unsigned int len)110 unsigned long adler32( unsigned long adler, const unsigned char *buf, unsigned int len )
111 {
112   unsigned long sum2;
113   unsigned n;
114 
115   /* split Adler-32 into component sums */
116   sum2 = (adler >> 16) & 0xffff;
117   adler &= 0xffff;
118 
119   /* in case user likes doing a byte at a time, keep it fast */
120   if (len == 1) {
121     adler += buf[0];
122     if (adler >= BASE)
123       adler -= BASE;
124     sum2 += adler;
125     if (sum2 >= BASE)
126       sum2 -= BASE;
127     return adler | (sum2 << 16);
128   }
129 
130   /* initial Adler-32 value (deferred check for len == 1 speed) */
131   if (buf == 0)
132     return 1L;
133 
134   /* in case short lengths are provided, keep it somewhat fast */
135   if (len < 16) {
136     while (len--) {
137       adler += *buf++;
138       sum2 += adler;
139     }
140     if (adler >= BASE)
141       adler -= BASE;
142     MOD28(sum2);            /* only added so many BASE's */
143     return adler | (sum2 << 16);
144   }
145 
146   /* do length NMAX blocks -- requires just one modulo operation */
147   while (len >= NMAX) {
148     len -= NMAX;
149     n = NMAX / 16;          /* NMAX is divisible by 16 */
150     do {
151       DO16(buf);          /* 16 sums unrolled */
152       buf += 16;
153     } while (--n);
154     MOD(adler);
155     MOD(sum2);
156   }
157 
158   /* do remaining bytes (less than NMAX, still just one modulo) */
159   if (len) {                  /* avoid modulos if none remaining */
160     while (len >= 16) {
161       len -= 16;
162       DO16(buf);
163       buf += 16;
164     }
165     while (len--) {
166       adler += *buf++;
167       sum2 += adler;
168     }
169     MOD(adler);
170     MOD(sum2);
171   }
172 
173   /* return recombined sums */
174   return adler | (sum2 << 16);
175 }
176 #endif
177 
InitFilmDetection(void)178 void InitFilmDetection(void)
179 {
180   g_ary_idx = -1;
181   g_bInitPhase = 1;
182   memset((uint8_t*) ary_frame_motion_ratio, 0, sizeof(int)*MAXFRAME);
183   memset((uint8_t*) ary_IsSceneChangeTh, 0, sizeof(int)*MAXFRAME);
184   frame_motion_T1B0 = 0;
185   frame_motion_T0B1 = 0;
186   frame_motion_T0B0 = 0;
187   frame_motion_T1B1 = 0;
188 
189   reg_fod_mot_diff_th = 0;
190   reg_fod_med_filter_th = 0;
191   reg_fod_mot_diff_fm_th = 0;
192   reg_fod_med_filter_fm_th = 0;
193   g_Height = g_Width = g_Height_remain = g_Width_remain = 0;
194   g_pitch  = g_tile_width = g_tile_height = g_tile_w_mod = 0;
195   g_tile_w_shift = g_fod_win_en = 0;
196   g_sceneChangeTh = 800000;
197   g_base_pos = 0;
198 }
199 
200 extern void _MApi_PrintMem(MS_VIRT u32Addr, MS_U32 u32Size);
201 
copyFrameBuffer(unsigned char * dst,unsigned char * src,int bufsize)202 void copyFrameBuffer(unsigned char *dst, unsigned char *src, int bufsize)
203 {
204 #ifdef DEBUG_INFO
205   unsigned long curimg = 0;
206   g_checksum = adler32(g_checksum, src, 0x100);
207   curimg = adler32(curimg, src, 0x100);
208   printf("[prv-chk=0x%lx][cur-chk=0x%lx][size=0x100][osize=%d]\n", g_checksum, curimg, bufsize);
209 
210 //  unsigned long curimg = 0;
211 //  g_checksum = adler32(g_checksum, src, bufsize);
212 //  curimg = adler32(curimg, src, bufsize);
213 //  printf("[prv-chk=0x%lx][cur-chk=0x%lx][size=%d]\n", g_checksum, curimg, bufsize);
214 #endif
215 //                MS_U32 u32Timer= MsOS_GetSystemTime();
216 
217 #ifdef SUPPORT_TILE
218 #ifdef ONLY_Detect_Crop_Region
219   if (g_fod_win_en == 1) {
220      int base_pos = g_base_pos;
221      int y;
222      for( y = Y_START ; y < Y_END ; y += TILE_Height ) {
223        //memcpy(dst+base_pos, src+base_pos, (TILE_Height * (X_END - X_START)));
224        MDrv_BDMA_MemCopy(MsOS_VA2PA((MS_VIRT)(src+base_pos)), MsOS_VA2PA((MS_VIRT)(dst+base_pos)), (TILE_Height * (X_END - X_START)));
225 
226        base_pos += (TILE_Height * g_pitch);
227      }
228   } else
229 #endif
230 #endif
231   {
232 //    memcpy(dst, src, bufsize);
233        MDrv_BDMA_MemCopy(MsOS_VA2PA((MS_VIRT)src), MsOS_VA2PA((MS_VIRT)dst), bufsize);
234   }
235 //                printf("cp:[%dms]\n", MsOS_GetSystemTime()-u32Timer);
236 
237 }
238 
setHeight_Width(FODInfo * fod)239 int setHeight_Width(FODInfo *fod)
240 {
241   int retval = 0;
242   int pad_w;
243   g_Height = fod->height;
244   g_Width  = fod->width;
245   g_Height_remain = (g_Height % fod->tile_height);
246   g_tile_width  = fod->tile_width;
247   g_tile_height = fod->tile_height;
248 
249   if (g_tile_height != TILE_Height) {
250     printf("[FOD][Warning] TILE Height is invalid\n");
251     g_tile_height = TILE_Height;
252     retval = 1;
253   }
254   if (g_tile_width == TILE_Width1) {
255     g_tile_w_mod = W_Mod1;
256     g_tile_w_shift = W_shift1;
257   } else if (g_tile_width == TILE_Width2) {
258     g_tile_w_mod = W_Mod2;
259     g_tile_w_shift = W_shift2;
260   } else {
261     printf("[FOD][Warning] TILE Width is invalid\n");
262     g_tile_w_mod = W_Mod1;
263     g_tile_width = TILE_Width1;
264     g_tile_w_shift = W_shift1;
265     retval = 1;
266   }
267   g_Width_remain  = (g_Width  % g_tile_width);
268   pad_w = (g_Width_remain != 0) ? g_tile_width - g_Width_remain : 0;
269   g_pitch = g_Width + pad_w;
270 
271 #ifdef ONLY_Detect_Crop_Region
272   if (g_Height >= 1080 && g_Width >= 1920) {
273     int base_y = g_tile_width*(Y_START & H_Mod) + (Y_START  >> H_shift) * (TILE_Height * g_pitch);
274     int base_x =  (X_START >> g_tile_w_shift) * (g_tile_width * TILE_Height);
275     int x_pos  =  (X_START & g_tile_w_mod) + base_x;
276     g_fod_win_en = 1;
277     g_base_pos = base_y + x_pos;
278     g_sceneChangeTh = 200000;
279 
280   } else
281 #endif
282   {
283     g_fod_win_en = 0;
284     g_sceneChangeTh = 800000;
285   }
286 
287   if (g_pitch != fod->pitch) {
288     printf("[FOD][Warning] pitch mismatch: h=%d/w=%d/p=%d/Tw=%d/Th=%d\n",
289             g_Height,
290             g_Width,
291             g_pitch,
292             fod->tile_width,
293             fod->tile_height);
294     retval = 1;
295   }
296   return retval;
297 }
298 
getTileWidth(void)299 int  getTileWidth(void)
300 {
301   return g_tile_width;
302 }
getTileHeight(void)303 int  getTileHeight(void)
304 {
305   return g_tile_height;
306 }
307 
getFodWinEnable(void)308 int getFodWinEnable(void)
309 {
310   return g_fod_win_en;
311 }
312 
detFieldOrderFW(void)313 int detFieldOrderFW(void)
314 {
315   int inv_det = 1;
316   int ratio_sum2 = 0;
317   int i;
318 
319   if ( g_bInitPhase == 1 && g_ary_idx < det_length) {
320     return 0;
321   }
322   g_bInitPhase = 0;
323 
324     for (i = 0; i < det_length; i++)
325     {
326       int ary_idx = ((g_ary_idx-i) + MAXFRAME) % MAXFRAME;
327 
328       if(ary_IsSceneChangeTh[ary_idx] == 1) {
329 #ifdef DEBUG_INFO
330         printf("[FOD] ret=0 scene changed\n");
331 #endif
332         return 0;
333       }
334 
335       ratio_sum2 += minmax( (256 - ary_frame_motion_ratio[ary_idx]), 0, OneFrameStep);
336      }
337 
338      ratio_sum2 = minmax( ratio_sum2, 0, 255 );
339 
340     if ( ratio_sum2 > lowTh ) {
341       inv_det = 1;
342     } else {
343       inv_det = 0;
344     }
345 #ifdef DEBUG_INFO
346     printf("[FOD] ret=%d\n", inv_det);
347 #endif
348     return inv_det;
349   }
350 
351 
352 #ifdef USE_NEON
vmed3_i8(uint8x8_t A,uint8x8_t B,uint8x8_t C)353 static uint8x8_t vmed3_i8 (uint8x8_t A, uint8x8_t B, uint8x8_t C)
354 {
355   return vmax_u8(vmin_u8(A, B), vmin_u8(vmax_u8(A, B), C));
356 }
357 
Create16ByteAligned(uint8_t ** org,int size)358 uint8_t* Create16ByteAligned(uint8_t** org, int size)
359 {
360     *org = (uint8_t *) malloc(size+15);
361     return (uint8_t *) (((uintptr_t)*org+15) & ~ (uintptr_t)0x0F);
362 }
363 #ifdef FILE_DBG2
myprintf(uint8x8_t rst,int x,int y,char * myname)364 static inline void myprintf(uint8x8_t rst, int x, int y, char* myname)
365 {
366   FILE *fptr = fopen("debug.txt","a");
367   fprintf(fptr, "%s[x=%d, y=%d] %x %x %x %x %x %x %x %x\n",
368            myname, x, y,
369            vget_lane_u8(rst, 0),
370            vget_lane_u8(rst, 1),
371            vget_lane_u8(rst, 2),
372            vget_lane_u8(rst, 3),
373            vget_lane_u8(rst, 4),
374            vget_lane_u8(rst, 5),
375            vget_lane_u8(rst, 6),
376            vget_lane_u8(rst, 7));
377   fclose(fptr);
378 }
379 #endif
380 
detFieldOrderBot(unsigned char * preField,unsigned char * curField,unsigned char * nxtField,unsigned char * nx2Field,int CurIsBot)381 void detFieldOrderBot( unsigned char*preField, unsigned char*curField, unsigned char*nxtField, unsigned char*nx2Field, int CurIsBot)
382 {
383   uint8x8_t mot_diff_th      = vdup_n_u8(2);    //o_reg_fod_mot_diff_th 2
384   uint8x8_t med_filter_th    = vdup_n_u8(2);    //o_reg_fod_med_filter_th 2
385   uint8x8_t mot_diff_fm_th   = vdup_n_u8(2);    //o_reg_fod_mot_diff_fm_th 2
386   uint8x8_t med_filter_fm_th = vdup_n_u8(2);    //o_reg_fod_med_filter_fm_th 2
387 
388 
389   uint8x8_t filter1, filter2, diff2;
390   uint8x8_t filter4;
391   uint8x8_t rst;
392 #ifndef REMOVE_T0B0
393   uint8x8_t filter3;
394 #endif
395 
396   int yu, yd, y;
397 
398   int x_start = (g_fod_win_en == 1) ? X_START : 0;
399   int x_end = (g_fod_win_en == 1) ? X_END : g_Width;
400   int y_start = (g_fod_win_en == 1) ? Y_START : 0;
401   int y_end = (g_fod_win_en == 1) ? Y_END : g_Height;
402 #ifdef SUPPORT_TILE
403   int stride = g_tile_width;
404   int base_x = 0;
405 #else
406   int stride = g_Width;
407 #endif
408 
409   frame_motion_T1B0 = 0;
410   frame_motion_T0B1 = 0;
411 #ifndef REMOVE_T0B0
412   frame_motion_T0B0 = 0; //keep T1B1, remove T0B0
413 #endif
414   frame_motion_T1B1 = 0;
415 
416   for( y = y_start ; y < y_end ; y+=2 )
417   {
418     int base_yu, base_y, base_yd, x;
419     yu = y - 2;
420     if (yu <= y_start)
421       yu = y;
422 
423     yd = y + 2;
424     if (yd >= y_end)
425       yd = y;
426 
427 
428 #ifdef SUPPORT_TILE
429     base_yu = stride*(yu & H_Mod) + (yu >> H_shift) * (TILE_Height * g_pitch);
430     base_y  = stride*(y  & H_Mod) + (y  >> H_shift) * (TILE_Height * g_pitch);
431     base_yd = stride*(yd & H_Mod)+  (yd >> H_shift) * (TILE_Height * g_pitch);
432 #else
433     base_yu = stride*yu;
434     base_y  = stride*y;
435     base_yd = stride*yd;
436 #endif
437 
438     for( x = x_start ; x < x_end; x+=8 )
439     {
440       uint8x8_t f0_y0, f1_y0, f2_y0, f3_y0;
441       uint8x8_t f0_y1, f2_y1;
442       uint8x8_t r_filter1, r_filter2, r_filter4;
443       uint8x8_t r_diff2;
444       int x_pos;
445 #ifndef REMOVE_T0B0
446       uint8x8_t  r_filter3;
447 #endif
448 #ifdef SUPPORT_TILE
449       base_x = (x >> g_tile_w_shift) * (g_tile_width * TILE_Height);
450       x_pos =  (x & g_tile_w_mod) + base_x;
451 #else
452       x_pos = x;
453 #endif
454 
455       /*
456       int test_f1_yu = curField.Y(x, yu)>>5;
457       int test_f3_yu = nx2Field.Y(x, yu)>>5;
458       int test_f0_y0 = preField.Y(x, y)>>5;
459       int test_f1_y0 = curField.Y(x, y)>>5;
460       int test_f2_y0 = nxtField.Y(x, y)>>5;
461       int test_f3_y0 = nx2Field.Y(x, y)>>5;
462       int test_f0_y1 = preField.Y(x, yd)>>5;
463       int test_f2_y1 = nxtField.Y(x, yd)>>5;
464       */
465 
466       f0_y0 = vshr_n_u8(vld1_u8(preField + base_y + x_pos ), 3);
467       f1_y0 = vshr_n_u8(vld1_u8(curField + base_y + x_pos ), 3);
468       f2_y0 = vshr_n_u8(vld1_u8(nxtField + base_y + x_pos ), 3);
469       f3_y0 = vshr_n_u8(vld1_u8(nx2Field + base_y + x_pos ), 3);
470       f0_y1 = vshr_n_u8(vld1_u8(preField + base_yd + x_pos), 3);
471       f2_y1 = vshr_n_u8(vld1_u8(nxtField + base_yd + x_pos), 3);
472       //myprintf(f0_y0, x, y, "f0_y0");
473 
474       /*
475       f1_yu = vld1_u8(p_curField+base_yu);
476       f3_yu = vld1_u8(p_nx2Field+base_yu);
477       f0_y0 = vld1_u8(p_preField+base_y );
478       f1_y0 = vld1_u8(p_curField+base_y );
479       f2_y0 = vld1_u8(p_nxtField+base_y );
480       f3_y0 = vld1_u8(p_nx2Field+base_y );
481       f0_y1 = vld1_u8(p_preField+base_yd);
482       f2_y1 = vld1_u8(p_nxtField+base_yd);
483 
484       f1_yu = vshr_n_u8(f1_yu, 5);
485       f3_yu = vshr_n_u8(f3_yu, 5);
486       f0_y0 = vshr_n_u8(f0_y0, 5);
487       f1_y0 = vshr_n_u8(f1_y0, 5);
488       f2_y0 = vshr_n_u8(f2_y0, 5);
489       f3_y0 = vshr_n_u8(f3_y0, 5);
490       f0_y1 = vshr_n_u8(f0_y1, 5);
491       f2_y1 = vshr_n_u8(f2_y1, 5);*/
492 
493 
494       /*
495       diff1 = abs(f0_y0 - f2_y0);
496       if (diff1 > mot_diff_th)
497       {
498       filter1 = abs(med3(f1_yu, f2_y0, f1_y0) - f2_y0);
499       if ( (filter1 > med_filter_th) )
500       frame_motion_T1B0++;
501 
502       filter2 = abs(med3(f3_yu, f0_y0, f3_y0) - f0_y0);
503       if ( (filter2 > med_filter_th) )
504       frame_motion_T0B1++;
505       }
506       */
507 
508       //if(realline_cycl==1)
509       /*
510       diff2 = abs(f1_y0 - f3_y0);
511       if (diff2 > mot_diff_th)
512       {
513         filter1 = abs(med3(f2_y0, f1_y0, f2_y1) - f1_y0);
514         if ( (filter1 > med_filter_th) )
515           frame_motion_T1B0++;
516 
517         filter2 = abs(med3(f0_y0, f3_y0, f0_y1) - f3_y0);
518         if ( (filter2 > med_filter_th) )
519           frame_motion_T0B1++;
520       }*/
521 
522       diff2   = vabd_u8(f1_y0, f3_y0);                                   //diff2 = abs(f1_y0 - f3_y0);
523       r_diff2 = vcgt_u8(diff2, mot_diff_th);                             //if (diff2 > mot_diff_th)
524       filter1 = vabd_u8(vmed3_i8(f2_y0, f1_y0, f2_y1), f1_y0);           //filter1 = abs(med3(f2_y0, f1_y0, f2_y1) - f1_y0);
525       r_filter1 = vcgt_u8(filter1, med_filter_th);                       //if ( (filter1 > med_filter_th) )
526       rst = vtst_u8(r_diff2, r_filter1);
527       rst = vshr_n_u8(rst, 7);
528       frame_motion_T1B0  += vget_lane_u8(rst, 0);               //frame_motion_T1B0++;
529       frame_motion_T1B0  += vget_lane_u8(rst, 1);
530       frame_motion_T1B0  += vget_lane_u8(rst, 2);
531       frame_motion_T1B0  += vget_lane_u8(rst, 3);
532       frame_motion_T1B0  += vget_lane_u8(rst, 4);
533       frame_motion_T1B0  += vget_lane_u8(rst, 5);
534       frame_motion_T1B0  += vget_lane_u8(rst, 6);
535       frame_motion_T1B0  += vget_lane_u8(rst, 7);
536 
537       filter2 = vabd_u8(vmed3_i8(f0_y0, f3_y0, f0_y1), f3_y0);           //filter2 = abs(med3(f0_y0, f3_y0, f0_y1) - f3_y0);
538       r_filter2 = vcgt_u8(filter2, med_filter_th);                       //if ( (filter2 > med_filter_th) )
539       rst = vtst_u8(r_diff2, r_filter2);
540       rst = vshr_n_u8(rst, 7);
541       frame_motion_T0B1  += vget_lane_u8(rst, 0);               //frame_motion_T0B1++;
542       frame_motion_T0B1  += vget_lane_u8(rst, 1);
543       frame_motion_T0B1  += vget_lane_u8(rst, 2);
544       frame_motion_T0B1  += vget_lane_u8(rst, 3);
545       frame_motion_T0B1  += vget_lane_u8(rst, 4);
546       frame_motion_T0B1  += vget_lane_u8(rst, 5);
547       frame_motion_T0B1  += vget_lane_u8(rst, 6);
548       frame_motion_T0B1  += vget_lane_u8(rst, 7);
549       /*
550       if (diff2 > mot_diff_fm_th)
551       {
552         filter3 = abs(med3(f0_y0, f1_y0, f0_y1) - f1_y0);
553         if ( (filter3 > med_filter_fm_th) )
554           frame_motion_T0B0++;
555 
556         filter4 = abs(med3(f2_y0, f3_y0, f2_y1) - f3_y0);
557         if ( (filter4 > med_filter_fm_th) )
558           frame_motion_T1B1++;
559       }*/
560       r_diff2 = vcgt_u8(diff2, mot_diff_fm_th);                          //if (diff2 > mot_diff_fm_th)
561 #ifndef REMOVE_T0B0
562       filter3 = vabd_u8(vmed3_i8(f0_y0, f1_y0, f0_y1), f1_y0);           //filter3 = abs(med3(f0_y0, f1_y0, f0_y1) - f1_y0);
563       r_filter3 = vcgt_u8(filter3, med_filter_fm_th);                    //if ( (filter3 > med_filter_fm_th) )
564       rst = vtst_u8(r_diff2, r_filter3);
565       rst = vshr_n_u8(rst, 7);
566       frame_motion_T0B0  += vget_lane_u8(rst, 0);               //frame_motion_T0B0++;
567       frame_motion_T0B0  += vget_lane_u8(rst, 1);
568       frame_motion_T0B0  += vget_lane_u8(rst, 2);
569       frame_motion_T0B0  += vget_lane_u8(rst, 3);
570       frame_motion_T0B0  += vget_lane_u8(rst, 4);
571       frame_motion_T0B0  += vget_lane_u8(rst, 5);
572       frame_motion_T0B0  += vget_lane_u8(rst, 6);
573       frame_motion_T0B0  += vget_lane_u8(rst, 7);
574 #endif
575 #ifndef REMOVE_T1B1
576       filter4 = vabd_u8(vmed3_i8(f2_y0, f3_y0, f2_y1), f3_y0);           //filter4 = abs(med3(f2_y0, f3_y0, f2_y1) - f3_y0);
577       r_filter4 = vcgt_u8(filter4, med_filter_fm_th);                    //if ( (filter4 > med_filter_fm_th) )
578       rst = vtst_u8(r_diff2, r_filter4);
579       rst = vshr_n_u8(rst, 7);
580       frame_motion_T1B1  += vget_lane_u8(rst, 0);               //frame_motion_T1B1++;
581       frame_motion_T1B1  += vget_lane_u8(rst, 1);
582       frame_motion_T1B1  += vget_lane_u8(rst, 2);
583       frame_motion_T1B1  += vget_lane_u8(rst, 3);
584       frame_motion_T1B1  += vget_lane_u8(rst, 4);
585       frame_motion_T1B1  += vget_lane_u8(rst, 5);
586       frame_motion_T1B1  += vget_lane_u8(rst, 6);
587       frame_motion_T1B1  += vget_lane_u8(rst, 7);
588 #endif
589     }
590   }
591 }
detFieldOrderTop(unsigned char * preField,unsigned char * curField,unsigned char * nxtField,unsigned char * nx2Field,int CurIsBot)592 void detFieldOrderTop( unsigned char*preField, unsigned char*curField, unsigned char*nxtField, unsigned char*nx2Field, int CurIsBot )
593 {
594   uint8x8_t mot_diff_th      = vdup_n_u8(2);    //o_reg_fod_mot_diff_th 2
595   uint8x8_t med_filter_th    = vdup_n_u8(2);    //o_reg_fod_med_filter_th 2
596   uint8x8_t mot_diff_fm_th   = vdup_n_u8(2);    //o_reg_fod_mot_diff_fm_th 2
597   uint8x8_t med_filter_fm_th = vdup_n_u8(2);    //o_reg_fod_med_filter_fm_th 2
598 
599   uint8x8_t filter1, filter2;
600   uint8x8_t filter4;
601 #ifndef REMOVE_T0B0
602   uint8x8_t filter3;
603 #endif
604 
605   int yu, yd, y;
606 
607   int x_start = (g_fod_win_en == 1) ? X_START : 0;
608   int x_end = (g_fod_win_en == 1) ? X_END : g_Width;
609   int y_start = (g_fod_win_en == 1) ? Y_START : 0;
610   int y_end = (g_fod_win_en == 1) ? Y_END : g_Height;
611 #ifdef SUPPORT_TILE
612   int stride = g_tile_width;
613   int base_x = 0;
614 #else
615   int stride = g_Width;
616 #endif
617 
618   frame_motion_T1B0 = 0;
619   frame_motion_T0B1 = 0;
620 #ifndef REMOVE_T0B0
621   frame_motion_T0B0 = 0;
622 #endif
623   frame_motion_T1B1 = 0;
624 
625   for( y = y_start ; y < y_end ; y+=2 )
626   {
627     int base_yu, base_y, base_yd, x;
628     yu = y - 2;
629     if (yu < y_start)
630       yu = y;
631 
632     yd = y + 2;
633     if (yd >= y_end)
634       yd = y;
635 
636 #ifdef SUPPORT_TILE
637     base_yu = stride*(yu & H_Mod) + (yu >> H_shift) * (TILE_Height * g_pitch);
638     base_y  = stride*(y  & H_Mod) + (y  >> H_shift) * (TILE_Height * g_pitch);
639     base_yd = stride*(yd & H_Mod)+  (yd >> H_shift) * (TILE_Height * g_pitch);
640 #else
641     base_yu = stride*yu;
642     base_y  = stride*y;
643     base_yd = stride*yd;
644 #endif
645 
646 
647 
648     for( x = x_start ; x < x_end; x+=8 )
649     {
650       uint8x8_t f0_y0, f1_y0, f2_y0, f3_y0, f2_yu, f0_yu;
651       uint8x8_t  r_filter1, r_filter2, r_filter4;
652 #ifndef REMOVE_T0B0
653       uint8x8_t r_filter3;
654       uint8x8_t diff3;
655 #endif
656       uint8x8_t rst;
657 
658       uint8x8_t diff1, r_diff1;
659       uint8x8_t diff2, r_diff2;
660       uint8x8_t r_diff3;
661       int x_pos;
662 
663 #ifdef SUPPORT_TILE
664       base_x = (x >> g_tile_w_shift) * (g_tile_width * TILE_Height);
665       x_pos =  (x & g_tile_w_mod) + base_x;
666 #else
667       x_pos = x;
668 #endif
669 
670 
671 
672       f0_y0 = vshr_n_u8(vld1_u8(preField + base_y + x_pos ), 3);
673       f0_yu = vshr_n_u8(vld1_u8(preField + base_yu + x_pos ), 3);
674       f1_y0 = vshr_n_u8(vld1_u8(curField + base_y + x_pos ), 3);
675       f2_y0 = vshr_n_u8(vld1_u8(nxtField + base_y + x_pos ), 3);
676       f2_yu = vshr_n_u8(vld1_u8(nxtField + base_yu + x_pos ), 3);
677       f3_y0 = vshr_n_u8(vld1_u8(nx2Field + base_y + x_pos ), 3);
678       /*
679       //if(realline_cycl==0)
680       diff = abs((f0_y0>>5) - (f2_y0>>5) );
681       diff = (diff > mot_diff_th);
682       filter1 = abs(med3( (f1_y0>>5), (f2_y0>>5), (f1_yd>>5) ) - (f2_y0>>5) );
683       if ( diff && (filter1 > med_filter_th) )
684         frame_motion_T1B0++;*/
685 
686       /*
687       //if(realline_cycl==1)
688       diff = abs((f1_y0>>5) - (f3_y0>>5) );
689       diff = (diff > mot_diff_th);
690       filter1 = abs(med3( (f2_yu>>5), (f1_y0>>5), (f2_yd>>5) ) - (f1_y0>>5) );
691       if (diff && (filter1 > med_filter_th) )
692         frame_motion_T1B0++;
693       */
694 
695       diff1   = vabd_u8(f1_y0, f3_y0);
696       r_diff1 = vcgt_u8(diff1, mot_diff_th);
697       filter1 = vabd_u8(vmed3_i8(f2_yu, f1_y0, f2_y0), f1_y0);
698       r_filter1 = vcgt_u8(filter1, med_filter_th);
699       rst = vtst_u8(r_diff1, r_filter1);
700       rst = vshr_n_u8(rst, 7);
701       frame_motion_T1B0  += vget_lane_u8(rst, 0);
702       frame_motion_T1B0  += vget_lane_u8(rst, 1);
703       frame_motion_T1B0  += vget_lane_u8(rst, 2);
704       frame_motion_T1B0  += vget_lane_u8(rst, 3);
705       frame_motion_T1B0  += vget_lane_u8(rst, 4);
706       frame_motion_T1B0  += vget_lane_u8(rst, 5);
707       frame_motion_T1B0  += vget_lane_u8(rst, 6);
708       frame_motion_T1B0  += vget_lane_u8(rst, 7);
709       /*
710       filter2 = abs(med3( (f0_yu>>5), (f3_y0>>5), (f0_yd>>5) ) - (f3_y0>>5) );
711       if ( diff && (filter2 > med_filter_th) )
712         frame_motion_T0B1++;*/
713 
714       diff2   = vabd_u8(f3_y0, f1_y0);
715       r_diff2 = vcgt_u8(diff2, mot_diff_th);
716       filter2 = vabd_u8(vmed3_i8(f0_yu, f3_y0, f0_y0), f3_y0);
717       r_filter2 = vcgt_u8(filter2, med_filter_th);
718       rst = vtst_u8(r_diff2, r_filter2);
719       rst = vshr_n_u8(rst, 7);
720       frame_motion_T0B1  += vget_lane_u8(rst, 0);
721       frame_motion_T0B1  += vget_lane_u8(rst, 1);
722       frame_motion_T0B1  += vget_lane_u8(rst, 2);
723       frame_motion_T0B1  += vget_lane_u8(rst, 3);
724       frame_motion_T0B1  += vget_lane_u8(rst, 4);
725       frame_motion_T0B1  += vget_lane_u8(rst, 5);
726       frame_motion_T0B1  += vget_lane_u8(rst, 6);
727       frame_motion_T0B1  += vget_lane_u8(rst, 7);
728 
729       r_diff3 = vcgt_u8(diff1, mot_diff_fm_th);
730 #ifndef REMOVE_T0B0
731       /*
732       filter3 = abs(med3( (f0_yu>>5), (f1_y0>>5), (f0_y0>>5) ) - (f1_y0>>5) );
733       if ( diff && (filter3 > med_filter_fm_th) )
734         frame_motion_T0B0++;*/
735       filter3 = vabd_u8(vmed3_i8(f0_yu, f1_y0, f0_y0), f1_y0);
736       r_filter3 = vcgt_u8(filter3, med_filter_fm_th);
737       rst = vtst_u8(r_diff3, r_filter3);
738       rst = vshr_n_u8(rst, 7);
739       frame_motion_T0B0  += vget_lane_u8(rst, 0);
740       frame_motion_T0B0  += vget_lane_u8(rst, 1);
741       frame_motion_T0B0  += vget_lane_u8(rst, 2);
742       frame_motion_T0B0  += vget_lane_u8(rst, 3);
743       frame_motion_T0B0  += vget_lane_u8(rst, 4);
744       frame_motion_T0B0  += vget_lane_u8(rst, 5);
745       frame_motion_T0B0  += vget_lane_u8(rst, 6);
746       frame_motion_T0B0  += vget_lane_u8(rst, 7);
747 #endif
748 #ifndef REMOVE_T1B1
749       /*
750       filter4 = abs(med3( (f2_yu>>5), (f3_y0>>5), (f2_yd>>5) ) - (f3_y0>>5) );
751       if ( diff && (filter4 > med_filter_fm_th) )
752         frame_motion_T1B1++;*/
753       filter4 = vabd_u8(vmed3_i8(f2_yu, f3_y0, f2_y0), f3_y0);
754       r_filter4 = vcgt_u8(filter4, med_filter_fm_th);
755       rst = vtst_u8(r_diff3, r_filter4);
756       rst = vshr_n_u8(rst, 7);
757       frame_motion_T1B1  += vget_lane_u8(rst, 0);
758       frame_motion_T1B1  += vget_lane_u8(rst, 1);
759       frame_motion_T1B1  += vget_lane_u8(rst, 2);
760       frame_motion_T1B1  += vget_lane_u8(rst, 3);
761       frame_motion_T1B1  += vget_lane_u8(rst, 4);
762       frame_motion_T1B1  += vget_lane_u8(rst, 5);
763       frame_motion_T1B1  += vget_lane_u8(rst, 6);
764       frame_motion_T1B1  += vget_lane_u8(rst, 7);
765 #endif
766     }
767   }
768 
769 }
770 #endif
771 #define mymax(a,b)            (((a) > (b)) ? (a) : (b))
fastabs(int v)772 static unsigned int fastabs(int v)
773 {
774   unsigned int r;
775   int const mask = (v >> sizeof(int)) * CHAR_BIT - 1;
776   r = (v + mask) ^ mask;
777   return r;
778 }
dumpDetFieldOrder_status(int CurIsBot)779 void dumpDetFieldOrder_status(int CurIsBot)
780 {
781   float ratio;
782   int motion_T0B1, motion_T1B0;
783   int bT1B0, bT0B1, bRatio;
784 
785 #ifdef FILE_DBG
786     char ofile[128] = "DUMP_DetFieldOrder.txt";
787     FILE *fptr = fopen(ofile, "a");
788     if( fptr == NULL ) return;
789 #endif
790     g_ary_idx++;
791     if (g_ary_idx == MAXFRAME)
792       g_ary_idx = 0;
793 #ifdef FILE_DBG
794     if(g_ary_idx == 0 && g_bInitPhase == 1)
795     {
796       fprintf(fptr, "// motionT0B1(TFF), motionT1B0(BFF), motionT0B0, curField(Top0/Bot1)\n");
797     }
798 #endif
799     //dump1 << "// " << dec << item_idx++ << " Motion_cnt_all_status_pre32 " << _dumpPnrStatus.Motion_cnt_all_status_pre32 << "\n";
800     //dump1 << hex << setw(5) << frame_motion_T0B1[idx] << ", " << frame_motion_T1B0[idx] << "\n";
801     motion_T0B1 = mymax(frame_motion_T0B1, 1);
802     motion_T1B0 = mymax(frame_motion_T1B0, 1);
803 
804     bT1B0 = frame_motion_T1B0 > g_sceneChangeTh;
805     bT0B1 = frame_motion_T0B1 > g_sceneChangeTh;
806 
807     ratio = (float)motion_T0B1/(float)motion_T1B0;
808 
809     ary_frame_motion_ratio[g_ary_idx] = (int)(ratio*256.0);
810     bRatio = (fastabs(ary_frame_motion_ratio[g_ary_idx] - 256) < 16);
811     ary_IsSceneChangeTh[g_ary_idx] = (bT0B1 && bT1B0 && bRatio);
812 #ifdef FILE_DBG
813     fprintf(fptr, "%05x_%05x_%05x_%d, ratio=%d, bT0B1=%d bT1B0=%d bRatio=%d\n",
814                   frame_motion_T0B1,
815                   frame_motion_T1B0,
816                   frame_motion_T1B1,
817                   CurIsBot, ary_frame_motion_ratio[g_ary_idx], bT0B1, bT1B0, bRatio);
818     fclose(fptr);
819 #endif
820 
821 #ifdef DEBUG_INFO
822     printf("[FOD] %05x_%05x_%05x_%d, ratio=%d, bT0B1=%d bT1B0=%d bRatio=%d\n",
823       frame_motion_T0B1,
824       frame_motion_T1B0,
825       frame_motion_T1B1,
826       CurIsBot, ary_frame_motion_ratio[g_ary_idx], bT0B1, bT1B0, bRatio);
827 #endif
828 
829 }
830 #endif