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