]> git.sesse.net Git - x264/blob - common/predict.c
revert 216, another try at max_dec_frame_buffering.
[x264] / common / predict.c
1 /*****************************************************************************
2  * predict.c: h264 encoder
3  *****************************************************************************
4  * Copyright (C) 2003 Laurent Aimar
5  * $Id: predict.c,v 1.1 2004/06/03 19:27:07 fenrir Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /* XXX predict4x4 are inspired from ffmpeg h264 decoder
25  */
26
27 #ifdef HAVE_STDINT_H
28 #include <stdint.h>
29 #else
30 #include <inttypes.h>
31 #endif
32 #include <stdlib.h>
33 #include <stdarg.h>
34
35 #include "common.h"
36 #include "macroblock.h"
37
38 #ifdef _MSC_VER
39 #undef HAVE_MMXEXT  /* not finished now */
40 #endif
41 #ifdef HAVE_MMXEXT
42 #   include "i386/predict.h"
43 #endif
44
45 static inline int clip_uint8( int a )
46 {
47     if (a&(~255))
48         return (-a)>>31;
49     else
50         return a;
51 }
52
53 /****************************************************************************
54  * 16x16 prediction for intra block DC, H, V, P
55  ****************************************************************************/
56 static void predict_16x16_dc( uint8_t *src, int i_stride )
57 {
58     int dc = 0;
59     int i, j;
60
61     /* calculate DC value */
62     for( i = 0; i < 16; i++ )
63     {
64         dc += src[-1 + i * i_stride];
65         dc += src[i - i_stride];
66     }
67     dc = ( dc + 16 ) >> 5;
68
69     for( i = 0; i < 16; i++ )
70     {
71         for( j = 0; j < 16; j++ )
72         {
73             src[j] = dc;
74         }
75         src += i_stride;
76     }
77 }
78 static void predict_16x16_dc_left( uint8_t *src, int i_stride )
79 {
80     int dc = 0;
81     int i,j;
82
83     for( i = 0; i < 16; i++ )
84     {
85         dc += src[-1 + i * i_stride];
86     }
87     dc = ( dc + 8 ) >> 4;
88
89     for( i = 0; i < 16; i++ )
90     {
91         for( j = 0; j < 16; j++ )
92         {
93             src[j] = dc;
94         }
95         src += i_stride;
96     }
97 }
98 static void predict_16x16_dc_top( uint8_t *src, int i_stride )
99 {
100     int dc = 0;
101     int i,j;
102
103     for( i = 0; i < 16; i++ )
104     {
105         dc += src[i - i_stride];
106     }
107     dc = ( dc + 8 ) >> 4;
108
109     for( i = 0; i < 16; i++ )
110     {
111         for( j = 0; j < 16; j++ )
112         {
113             src[j] = dc;
114         }
115         src += i_stride;
116     }
117 }
118 static void predict_16x16_dc_128( uint8_t *src, int i_stride )
119 {
120     int i,j;
121
122     for( i = 0; i < 16; i++ )
123     {
124         for( j = 0; j < 16; j++ )
125         {
126             src[j] = 128;
127         }
128         src += i_stride;
129     }
130 }
131 static void predict_16x16_h( uint8_t *src, int i_stride )
132 {
133     int i,j;
134
135     for( i = 0; i < 16; i++ )
136     {
137         uint8_t v;
138
139         v = src[-1];
140         for( j = 0; j < 16; j++ )
141         {
142             src[j] = v;
143         }
144         src += i_stride;
145
146     }
147 }
148 static void predict_16x16_v( uint8_t *src, int i_stride )
149 {
150     int i,j;
151
152     for( i = 0; i < 16; i++ )
153     {
154         for( j = 0; j < 16; j++ )
155         {
156             src[i * i_stride +j] = src[j - i_stride];
157         }
158     }
159 }
160 static void predict_16x16_p( uint8_t *src, int i_stride )
161 {
162     int x, y, i;
163     int a, b, c;
164     int H = 0;
165     int V = 0;
166     int i00;
167
168     /* calcule H and V */
169     for( i = 0; i <= 7; i++ )
170     {
171         H += ( i + 1 ) * ( src[ 8 + i - i_stride ] - src[6 -i -i_stride] );
172         V += ( i + 1 ) * ( src[-1 + (8+i)*i_stride] - src[-1 + (6-i)*i_stride] );
173     }
174
175     a = 16 * ( src[-1 + 15*i_stride] + src[15 - i_stride] );
176     b = ( 5 * H + 32 ) >> 6;
177     c = ( 5 * V + 32 ) >> 6;
178
179     i00 = a - b * 7 - c * 7 + 16;
180
181     for( y = 0; y < 16; y++ )
182     {
183         for( x = 0; x < 16; x++ )
184         {
185             int pix;
186
187             pix = (i00+b*x)>>5;
188
189             src[x] = clip_uint8( pix );
190         }
191         src += i_stride;
192         i00 += c;
193     }
194 }
195
196
197 /****************************************************************************
198  * 8x8 prediction for intra chroma block DC, H, V, P
199  ****************************************************************************/
200 static void predict_8x8c_dc_128( uint8_t *src, int i_stride )
201 {
202     int x,y;
203
204     for( y = 0; y < 8; y++ )
205     {
206         for( x = 0; x < 8; x++ )
207         {
208             src[x] = 128;
209         }
210         src += i_stride;
211     }
212 }
213 static void predict_8x8c_dc_left( uint8_t *src, int i_stride )
214 {
215     int x,y;
216     int dc0 = 0, dc1 = 0;
217
218     for( y = 0; y < 4; y++ )
219     {
220         dc0 += src[y * i_stride     - 1];
221         dc1 += src[(y+4) * i_stride - 1];
222     }
223     dc0 = ( dc0 + 2 ) >> 2;
224     dc1 = ( dc1 + 2 ) >> 2;
225
226     for( y = 0; y < 4; y++ )
227     {
228         for( x = 0; x < 8; x++ )
229         {
230             src[           x] = dc0;
231             src[4*i_stride+x] = dc1;
232         }
233         src += i_stride;
234     }
235 }
236 static void predict_8x8c_dc_top( uint8_t *src, int i_stride )
237 {
238     int x,y;
239     int dc0 = 0, dc1 = 0;
240
241     for( x = 0; x < 4; x++ )
242     {
243         dc0 += src[x     - i_stride];
244         dc1 += src[x + 4 - i_stride];
245     }
246     dc0 = ( dc0 + 2 ) >> 2;
247     dc1 = ( dc1 + 2 ) >> 2;
248
249     for( y = 0; y < 8; y++ )
250     {
251         for( x = 0; x < 4; x++ )
252         {
253             src[x    ] = dc0;
254             src[x + 4] = dc1;
255         }
256         src += i_stride;
257     }
258 }
259 static void predict_8x8c_dc( uint8_t *src, int i_stride )
260 {
261     int x,y;
262     int s0 = 0, s1 = 0, s2 = 0, s3 = 0;
263     int dc0, dc1, dc2, dc3;
264     int i;
265
266     /* First do :
267           s0 s1
268        s2
269        s3
270     */
271     for( i = 0; i < 4; i++ )
272     {
273         s0 += src[i - i_stride];
274         s1 += src[i + 4 - i_stride];
275         s2 += src[-1 + i * i_stride];
276         s3 += src[-1 + (i+4)*i_stride];
277     }
278     /* now calculate
279        dc0 dc1
280        dc2 dc3
281      */
282     dc0 = ( s0 + s2 + 4 ) >> 3;
283     dc1 = ( s1 + 2 ) >> 2;
284     dc2 = ( s3 + 2 ) >> 2;
285     dc3 = ( s1 + s3 + 4 ) >> 3;
286
287     for( y = 0; y < 4; y++ )
288     {
289         for( x = 0; x < 4; x++ )
290         {
291             src[             x    ] = dc0;
292             src[             x + 4] = dc1;
293             src[4*i_stride + x    ] = dc2;
294             src[4*i_stride + x + 4] = dc3;
295         }
296         src += i_stride;
297     }
298 }
299
300 static void predict_8x8c_h( uint8_t *src, int i_stride )
301 {
302     int i,j;
303
304     for( i = 0; i < 8; i++ )
305     {
306         uint8_t v;
307
308         v = src[-1];
309
310         for( j = 0; j < 8; j++ )
311         {
312             src[j] = v;
313         }
314         src += i_stride;
315     }
316 }
317 static void predict_8x8c_v( uint8_t *src, int i_stride )
318 {
319     int i,j;
320
321     for( i = 0; i < 8; i++ )
322     {
323         for( j = 0; j < 8; j++ )
324         {
325             src[i * i_stride +j] = src[j - i_stride];
326         }
327     }
328 }
329
330 static void predict_8x8c_p( uint8_t *src, int i_stride )
331 {
332     int i;
333     int x,y;
334     int a, b, c;
335     int H = 0;
336     int V = 0;
337     int i00;
338
339     for( i = 0; i < 4; i++ )
340     {
341         H += ( i + 1 ) * ( src[4+i - i_stride] - src[2 - i -i_stride] );
342         V += ( i + 1 ) * ( src[-1 +(i+4)*i_stride] - src[-1+(2-i)*i_stride] );
343     }
344
345     a = 16 * ( src[-1+7*i_stride] + src[7 - i_stride] );
346     b = ( 17 * H + 16 ) >> 5;
347     c = ( 17 * V + 16 ) >> 5;
348     i00 = a -3*b -3*c + 16;
349
350     for( y = 0; y < 8; y++ )
351     {
352         for( x = 0; x < 8; x++ )
353         {
354             int pix;
355
356             pix = (i00 +b*x) >> 5;
357             src[x] = clip_uint8( pix );
358         }
359         src += i_stride;
360         i00 += c;
361     }
362 }
363
364 /****************************************************************************
365  * 4x4 prediction for intra luma block
366  ****************************************************************************/
367 static void predict_4x4_dc_128( uint8_t *src, int i_stride )
368 {
369     int x,y;
370     for( y = 0; y < 4; y++ )
371     {
372         for( x = 0; x < 4; x++ )
373         {
374             src[x] = 128;
375         }
376         src += i_stride;
377     }
378 }
379 static void predict_4x4_dc_left( uint8_t *src, int i_stride )
380 {
381     int x,y;
382     int dc = ( src[-1+0*i_stride] + src[-1+i_stride]+
383                src[-1+2*i_stride] + src[-1+3*i_stride] + 2 ) >> 2;
384
385     for( y = 0; y < 4; y++ )
386     {
387         for( x = 0; x < 4; x++ )
388         {
389             src[x] = dc;
390         }
391         src += i_stride;
392     }
393 }
394 static void predict_4x4_dc_top( uint8_t *src, int i_stride )
395 {
396     int x,y;
397     int dc = ( src[0 - i_stride] + src[1 - i_stride] +
398                src[2 - i_stride] + src[3 - i_stride] + 2 ) >> 2;
399
400     for( y = 0; y < 4; y++ )
401     {
402         for( x = 0; x < 4; x++ )
403         {
404             src[x] = dc;
405         }
406         src += i_stride;
407     }
408 }
409 static void predict_4x4_dc( uint8_t *src, int i_stride )
410 {
411     int x,y;
412     int dc = ( src[-1+0*i_stride] + src[-1+i_stride]+
413                src[-1+2*i_stride] + src[-1+3*i_stride] +
414                src[0 - i_stride]  + src[1 - i_stride] +
415                src[2 - i_stride]  + src[3 - i_stride] + 4 ) >> 3;
416
417     for( y = 0; y < 4; y++ )
418     {
419         for( x = 0; x < 4; x++ )
420         {
421             src[x] = dc;
422         }
423         src += i_stride;
424     }
425 }
426 static void predict_4x4_h( uint8_t *src, int i_stride )
427 {
428     int i,j;
429
430     for( i = 0; i < 4; i++ )
431     {
432         uint8_t v;
433
434         v = src[-1];
435
436         for( j = 0; j < 4; j++ )
437         {
438             src[j] = v;
439         }
440         src += i_stride;
441     }
442 }
443 static void predict_4x4_v( uint8_t *src, int i_stride )
444 {
445     int i,j;
446
447     for( i = 0; i < 4; i++ )
448     {
449         for( j = 0; j < 4; j++ )
450         {
451             src[i * i_stride +j] = src[j - i_stride];
452         }
453     }
454 }
455
456 #define PREDICT_4x4_LOAD_LEFT \
457     const int l0 = src[-1+0*i_stride];   \
458     const int l1 = src[-1+1*i_stride];   \
459     const int l2 = src[-1+2*i_stride];   \
460     const int l3 = src[-1+3*i_stride];
461
462 #define PREDICT_4x4_LOAD_TOP \
463     const int t0 = src[0-1*i_stride];   \
464     const int t1 = src[1-1*i_stride];   \
465     const int t2 = src[2-1*i_stride];   \
466     const int t3 = src[3-1*i_stride];
467
468 #define PREDICT_4x4_LOAD_TOP_RIGHT \
469     const int t4 = src[4-1*i_stride];   \
470     const int t5 = src[5-1*i_stride];   \
471     const int t6 = src[6-1*i_stride];   \
472     const int t7 = src[7-1*i_stride];
473
474
475 static void predict_4x4_ddl( uint8_t *src, int i_stride )
476 {
477     PREDICT_4x4_LOAD_TOP
478     PREDICT_4x4_LOAD_TOP_RIGHT
479
480     src[0*i_stride+0] = ( t0 + 2*t1+ t2 + 2 ) >> 2;
481
482     src[0*i_stride+1] =
483     src[1*i_stride+0] = ( t1 + 2*t2+ t3 + 2 ) >> 2;
484
485     src[0*i_stride+2] =
486     src[1*i_stride+1] =
487     src[2*i_stride+0] = ( t2 + 2*t3+ t4 + 2 ) >> 2;
488
489     src[0*i_stride+3] =
490     src[1*i_stride+2] =
491     src[2*i_stride+1] =
492     src[3*i_stride+0] = ( t3 + 2*t4+ t5 + 2 ) >> 2;
493
494     src[1*i_stride+3] =
495     src[2*i_stride+2] =
496     src[3*i_stride+1] = ( t4 + 2*t5+ t6 + 2 ) >> 2;
497
498     src[2*i_stride+3] =
499     src[3*i_stride+2] = ( t5 + 2*t6+ t7 + 2 ) >> 2;
500
501     src[3*i_stride+3] = ( t6 + 3 * t7 + 2 ) >> 2;
502 }
503 static void predict_4x4_ddr( uint8_t *src, int i_stride )
504 {
505     const int lt = src[-1-i_stride];
506     PREDICT_4x4_LOAD_LEFT
507     PREDICT_4x4_LOAD_TOP
508
509     src[0*i_stride+0] =
510     src[1*i_stride+1] =
511     src[2*i_stride+2] =
512     src[3*i_stride+3] = ( t0 + 2*lt +l0 + 2 ) >> 2;
513
514     src[0*i_stride+1] =
515     src[1*i_stride+2] =
516     src[2*i_stride+3] = ( lt + 2 * t0 + t1 + 2 ) >> 2;
517
518     src[0*i_stride+2] =
519     src[1*i_stride+3] = ( t0 + 2 * t1 + t2 + 2 ) >> 2;
520
521     src[0*i_stride+3] = ( t1 + 2 * t2 + t3 + 2 ) >> 2;
522
523     src[1*i_stride+0] =
524     src[2*i_stride+1] =
525     src[3*i_stride+2] = ( lt + 2 * l0 + l1 + 2 ) >> 2;
526
527     src[2*i_stride+0] =
528     src[3*i_stride+1] = ( l0 + 2 * l1 + l2 + 2 ) >> 2;
529
530     src[3*i_stride+0] = ( l1 + 2 * l2 + l3 + 2 ) >> 2;
531 }
532
533 static void predict_4x4_vr( uint8_t *src, int i_stride )
534 {
535     const int lt = src[-1-i_stride];
536     PREDICT_4x4_LOAD_LEFT
537     PREDICT_4x4_LOAD_TOP
538     /* produce warning as l3 is unused */
539
540     src[0*i_stride+0]=
541     src[2*i_stride+1]= ( lt + t0 + 1 ) >> 1;
542
543     src[0*i_stride+1]=
544     src[2*i_stride+2]= ( t0 + t1 + 1 ) >> 1;
545
546     src[0*i_stride+2]=
547     src[2*i_stride+3]= ( t1 + t2 + 1 ) >> 1;
548
549     src[0*i_stride+3]= ( t2 + t3 + 1 ) >> 1;
550
551     src[1*i_stride+0]=
552     src[3*i_stride+1]= ( l0 + 2 * lt + t0 + 2 ) >> 2;
553
554     src[1*i_stride+1]=
555     src[3*i_stride+2]= ( lt + 2 * t0 + t1 + 2 ) >> 2;
556
557     src[1*i_stride+2]=
558     src[3*i_stride+3]= ( t0 + 2 * t1 + t2 + 2) >> 2;
559
560     src[1*i_stride+3]= ( t1 + 2 * t2 + t3 + 2 ) >> 2;
561     src[2*i_stride+0]= ( lt + 2 * l0 + l1 + 2 ) >> 2;
562     src[3*i_stride+0]= ( l0 + 2 * l1 + l2 + 2 ) >> 2;
563 }
564
565 static void predict_4x4_hd( uint8_t *src, int i_stride )
566 {
567     const int lt= src[-1-1*i_stride];
568     PREDICT_4x4_LOAD_LEFT
569     PREDICT_4x4_LOAD_TOP
570     /* produce warning as t3 is unused */
571
572     src[0*i_stride+0]=
573     src[1*i_stride+2]= ( lt + l0 + 1 ) >> 1;
574     src[0*i_stride+1]=
575     src[1*i_stride+3]= ( l0 + 2 * lt + t0 + 2 ) >> 2;
576     src[0*i_stride+2]= ( lt + 2 * t0 + t1 + 2 ) >> 2;
577     src[0*i_stride+3]= ( t0 + 2 * t1 + t2 + 2 ) >> 2;
578     src[1*i_stride+0]=
579     src[2*i_stride+2]= ( l0 + l1 + 1 ) >> 1;
580     src[1*i_stride+1]=
581     src[2*i_stride+3]= ( lt + 2 * l0 + l1 + 2 ) >> 2;
582     src[2*i_stride+0]=
583     src[3*i_stride+2]= ( l1 + l2+ 1 ) >> 1;
584     src[2*i_stride+1]=
585     src[3*i_stride+3]= ( l0 + 2 * l1 + l2 + 2 ) >> 2;
586     src[3*i_stride+0]= ( l2 + l3 + 1 ) >> 1;
587     src[3*i_stride+1]= ( l1 + 2 * l2 + l3 + 2 ) >> 2;
588 }
589
590 static void predict_4x4_vl( uint8_t *src, int i_stride )
591 {
592     PREDICT_4x4_LOAD_TOP
593     PREDICT_4x4_LOAD_TOP_RIGHT
594     /* produce warning as t7 is unused */
595
596     src[0*i_stride+0]= ( t0 + t1 + 1 ) >> 1;
597     src[0*i_stride+1]=
598     src[2*i_stride+0]= ( t1 + t2 + 1 ) >> 1;
599     src[0*i_stride+2]=
600     src[2*i_stride+1]= ( t2 + t3 + 1 ) >> 1;
601     src[0*i_stride+3]=
602     src[2*i_stride+2]= ( t3 + t4+ 1 ) >> 1;
603     src[2*i_stride+3]= ( t4 + t5+ 1 ) >> 1;
604     src[1*i_stride+0]= ( t0 + 2 * t1 + t2 + 2 ) >> 2;
605     src[1*i_stride+1]=
606     src[3*i_stride+0]= ( t1 + 2 * t2 + t3 + 2 ) >> 2;
607     src[1*i_stride+2]=
608     src[3*i_stride+1]= ( t2 + 2 * t3 + t4 + 2 ) >> 2;
609     src[1*i_stride+3]=
610     src[3*i_stride+2]= ( t3 + 2 * t4 + t5 + 2 ) >> 2;
611     src[3*i_stride+3]= ( t4 + 2 * t5 + t6 + 2 ) >> 2;
612 }
613
614 static void predict_4x4_hu( uint8_t *src, int i_stride )
615 {
616     PREDICT_4x4_LOAD_LEFT
617
618     src[0*i_stride+0]= ( l0 + l1 + 1 ) >> 1;
619     src[0*i_stride+1]= ( l0 + 2 * l1 + l2 + 2 ) >> 2;
620
621     src[0*i_stride+2]=
622     src[1*i_stride+0]= ( l1 + l2 + 1 ) >> 1;
623
624     src[0*i_stride+3]=
625     src[1*i_stride+1]= ( l1 + 2*l2 + l3 + 2 ) >> 2;
626
627     src[1*i_stride+2]=
628     src[2*i_stride+0]= ( l2 + l3 + 1 ) >> 1;
629
630     src[1*i_stride+3]=
631     src[2*i_stride+1]= ( l2 + 2 * l3 + l3 + 2 ) >> 2;
632
633     src[2*i_stride+3]=
634     src[3*i_stride+1]=
635     src[3*i_stride+0]=
636     src[2*i_stride+2]=
637     src[3*i_stride+2]=
638     src[3*i_stride+3]= l3;
639 }
640
641 /****************************************************************************
642  * 8x8 prediction for intra luma block
643  ****************************************************************************/
644
645 #define SRC(x,y) src[(x)+(y)*i_stride]
646 #define PL(y) \
647     const int l##y = (SRC(-1,y-1) + 2*SRC(-1,y) + SRC(-1,y+1) + 2) >> 2;
648 #define PREDICT_8x8_LOAD_LEFT \
649     const int l0 = ((i_neighbor&MB_TOPLEFT ? SRC(-1,-1) : SRC(-1,0)) \
650                      + 2*SRC(-1,0) + SRC(-1,1) + 2) >> 2; \
651     PL(1) PL(2) PL(3) PL(4) PL(5) PL(6) \
652     const int l7 = (SRC(-1,6) + 3*SRC(-1,7) + 2) >> 2;
653
654 #define PT(x) \
655     const int t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2;
656 #define PREDICT_8x8_LOAD_TOP \
657     const int t0 = ((i_neighbor&MB_TOPLEFT ? SRC(-1,-1) : SRC(0,-1)) \
658                      + 2*SRC(0,-1) + SRC(1,-1) + 2) >> 2; \
659     PT(1) PT(2) PT(3) PT(4) PT(5) PT(6) \
660     const int t7 = ((i_neighbor&MB_TOPRIGHT ? SRC(8,-1) : SRC(7,-1)) \
661                      + 2*SRC(7,-1) + SRC(6,-1) + 2) >> 2; \
662
663 #define PTR(x) \
664     t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2;
665 #define PREDICT_8x8_LOAD_TOPRIGHT \
666     int t8, t9, t10, t11, t12, t13, t14, t15; \
667     if(i_neighbor&MB_TOPRIGHT) { \
668         PTR(8) PTR(9) PTR(10) PTR(11) PTR(12) PTR(13) PTR(14) \
669         t15 = (SRC(14,-1) + 3*SRC(15,-1) + 2) >> 2; \
670     } else t8=t9=t10=t11=t12=t13=t14=t15= SRC(7,-1);
671
672 #define PREDICT_8x8_LOAD_TOPLEFT \
673     const int lt = (SRC(-1,0) + 2*SRC(-1,-1) + SRC(0,-1) + 2) >> 2;
674
675 #define PREDICT_8x8_DC(v) \
676     int y; \
677     for( y = 0; y < 8; y++ ) { \
678         ((uint32_t*)src)[0] = \
679         ((uint32_t*)src)[1] = v; \
680         src += i_stride; \
681     }
682
683 static void predict_8x8_dc_128( uint8_t *src, int i_stride, int i_neighbor )
684 {
685     PREDICT_8x8_DC(0x80808080);
686 }
687 static void predict_8x8_dc_left( uint8_t *src, int i_stride, int i_neighbor )
688 {
689     PREDICT_8x8_LOAD_LEFT
690     const uint32_t dc = ((l0+l1+l2+l3+l4+l5+l6+l7+4) >> 3) * 0x01010101;
691     PREDICT_8x8_DC(dc);
692 }
693 static void predict_8x8_dc_top( uint8_t *src, int i_stride, int i_neighbor )
694 {
695     PREDICT_8x8_LOAD_TOP
696     const uint32_t dc = ((t0+t1+t2+t3+t4+t5+t6+t7+4) >> 3) * 0x01010101;
697     PREDICT_8x8_DC(dc);
698 }
699 static void predict_8x8_dc( uint8_t *src, int i_stride, int i_neighbor )
700 {
701     PREDICT_8x8_LOAD_LEFT
702     PREDICT_8x8_LOAD_TOP
703     const uint32_t dc = ((l0+l1+l2+l3+l4+l5+l6+l7
704                          +t0+t1+t2+t3+t4+t5+t6+t7+8) >> 4) * 0x01010101;
705     PREDICT_8x8_DC(dc);
706 }
707 static void predict_8x8_h( uint8_t *src, int i_stride, int i_neighbor )
708 {
709     PREDICT_8x8_LOAD_LEFT
710 #define ROW(y) ((uint32_t*)(src+y*i_stride))[0] =\
711                ((uint32_t*)(src+y*i_stride))[1] = 0x01010101U * l##y
712     ROW(0); ROW(1); ROW(2); ROW(3); ROW(4); ROW(5); ROW(6); ROW(7);
713 #undef ROW
714 }
715 static void predict_8x8_v( uint8_t *src, int i_stride, int i_neighbor )
716 {
717     int y;
718     PREDICT_8x8_LOAD_TOP;
719     src[0] = t0;
720     src[1] = t1;
721     src[2] = t2;
722     src[3] = t3;
723     src[4] = t4;
724     src[5] = t5;
725     src[6] = t6;
726     src[7] = t7;
727     for( y = 1; y < 8; y++ )
728         *(uint64_t*)(src+y*i_stride) = *(uint64_t*)src;
729 }
730 static void predict_8x8_ddl( uint8_t *src, int i_stride, int i_neighbor )
731 {
732     PREDICT_8x8_LOAD_TOP
733     PREDICT_8x8_LOAD_TOPRIGHT
734     SRC(0,0)= (t0 + 2*t1 + t2 + 2) >> 2;
735     SRC(0,1)=SRC(1,0)= (t1 + 2*t2 + t3 + 2) >> 2;
736     SRC(0,2)=SRC(1,1)=SRC(2,0)= (t2 + 2*t3 + t4 + 2) >> 2;
737     SRC(0,3)=SRC(1,2)=SRC(2,1)=SRC(3,0)= (t3 + 2*t4 + t5 + 2) >> 2;
738     SRC(0,4)=SRC(1,3)=SRC(2,2)=SRC(3,1)=SRC(4,0)= (t4 + 2*t5 + t6 + 2) >> 2;
739     SRC(0,5)=SRC(1,4)=SRC(2,3)=SRC(3,2)=SRC(4,1)=SRC(5,0)= (t5 + 2*t6 + t7 + 2) >> 2;
740     SRC(0,6)=SRC(1,5)=SRC(2,4)=SRC(3,3)=SRC(4,2)=SRC(5,1)=SRC(6,0)= (t6 + 2*t7 + t8 + 2) >> 2;
741     SRC(0,7)=SRC(1,6)=SRC(2,5)=SRC(3,4)=SRC(4,3)=SRC(5,2)=SRC(6,1)=SRC(7,0)= (t7 + 2*t8 + t9 + 2) >> 2;
742     SRC(1,7)=SRC(2,6)=SRC(3,5)=SRC(4,4)=SRC(5,3)=SRC(6,2)=SRC(7,1)= (t8 + 2*t9 + t10 + 2) >> 2;
743     SRC(2,7)=SRC(3,6)=SRC(4,5)=SRC(5,4)=SRC(6,3)=SRC(7,2)= (t9 + 2*t10 + t11 + 2) >> 2;
744     SRC(3,7)=SRC(4,6)=SRC(5,5)=SRC(6,4)=SRC(7,3)= (t10 + 2*t11 + t12 + 2) >> 2;
745     SRC(4,7)=SRC(5,6)=SRC(6,5)=SRC(7,4)= (t11 + 2*t12 + t13 + 2) >> 2;
746     SRC(5,7)=SRC(6,6)=SRC(7,5)= (t12 + 2*t13 + t14 + 2) >> 2;
747     SRC(6,7)=SRC(7,6)= (t13 + 2*t14 + t15 + 2) >> 2;
748     SRC(7,7)= (t14 + 3*t15 + 2) >> 2;
749 }
750 static void predict_8x8_ddr( uint8_t *src, int i_stride, int i_neighbor )
751 {
752     PREDICT_8x8_LOAD_TOP
753     PREDICT_8x8_LOAD_LEFT
754     PREDICT_8x8_LOAD_TOPLEFT
755     SRC(0,7)= (l7 + 2*l6 + l5 + 2) >> 2;
756     SRC(0,6)=SRC(1,7)= (l6 + 2*l5 + l4 + 2) >> 2;
757     SRC(0,5)=SRC(1,6)=SRC(2,7)= (l5 + 2*l4 + l3 + 2) >> 2;
758     SRC(0,4)=SRC(1,5)=SRC(2,6)=SRC(3,7)= (l4 + 2*l3 + l2 + 2) >> 2;
759     SRC(0,3)=SRC(1,4)=SRC(2,5)=SRC(3,6)=SRC(4,7)= (l3 + 2*l2 + l1 + 2) >> 2;
760     SRC(0,2)=SRC(1,3)=SRC(2,4)=SRC(3,5)=SRC(4,6)=SRC(5,7)= (l2 + 2*l1 + l0 + 2) >> 2;
761     SRC(0,1)=SRC(1,2)=SRC(2,3)=SRC(3,4)=SRC(4,5)=SRC(5,6)=SRC(6,7)= (l1 + 2*l0 + lt + 2) >> 2;
762     SRC(0,0)=SRC(1,1)=SRC(2,2)=SRC(3,3)=SRC(4,4)=SRC(5,5)=SRC(6,6)=SRC(7,7)= (l0 + 2*lt + t0 + 2) >> 2;
763     SRC(1,0)=SRC(2,1)=SRC(3,2)=SRC(4,3)=SRC(5,4)=SRC(6,5)=SRC(7,6)= (lt + 2*t0 + t1 + 2) >> 2;
764     SRC(2,0)=SRC(3,1)=SRC(4,2)=SRC(5,3)=SRC(6,4)=SRC(7,5)= (t0 + 2*t1 + t2 + 2) >> 2;
765     SRC(3,0)=SRC(4,1)=SRC(5,2)=SRC(6,3)=SRC(7,4)= (t1 + 2*t2 + t3 + 2) >> 2;
766     SRC(4,0)=SRC(5,1)=SRC(6,2)=SRC(7,3)= (t2 + 2*t3 + t4 + 2) >> 2;
767     SRC(5,0)=SRC(6,1)=SRC(7,2)= (t3 + 2*t4 + t5 + 2) >> 2;
768     SRC(6,0)=SRC(7,1)= (t4 + 2*t5 + t6 + 2) >> 2;
769     SRC(7,0)= (t5 + 2*t6 + t7 + 2) >> 2;
770   
771 }
772 static void predict_8x8_vr( uint8_t *src, int i_stride, int i_neighbor )
773 {
774     PREDICT_8x8_LOAD_TOP
775     PREDICT_8x8_LOAD_LEFT
776     PREDICT_8x8_LOAD_TOPLEFT
777     /* produce warning as l7 is unused */
778     SRC(0,6)= (l5 + 2*l4 + l3 + 2) >> 2;
779     SRC(0,7)= (l6 + 2*l5 + l4 + 2) >> 2;
780     SRC(0,4)=SRC(1,6)= (l3 + 2*l2 + l1 + 2) >> 2;
781     SRC(0,5)=SRC(1,7)= (l4 + 2*l3 + l2 + 2) >> 2;
782     SRC(0,2)=SRC(1,4)=SRC(2,6)= (l1 + 2*l0 + lt + 2) >> 2;
783     SRC(0,3)=SRC(1,5)=SRC(2,7)= (l2 + 2*l1 + l0 + 2) >> 2;
784     SRC(0,1)=SRC(1,3)=SRC(2,5)=SRC(3,7)= (l0 + 2*lt + t0 + 2) >> 2;
785     SRC(0,0)=SRC(1,2)=SRC(2,4)=SRC(3,6)= (lt + t0 + 1) >> 1;
786     SRC(1,1)=SRC(2,3)=SRC(3,5)=SRC(4,7)= (lt + 2*t0 + t1 + 2) >> 2;
787     SRC(1,0)=SRC(2,2)=SRC(3,4)=SRC(4,6)= (t0 + t1 + 1) >> 1;
788     SRC(2,1)=SRC(3,3)=SRC(4,5)=SRC(5,7)= (t0 + 2*t1 + t2 + 2) >> 2;
789     SRC(2,0)=SRC(3,2)=SRC(4,4)=SRC(5,6)= (t1 + t2 + 1) >> 1;
790     SRC(3,1)=SRC(4,3)=SRC(5,5)=SRC(6,7)= (t1 + 2*t2 + t3 + 2) >> 2;
791     SRC(3,0)=SRC(4,2)=SRC(5,4)=SRC(6,6)= (t2 + t3 + 1) >> 1;
792     SRC(4,1)=SRC(5,3)=SRC(6,5)=SRC(7,7)= (t2 + 2*t3 + t4 + 2) >> 2;
793     SRC(4,0)=SRC(5,2)=SRC(6,4)=SRC(7,6)= (t3 + t4 + 1) >> 1;
794     SRC(5,1)=SRC(6,3)=SRC(7,5)= (t3 + 2*t4 + t5 + 2) >> 2;
795     SRC(5,0)=SRC(6,2)=SRC(7,4)= (t4 + t5 + 1) >> 1;
796     SRC(6,1)=SRC(7,3)= (t4 + 2*t5 + t6 + 2) >> 2;
797     SRC(6,0)=SRC(7,2)= (t5 + t6 + 1) >> 1;
798     SRC(7,1)= (t5 + 2*t6 + t7 + 2) >> 2;
799     SRC(7,0)= (t6 + t7 + 1) >> 1;
800 }
801 static void predict_8x8_hd( uint8_t *src, int i_stride, int i_neighbor )
802 {
803     PREDICT_8x8_LOAD_TOP
804     PREDICT_8x8_LOAD_LEFT
805     PREDICT_8x8_LOAD_TOPLEFT
806     /* produce warning as t7 is unused */
807     SRC(0,7)= (l6 + l7 + 1) >> 1;
808     SRC(1,7)= (l5 + 2*l6 + l7 + 2) >> 2;
809     SRC(0,6)=SRC(2,7)= (l5 + l6 + 1) >> 1;
810     SRC(1,6)=SRC(3,7)= (l4 + 2*l5 + l6 + 2) >> 2;
811     SRC(0,5)=SRC(2,6)=SRC(4,7)= (l4 + l5 + 1) >> 1;
812     SRC(1,5)=SRC(3,6)=SRC(5,7)= (l3 + 2*l4 + l5 + 2) >> 2;
813     SRC(0,4)=SRC(2,5)=SRC(4,6)=SRC(6,7)= (l3 + l4 + 1) >> 1;
814     SRC(1,4)=SRC(3,5)=SRC(5,6)=SRC(7,7)= (l2 + 2*l3 + l4 + 2) >> 2;
815     SRC(0,3)=SRC(2,4)=SRC(4,5)=SRC(6,6)= (l2 + l3 + 1) >> 1;
816     SRC(1,3)=SRC(3,4)=SRC(5,5)=SRC(7,6)= (l1 + 2*l2 + l3 + 2) >> 2;
817     SRC(0,2)=SRC(2,3)=SRC(4,4)=SRC(6,5)= (l1 + l2 + 1) >> 1;
818     SRC(1,2)=SRC(3,3)=SRC(5,4)=SRC(7,5)= (l0 + 2*l1 + l2 + 2) >> 2;
819     SRC(0,1)=SRC(2,2)=SRC(4,3)=SRC(6,4)= (l0 + l1 + 1) >> 1;
820     SRC(1,1)=SRC(3,2)=SRC(5,3)=SRC(7,4)= (lt + 2*l0 + l1 + 2) >> 2;
821     SRC(0,0)=SRC(2,1)=SRC(4,2)=SRC(6,3)= (lt + l0 + 1) >> 1;
822     SRC(1,0)=SRC(3,1)=SRC(5,2)=SRC(7,3)= (l0 + 2*lt + t0 + 2) >> 2;
823     SRC(2,0)=SRC(4,1)=SRC(6,2)= (t1 + 2*t0 + lt + 2) >> 2;
824     SRC(3,0)=SRC(5,1)=SRC(7,2)= (t2 + 2*t1 + t0 + 2) >> 2;
825     SRC(4,0)=SRC(6,1)= (t3 + 2*t2 + t1 + 2) >> 2;
826     SRC(5,0)=SRC(7,1)= (t4 + 2*t3 + t2 + 2) >> 2;
827     SRC(6,0)= (t5 + 2*t4 + t3 + 2) >> 2;
828     SRC(7,0)= (t6 + 2*t5 + t4 + 2) >> 2;
829 }
830 static void predict_8x8_vl( uint8_t *src, int i_stride, int i_neighbor )
831 {
832     PREDICT_8x8_LOAD_TOP
833     PREDICT_8x8_LOAD_TOPRIGHT
834     SRC(0,0)= (t0 + t1 + 1) >> 1;
835     SRC(0,1)= (t0 + 2*t1 + t2 + 2) >> 2;
836     SRC(0,2)=SRC(1,0)= (t1 + t2 + 1) >> 1;
837     SRC(0,3)=SRC(1,1)= (t1 + 2*t2 + t3 + 2) >> 2;
838     SRC(0,4)=SRC(1,2)=SRC(2,0)= (t2 + t3 + 1) >> 1;
839     SRC(0,5)=SRC(1,3)=SRC(2,1)= (t2 + 2*t3 + t4 + 2) >> 2;
840     SRC(0,6)=SRC(1,4)=SRC(2,2)=SRC(3,0)= (t3 + t4 + 1) >> 1;
841     SRC(0,7)=SRC(1,5)=SRC(2,3)=SRC(3,1)= (t3 + 2*t4 + t5 + 2) >> 2;
842     SRC(1,6)=SRC(2,4)=SRC(3,2)=SRC(4,0)= (t4 + t5 + 1) >> 1;
843     SRC(1,7)=SRC(2,5)=SRC(3,3)=SRC(4,1)= (t4 + 2*t5 + t6 + 2) >> 2;
844     SRC(2,6)=SRC(3,4)=SRC(4,2)=SRC(5,0)= (t5 + t6 + 1) >> 1;
845     SRC(2,7)=SRC(3,5)=SRC(4,3)=SRC(5,1)= (t5 + 2*t6 + t7 + 2) >> 2;
846     SRC(3,6)=SRC(4,4)=SRC(5,2)=SRC(6,0)= (t6 + t7 + 1) >> 1;
847     SRC(3,7)=SRC(4,5)=SRC(5,3)=SRC(6,1)= (t6 + 2*t7 + t8 + 2) >> 2;
848     SRC(4,6)=SRC(5,4)=SRC(6,2)=SRC(7,0)= (t7 + t8 + 1) >> 1;
849     SRC(4,7)=SRC(5,5)=SRC(6,3)=SRC(7,1)= (t7 + 2*t8 + t9 + 2) >> 2;
850     SRC(5,6)=SRC(6,4)=SRC(7,2)= (t8 + t9 + 1) >> 1;
851     SRC(5,7)=SRC(6,5)=SRC(7,3)= (t8 + 2*t9 + t10 + 2) >> 2;
852     SRC(6,6)=SRC(7,4)= (t9 + t10 + 1) >> 1;
853     SRC(6,7)=SRC(7,5)= (t9 + 2*t10 + t11 + 2) >> 2;
854     SRC(7,6)= (t10 + t11 + 1) >> 1;
855     SRC(7,7)= (t10 + 2*t11 + t12 + 2) >> 2;
856 }
857 static void predict_8x8_hu( uint8_t *src, int i_stride, int i_neighbor )
858 {
859     PREDICT_8x8_LOAD_LEFT
860     SRC(0,0)= (l0 + l1 + 1) >> 1;
861     SRC(1,0)= (l0 + 2*l1 + l2 + 2) >> 2;
862     SRC(0,1)=SRC(2,0)= (l1 + l2 + 1) >> 1;
863     SRC(1,1)=SRC(3,0)= (l1 + 2*l2 + l3 + 2) >> 2;
864     SRC(0,2)=SRC(2,1)=SRC(4,0)= (l2 + l3 + 1) >> 1;
865     SRC(1,2)=SRC(3,1)=SRC(5,0)= (l2 + 2*l3 + l4 + 2) >> 2;
866     SRC(0,3)=SRC(2,2)=SRC(4,1)=SRC(6,0)= (l3 + l4 + 1) >> 1;
867     SRC(1,3)=SRC(3,2)=SRC(5,1)=SRC(7,0)= (l3 + 2*l4 + l5 + 2) >> 2;
868     SRC(0,4)=SRC(2,3)=SRC(4,2)=SRC(6,1)= (l4 + l5 + 1) >> 1;
869     SRC(1,4)=SRC(3,3)=SRC(5,2)=SRC(7,1)= (l4 + 2*l5 + l6 + 2) >> 2;
870     SRC(0,5)=SRC(2,4)=SRC(4,3)=SRC(6,2)= (l5 + l6 + 1) >> 1;
871     SRC(1,5)=SRC(3,4)=SRC(5,3)=SRC(7,2)= (l5 + 2*l6 + l7 + 2) >> 2;
872     SRC(0,6)=SRC(2,5)=SRC(4,4)=SRC(6,3)= (l6 + l7 + 1) >> 1;
873     SRC(1,6)=SRC(3,5)=SRC(5,4)=SRC(7,3)= (l6 + 3*l7 + 2) >> 2;
874     SRC(0,7)=SRC(1,7)=SRC(2,6)=SRC(2,7)=SRC(3,6)=
875     SRC(3,7)=SRC(4,5)=SRC(4,6)=SRC(4,7)=SRC(5,5)=
876     SRC(5,6)=SRC(5,7)=SRC(6,4)=SRC(6,5)=SRC(6,6)=
877     SRC(6,7)=SRC(7,4)=SRC(7,5)=SRC(7,6)=SRC(7,7)= l7;
878 }
879
880 /****************************************************************************
881  * Exported functions:
882  ****************************************************************************/
883 void x264_predict_16x16_init( int cpu, x264_predict_t pf[7] )
884 {
885     pf[I_PRED_16x16_V ]     = predict_16x16_v;
886     pf[I_PRED_16x16_H ]     = predict_16x16_h;
887     pf[I_PRED_16x16_DC]     = predict_16x16_dc;
888     pf[I_PRED_16x16_P ]     = predict_16x16_p;
889     pf[I_PRED_16x16_DC_LEFT]= predict_16x16_dc_left;
890     pf[I_PRED_16x16_DC_TOP ]= predict_16x16_dc_top;
891     pf[I_PRED_16x16_DC_128 ]= predict_16x16_dc_128;
892
893 #ifdef HAVE_MMXEXT
894     if( cpu&X264_CPU_MMXEXT )
895     {
896         x264_predict_16x16_init_mmxext( pf );
897     }
898 #endif
899 }
900
901 void x264_predict_8x8c_init( int cpu, x264_predict_t pf[7] )
902 {
903     pf[I_PRED_CHROMA_V ]     = predict_8x8c_v;
904     pf[I_PRED_CHROMA_H ]     = predict_8x8c_h;
905     pf[I_PRED_CHROMA_DC]     = predict_8x8c_dc;
906     pf[I_PRED_CHROMA_P ]     = predict_8x8c_p;
907     pf[I_PRED_CHROMA_DC_LEFT]= predict_8x8c_dc_left;
908     pf[I_PRED_CHROMA_DC_TOP ]= predict_8x8c_dc_top;
909     pf[I_PRED_CHROMA_DC_128 ]= predict_8x8c_dc_128;
910
911 #ifdef HAVE_MMXEXT
912     if( cpu&X264_CPU_MMXEXT )
913     {
914         x264_predict_8x8c_init_mmxext( pf );
915     }
916 #endif
917 }
918
919 void x264_predict_8x8_init( int cpu, x264_predict8x8_t pf[12] )
920 {
921     pf[I_PRED_8x8_V]      = predict_8x8_v;
922     pf[I_PRED_8x8_H]      = predict_8x8_h;
923     pf[I_PRED_8x8_DC]     = predict_8x8_dc;
924     pf[I_PRED_8x8_DDL]    = predict_8x8_ddl;
925     pf[I_PRED_8x8_DDR]    = predict_8x8_ddr;
926     pf[I_PRED_8x8_VR]     = predict_8x8_vr;
927     pf[I_PRED_8x8_HD]     = predict_8x8_hd;
928     pf[I_PRED_8x8_VL]     = predict_8x8_vl;
929     pf[I_PRED_8x8_HU]     = predict_8x8_hu;
930     pf[I_PRED_8x8_DC_LEFT]= predict_8x8_dc_left;
931     pf[I_PRED_8x8_DC_TOP] = predict_8x8_dc_top;
932     pf[I_PRED_8x8_DC_128] = predict_8x8_dc_128;
933 }
934
935 void x264_predict_4x4_init( int cpu, x264_predict_t pf[12] )
936 {
937     pf[I_PRED_4x4_V]      = predict_4x4_v;
938     pf[I_PRED_4x4_H]      = predict_4x4_h;
939     pf[I_PRED_4x4_DC]     = predict_4x4_dc;
940     pf[I_PRED_4x4_DDL]    = predict_4x4_ddl;
941     pf[I_PRED_4x4_DDR]    = predict_4x4_ddr;
942     pf[I_PRED_4x4_VR]     = predict_4x4_vr;
943     pf[I_PRED_4x4_HD]     = predict_4x4_hd;
944     pf[I_PRED_4x4_VL]     = predict_4x4_vl;
945     pf[I_PRED_4x4_HU]     = predict_4x4_hu;
946     pf[I_PRED_4x4_DC_LEFT]= predict_4x4_dc_left;
947     pf[I_PRED_4x4_DC_TOP] = predict_4x4_dc_top;
948     pf[I_PRED_4x4_DC_128] = predict_4x4_dc_128;
949
950 #ifdef HAVE_MMXEXT
951     if( cpu&X264_CPU_MMXEXT )
952     {
953         x264_predict_4x4_init_mmxext( pf );
954     }
955 #endif
956 }
957