PageRenderTime 537ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/Avc/pred_intra.cpp

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