1// -*- c++ -*-
2
3		// First, get and save our possible Bob values
4		// Assume our pixels are layed out as follows with x the calc'd bob value
5		// and the other pixels are from the current field
6		//
7		//	  j a b c k		current field
8		//            x			calculated line
9		//        m d e f n		current field
10		//
11		// we calc the bob value luma value as:
12        // if |j - n| < Thres && |a - m| > Thres
13        //  avg(j,n)
14        // end if
15        // if |k - m| < Thres && |c - n| > Thres
16        //  avg(k,m)
17        // end if
18        // if |c - d| < Thres && |b - f| > Thres
19        //  avg(c,d)
20        // end if
21        // if |a - f| < Thres && |b - d| > Thres
22        //  avg(a,f)
23        // end if
24        // if |b - e| < Thres
25        //  avg(b,e)
26        // end if
27        // pickup any thing not yet set with avg(b,e)
28
29#ifndef IS_C
30
31		// j, n
32        "pxor %%mm5, %%mm5\n\t"
33        "pxor %%mm6, %%mm6\n\t"
34        "pxor %%mm7, %%mm7\n\t"
35
36		"movq    -2(%%"XBX"), %%mm0\n\t"		// value a from top left
37		"movq    -4(%%"XBX", %%"XCX"), %%mm1\n\t"	// value m from bottom right
38
39		"movq	%%mm0, %%mm3\n\t"
40		"psubusb	%%mm1, %%mm3\n\t"
41		"psubusb %%mm0, %%mm1\n\t"
42		"por		%%mm1, %%mm3\n\t"					// abs(a,m)
43
44		"psubusb "_DiffThres", %%mm3\n\t"		// nonzero where abs(a,m) > Thres else 0
45		"pxor	%%mm4, %%mm4\n\t"
46		"pcmpeqb %%mm4, %%mm3\n\t"			// now ff where abs(a,m) < Thres, else 00
47		"pcmpeqb	%%mm3, %%mm4\n\t"			// here ff where abs(a,m) > Thres, else 00
48
49
50		"movq    -4(%%"XBX"), %%mm0\n\t"		// value j
51		"movq    4(%%"XBX", %%"XCX"), %%mm1\n\t"	// value n
52		"movq	%%mm0, %%mm2\n\t"
53		V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask)	// avg(j,n)
54        "movq	%%mm0, %%mm3\n\t"
55		"psubusb	%%mm1, %%mm0\n\t"
56		"psubusb %%mm3, %%mm1\n\t"
57		"por		%%mm1, %%mm0\n\t"					// abs(j,n)
58
59        "movq    %%mm0, %%mm1\n\t"
60		"psubusb "_DiffThres", %%mm1\n\t"		// nonzero where abs(j,n) > Thres else 0
61		"pxor	%%mm3, %%mm3\n\t"
62		"pcmpeqb %%mm3, %%mm1\n\t"			// now ff where abs(j,n) < Thres, else 00
63
64        "pand    %%mm4, %%mm1\n\t"
65        "pand    %%mm1, %%mm2\n\t"
66        "pand    %%mm1, %%mm0\n\t"
67
68        "movq    %%mm1, %%mm3\n\t"
69        "pxor    %%mm5, %%mm3\n\t"
70        "pand    %%mm3, %%mm6\n\t"
71        "pand    %%mm3, %%mm7\n\t"
72        "pand    %%mm3, %%mm5\n\t"
73
74        "por     %%mm1, %%mm5\n\t"
75        "por     %%mm2, %%mm6\n\t"
76        "por     %%mm0, %%mm7\n\t"
77
78        // k & m
79		"movq    2(%%"XBX"), %%mm0\n\t"		// value c from top left
80		"movq    4(%%"XBX", %%"XCX"), %%mm1\n\t"	// value n from bottom right
81
82		"movq	%%mm0, %%mm3\n\t"
83		"psubusb	%%mm1, %%mm3\n\t"
84		"psubusb %%mm0, %%mm1\n\t"
85		"por		%%mm1, %%mm3\n\t"					// abs(c,n)
86
87		"psubusb "_DiffThres", %%mm3\n\t"		// nonzero where abs(c,n) > Thres else 0
88		"pxor	%%mm4, %%mm4\n\t"
89		"pcmpeqb %%mm4, %%mm3\n\t"			// now ff where abs(c,n) < Thres, else 00
90		"pcmpeqb	%%mm3, %%mm4\n\t"			// here ff where abs(c,n) > Thres, else 00
91
92
93		"movq    4(%%"XBX"), %%mm0\n\t"		// value k
94		"movq    -4(%%"XBX", %%"XCX"), %%mm1\n\t"	// value m
95		"movq	%%mm0, %%mm2\n\t"
96		V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask)	// avg(k,m)
97        "movq	%%mm0, %%mm3\n\t"
98		"psubusb	%%mm1, %%mm0\n\t"
99		"psubusb %%mm3, %%mm1\n\t"
100		"por		%%mm1, %%mm0\n\t"					// abs(k,m)
101
102        "movq    %%mm0, %%mm1\n\t"
103		"psubusb "_DiffThres", %%mm1\n\t"		// nonzero where abs(k,m) > Thres else 0
104		"pxor	%%mm3, %%mm3\n\t"
105		"pcmpeqb %%mm3, %%mm1\n\t"			// now ff where abs(k,m) < Thres, else 00
106
107        "pand    %%mm4, %%mm1\n\t"
108
109        "pand    %%mm1, %%mm2\n\t"
110        "pand    %%mm1, %%mm0\n\t"
111
112        "movq    %%mm1, %%mm3\n\t"
113        "pxor    %%mm5, %%mm3\n\t"
114        "pand    %%mm3, %%mm6\n\t"
115        "pand    %%mm3, %%mm7\n\t"
116        "pand    %%mm3, %%mm5\n\t"
117
118        "por     %%mm1, %%mm5\n\t"
119        "por     %%mm2, %%mm6\n\t"
120        "por     %%mm0, %%mm7\n\t"
121
122
123        // c & d
124		"movq    (%%"XBX"), %%mm0\n\t"		// value b from top left
125		"movq    2(%%"XBX", %%"XCX"), %%mm1\n\t"	// value f from bottom right
126
127		"movq	%%mm0, %%mm3\n\t"
128		"psubusb	%%mm1, %%mm3\n\t"
129		"psubusb %%mm0, %%mm1\n\t"
130		"por		%%mm1, %%mm3\n\t"					// abs(b,f)
131
132		"psubusb "_DiffThres", %%mm3\n\t"		// nonzero where abs(b,f) > Thres else 0
133		"pxor	%%mm4, %%mm4\n\t"
134		"pcmpeqb %%mm4, %%mm3\n\t"			// now ff where abs(b,f) < Thres, else 00
135		"pcmpeqb	%%mm3, %%mm4\n\t"			// here ff where abs(b,f) > Thres, else 00
136
137		"movq    2(%%"XBX"), %%mm0\n\t"		// value c
138		"movq    -2(%%"XBX", %%"XCX"), %%mm1\n\t"	// value d
139		"movq	%%mm0, %%mm2\n\t"
140		V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask)	// avg(c,d)
141        "movq	%%mm0, %%mm3\n\t"
142		"psubusb	%%mm1, %%mm0\n\t"
143		"psubusb %%mm3, %%mm1\n\t"
144		"por		%%mm1, %%mm0\n\t"					// abs(c,d)
145
146        "movq    %%mm0, %%mm1\n\t"
147		"psubusb "_DiffThres", %%mm1\n\t"		// nonzero where abs(c,d) > Thres else 0
148		"pxor	%%mm3, %%mm3\n\t"
149        "pcmpeqb %%mm3, %%mm1\n\t"			// now ff where abs(c,d) < Thres, else 00
150
151        "pand    %%mm4, %%mm1\n\t"
152
153        "pand    %%mm1, %%mm2\n\t"
154        "pand    %%mm1, %%mm0\n\t"
155
156        "movq    %%mm1, %%mm3\n\t"
157        "pxor    %%mm5, %%mm3\n\t"
158        "pand    %%mm3, %%mm6\n\t"
159        "pand    %%mm3, %%mm7\n\t"
160        "pand    %%mm3, %%mm5\n\t"
161
162        "por     %%mm1, %%mm5\n\t"
163        "por     %%mm2, %%mm6\n\t"
164        "por     %%mm0, %%mm7\n\t"
165
166        // a & f
167		"movq    (%%"XBX"), %%mm0\n\t"		// value b from top left
168		"movq    -2(%%"XBX", %%"XCX"), %%mm1\n\t"	// value d from bottom right
169
170		"movq	%%mm0, %%mm3\n\t"
171		"psubusb	%%mm1, %%mm3\n\t"
172		"psubusb %%mm0, %%mm1\n\t"
173		"por		%%mm1, %%mm3\n\t"					// abs(b,d)
174
175		"psubusb "_DiffThres", %%mm3\n\t"	// nonzero where abs(b,d) > Thres else 0
176		"pxor	%%mm4, %%mm4\n\t"
177		"pcmpeqb %%mm4, %%mm3\n\t"			// now ff where abs(b,d) < Thres, else 00
178		"pcmpeqb	%%mm3, %%mm4\n\t"			// here ff where abs(b,d) > Thres, else 00
179
180		"movq    -2(%%"XBX"), %%mm0\n\t"		// value a
181		"movq    2(%%"XBX", %%"XCX"), %%mm1\n\t"	// value f
182		"movq	%%mm0, %%mm2\n\t"
183		V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask)	// avg(a,f)
184        "movq	%%mm0, %%mm3\n\t"
185        "psubusb	%%mm1, %%mm0\n\t"
186		"psubusb %%mm3, %%mm1\n\t"
187		"por		%%mm1, %%mm0\n\t"					// abs(a,f)
188
189        "movq    %%mm0, %%mm1\n\t"
190		"psubusb "_DiffThres", %%mm1\n\t"		// nonzero where abs(a,f) > Thres else 0
191		"pxor	%%mm3, %%mm3\n\t"
192		"pcmpeqb %%mm3, %%mm1\n\t"			// now ff where abs(a,f) < Thres, else 00
193
194        "pand    %%mm4, %%mm1\n\t"
195
196        "pand    %%mm1, %%mm2\n\t"
197        "pand    %%mm1, %%mm0\n\t"
198
199        "movq    %%mm1, %%mm3\n\t"
200        "pxor    %%mm5, %%mm3\n\t"
201        "pand    %%mm3, %%mm6\n\t"
202        "pand    %%mm3, %%mm7\n\t"
203        "pand    %%mm3, %%mm5\n\t"
204
205        "por     %%mm1, %%mm5\n\t"
206        "por     %%mm2, %%mm6\n\t"
207        "por     %%mm0, %%mm7\n\t"
208
209 		"pand	"_YMask", %%mm5\n\t"		// mask out chroma from here
210 		"pand	"_YMask", %%mm6\n\t"			// mask out chroma from here
211 		"pand	"_YMask", %%mm7\n\t"			// mask out chroma from here
212
213		// b,e
214		"movq    (%%"XBX"), %%mm0\n\t"		// value b from top
215		"movq    (%%"XBX", %%"XCX"), %%mm1\n\t"	// value e from bottom
216		"movq	%%mm0, %%mm2\n\t"
217		V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask)	// avg(b,e)
218        "movq	%%mm0, %%mm3\n\t"
219        "psubusb	%%mm1, %%mm0\n\t"
220		"psubusb %%mm3, %%mm1\n\t"
221		"por		%%mm1, %%mm0\n\t"					// abs(b,e)
222
223        "movq    %%mm0, %%mm1\n\t"
224		"psubusb "_DiffThres", %%mm1\n\t"		// nonzero where abs(b,e) > Thres else 0
225		"pxor	%%mm3, %%mm3\n\t"
226		"pcmpeqb %%mm3, %%mm1\n\t"		// now ff where abs(b,e) < Thres, else 00
227
228        "pand    %%mm1, %%mm2\n\t"
229        "pand    %%mm1, %%mm0\n\t"
230
231        "movq    %%mm1, %%mm3\n\t"
232        "pxor    %%mm5, %%mm3\n\t"
233        "pand    %%mm3, %%mm6\n\t"
234        "pand    %%mm3, %%mm7\n\t"
235        "pand    %%mm3, %%mm5\n\t"
236
237        "por     %%mm1, %%mm5\n\t"
238        "por     %%mm2, %%mm6\n\t"
239        "por     %%mm0, %%mm7\n\t"
240
241		// bob in any leftovers
242		"movq    (%%"XBX"), %%mm0\n\t"		// value b from top
243		"movq    (%%"XBX", %%"XCX"), %%mm1\n\t"	// value e from bottom
244
245
246// We will also calc here the max/min values to later limit comb
247// so the max excursion will not exceed the Max_Comb constant
248
249#ifdef SKIP_SEARCH
250		"movq	%%mm0, %%mm2\n\t"
251//		pminub	%%mm2, %%mm1
252		V_PMINUB ("%%mm2", "%%mm1", "%%mm4")
253
254//		pmaxub	%%mm6, %%mm2			// clip our current results so far to be above this
255		V_PMAXUB ("%%mm6", "%%mm2")
256        "movq	%%mm0, %%mm2\n\t"
257		V_PMAXUB ("%%mm2", "%%mm1")
258//		pminub	%%mm6, %%mm2			// clip our current results so far to be below this
259		V_PMINUB ("%%mm6", "%%mm2", "%%mm4")
260
261#else
262        "movq	%%mm0, %%mm2\n\t"
263		"movq	(%%"XAX"), %%mm4\n\t"
264		"psubusb %%mm4, %%mm2\n\t"
265		"psubusb %%mm0, %%mm4\n\t"
266		"por		%%mm2, %%mm4\n\t"			// abs diff
267
268		"movq	%%mm1, %%mm2\n\t"
269		"movq	(%%"XAX", %%"XCX"), %%mm3\n\t"
270		"psubusb %%mm3, %%mm2\n\t"
271		"psubusb %%mm1, %%mm3\n\t"
272		"por		%%mm2, %%mm3\n\t"			// abs diff
273//		pmaxub  %%mm3, %%mm4			// top or bottom pixel moved most
274		V_PMAXUB ("%%mm3", "%%mm4")			// top or bottom pixel moved most
275        "psubusb "_DiffThres", %%mm3\n\t"		// moved more than allowed? or goes to 0?
276		"pxor	%%mm4, %%mm4\n\t"
277		"pcmpeqb %%mm4, %%mm3\n\t"			// now ff where low motion, else high motion
278
279		"movq	%%mm0, %%mm2\n\t"
280//		pminub	%%mm2, %%mm1
281		V_PMINUB ("%%mm2", "%%mm1", "%%mm4")
282
283//		pmaxub	%%mm6, %%mm2			// clip our current results so far to be above this
284		V_PMAXUB ("%%mm6", "%%mm2")
285
286        "psubusb %%mm3, %%mm2\n\t"			// maybe decrease it to 0000.. if no surround motion
287		"movq	%%mm2, "_Min_Vals"\n\t"
288
289		"movq	%%mm0, %%mm2\n\t"
290		V_PMAXUB ("%%mm2", "%%mm1")
291//		pminub	%%mm6, %%mm2			// clip our current results so far to be below this
292		V_PMINUB ("%%mm6", "%%mm2", "%%mm4")
293        "paddusb %%mm3, %%mm2\n\t"			// maybe increase it to ffffff if no surround motion
294		"movq	%%mm2, "_Max_Vals"\n\t"
295#endif
296
297		"movq	%%mm0, %%mm2\n\t"
298//		pavgb	%%mm2, %%mm1					// avg(b,e)
299		V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask)	// avg(b,e)
300
301        "movq	%%mm0, %%mm3\n\t"
302		"psubusb	%%mm1, %%mm3\n\t"
303		"psubusb %%mm0, %%mm1\n\t"
304		"por		%%mm1, %%mm3\n\t"			// abs(b,e)
305		"movq	%%mm3, %%mm1\n\t"			// keep copy of diffs
306
307		"pxor	%%mm4, %%mm4\n\t"
308		"psubusb %%mm7, %%mm3\n\t"			// nonzero where new weights bigger, else 0
309		"pcmpeqb %%mm4, %%mm3\n\t"			// now ff where new better, else 00
310        "pcmpeqb %%mm0, %%mm0\n\t"
311        "pandn   %%mm0, %%mm5\n\t"
312        "por     %%mm5, %%mm3\n\t"
313		"pcmpeqb	%%mm3, %%mm4\n\t"			// here ff where old better, else 00
314
315		"pand	%%mm3, %%mm1\n\t"
316		"pand	%%mm3, %%mm2\n\t"
317
318		"pand    %%mm4, %%mm6\n\t"
319		"pand    %%mm4, %%mm7\n\t"
320
321		"por		%%mm2, %%mm6\n\t"			// our x2 value
322		"por		%%mm1, %%mm7\n\t"			// our x2 diffs
323		"movq	%%mm7, %%mm4\n\t"			// save as bob uncertainty indicator
324
325#else
326
327        diff[0] = -1;
328        diff[1] = -1;
329	best[0] = 0;
330	best[1] = 0;
331	// j, n
332        if (ABS (pBob[-2] - pBob[src_pitch2 - 4]) < DiffThres &&
333	    ABS (pBob[-4] - pBob[src_pitch2 + 4]) > DiffThres) {
334	   best[0] = (pBob[-2] + pBob[src_pitch2 - 4]) / 2;
335	   diff[0] = ABS (pBob[-2] - pBob[src_pitch2 - 4]);
336	}
337        if (ABS (pBob[-1] - pBob[src_pitch2 - 3]) < DiffThres &&
338	    ABS (pBob[-3] - pBob[src_pitch2 + 5]) > DiffThres) {
339	   best[1] = (pBob[-1] + pBob[src_pitch2 - 3]) / 2;
340	   diff[1] = ABS (pBob[-1] - pBob[src_pitch2 - 3]);
341	}
342
343        // k & m
344        if (ABS (pBob[2] - pBob[src_pitch2 + 4]) < DiffThres &&
345	    ABS (pBob[4] - pBob[src_pitch2 - 4]) > DiffThres) {
346	   best[0] = (pBob[4] + pBob[src_pitch2 - 4]) / 2;
347	   diff[0] = ABS (pBob[4] - pBob[src_pitch2 - 4]);
348	}
349
350        if (ABS (pBob[3] - pBob[src_pitch2 + 5]) < DiffThres &&
351	    ABS (pBob[5] - pBob[src_pitch2 - 3]) > DiffThres) {
352	   best[1] = (pBob[5] + pBob[src_pitch2 - 3]) / 2;
353	   diff[1] = ABS (pBob[5] - pBob[src_pitch2 - 3]);
354	}
355
356        // c & d
357	if (ABS (pBob[0] - pBob[src_pitch2 + 2]) < DiffThres &&
358	    ABS (pBob[2] - pBob[src_pitch2 - 2]) > DiffThres) {
359	   best[0] = (pBob[2] + pBob[src_pitch2 - 2]) / 2;
360	   diff[0] = ABS (pBob[2] - pBob[src_pitch2 - 2]);
361	}
362
363	if (ABS (pBob[1] - pBob[src_pitch2 + 3]) < DiffThres &&
364	    ABS (pBob[3] - pBob[src_pitch2 - 1]) > DiffThres) {
365	   best[1] = (pBob[3] + pBob[src_pitch2 - 1]) / 2;
366	   diff[1] = ABS (pBob[3] - pBob[src_pitch2 - 1]);
367	}
368
369        // a & f
370	if (ABS (pBob[0] - pBob[src_pitch2 - 2]) < DiffThres &&
371	    ABS (pBob[-2] - pBob[src_pitch2 + 2]) > DiffThres) {
372	   best[0] = (pBob[-2] + pBob[src_pitch2 + 2]) / 2;
373	   diff[0] = ABS (pBob[-2] - pBob[src_pitch2 + 2]);
374	}
375
376	if (ABS (pBob[1] - pBob[src_pitch2 - 1]) < DiffThres &&
377	    ABS (pBob[-1] - pBob[src_pitch2 + 3]) > DiffThres) {
378	   best[1] = (pBob[-1] + pBob[src_pitch2 + 3]) / 2;
379	   diff[1] = ABS (pBob[-1] - pBob[src_pitch2 + 3]);
380	}
381
382	// b,e
383	if (ABS (pBob[0] - pBob[src_pitch2]) < DiffThres) {
384	   best[0] = (pBob[0] + pBob[src_pitch2]) / 2;
385	   diff[0] = ABS (pBob[0] - pBob[src_pitch2]);
386	}
387
388	if (ABS (pBob[1] - pBob[src_pitch2 + 1]) < DiffThres) {
389	   best[1] = (pBob[1] + pBob[src_pitch2 + 1]) / 2;
390	   diff[1] = ABS (pBob[1] - pBob[src_pitch2 + 1]);
391	}
392
393
394// We will also calc here the max/min values to later limit comb
395// so the max excursion will not exceed the Max_Comb constant
396
397#ifdef SKIP_SEARCH
398		best[0] = CLAMP (best[0], MIN (pBob[src_pitch2], pBob[0]), MAX (pBob[src_pitch2], pBob[0]));
399		best[1] = CLAMP (best[1], MIN (pBob[src_pitch2 + 1], pBob[1]), MAX (pBob[src_pitch2 + 1], pBob[1]));
400#else
401		mov[0] = MAX (ABS (pBob[0] - pBobP[0]), ABS (pBob[src_pitch2] - pBobP[src_pitch2]));
402		mov[1] = MAX (ABS (pBob[1] - pBobP[1]), ABS (pBob[src_pitch2 + 1] - pBobP[src_pitch2 + 1]));
403
404		MinVals[0] = 0;
405		MinVals[1] = 0;
406		MaxVals[0] = 255;
407		MaxVals[1] = 255;
408		if (mov[0] > DiffThres) {
409		  MinVals[0] = MAX (MIN (pBob[0], pBob[src_pitch2]), best[0]);
410		  MaxVals[0] = MIN (MAX (pBob[0], pBob[src_pitch2]), best[0]);
411		}
412
413		if (mov[1] > DiffThres) {
414		  MinVals[1] = MAX (MIN (pBob[1], pBob[src_pitch2+1]), best[1]);
415		  MaxVals[1] = MIN (MAX (pBob[1], pBob[src_pitch2+1]), best[1]);
416		}
417
418		best[0] = CLAMP (best[0], MIN (pBob[src_pitch2], pBob[0]), MAX (pBob[src_pitch2], pBob[0]));
419		best[1] = CLAMP (best[1], MIN (pBob[src_pitch2 + 1], pBob[1]), MAX (pBob[src_pitch2 + 1], pBob[1]));
420#endif
421		avg[0] = (pBob[src_pitch2] + pBob[0]) / 2;
422		avg[1] = (pBob[src_pitch2 + 1] + pBob[1]) / 2;
423		diff2[0] = ABS (pBob[src_pitch2 + 1] - pBob[1]);
424		diff2[1] = ABS (pBob[src_pitch2 + 1] - pBob[1]);
425
426		if (diff[0] == -1 || diff2[0] < diff[0]) {
427		  best[0] = avg[0];
428		  diff[0] = diff2[0];
429		}
430
431		if (diff[1] == -1 || diff2[1] < diff[1]) {
432		  best[1] = avg[1];
433		  diff[1] = diff2[1];
434		}
435#endif
436