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