• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 #include "avcdec_lib.h"
19 #include "oscl_mem.h"
20 
21 #define CLIP_COMP  *comp++ = (uint8)(((uint)temp>0xFF)? 0xFF&(~(temp>>31)): temp)
22 #define CLIP_RESULT(x)      if((uint)x > 0xFF){ \
23                  x = 0xFF & (~(x>>31));}
24 
25 
26 /* We should combine the Intra4x4 functions with residual decoding and compensation  */
IntraMBPrediction(AVCCommonObj * video)27 AVCStatus IntraMBPrediction(AVCCommonObj *video)
28 {
29     int component, SubBlock_indx, temp;
30     AVCStatus status;
31     AVCMacroblock *currMB = video->currMB;
32     AVCPictureData *currPic = video->currPic;
33     uint8 *curL, *curCb, *curCr;
34     uint8 *comp;
35     int block_x, block_y, offset;
36     int16 *dataBlock = video->block;
37     uint8 *predCb, *predCr;
38 #ifdef USE_PRED_BLOCK
39     uint8 *pred;
40 #endif
41     int pitch = currPic->pitch;
42     uint32 cbp4x4 = video->cbp4x4;
43 
44     offset = (video->mb_y << 4) * pitch + (video->mb_x << 4);
45     curL = currPic->Sl + offset;
46 
47 #ifdef USE_PRED_BLOCK
48     video->pred_block = video->pred + 84;  /* point to separate prediction memory */
49     pred = video->pred_block;
50     video->pred_pitch = 20;
51 #else
52     video->pred_block = curL;   /* point directly to the frame buffer */
53     video->pred_pitch = pitch;
54 #endif
55 
56     if (currMB->mbMode == AVC_I4)
57     {
58         /* luminance first */
59         block_x = block_y = 0;
60         for (component = 0; component < 4; component++)
61         {
62             block_x = ((component & 1) << 1);
63             block_y = ((component >> 1) << 1);
64             comp = curL;// + (block_x<<2) + (block_y<<2)*currPic->pitch;
65 
66             for (SubBlock_indx = 0; SubBlock_indx < 4; SubBlock_indx++)
67             {
68                 status = Intra_4x4(video, block_x, block_y, comp);
69                 if (status != AVC_SUCCESS)
70                 {
71                     return status;
72                 }
73                 /* transform following the 4x4 prediction, can't be SIMD
74                 with other blocks. */
75 #ifdef USE_PRED_BLOCK
76                 if (cbp4x4&(1 << ((block_y << 2) + block_x)))
77                 {
78                     itrans(dataBlock, pred, pred, 20);
79                 }
80 #else
81                 if (cbp4x4&(1 << ((block_y << 2) + block_x)))
82                 {
83                     itrans(dataBlock, comp, comp, pitch);
84                 }
85 #endif
86                 temp = SubBlock_indx & 1;
87                 if (temp)
88                 {
89                     block_y++;
90                     block_x--;
91                     dataBlock += 60;
92 #ifdef USE_PRED_BLOCK
93                     pred += 76;
94 #else
95                     comp += ((pitch << 2) - 4);
96 #endif
97                 }
98                 else
99                 {
100                     block_x++;
101                     dataBlock += 4;
102 #ifdef USE_PRED_BLOCK
103                     pred += 4;
104 #else
105                     comp += 4;
106 #endif
107                 }
108             }
109             if (component&1)
110             {
111 #ifdef USE_PRED_BLOCK
112                 pred -= 8;
113 #else
114                 curL += (pitch << 3) - 8;
115 #endif
116                 dataBlock -= 8;
117             }
118             else
119             {
120 #ifdef USE_PRED_BLOCK
121                 pred -= 152;
122 #else
123                 curL += 8;
124 #endif
125                 dataBlock -= 120;
126             }
127         }
128         cbp4x4 >>= 16;
129     }
130     else   /* AVC_I16 */
131     {
132 #ifdef MB_BASED_DEBLOCK
133         video->pintra_pred_top = video->intra_pred_top + (video->mb_x << 4);
134         video->pintra_pred_left = video->intra_pred_left + 1;
135         video->intra_pred_topleft = video->intra_pred_left[0];
136         pitch = 1;
137 #else
138         video->pintra_pred_top = curL - pitch;
139         video->pintra_pred_left = curL - 1;
140         if (video->mb_y)
141         {
142             video->intra_pred_topleft = *(curL - pitch - 1);
143         }
144 #endif
145         switch (currMB->i16Mode)
146         {
147             case AVC_I16_Vertical:      /* Intra_16x16_Vertical */
148                 /* check availability of top */
149                 if (video->intraAvailB)
150                 {
151                     Intra_16x16_Vertical(video);
152                 }
153                 else
154                 {
155                     return AVC_FAIL;
156                 }
157                 break;
158             case AVC_I16_Horizontal:        /* Intra_16x16_Horizontal */
159                 /* check availability of left */
160                 if (video->intraAvailA)
161                 {
162                     Intra_16x16_Horizontal(video, pitch);
163                 }
164                 else
165                 {
166                     return AVC_FAIL;
167                 }
168                 break;
169             case AVC_I16_DC:        /* Intra_16x16_DC */
170                 Intra_16x16_DC(video, pitch);
171                 break;
172             case AVC_I16_Plane:     /* Intra_16x16_Plane */
173                 if (video->intraAvailA && video->intraAvailB && video->intraAvailD)
174                 {
175                     Intra_16x16_Plane(video, pitch);
176                 }
177                 else
178                 {
179                     return AVC_FAIL;
180                 }
181                 break;
182             default:
183                 break;
184         }
185 
186         pitch = currPic->pitch;
187 
188         /* transform */
189         /* can go in raster scan order now */
190         /* can be done in SIMD,  */
191         for (block_y = 4; block_y > 0; block_y--)
192         {
193             for (block_x = 4; block_x > 0; block_x--)
194             {
195 #ifdef USE_PRED_BLOCK
196                 if (cbp4x4&1)
197                 {
198                     itrans(dataBlock, pred, pred, 20);
199                 }
200 #else
201                 if (cbp4x4&1)
202                 {
203                     itrans(dataBlock, curL, curL, pitch);
204                 }
205 #endif
206                 cbp4x4 >>= 1;
207                 dataBlock += 4;
208 #ifdef USE_PRED_BLOCK
209                 pred += 4;
210 #else
211                 curL += 4;
212 #endif
213             }
214             dataBlock += 48;
215 #ifdef USE_PRED_BLOCK
216             pred += 64;
217 #else
218             curL += ((pitch << 2) - 16);
219 #endif
220         }
221     }
222 
223     offset = (offset >> 2) + (video->mb_x << 2); //((video->mb_y << 3)* pitch + (video->mb_x << 3));
224     curCb = currPic->Scb + offset;
225     curCr = currPic->Scr + offset;
226 
227 #ifdef MB_BASED_DEBLOCK
228     video->pintra_pred_top_cb = video->intra_pred_top_cb + (video->mb_x << 3);
229     video->pintra_pred_left_cb = video->intra_pred_left_cb + 1;
230     video->intra_pred_topleft_cb = video->intra_pred_left_cb[0];
231     video->pintra_pred_top_cr = video->intra_pred_top_cr + (video->mb_x << 3);
232     video->pintra_pred_left_cr = video->intra_pred_left_cr + 1;
233     video->intra_pred_topleft_cr = video->intra_pred_left_cr[0];
234     pitch  = 1;
235 #else
236     pitch >>= 1;
237     video->pintra_pred_top_cb = curCb - pitch;
238     video->pintra_pred_left_cb = curCb - 1;
239     video->pintra_pred_top_cr = curCr - pitch;
240     video->pintra_pred_left_cr = curCr - 1;
241 
242     if (video->mb_y)
243     {
244         video->intra_pred_topleft_cb = *(curCb - pitch - 1);
245         video->intra_pred_topleft_cr = *(curCr - pitch - 1);
246     }
247 #endif
248 
249 #ifdef USE_PRED_BLOCK
250     predCb = video->pred + 452;
251     predCr = predCb + 144;
252     video->pred_pitch = 12;
253 #else
254     predCb = curCb;
255     predCr = curCr;
256     video->pred_pitch = currPic->pitch >> 1;
257 #endif
258     /* chrominance */
259     switch (currMB->intra_chroma_pred_mode)
260     {
261         case AVC_IC_DC:     /* Intra_Chroma_DC */
262             Intra_Chroma_DC(video, pitch, predCb, predCr);
263             break;
264         case AVC_IC_Horizontal:     /* Intra_Chroma_Horizontal */
265             if (video->intraAvailA)
266             {
267                 /* check availability of left */
268                 Intra_Chroma_Horizontal(video, pitch, predCb, predCr);
269             }
270             else
271             {
272                 return AVC_FAIL;
273             }
274             break;
275         case AVC_IC_Vertical:       /* Intra_Chroma_Vertical */
276             if (video->intraAvailB)
277             {
278                 /* check availability of top */
279                 Intra_Chroma_Vertical(video, predCb, predCr);
280             }
281             else
282             {
283                 return AVC_FAIL;
284             }
285             break;
286         case AVC_IC_Plane:      /* Intra_Chroma_Plane */
287             if (video->intraAvailA && video->intraAvailB && video->intraAvailD)
288             {
289                 /* check availability of top and left */
290                 Intra_Chroma_Plane(video, pitch, predCb, predCr);
291             }
292             else
293             {
294                 return AVC_FAIL;
295             }
296             break;
297         default:
298             break;
299     }
300 
301     /* transform, done in raster scan manner */
302     pitch = currPic->pitch >> 1;
303 
304     for (block_y = 2; block_y > 0; block_y--)
305     {
306         for (block_x = 2; block_x > 0; block_x--)
307         {
308 #ifdef USE_PRED_BLOCK
309             if (cbp4x4&1)
310             {
311                 ictrans(dataBlock, predCb, predCb, 12);
312             }
313 #else
314             if (cbp4x4&1)
315             {
316                 ictrans(dataBlock, curCb, curCb, pitch);
317             }
318 #endif
319             cbp4x4 >>= 1;
320             dataBlock += 4;
321 #ifdef USE_PRED_BLOCK
322             predCb += 4;
323 #else
324             curCb += 4;
325 #endif
326         }
327         for (block_x = 2; block_x > 0; block_x--)
328         {
329 #ifdef USE_PRED_BLOCK
330             if (cbp4x4&1)
331             {
332                 ictrans(dataBlock, predCr, predCr, 12);
333             }
334 #else
335             if (cbp4x4&1)
336             {
337                 ictrans(dataBlock, curCr, curCr, pitch);
338             }
339 #endif
340             cbp4x4 >>= 1;
341             dataBlock += 4;
342 #ifdef USE_PRED_BLOCK
343             predCr += 4;
344 #else
345             curCr += 4;
346 #endif
347         }
348         dataBlock += 48;
349 #ifdef USE_PRED_BLOCK
350         predCb += 40;
351         predCr += 40;
352 #else
353         curCb += ((pitch << 2) - 8);
354         curCr += ((pitch << 2) - 8);
355 #endif
356     }
357 
358 #ifdef MB_BASED_DEBLOCK
359     SaveNeighborForIntraPred(video, offset);
360 #endif
361     return AVC_SUCCESS;
362 }
363 
364 #ifdef MB_BASED_DEBLOCK
SaveNeighborForIntraPred(AVCCommonObj * video,int offset)365 void SaveNeighborForIntraPred(AVCCommonObj *video, int offset)
366 {
367     AVCPictureData *currPic = video->currPic;
368     int pitch;
369     uint8 *pred, *predCb, *predCr;
370     uint8 *tmp_ptr, tmp_byte;
371     uint32 tmp_word;
372     int mb_x = video->mb_x;
373 
374     /* save the value for intra prediction  */
375 #ifdef USE_PRED_BLOCK
376     pitch = 20;
377     pred = video->pred + 384; /* bottom line for Y */
378     predCb = pred + 152;    /* bottom line for Cb */
379     predCr = predCb + 144;  /* bottom line for Cr */
380 #else
381     pitch = currPic->pitch;
382     tmp_word = offset + (pitch << 2) - (pitch >> 1);
383     predCb = currPic->Scb + tmp_word;/* bottom line for Cb */
384     predCr = currPic->Scr + tmp_word;/* bottom line for Cr */
385 
386     offset = (offset << 2) - (mb_x << 4);
387     pred = currPic->Sl + offset + (pitch << 4) - pitch;/* bottom line for Y */
388 
389 #endif
390 
391     video->intra_pred_topleft = video->intra_pred_top[(mb_x<<4)+15];
392     video->intra_pred_topleft_cb = video->intra_pred_top_cb[(mb_x<<3)+7];
393     video->intra_pred_topleft_cr = video->intra_pred_top_cr[(mb_x<<3)+7];
394 
395     /* then copy to video->intra_pred_top, intra_pred_top_cb, intra_pred_top_cr */
396     /*oscl_memcpy(video->intra_pred_top + (mb_x<<4), pred, 16);
397     oscl_memcpy(video->intra_pred_top_cb + (mb_x<<3), predCb, 8);
398     oscl_memcpy(video->intra_pred_top_cr + (mb_x<<3), predCr, 8);*/
399     tmp_ptr = video->intra_pred_top + (mb_x << 4);
400     *((uint32*)tmp_ptr) = *((uint32*)pred);
401     *((uint32*)(tmp_ptr + 4)) = *((uint32*)(pred + 4));
402     *((uint32*)(tmp_ptr + 8)) = *((uint32*)(pred + 8));
403     *((uint32*)(tmp_ptr + 12)) = *((uint32*)(pred + 12));
404     tmp_ptr = video->intra_pred_top_cb + (mb_x << 3);
405     *((uint32*)tmp_ptr) = *((uint32*)predCb);
406     *((uint32*)(tmp_ptr + 4)) = *((uint32*)(predCb + 4));
407     tmp_ptr = video->intra_pred_top_cr + (mb_x << 3);
408     *((uint32*)tmp_ptr) = *((uint32*)predCr);
409     *((uint32*)(tmp_ptr + 4)) = *((uint32*)(predCr + 4));
410 
411 
412     /* now save last column */
413 #ifdef USE_PRED_BLOCK
414     pred = video->pred + 99;    /* last column*/
415 #else
416     pred -= ((pitch << 4) - pitch - 15);    /* last column */
417 #endif
418     tmp_ptr = video->intra_pred_left;
419     tmp_word = video->intra_pred_topleft;
420     tmp_byte = *(pred);
421     tmp_word |= (tmp_byte << 8);
422     tmp_byte = *(pred += pitch);
423     tmp_word |= (tmp_byte << 16);
424     tmp_byte = *(pred += pitch);
425     tmp_word |= (tmp_byte << 24);
426     *((uint32*)tmp_ptr) = tmp_word;
427     tmp_word = *(pred += pitch);
428     tmp_byte = *(pred += pitch);
429     tmp_word |= (tmp_byte << 8);
430     tmp_byte = *(pred += pitch);
431     tmp_word |= (tmp_byte << 16);
432     tmp_byte = *(pred += pitch);
433     tmp_word |= (tmp_byte << 24);
434     *((uint32*)(tmp_ptr += 4)) = tmp_word;
435     tmp_word = *(pred += pitch);
436     tmp_byte = *(pred += pitch);
437     tmp_word |= (tmp_byte << 8);
438     tmp_byte = *(pred += pitch);
439     tmp_word |= (tmp_byte << 16);
440     tmp_byte = *(pred += pitch);
441     tmp_word |= (tmp_byte << 24);
442     *((uint32*)(tmp_ptr += 4)) = tmp_word;
443     tmp_word = *(pred += pitch);
444     tmp_byte = *(pred += pitch);
445     tmp_word |= (tmp_byte << 8);
446     tmp_byte = *(pred += pitch);
447     tmp_word |= (tmp_byte << 16);
448     tmp_byte = *(pred += pitch);
449     tmp_word |= (tmp_byte << 24);
450     *((uint32*)(tmp_ptr += 4)) = tmp_word;
451     *(tmp_ptr += 4) = *(pred += pitch);
452 
453     /* now for Cb */
454 #ifdef USE_PRED_BLOCK
455     predCb = video->pred + 459;
456     pitch = 12;
457 #else
458     pitch >>= 1;
459     predCb -= (7 * pitch - 7);
460 #endif
461     tmp_ptr = video->intra_pred_left_cb;
462     tmp_word = video->intra_pred_topleft_cb;
463     tmp_byte = *(predCb);
464     tmp_word |= (tmp_byte << 8);
465     tmp_byte = *(predCb += pitch);
466     tmp_word |= (tmp_byte << 16);
467     tmp_byte = *(predCb += pitch);
468     tmp_word |= (tmp_byte << 24);
469     *((uint32*)tmp_ptr) = tmp_word;
470     tmp_word = *(predCb += pitch);
471     tmp_byte = *(predCb += pitch);
472     tmp_word |= (tmp_byte << 8);
473     tmp_byte = *(predCb += pitch);
474     tmp_word |= (tmp_byte << 16);
475     tmp_byte = *(predCb += pitch);
476     tmp_word |= (tmp_byte << 24);
477     *((uint32*)(tmp_ptr += 4)) = tmp_word;
478     *(tmp_ptr += 4) = *(predCb += pitch);
479 
480     /* now for Cr */
481 #ifdef USE_PRED_BLOCK
482     predCr = video->pred + 603;
483 #else
484     predCr -= (7 * pitch - 7);
485 #endif
486     tmp_ptr = video->intra_pred_left_cr;
487     tmp_word = video->intra_pred_topleft_cr;
488     tmp_byte = *(predCr);
489     tmp_word |= (tmp_byte << 8);
490     tmp_byte = *(predCr += pitch);
491     tmp_word |= (tmp_byte << 16);
492     tmp_byte = *(predCr += pitch);
493     tmp_word |= (tmp_byte << 24);
494     *((uint32*)tmp_ptr) = tmp_word;
495     tmp_word = *(predCr += pitch);
496     tmp_byte = *(predCr += pitch);
497     tmp_word |= (tmp_byte << 8);
498     tmp_byte = *(predCr += pitch);
499     tmp_word |= (tmp_byte << 16);
500     tmp_byte = *(predCr += pitch);
501     tmp_word |= (tmp_byte << 24);
502     *((uint32*)(tmp_ptr += 4)) = tmp_word;
503     *(tmp_ptr += 4) = *(predCr += pitch);
504 
505     return ;
506 }
507 #endif /* MB_BASED_DEBLOCK */
508 
Intra_4x4(AVCCommonObj * video,int block_x,int block_y,uint8 * comp)509 AVCStatus Intra_4x4(AVCCommonObj *video, int block_x, int block_y, uint8 *comp)
510 {
511     AVCMacroblock *currMB = video->currMB;
512     int block_offset;
513     AVCNeighborAvailability availability;
514     int pitch = video->currPic->pitch;
515 
516 #ifdef USE_PRED_BLOCK
517     block_offset = (block_y * 80) + (block_x << 2);
518 #else
519     block_offset = (block_y << 2) * pitch + (block_x << 2);
520 #endif
521 
522 #ifdef MB_BASED_DEBLOCK
523     /* boundary blocks use video->pred_intra_top, pred_intra_left, pred_intra_topleft */
524     if (!block_x)
525     {
526         video->pintra_pred_left = video->intra_pred_left + 1 + (block_y << 2);
527         pitch = 1;
528     }
529     else
530     {
531         video->pintra_pred_left = video->pred_block + block_offset - 1;
532         pitch = video->pred_pitch;
533     }
534 
535     if (!block_y)
536     {
537         video->pintra_pred_top = video->intra_pred_top + (block_x << 2) + (video->mb_x << 4);
538     }
539     else
540     {
541         video->pintra_pred_top = video->pred_block + block_offset - video->pred_pitch;
542     }
543 
544     if (!block_x)
545     {
546         video->intra_pred_topleft = video->intra_pred_left[block_y<<2];
547     }
548     else if (!block_y)
549     {
550         video->intra_pred_topleft = video->intra_pred_top[(video->mb_x<<4)+(block_x<<2)-1];
551     }
552     else
553     {
554         video->intra_pred_topleft = video->pred_block[block_offset - video->pred_pitch - 1];
555     }
556 
557 #else
558     /* normal case */
559     video->pintra_pred_top = comp - pitch;
560     video->pintra_pred_left = comp - 1;
561     if (video->mb_y || block_y)
562     {
563         video->intra_pred_topleft = *(comp - pitch - 1);
564     }
565 #endif
566 
567     switch (currMB->i4Mode[(block_y << 2) + block_x])
568     {
569         case AVC_I4_Vertical:       /* Intra_4x4_Vertical */
570             if (block_y > 0 || video->intraAvailB)/* to prevent out-of-bound access*/
571             {
572                 Intra_4x4_Vertical(video,  block_offset);
573             }
574             else
575             {
576                 return AVC_FAIL;
577             }
578             break;
579 
580         case AVC_I4_Horizontal:     /* Intra_4x4_Horizontal */
581             if (block_x || video->intraAvailA)  /* to prevent out-of-bound access */
582             {
583                 Intra_4x4_Horizontal(video, pitch, block_offset);
584             }
585             else
586             {
587                 return AVC_FAIL;
588             }
589             break;
590 
591         case AVC_I4_DC:     /* Intra_4x4_DC */
592             availability.left = TRUE;
593             availability.top = TRUE;
594             if (!block_y)
595             { /* check availability up */
596                 availability.top = video->intraAvailB ;
597             }
598             if (!block_x)
599             { /* check availability left */
600                 availability.left = video->intraAvailA ;
601             }
602             Intra_4x4_DC(video, pitch, block_offset, &availability);
603             break;
604 
605         case AVC_I4_Diagonal_Down_Left:     /* Intra_4x4_Diagonal_Down_Left */
606             /* lookup table will be more appropriate for this case  */
607             if (block_y == 0 && !video->intraAvailB)
608             {
609                 return AVC_FAIL;
610             }
611 
612             availability.top_right = BlkTopRight[(block_y<<2) + block_x];
613 
614             if (availability.top_right == 2)
615             {
616                 availability.top_right = video->intraAvailB;
617             }
618             else if (availability.top_right == 3)
619             {
620                 availability.top_right = video->intraAvailC;
621             }
622 
623             Intra_4x4_Down_Left(video, block_offset, &availability);
624             break;
625 
626         case AVC_I4_Diagonal_Down_Right:        /* Intra_4x4_Diagonal_Down_Right */
627             if ((block_y && block_x)  /* to prevent out-of-bound access */
628                     || (block_y && video->intraAvailA)
629                     || (block_x && video->intraAvailB)
630                     || (video->intraAvailA && video->intraAvailD && video->intraAvailB))
631             {
632                 Intra_4x4_Diagonal_Down_Right(video, pitch, block_offset);
633             }
634             else
635             {
636                 return AVC_FAIL;
637             }
638             break;
639 
640         case AVC_I4_Vertical_Right:     /* Intra_4x4_Vertical_Right */
641             if ((block_y && block_x)  /* to prevent out-of-bound access */
642                     || (block_y && video->intraAvailA)
643                     || (block_x && video->intraAvailB)
644                     || (video->intraAvailA && video->intraAvailD && video->intraAvailB))
645             {
646                 Intra_4x4_Diagonal_Vertical_Right(video, pitch, block_offset);
647             }
648             else
649             {
650                 return AVC_FAIL;
651             }
652             break;
653 
654         case AVC_I4_Horizontal_Down:        /* Intra_4x4_Horizontal_Down */
655             if ((block_y && block_x)  /* to prevent out-of-bound access */
656                     || (block_y && video->intraAvailA)
657                     || (block_x && video->intraAvailB)
658                     || (video->intraAvailA && video->intraAvailD && video->intraAvailB))
659             {
660                 Intra_4x4_Diagonal_Horizontal_Down(video, pitch, block_offset);
661             }
662             else
663             {
664                 return AVC_FAIL;
665             }
666             break;
667 
668         case AVC_I4_Vertical_Left:      /* Intra_4x4_Vertical_Left */
669             /* lookup table may be more appropriate for this case  */
670             if (block_y == 0 && !video->intraAvailB)
671             {
672                 return AVC_FAIL;
673             }
674 
675             availability.top_right = BlkTopRight[(block_y<<2) + block_x];
676 
677             if (availability.top_right == 2)
678             {
679                 availability.top_right = video->intraAvailB;
680             }
681             else if (availability.top_right == 3)
682             {
683                 availability.top_right = video->intraAvailC;
684             }
685 
686             Intra_4x4_Vertical_Left(video,  block_offset, &availability);
687             break;
688 
689         case AVC_I4_Horizontal_Up:      /* Intra_4x4_Horizontal_Up */
690             if (block_x || video->intraAvailA)
691             {
692                 Intra_4x4_Horizontal_Up(video, pitch, block_offset);
693             }
694             else
695             {
696                 return AVC_FAIL;
697             }
698             break;
699 
700 
701         default:
702 
703             break;
704     }
705 
706     return AVC_SUCCESS;
707 }
708 
709 
710 /* =============================== BEGIN 4x4
711 MODES======================================*/
Intra_4x4_Vertical(AVCCommonObj * video,int block_offset)712 void Intra_4x4_Vertical(AVCCommonObj *video,  int block_offset)
713 {
714     uint8 *comp_ref = video->pintra_pred_top;
715     uint32 temp;
716     uint8 *pred = video->pred_block + block_offset;
717     int pred_pitch = video->pred_pitch;
718 
719     /*P = (int) *comp_ref++;
720     Q = (int) *comp_ref++;
721     R = (int) *comp_ref++;
722     S = (int) *comp_ref++;
723     temp = S|(R<<8)|(Q<<16)|(P<<24);*/
724     temp = *((uint32*)comp_ref);
725 
726     *((uint32*)pred) =  temp; /* write 4 at a time */
727     pred += pred_pitch;
728     *((uint32*)pred) =  temp;
729     pred += pred_pitch;
730     *((uint32*)pred) =  temp;
731     pred += pred_pitch;
732     *((uint32*)pred) =  temp;
733 
734     return ;
735 }
736 
Intra_4x4_Horizontal(AVCCommonObj * video,int pitch,int block_offset)737 void Intra_4x4_Horizontal(AVCCommonObj *video, int pitch, int block_offset)
738 {
739     uint8   *comp_ref = video->pintra_pred_left;
740     uint32 temp;
741     int P;
742     uint8 *pred = video->pred_block + block_offset;
743     int pred_pitch = video->pred_pitch;
744 
745     P = *comp_ref;
746     temp = P | (P << 8);
747     temp = temp | (temp << 16);
748     *((uint32*)pred) = temp;
749     pred += pred_pitch;
750     comp_ref += pitch;
751     P = *comp_ref;
752     temp = P | (P << 8);
753     temp = temp | (temp << 16);
754     *((uint32*)pred) = temp;
755     pred += pred_pitch;
756     comp_ref += pitch;
757     P = *comp_ref;
758     temp = P | (P << 8);
759     temp = temp | (temp << 16);
760     *((uint32*)pred) = temp;
761     pred += pred_pitch;
762     comp_ref += pitch;
763     P = *comp_ref;
764     temp = P | (P << 8);
765     temp = temp | (temp << 16);
766     *((uint32*)pred) = temp;
767 
768     return ;
769 }
770 
Intra_4x4_DC(AVCCommonObj * video,int pitch,int block_offset,AVCNeighborAvailability * availability)771 void Intra_4x4_DC(AVCCommonObj *video, int pitch, int block_offset,
772                   AVCNeighborAvailability *availability)
773 {
774     uint8   *comp_ref = video->pintra_pred_left;
775     uint32  temp;
776     int DC;
777     uint8 *pred = video->pred_block + block_offset;
778     int pred_pitch = video->pred_pitch;
779 
780     if (availability->left)
781     {
782         DC = *comp_ref;
783         comp_ref += pitch;
784         DC += *comp_ref;
785         comp_ref += pitch;
786         DC += *comp_ref;
787         comp_ref += pitch;
788         DC += *comp_ref;
789         comp_ref = video->pintra_pred_top;
790 
791         if (availability->top)
792         {
793             DC = (comp_ref[0] + comp_ref[1] + comp_ref[2] + comp_ref[3] + DC + 4) >> 3;
794         }
795         else
796         {
797             DC = (DC + 2) >> 2;
798 
799         }
800     }
801     else if (availability->top)
802     {
803         comp_ref = video->pintra_pred_top;
804         DC = (comp_ref[0] + comp_ref[1] + comp_ref[2] + comp_ref[3] + 2) >> 2;
805 
806     }
807     else
808     {
809         DC = 128;
810     }
811 
812     temp = DC | (DC << 8);
813     temp = temp | (temp << 16);
814     *((uint32*)pred) = temp;
815     pred += pred_pitch;
816     *((uint32*)pred) = temp;
817     pred += pred_pitch;
818     *((uint32*)pred) = temp;
819     pred += pred_pitch;
820     *((uint32*)pred) = temp;
821 
822     return ;
823 }
824 
Intra_4x4_Down_Left(AVCCommonObj * video,int block_offset,AVCNeighborAvailability * availability)825 void Intra_4x4_Down_Left(AVCCommonObj *video, int block_offset,
826                          AVCNeighborAvailability *availability)
827 {
828     uint8   *comp_refx = video->pintra_pred_top;
829     uint32 temp;
830     int r0, r1, r2, r3, r4, r5, r6, r7;
831     uint8 *pred = video->pred_block + block_offset;
832     int pred_pitch = video->pred_pitch;
833 
834     r0 = *comp_refx++;
835     r1 = *comp_refx++;
836     r2 = *comp_refx++;
837     r3 = *comp_refx++;
838     if (availability->top_right)
839     {
840         r4 = *comp_refx++;
841         r5 = *comp_refx++;
842         r6 = *comp_refx++;
843         r7 = *comp_refx++;
844     }
845     else
846     {
847         r4 = r3;
848         r5 = r3;
849         r6 = r3;
850         r7 = r3;
851     }
852 
853     r0 += (r1 << 1);
854     r0 += r2;
855     r0 += 2;
856     r0 >>= 2;
857     r1 += (r2 << 1);
858     r1 += r3;
859     r1 += 2;
860     r1 >>= 2;
861     r2 += (r3 << 1);
862     r2 += r4;
863     r2 += 2;
864     r2 >>= 2;
865     r3 += (r4 << 1);
866     r3 += r5;
867     r3 += 2;
868     r3 >>= 2;
869     r4 += (r5 << 1);
870     r4 += r6;
871     r4 += 2;
872     r4 >>= 2;
873     r5 += (r6 << 1);
874     r5 += r7;
875     r5 += 2;
876     r5 >>= 2;
877     r6 += (3 * r7);
878     r6 += 2;
879     r6 >>= 2;
880 
881     temp = r0 | (r1 << 8);
882     temp |= (r2 << 16);
883     temp |= (r3 << 24);
884     *((uint32*)pred) = temp;
885     pred += pred_pitch;
886 
887     temp = (temp >> 8) | (r4 << 24);
888     *((uint32*)pred) = temp;
889     pred += pred_pitch;
890 
891     temp = (temp >> 8) | (r5 << 24);
892     *((uint32*)pred) = temp;
893     pred += pred_pitch;
894 
895     temp = (temp >> 8) | (r6 << 24);
896     *((uint32*)pred) = temp;
897 
898     return ;
899 }
900 
Intra_4x4_Diagonal_Down_Right(AVCCommonObj * video,int pitch,int block_offset)901 void Intra_4x4_Diagonal_Down_Right(AVCCommonObj *video, int pitch, int
902                                    block_offset)
903 {
904     uint8 *comp_refx = video->pintra_pred_top;
905     uint8 *comp_refy = video->pintra_pred_left;
906     uint32 temp;
907     int P_x, Q_x, R_x, P_y, Q_y, R_y, D;
908     int x0, x1, x2;
909     uint8 *pred = video->pred_block + block_offset;
910     int pred_pitch = video->pred_pitch;
911 
912     temp = *((uint32*)comp_refx); /* read 4 bytes */
913     x0 = temp & 0xFF;
914     x1 = (temp >> 8) & 0xFF;
915     x2 = (temp >> 16) & 0xFF;
916 
917     Q_x = (x0 + 2 * x1 + x2 + 2) >> 2;
918     R_x = (x1 + 2 * x2 + (temp >> 24) + 2) >> 2;
919 
920     x2 = video->intra_pred_topleft; /* re-use x2 instead of y0 */
921     P_x = (x2 + 2 * x0 + x1 + 2) >> 2;
922 
923     x1 = *comp_refy;
924     comp_refy += pitch; /* re-use x1 instead of y1 */
925     D = (x0 + 2 * x2 + x1 + 2) >> 2;
926 
927     x0 = *comp_refy;
928     comp_refy += pitch; /* re-use x0 instead of y2 */
929     P_y = (x2 + 2 * x1 + x0 + 2) >> 2;
930 
931     x2 = *comp_refy;
932     comp_refy += pitch; /* re-use x2 instead of y3 */
933     Q_y = (x1 + 2 * x0 + x2 + 2) >> 2;
934 
935     x1 = *comp_refy;                    /* re-use x1 instead of y4 */
936     R_y = (x0 + 2 * x2 + x1 + 2) >> 2;
937 
938     /* we can pack these  */
939     temp =  D | (P_x << 8);   //[D   P_x Q_x R_x]
940     //[P_y D   P_x Q_x]
941     temp |= (Q_x << 16); //[Q_y P_y D   P_x]
942     temp |= (R_x << 24);  //[R_y Q_y P_y D  ]
943     *((uint32*)pred) = temp;
944     pred += pred_pitch;
945 
946     temp =  P_y | (D << 8);
947     temp |= (P_x << 16);
948     temp |= (Q_x << 24);
949     *((uint32*)pred) = temp;
950     pred += pred_pitch;
951 
952     temp =  Q_y | (P_y << 8);
953     temp |= (D << 16);
954     temp |= (P_x << 24);
955     *((uint32*)pred) = temp;
956     pred += pred_pitch;
957 
958     temp = R_y | (Q_y << 8);
959     temp |= (P_y << 16);
960     temp |= (D << 24);
961     *((uint32*)pred) = temp;
962 
963     return ;
964 }
965 
Intra_4x4_Diagonal_Vertical_Right(AVCCommonObj * video,int pitch,int block_offset)966 void    Intra_4x4_Diagonal_Vertical_Right(AVCCommonObj *video, int pitch, int block_offset)
967 {
968     uint8   *comp_refx = video->pintra_pred_top;
969     uint8   *comp_refy = video->pintra_pred_left;
970     uint32 temp;
971     int P0, Q0, R0, S0, P1, Q1, R1, P2, Q2, D;
972     int x0, x1, x2;
973     uint8 *pred = video->pred_block + block_offset;
974     int pred_pitch = video->pred_pitch;
975 
976     x0 = *comp_refx++;
977     x1 = *comp_refx++;
978     Q0 = x0 + x1 + 1;
979 
980     x2 = *comp_refx++;
981     R0 = x1 + x2 + 1;
982 
983     x1 = *comp_refx++; /* reuse x1 instead of x3 */
984     S0 = x2 + x1 + 1;
985 
986     x1 = video->intra_pred_topleft; /* reuse x1 instead of y0 */
987     P0 = x1 + x0 + 1;
988 
989     x2 = *comp_refy;
990     comp_refy += pitch; /* reuse x2 instead of y1 */
991     D = (x2 + 2 * x1 + x0 + 2) >> 2;
992 
993     P1 = (P0 + Q0) >> 2;
994     Q1 = (Q0 + R0) >> 2;
995     R1 = (R0 + S0) >> 2;
996 
997     P0 >>= 1;
998     Q0 >>= 1;
999     R0 >>= 1;
1000     S0 >>= 1;
1001 
1002     x0 = *comp_refy;
1003     comp_refy += pitch; /* reuse x0 instead of y2 */
1004     P2 = (x1 + 2 * x2 + x0 + 2) >> 2;
1005     x1 = *comp_refy;
1006     comp_refy += pitch; /* reuse x1 instead of y3 */
1007     Q2 = (x2 + 2 * x0 + x1 + 2) >> 2;
1008 
1009     temp =  P0 | (Q0 << 8);  //[P0 Q0 R0 S0]
1010     //[D  P1 Q1 R1]
1011     temp |= (R0 << 16); //[P2 P0 Q0 R0]
1012     temp |= (S0 << 24); //[Q2 D  P1 Q1]
1013     *((uint32*)pred) =  temp;
1014     pred += pred_pitch;
1015 
1016     temp =  D | (P1 << 8);
1017     temp |= (Q1 << 16);
1018     temp |= (R1 << 24);
1019     *((uint32*)pred) =  temp;
1020     pred += pred_pitch;
1021 
1022     temp = P2 | (P0 << 8);
1023     temp |= (Q0 << 16);
1024     temp |= (R0 << 24);
1025     *((uint32*)pred) =  temp;
1026     pred += pred_pitch;
1027 
1028     temp = Q2 | (D << 8);
1029     temp |= (P1 << 16);
1030     temp |= (Q1 << 24);
1031     *((uint32*)pred) =  temp;
1032 
1033     return ;
1034 }
1035 
Intra_4x4_Diagonal_Horizontal_Down(AVCCommonObj * video,int pitch,int block_offset)1036 void Intra_4x4_Diagonal_Horizontal_Down(AVCCommonObj *video, int pitch,
1037                                         int block_offset)
1038 {
1039     uint8   *comp_refx = video->pintra_pred_top;
1040     uint8   *comp_refy = video->pintra_pred_left;
1041     uint32 temp;
1042     int P0, Q0, R0, S0, P1, Q1, R1, P2, Q2, D;
1043     int x0, x1, x2;
1044     uint8 *pred = video->pred_block + block_offset;
1045     int pred_pitch = video->pred_pitch;
1046 
1047     x0 = *comp_refx++;
1048     x1 = *comp_refx++;
1049     x2 = *comp_refx++;
1050     Q2 = (x0 + 2 * x1 + x2 + 2) >> 2;
1051 
1052     x2 = video->intra_pred_topleft; /* reuse x2 instead of y0 */
1053     P2 = (x2 + 2 * x0 + x1 + 2) >> 2;
1054 
1055     x1 = *comp_refy;
1056     comp_refy += pitch; /* reuse x1 instead of y1 */
1057     D = (x1 + 2 * x2 + x0 + 2) >> 2;
1058     P0 = x2 + x1 + 1;
1059 
1060     x0 = *comp_refy;
1061     comp_refy += pitch; /* reuse x0 instead of y2 */
1062     Q0 = x1 + x0 + 1;
1063 
1064     x1 = *comp_refy;
1065     comp_refy += pitch; /* reuse x1 instead of y3 */
1066     R0 = x0 + x1 + 1;
1067 
1068     x2 = *comp_refy;    /* reuse x2 instead of y4 */
1069     S0 = x1 + x2 + 1;
1070 
1071     P1 = (P0 + Q0) >> 2;
1072     Q1 = (Q0 + R0) >> 2;
1073     R1 = (R0 + S0) >> 2;
1074 
1075     P0 >>= 1;
1076     Q0 >>= 1;
1077     R0 >>= 1;
1078     S0 >>= 1;
1079 
1080 
1081     /* we can pack these  */
1082     temp = P0 | (D << 8);   //[P0 D  P2 Q2]
1083     //[Q0 P1 P0 D ]
1084     temp |= (P2 << 16);  //[R0 Q1 Q0 P1]
1085     temp |= (Q2 << 24); //[S0 R1 R0 Q1]
1086     *((uint32*)pred) = temp;
1087     pred += pred_pitch;
1088 
1089     temp = Q0 | (P1 << 8);
1090     temp |= (P0 << 16);
1091     temp |= (D << 24);
1092     *((uint32*)pred) = temp;
1093     pred += pred_pitch;
1094 
1095     temp = R0 | (Q1 << 8);
1096     temp |= (Q0 << 16);
1097     temp |= (P1 << 24);
1098     *((uint32*)pred) = temp;
1099     pred += pred_pitch;
1100 
1101     temp = S0 | (R1 << 8);
1102     temp |= (R0 << 16);
1103     temp |= (Q1 << 24);
1104     *((uint32*)pred) = temp;
1105 
1106     return ;
1107 }
1108 
Intra_4x4_Vertical_Left(AVCCommonObj * video,int block_offset,AVCNeighborAvailability * availability)1109 void Intra_4x4_Vertical_Left(AVCCommonObj *video, int block_offset, AVCNeighborAvailability *availability)
1110 {
1111     uint8   *comp_refx = video->pintra_pred_top;
1112     uint32 temp1, temp2;
1113     int x0, x1, x2, x3, x4, x5, x6;
1114     uint8 *pred = video->pred_block + block_offset;
1115     int pred_pitch = video->pred_pitch;
1116 
1117     x0 = *comp_refx++;
1118     x1 = *comp_refx++;
1119     x2 = *comp_refx++;
1120     x3 = *comp_refx++;
1121     if (availability->top_right)
1122     {
1123         x4 = *comp_refx++;
1124         x5 = *comp_refx++;
1125         x6 = *comp_refx++;
1126     }
1127     else
1128     {
1129         x4 = x3;
1130         x5 = x3;
1131         x6 = x3;
1132     }
1133 
1134     x0 += x1 + 1;
1135     x1 += x2 + 1;
1136     x2 += x3 + 1;
1137     x3 += x4 + 1;
1138     x4 += x5 + 1;
1139     x5 += x6 + 1;
1140 
1141     temp1 = (x0 >> 1);
1142     temp1 |= ((x1 >> 1) << 8);
1143     temp1 |= ((x2 >> 1) << 16);
1144     temp1 |= ((x3 >> 1) << 24);
1145 
1146     *((uint32*)pred) = temp1;
1147     pred += pred_pitch;
1148 
1149     temp2 = ((x0 + x1) >> 2);
1150     temp2 |= (((x1 + x2) >> 2) << 8);
1151     temp2 |= (((x2 + x3) >> 2) << 16);
1152     temp2 |= (((x3 + x4) >> 2) << 24);
1153 
1154     *((uint32*)pred) = temp2;
1155     pred += pred_pitch;
1156 
1157     temp1 = (temp1 >> 8) | ((x4 >> 1) << 24);   /* rotate out old value */
1158     *((uint32*)pred) = temp1;
1159     pred += pred_pitch;
1160 
1161     temp2 = (temp2 >> 8) | (((x4 + x5) >> 2) << 24); /* rotate out old value */
1162     *((uint32*)pred) = temp2;
1163     pred += pred_pitch;
1164 
1165     return ;
1166 }
1167 
Intra_4x4_Horizontal_Up(AVCCommonObj * video,int pitch,int block_offset)1168 void Intra_4x4_Horizontal_Up(AVCCommonObj *video, int pitch, int block_offset)
1169 {
1170     uint8   *comp_refy = video->pintra_pred_left;
1171     uint32 temp;
1172     int Q0, R0, Q1, D0, D1, P0, P1;
1173     int y0, y1, y2, y3;
1174     uint8 *pred = video->pred_block + block_offset;
1175     int pred_pitch = video->pred_pitch;
1176 
1177     y0 = *comp_refy;
1178     comp_refy += pitch;
1179     y1 = *comp_refy;
1180     comp_refy += pitch;
1181     y2 = *comp_refy;
1182     comp_refy += pitch;
1183     y3 = *comp_refy;
1184 
1185     Q0 = (y1 + y2 + 1) >> 1;
1186     Q1 = (y1 + (y2 << 1) + y3 + 2) >> 2;
1187     P0 = ((y0 + y1 + 1) >> 1);
1188     P1 = ((y0 + (y1 << 1) + y2 + 2) >> 2);
1189 
1190     temp = P0 | (P1 << 8);      // [P0 P1 Q0 Q1]
1191     temp |= (Q0 << 16);     // [Q0 Q1 R0 DO]
1192     temp |= (Q1 << 24);     // [R0 D0 D1 D1]
1193     *((uint32*)pred) = temp;      // [D1 D1 D1 D1]
1194     pred += pred_pitch;
1195 
1196     D0 = (y2 + 3 * y3 + 2) >> 2;
1197     R0 = (y2 + y3 + 1) >> 1;
1198 
1199     temp = Q0 | (Q1 << 8);
1200     temp |= (R0 << 16);
1201     temp |= (D0 << 24);
1202     *((uint32*)pred) = temp;
1203     pred += pred_pitch;
1204 
1205     D1 = y3;
1206 
1207     temp = R0 | (D0 << 8);
1208     temp |= (D1 << 16);
1209     temp |= (D1 << 24);
1210     *((uint32*)pred) = temp;
1211     pred += pred_pitch;
1212 
1213     temp = D1 | (D1 << 8);
1214     temp |= (temp << 16);
1215     *((uint32*)pred) = temp;
1216 
1217     return ;
1218 }
1219 /* =============================== END 4x4 MODES======================================*/
Intra_16x16_Vertical(AVCCommonObj * video)1220 void  Intra_16x16_Vertical(AVCCommonObj *video)
1221 {
1222     int i;
1223     uint32 temp1, temp2, temp3, temp4;
1224     uint8   *comp_ref = video->pintra_pred_top;
1225     uint8 *pred = video->pred_block;
1226     int pred_pitch = video->pred_pitch;
1227 
1228     temp1 = *((uint32*)comp_ref);
1229     comp_ref += 4;
1230 
1231     temp2 = *((uint32*)comp_ref);
1232     comp_ref += 4;
1233 
1234     temp3 = *((uint32*)comp_ref);
1235     comp_ref += 4;
1236 
1237     temp4 = *((uint32*)comp_ref);
1238     comp_ref += 4;
1239 
1240     i = 16;
1241     while (i > 0)
1242     {
1243         *((uint32*)pred) = temp1;
1244         *((uint32*)(pred + 4)) = temp2;
1245         *((uint32*)(pred + 8)) = temp3;
1246         *((uint32*)(pred + 12)) = temp4;
1247         pred += pred_pitch;
1248         i--;
1249     }
1250 
1251     return ;
1252 }
1253 
Intra_16x16_Horizontal(AVCCommonObj * video,int pitch)1254 void Intra_16x16_Horizontal(AVCCommonObj *video, int pitch)
1255 {
1256     int i;
1257     uint32 temp;
1258     uint8 *comp_ref = video->pintra_pred_left;
1259     uint8 *pred = video->pred_block;
1260     int pred_pitch = video->pred_pitch;
1261 
1262     for (i = 0; i < 16; i++)
1263     {
1264         temp = *comp_ref;
1265         temp |= (temp << 8);
1266         temp |= (temp << 16);
1267         *((uint32*)pred) = temp;
1268         *((uint32*)(pred + 4)) = temp;
1269         *((uint32*)(pred + 8)) = temp;
1270         *((uint32*)(pred + 12)) = temp;
1271         pred += pred_pitch;
1272         comp_ref += pitch;
1273     }
1274 }
1275 
1276 
Intra_16x16_DC(AVCCommonObj * video,int pitch)1277 void  Intra_16x16_DC(AVCCommonObj *video, int pitch)
1278 {
1279     int i;
1280     uint32 temp, temp2;
1281     uint8 *comp_ref_x = video->pintra_pred_top;
1282     uint8 *comp_ref_y = video->pintra_pred_left;
1283     int sum = 0;
1284     uint8 *pred = video->pred_block;
1285     int pred_pitch = video->pred_pitch;
1286 
1287     if (video->intraAvailB)
1288     {
1289         temp = *((uint32*)comp_ref_x);
1290         comp_ref_x += 4;
1291         temp2 = (temp >> 8) & 0xFF00FF;
1292         temp &= 0xFF00FF;
1293         temp += temp2;
1294         sum = temp + (temp >> 16);
1295         temp = *((uint32*)comp_ref_x);
1296         comp_ref_x += 4;
1297         temp2 = (temp >> 8) & 0xFF00FF;
1298         temp &= 0xFF00FF;
1299         temp += temp2;
1300         sum += temp + (temp >> 16);
1301         temp = *((uint32*)comp_ref_x);
1302         comp_ref_x += 4;
1303         temp2 = (temp >> 8) & 0xFF00FF;
1304         temp &= 0xFF00FF;
1305         temp += temp2;
1306         sum += temp + (temp >> 16);
1307         temp = *((uint32*)comp_ref_x);
1308         comp_ref_x += 4;
1309         temp2 = (temp >> 8) & 0xFF00FF;
1310         temp &= 0xFF00FF;
1311         temp += temp2;
1312         sum += temp + (temp >> 16);
1313         sum &= 0xFFFF;
1314 
1315         if (video->intraAvailA)
1316         {
1317             for (i = 0; i < 16; i++)
1318             {
1319                 sum += (*comp_ref_y);
1320                 comp_ref_y += pitch;
1321             }
1322             sum = (sum + 16) >> 5;
1323         }
1324         else
1325         {
1326             sum = (sum + 8) >> 4;
1327         }
1328     }
1329     else if (video->intraAvailA)
1330     {
1331         for (i = 0; i < 16; i++)
1332         {
1333             sum += *comp_ref_y;
1334             comp_ref_y += pitch;
1335         }
1336         sum = (sum + 8) >> 4;
1337     }
1338     else
1339     {
1340         sum = 128;
1341     }
1342 
1343     temp = sum | (sum << 8);
1344     temp |= (temp << 16);
1345 
1346     for (i = 0; i < 16; i++)
1347     {
1348         *((uint32*)pred) = temp;
1349         *((uint32*)(pred + 4)) = temp;
1350         *((uint32*)(pred + 8)) = temp;
1351         *((uint32*)(pred + 12)) = temp;
1352         pred += pred_pitch;
1353     }
1354 
1355 }
1356 
Intra_16x16_Plane(AVCCommonObj * video,int pitch)1357 void Intra_16x16_Plane(AVCCommonObj *video, int pitch)
1358 {
1359     int i, a_16, b, c, factor_c;
1360     uint8 *comp_ref_x = video->pintra_pred_top;
1361     uint8 *comp_ref_y = video->pintra_pred_left;
1362     uint8 *comp_ref_x0, *comp_ref_x1, *comp_ref_y0, *comp_ref_y1;
1363     int H = 0, V = 0 , tmp;
1364     uint8 *pred = video->pred_block;
1365     uint32 temp;
1366     uint8 byte1, byte2, byte3;
1367     int value;
1368     int pred_pitch = video->pred_pitch;
1369 
1370     comp_ref_x0 = comp_ref_x + 8;
1371     comp_ref_x1 = comp_ref_x + 6;
1372     comp_ref_y0 = comp_ref_y + (pitch << 3);
1373     comp_ref_y1 = comp_ref_y + 6 * pitch;
1374 
1375     for (i = 1; i < 8; i++)
1376     {
1377         H += i * (*comp_ref_x0++ - *comp_ref_x1--);
1378         V += i * (*comp_ref_y0 - *comp_ref_y1);
1379         comp_ref_y0 += pitch;
1380         comp_ref_y1 -= pitch;
1381     }
1382 
1383     H += i * (*comp_ref_x0++ - video->intra_pred_topleft);
1384     V += i * (*comp_ref_y0 - *comp_ref_y1);
1385 
1386 
1387     a_16 = ((*(comp_ref_x + 15) + *(comp_ref_y + 15 * pitch)) << 4) + 16;;
1388     b = (5 * H + 32) >> 6;
1389     c = (5 * V + 32) >> 6;
1390 
1391     tmp = 0;
1392 
1393     for (i = 0; i < 16; i++)
1394     {
1395         factor_c = a_16 + c * (tmp++ - 7);
1396 
1397         factor_c -= 7 * b;
1398 
1399         value = factor_c >> 5;
1400         factor_c += b;
1401         CLIP_RESULT(value)
1402         byte1 = value;
1403         value = factor_c >> 5;
1404         factor_c += b;
1405         CLIP_RESULT(value)
1406         byte2 = value;
1407         value = factor_c >> 5;
1408         factor_c += b;
1409         CLIP_RESULT(value)
1410         byte3 = value;
1411         value = factor_c >> 5;
1412         factor_c += b;
1413         CLIP_RESULT(value)
1414         temp = byte1 | (byte2 << 8);
1415         temp |= (byte3 << 16);
1416         temp |= (value << 24);
1417         *((uint32*)pred) = temp;
1418 
1419         value = factor_c >> 5;
1420         factor_c += b;
1421         CLIP_RESULT(value)
1422         byte1 = value;
1423         value = factor_c >> 5;
1424         factor_c += b;
1425         CLIP_RESULT(value)
1426         byte2 = value;
1427         value = factor_c >> 5;
1428         factor_c += b;
1429         CLIP_RESULT(value)
1430         byte3 = value;
1431         value = factor_c >> 5;
1432         factor_c += b;
1433         CLIP_RESULT(value)
1434         temp = byte1 | (byte2 << 8);
1435         temp |= (byte3 << 16);
1436         temp |= (value << 24);
1437         *((uint32*)(pred + 4)) = temp;
1438 
1439         value = factor_c >> 5;
1440         factor_c += b;
1441         CLIP_RESULT(value)
1442         byte1 = value;
1443         value = factor_c >> 5;
1444         factor_c += b;
1445         CLIP_RESULT(value)
1446         byte2 = value;
1447         value = factor_c >> 5;
1448         factor_c += b;
1449         CLIP_RESULT(value)
1450         byte3 = value;
1451         value = factor_c >> 5;
1452         factor_c += b;
1453         CLIP_RESULT(value)
1454         temp = byte1 | (byte2 << 8);
1455         temp |= (byte3 << 16);
1456         temp |= (value << 24);
1457         *((uint32*)(pred + 8)) = temp;
1458 
1459         value = factor_c >> 5;
1460         factor_c += b;
1461         CLIP_RESULT(value)
1462         byte1 = value;
1463         value = factor_c >> 5;
1464         factor_c += b;
1465         CLIP_RESULT(value)
1466         byte2 = value;
1467         value = factor_c >> 5;
1468         factor_c += b;
1469         CLIP_RESULT(value)
1470         byte3 = value;
1471         value = factor_c >> 5;
1472         CLIP_RESULT(value)
1473         temp = byte1 | (byte2 << 8);
1474         temp |= (byte3 << 16);
1475         temp |= (value << 24);
1476         *((uint32*)(pred + 12)) = temp;
1477         pred += pred_pitch;
1478     }
1479 }
1480 
1481 /************** Chroma intra prediction *********************/
1482 
Intra_Chroma_DC(AVCCommonObj * video,int pitch,uint8 * predCb,uint8 * predCr)1483 void Intra_Chroma_DC(AVCCommonObj *video, int pitch, uint8 *predCb, uint8 *predCr)
1484 {
1485     int i;
1486     uint32 temp, temp2, pred_a, pred_b;
1487     uint8 *comp_ref_x, *comp_ref_y;
1488     uint8 *comp_ref_cb_x = video->pintra_pred_top_cb;
1489     uint8 *comp_ref_cb_y = video->pintra_pred_left_cb;
1490     uint8 *comp_ref_cr_x = video->pintra_pred_top_cr;
1491     uint8 *comp_ref_cr_y = video->pintra_pred_left_cr;
1492     int  component, j;
1493     int  sum_x0, sum_x1, sum_y0, sum_y1;
1494     int pred_0[2], pred_1[2], pred_2[2], pred_3[2];
1495     int pred_pitch = video->pred_pitch;
1496     uint8 *pred;
1497 
1498     if (video->intraAvailB & video->intraAvailA)
1499     {
1500         comp_ref_x = comp_ref_cb_x;
1501         comp_ref_y = comp_ref_cb_y;
1502         for (i = 0; i < 2; i++)
1503         {
1504             temp = *((uint32*)comp_ref_x);
1505             comp_ref_x += 4;
1506             temp2 = (temp >> 8) & 0xFF00FF;
1507             temp &= 0xFF00FF;
1508             temp += temp2;
1509             temp += (temp >> 16);
1510             sum_x0 = temp & 0xFFFF;
1511 
1512             temp = *((uint32*)comp_ref_x);
1513             temp2 = (temp >> 8) & 0xFF00FF;
1514             temp &= 0xFF00FF;
1515             temp += temp2;
1516             temp += (temp >> 16);
1517             sum_x1 = temp & 0xFFFF;
1518 
1519             pred_1[i] = (sum_x1 + 2) >> 2;
1520 
1521             sum_y0 = *comp_ref_y;
1522             sum_y0 += *(comp_ref_y += pitch);
1523             sum_y0 += *(comp_ref_y += pitch);
1524             sum_y0 += *(comp_ref_y += pitch);
1525 
1526             sum_y1 = *(comp_ref_y += pitch);
1527             sum_y1 += *(comp_ref_y += pitch);
1528             sum_y1 += *(comp_ref_y += pitch);
1529             sum_y1 += *(comp_ref_y += pitch);
1530 
1531             pred_2[i] = (sum_y1 + 2) >> 2;
1532 
1533             pred_0[i] = (sum_y0 + sum_x0 + 4) >> 3;
1534             pred_3[i] = (sum_y1 + sum_x1 + 4) >> 3;
1535 
1536             comp_ref_x = comp_ref_cr_x;
1537             comp_ref_y = comp_ref_cr_y;
1538         }
1539     }
1540 
1541     else if (video->intraAvailA)
1542     {
1543         comp_ref_y = comp_ref_cb_y;
1544         for (i = 0; i < 2; i++)
1545         {
1546             sum_y0 = *comp_ref_y;
1547             sum_y0 += *(comp_ref_y += pitch);
1548             sum_y0 += *(comp_ref_y += pitch);
1549             sum_y0 += *(comp_ref_y += pitch);
1550 
1551             sum_y1 = *(comp_ref_y += pitch);
1552             sum_y1 += *(comp_ref_y += pitch);
1553             sum_y1 += *(comp_ref_y += pitch);
1554             sum_y1 += *(comp_ref_y += pitch);
1555 
1556             pred_0[i] = pred_1[i] = (sum_y0 + 2) >> 2;
1557             pred_2[i] = pred_3[i] = (sum_y1 + 2) >> 2;
1558             comp_ref_y = comp_ref_cr_y;
1559         }
1560     }
1561     else if (video->intraAvailB)
1562     {
1563         comp_ref_x = comp_ref_cb_x;
1564         for (i = 0; i < 2; i++)
1565         {
1566             temp = *((uint32*)comp_ref_x);
1567             comp_ref_x += 4;
1568             temp2 = (temp >> 8) & 0xFF00FF;
1569             temp &= 0xFF00FF;
1570             temp += temp2;
1571             temp += (temp >> 16);
1572             sum_x0 = temp & 0xFFFF;
1573 
1574             temp = *((uint32*)comp_ref_x);
1575             temp2 = (temp >> 8) & 0xFF00FF;
1576             temp &= 0xFF00FF;
1577             temp += temp2;
1578             temp += (temp >> 16);
1579             sum_x1 = temp & 0xFFFF;
1580 
1581             pred_0[i] = pred_2[i] = (sum_x0 + 2) >> 2;
1582             pred_1[i] = pred_3[i] = (sum_x1 + 2) >> 2;
1583             comp_ref_x = comp_ref_cr_x;
1584         }
1585     }
1586     else
1587     {
1588         pred_0[0] = pred_0[1] = pred_1[0] = pred_1[1] =
1589                                                 pred_2[0] = pred_2[1] = pred_3[0] = pred_3[1] = 128;
1590     }
1591 
1592     pred = predCb;
1593     for (component = 0; component < 2; component++)
1594     {
1595         pred_a = pred_0[component];
1596         pred_b = pred_1[component];
1597         pred_a |= (pred_a << 8);
1598         pred_a |= (pred_a << 16);
1599         pred_b |= (pred_b << 8);
1600         pred_b |= (pred_b << 16);
1601 
1602         for (i = 4; i < 6; i++)
1603         {
1604             for (j = 0; j < 4; j++) /* 4 lines */
1605             {
1606                 *((uint32*)pred) = pred_a;
1607                 *((uint32*)(pred + 4)) = pred_b;
1608                 pred += pred_pitch; /* move to the next line */
1609             }
1610             pred_a = pred_2[component];
1611             pred_b = pred_3[component];
1612             pred_a |= (pred_a << 8);
1613             pred_a |= (pred_a << 16);
1614             pred_b |= (pred_b << 8);
1615             pred_b |= (pred_b << 16);
1616         }
1617         pred = predCr; /* point to cr */
1618     }
1619 }
1620 
Intra_Chroma_Horizontal(AVCCommonObj * video,int pitch,uint8 * predCb,uint8 * predCr)1621 void  Intra_Chroma_Horizontal(AVCCommonObj *video, int pitch, uint8 *predCb, uint8 *predCr)
1622 {
1623     int i;
1624     uint32 temp;
1625     uint8   *comp_ref_cb_y = video->pintra_pred_left_cb;
1626     uint8   *comp_ref_cr_y = video->pintra_pred_left_cr;
1627     uint8  *comp;
1628     int component, j;
1629     int     pred_pitch = video->pred_pitch;
1630     uint8   *pred;
1631 
1632     comp = comp_ref_cb_y;
1633     pred = predCb;
1634     for (component = 0; component < 2; component++)
1635     {
1636         for (i = 4; i < 6; i++)
1637         {
1638             for (j = 0; j < 4; j++)
1639             {
1640                 temp = *comp;
1641                 comp += pitch;
1642                 temp |= (temp << 8);
1643                 temp |= (temp << 16);
1644                 *((uint32*)pred) = temp;
1645                 *((uint32*)(pred + 4)) = temp;
1646                 pred += pred_pitch;
1647             }
1648         }
1649         comp = comp_ref_cr_y;
1650         pred = predCr; /* point to cr */
1651     }
1652 
1653 }
1654 
Intra_Chroma_Vertical(AVCCommonObj * video,uint8 * predCb,uint8 * predCr)1655 void  Intra_Chroma_Vertical(AVCCommonObj *video, uint8 *predCb, uint8 *predCr)
1656 {
1657     uint32  temp1, temp2;
1658     uint8   *comp_ref_cb_x = video->pintra_pred_top_cb;
1659     uint8   *comp_ref_cr_x = video->pintra_pred_top_cr;
1660     uint8   *comp_ref;
1661     int     component, j;
1662     int     pred_pitch = video->pred_pitch;
1663     uint8   *pred;
1664 
1665     comp_ref = comp_ref_cb_x;
1666     pred = predCb;
1667     for (component = 0; component < 2; component++)
1668     {
1669         temp1 = *((uint32*)comp_ref);
1670         temp2 = *((uint32*)(comp_ref + 4));
1671         for (j = 0; j < 8; j++)
1672         {
1673             *((uint32*)pred) = temp1;
1674             *((uint32*)(pred + 4)) = temp2;
1675             pred += pred_pitch;
1676         }
1677         comp_ref = comp_ref_cr_x;
1678         pred = predCr; /* point to cr */
1679     }
1680 
1681 }
1682 
Intra_Chroma_Plane(AVCCommonObj * video,int pitch,uint8 * predCb,uint8 * predCr)1683 void  Intra_Chroma_Plane(AVCCommonObj *video, int pitch, uint8 *predCb, uint8 *predCr)
1684 {
1685     int i;
1686     int a_16_C[2], b_C[2], c_C[2], a_16, b, c, factor_c;
1687     uint8 *comp_ref_x, *comp_ref_y, *comp_ref_x0, *comp_ref_x1,  *comp_ref_y0, *comp_ref_y1;
1688     int component, j;
1689     int H, V, tmp;
1690     uint32 temp;
1691     uint8 byte1, byte2, byte3;
1692     int value;
1693     uint8 topleft;
1694     int pred_pitch = video->pred_pitch;
1695     uint8 *pred;
1696 
1697     comp_ref_x = video->pintra_pred_top_cb;
1698     comp_ref_y = video->pintra_pred_left_cb;
1699     topleft = video->intra_pred_topleft_cb;
1700 
1701     for (component = 0; component < 2; component++)
1702     {
1703         H = V = 0;
1704         comp_ref_x0 = comp_ref_x + 4;
1705         comp_ref_x1 = comp_ref_x + 2;
1706         comp_ref_y0 = comp_ref_y + (pitch << 2);
1707         comp_ref_y1 = comp_ref_y + (pitch << 1);
1708         for (i = 1; i < 4; i++)
1709         {
1710             H += i * (*comp_ref_x0++ - *comp_ref_x1--);
1711             V += i * (*comp_ref_y0 - *comp_ref_y1);
1712             comp_ref_y0 += pitch;
1713             comp_ref_y1 -= pitch;
1714         }
1715         H += i * (*comp_ref_x0++ - topleft);
1716         V += i * (*comp_ref_y0 - *comp_ref_y1);
1717 
1718         a_16_C[component] = ((*(comp_ref_x + 7) + *(comp_ref_y + 7 * pitch)) << 4) + 16;
1719         b_C[component] = (17 * H + 16) >> 5;
1720         c_C[component] = (17 * V + 16) >> 5;
1721 
1722         comp_ref_x = video->pintra_pred_top_cr;
1723         comp_ref_y = video->pintra_pred_left_cr;
1724         topleft = video->intra_pred_topleft_cr;
1725     }
1726 
1727     pred = predCb;
1728     for (component = 0; component < 2; component++)
1729     {
1730         a_16 = a_16_C[component];
1731         b = b_C[component];
1732         c = c_C[component];
1733         tmp = 0;
1734         for (i = 4; i < 6; i++)
1735         {
1736             for (j = 0; j < 4; j++)
1737             {
1738                 factor_c = a_16 + c * (tmp++ - 3);
1739 
1740                 factor_c -= 3 * b;
1741 
1742                 value = factor_c >> 5;
1743                 factor_c += b;
1744                 CLIP_RESULT(value)
1745                 byte1 = value;
1746                 value = factor_c >> 5;
1747                 factor_c += b;
1748                 CLIP_RESULT(value)
1749                 byte2 = value;
1750                 value = factor_c >> 5;
1751                 factor_c += b;
1752                 CLIP_RESULT(value)
1753                 byte3 = value;
1754                 value = factor_c >> 5;
1755                 factor_c += b;
1756                 CLIP_RESULT(value)
1757                 temp = byte1 | (byte2 << 8);
1758                 temp |= (byte3 << 16);
1759                 temp |= (value << 24);
1760                 *((uint32*)pred) = temp;
1761 
1762                 value = factor_c >> 5;
1763                 factor_c += b;
1764                 CLIP_RESULT(value)
1765                 byte1 = value;
1766                 value = factor_c >> 5;
1767                 factor_c += b;
1768                 CLIP_RESULT(value)
1769                 byte2 = value;
1770                 value = factor_c >> 5;
1771                 factor_c += b;
1772                 CLIP_RESULT(value)
1773                 byte3 = value;
1774                 value = factor_c >> 5;
1775                 factor_c += b;
1776                 CLIP_RESULT(value)
1777                 temp = byte1 | (byte2 << 8);
1778                 temp |= (byte3 << 16);
1779                 temp |= (value << 24);
1780                 *((uint32*)(pred + 4)) = temp;
1781                 pred += pred_pitch;
1782             }
1783         }
1784         pred = predCr; /* point to cr */
1785     }
1786 }
1787 
1788