PageRenderTime 58ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/Avc/mb_access.cpp

http://github.com/mbebenita/Broadway
C++ | 471 lines | 379 code | 54 blank | 38 comment | 99 complexity | d9b7dcf8927defa147d8dcd8ca4821bb 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 <string.h>
  19. #include "avclib_common.h"
  20. OSCL_EXPORT_REF void InitNeighborAvailability(AVCCommonObj *video, int mbNum)
  21. {
  22. int PicWidthInMbs = video->PicWidthInMbs;
  23. // do frame-only and postpone intraAvail calculattion
  24. video->mbAddrA = mbNum - 1;
  25. video->mbAddrB = mbNum - PicWidthInMbs;
  26. video->mbAddrC = mbNum - PicWidthInMbs + 1;
  27. video->mbAddrD = mbNum - PicWidthInMbs - 1;
  28. video->mbAvailA = video->mbAvailB = video->mbAvailC = video->mbAvailD = 0;
  29. if (video->mb_x)
  30. {
  31. video->mbAvailA = (video->mblock[video->mbAddrA].slice_id == video->currMB->slice_id);
  32. if (video->mb_y)
  33. {
  34. video->mbAvailD = (video->mblock[video->mbAddrD].slice_id == video->currMB->slice_id);
  35. }
  36. }
  37. if (video->mb_y)
  38. {
  39. video->mbAvailB = (video->mblock[video->mbAddrB].slice_id == video->currMB->slice_id);
  40. if (video->mb_x < (PicWidthInMbs - 1))
  41. {
  42. video->mbAvailC = (video->mblock[video->mbAddrC].slice_id == video->currMB->slice_id);
  43. }
  44. }
  45. return ;
  46. }
  47. bool mb_is_available(AVCMacroblock *mblock, uint PicSizeInMbs, int mbAddr, int currMbAddr)
  48. {
  49. if (mbAddr < 0 || mbAddr >= (int)PicSizeInMbs)
  50. {
  51. return FALSE;
  52. }
  53. if (mblock[mbAddr].slice_id != mblock[currMbAddr].slice_id)
  54. {
  55. return FALSE;
  56. }
  57. return TRUE;
  58. }
  59. OSCL_EXPORT_REF int predict_nnz(AVCCommonObj *video, int i, int j)
  60. {
  61. int pred_nnz = 0;
  62. int cnt = 1;
  63. AVCMacroblock *tempMB;
  64. /* left block */
  65. /*getLuma4x4Neighbour(video, mb_nr, i, j, -1, 0, &pix);
  66. leftMB = video->mblock + pix.mb_addr; */
  67. /* replace the above with below (won't work for field decoding), 1/19/04 */
  68. if (i)
  69. {
  70. pred_nnz = video->currMB->nz_coeff[(j<<2)+i-1];
  71. }
  72. else
  73. {
  74. if (video->mbAvailA)
  75. {
  76. tempMB = video->mblock + video->mbAddrA;
  77. pred_nnz = tempMB->nz_coeff[(j<<2)+3];
  78. }
  79. else
  80. {
  81. cnt = 0;
  82. }
  83. }
  84. /* top block */
  85. /*getLuma4x4Neighbour(video, mb_nr, i, j, 0, -1, &pix);
  86. topMB = video->mblock + pix.mb_addr;*/
  87. /* replace the above with below (won't work for field decoding), 1/19/04 */
  88. if (j)
  89. {
  90. pred_nnz += video->currMB->nz_coeff[((j-1)<<2)+i];
  91. cnt++;
  92. }
  93. else
  94. {
  95. if (video->mbAvailB)
  96. {
  97. tempMB = video->mblock + video->mbAddrB;
  98. pred_nnz += tempMB->nz_coeff[12+i];
  99. cnt++;
  100. }
  101. }
  102. if (cnt == 2)
  103. {
  104. pred_nnz = (pred_nnz + 1) >> 1;
  105. }
  106. return pred_nnz;
  107. }
  108. OSCL_EXPORT_REF int predict_nnz_chroma(AVCCommonObj *video, int i, int j)
  109. {
  110. int pred_nnz = 0;
  111. int cnt = 1;
  112. AVCMacroblock *tempMB;
  113. /* left block */
  114. /*getChroma4x4Neighbour(video, mb_nr, i%2, j-4, -1, 0, &pix);
  115. leftMB = video->mblock + pix.mb_addr;*/
  116. /* replace the above with below (won't work for field decoding), 1/19/04 */
  117. if (i&1)
  118. {
  119. pred_nnz = video->currMB->nz_coeff[(j<<2)+i-1];
  120. }
  121. else
  122. {
  123. if (video->mbAvailA)
  124. {
  125. tempMB = video->mblock + video->mbAddrA;
  126. pred_nnz = tempMB->nz_coeff[(j<<2)+i+1];
  127. }
  128. else
  129. {
  130. cnt = 0;
  131. }
  132. }
  133. /* top block */
  134. /*getChroma4x4Neighbour(video, mb_nr, i%2, j-4, 0, -1, &pix);
  135. topMB = video->mblock + pix.mb_addr;*/
  136. /* replace the above with below (won't work for field decoding), 1/19/04 */
  137. if (j&1)
  138. {
  139. pred_nnz += video->currMB->nz_coeff[((j-1)<<2)+i];
  140. cnt++;
  141. }
  142. else
  143. {
  144. if (video->mbAvailB)
  145. {
  146. tempMB = video->mblock + video->mbAddrB;
  147. pred_nnz += tempMB->nz_coeff[20+i];
  148. cnt++;
  149. }
  150. }
  151. if (cnt == 2)
  152. {
  153. pred_nnz = (pred_nnz + 1) >> 1;
  154. }
  155. return pred_nnz;
  156. }
  157. OSCL_EXPORT_REF void GetMotionVectorPredictor(AVCCommonObj *video, int encFlag)
  158. {
  159. AVCMacroblock *currMB = video->currMB;
  160. AVCMacroblock *MB_A, *MB_B, *MB_C, *MB_D;
  161. int block_x, block_y, block_x_1, block_y_1, new_block_x;
  162. int mbPartIdx, subMbPartIdx, offset_indx;
  163. int16 *mv, pmv_x, pmv_y;
  164. int nmSubMbHeight, nmSubMbWidth, mbPartIdx_X, mbPartIdx_Y;
  165. int avail_a, avail_b, avail_c;
  166. const static uint32 C = 0x5750;
  167. int i, j, offset_MbPart_indx, refIdxLXA, refIdxLXB, refIdxLXC = 0, curr_ref_idx;
  168. int pmv_A_x, pmv_B_x, pmv_C_x = 0, pmv_A_y, pmv_B_y, pmv_C_y = 0;
  169. /* we have to take care of Intra/skip blocks somewhere, i.e. set MV to 0 and set ref to -1! */
  170. /* we have to populate refIdx as well */
  171. MB_A = &video->mblock[video->mbAddrA];
  172. MB_B = &video->mblock[video->mbAddrB];
  173. if (currMB->mbMode == AVC_SKIP /* && !encFlag */) /* only for decoder */
  174. {
  175. currMB->ref_idx_L0[0] = currMB->ref_idx_L0[1] = currMB->ref_idx_L0[2] = currMB->ref_idx_L0[3] = 0;
  176. if (video->mbAvailA && video->mbAvailB)
  177. {
  178. if ((MB_A->ref_idx_L0[1] == 0 && MB_A->mvL0[3] == 0) ||
  179. (MB_B->ref_idx_L0[2] == 0 && MB_B->mvL0[12] == 0))
  180. {
  181. memset(currMB->mvL0, 0, sizeof(int32)*16);
  182. return;
  183. }
  184. }
  185. else
  186. {
  187. memset(currMB->mvL0, 0, sizeof(int32)*16);
  188. return;
  189. }
  190. video->mvd_l0[0][0][0] = 0;
  191. video->mvd_l0[0][0][1] = 0;
  192. }
  193. MB_C = &video->mblock[video->mbAddrC];
  194. MB_D = &video->mblock[video->mbAddrD];
  195. offset_MbPart_indx = 0;
  196. for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++)
  197. {
  198. offset_indx = 0;
  199. nmSubMbHeight = currMB->SubMbPartHeight[mbPartIdx] >> 2;
  200. nmSubMbWidth = currMB->SubMbPartWidth[mbPartIdx] >> 2;
  201. mbPartIdx_X = ((mbPartIdx + offset_MbPart_indx) & 1) << 1;
  202. mbPartIdx_Y = (mbPartIdx + offset_MbPart_indx) & 2;
  203. for (subMbPartIdx = 0; subMbPartIdx < currMB->NumSubMbPart[mbPartIdx]; subMbPartIdx++)
  204. {
  205. block_x = mbPartIdx_X + ((subMbPartIdx + offset_indx) & 1);
  206. block_y = mbPartIdx_Y + (((subMbPartIdx + offset_indx) >> 1) & 1);
  207. block_x_1 = block_x - 1;
  208. block_y_1 = block_y - 1;
  209. refIdxLXA = refIdxLXB = refIdxLXC = -1;
  210. pmv_A_x = pmv_A_y = pmv_B_x = pmv_B_y = pmv_C_x = pmv_C_y = 0;
  211. if (block_x)
  212. {
  213. avail_a = 1;
  214. refIdxLXA = currMB->ref_idx_L0[(block_y & 2) + (block_x_1 >> 1)];
  215. mv = (int16*)(currMB->mvL0 + (block_y << 2) + block_x_1);
  216. pmv_A_x = *mv++;
  217. pmv_A_y = *mv;
  218. }
  219. else
  220. {
  221. avail_a = video->mbAvailA;
  222. if (avail_a)
  223. {
  224. refIdxLXA = MB_A->ref_idx_L0[(block_y & 2) + 1];
  225. mv = (int16*)(MB_A->mvL0 + (block_y << 2) + 3);
  226. pmv_A_x = *mv++;
  227. pmv_A_y = *mv;
  228. }
  229. }
  230. if (block_y)
  231. {
  232. avail_b = 1;
  233. refIdxLXB = currMB->ref_idx_L0[(block_y_1 & 2) + (block_x >> 1)];
  234. mv = (int16*)(currMB->mvL0 + (block_y_1 << 2) + block_x);
  235. pmv_B_x = *mv++;
  236. pmv_B_y = *mv;
  237. }
  238. else
  239. {
  240. avail_b = video->mbAvailB;
  241. if (avail_b)
  242. {
  243. refIdxLXB = MB_B->ref_idx_L0[2 + (block_x >> 1)];
  244. mv = (int16*)(MB_B->mvL0 + 12 + block_x);
  245. pmv_B_x = *mv++;
  246. pmv_B_y = *mv;
  247. }
  248. }
  249. new_block_x = block_x + (currMB->SubMbPartWidth[mbPartIdx] >> 2) - 1;
  250. avail_c = (C >> ((block_y << 2) + new_block_x)) & 0x1;
  251. if (avail_c)
  252. {
  253. /* it guaranteed that block_y > 0 && new_block_x<3 ) */
  254. refIdxLXC = currMB->ref_idx_L0[(block_y_1 & 2) + ((new_block_x+1) >> 1)];
  255. mv = (int16*)(currMB->mvL0 + (block_y_1 << 2) + (new_block_x + 1));
  256. pmv_C_x = *mv++;
  257. pmv_C_y = *mv;
  258. }
  259. else
  260. {
  261. if (block_y == 0 && new_block_x < 3)
  262. {
  263. avail_c = video->mbAvailB;
  264. if (avail_c)
  265. {
  266. refIdxLXC = MB_B->ref_idx_L0[2 + ((new_block_x+1)>>1)];
  267. mv = (int16*)(MB_B->mvL0 + 12 + (new_block_x + 1));
  268. pmv_C_x = *mv++;
  269. pmv_C_y = *mv;
  270. }
  271. }
  272. else if (block_y == 0 && new_block_x == 3)
  273. {
  274. avail_c = video->mbAvailC;
  275. if (avail_c)
  276. {
  277. refIdxLXC = MB_C->ref_idx_L0[2];
  278. mv = (int16*)(MB_C->mvL0 + 12);
  279. pmv_C_x = *mv++;
  280. pmv_C_y = *mv;
  281. }
  282. }
  283. if (avail_c == 0)
  284. { /* check D */
  285. if (block_x && block_y)
  286. {
  287. avail_c = 1;
  288. refIdxLXC = currMB->ref_idx_L0[(block_y_1 & 2) + (block_x_1 >> 1)];
  289. mv = (int16*)(currMB->mvL0 + (block_y_1 << 2) + block_x_1);
  290. pmv_C_x = *mv++;
  291. pmv_C_y = *mv;
  292. }
  293. else if (block_y)
  294. {
  295. avail_c = video->mbAvailA;
  296. if (avail_c)
  297. {
  298. refIdxLXC = MB_A->ref_idx_L0[(block_y_1 & 2) + 1];
  299. mv = (int16*)(MB_A->mvL0 + (block_y_1 << 2) + 3);
  300. pmv_C_x = *mv++;
  301. pmv_C_y = *mv;
  302. }
  303. }
  304. else if (block_x)
  305. {
  306. avail_c = video->mbAvailB;
  307. if (avail_c)
  308. {
  309. refIdxLXC = MB_B->ref_idx_L0[2 + (block_x_1 >> 1)];
  310. mv = (int16*)(MB_B->mvL0 + 12 + block_x_1);
  311. pmv_C_x = *mv++;
  312. pmv_C_y = *mv;
  313. }
  314. }
  315. else
  316. {
  317. avail_c = video->mbAvailD;
  318. if (avail_c)
  319. {
  320. refIdxLXC = MB_D->ref_idx_L0[3];
  321. mv = (int16*)(MB_D->mvL0 + 15);
  322. pmv_C_x = *mv++;
  323. pmv_C_y = *mv;
  324. }
  325. }
  326. }
  327. }
  328. offset_indx = currMB->SubMbPartWidth[mbPartIdx] >> 3;
  329. curr_ref_idx = currMB->ref_idx_L0[(block_y & 2) + (block_x >> 1)];
  330. if (avail_a && !(avail_b || avail_c))
  331. {
  332. pmv_x = pmv_A_x;
  333. pmv_y = pmv_A_y;
  334. }
  335. else if (((curr_ref_idx == refIdxLXA) + (curr_ref_idx == refIdxLXB) + (curr_ref_idx == refIdxLXC)) == 1)
  336. {
  337. if (curr_ref_idx == refIdxLXA)
  338. {
  339. pmv_x = pmv_A_x;
  340. pmv_y = pmv_A_y;
  341. }
  342. else if (curr_ref_idx == refIdxLXB)
  343. {
  344. pmv_x = pmv_B_x;
  345. pmv_y = pmv_B_y;
  346. }
  347. else
  348. {
  349. pmv_x = pmv_C_x;
  350. pmv_y = pmv_C_y;
  351. }
  352. }
  353. else
  354. {
  355. pmv_x = AVC_MEDIAN(pmv_A_x, pmv_B_x, pmv_C_x);
  356. pmv_y = AVC_MEDIAN(pmv_A_y, pmv_B_y, pmv_C_y);
  357. }
  358. /* overwrite if special case */
  359. if (currMB->NumMbPart == 2)
  360. {
  361. if (currMB->MbPartWidth == 16)
  362. {
  363. if (mbPartIdx == 0)
  364. {
  365. if (refIdxLXB == curr_ref_idx)
  366. {
  367. pmv_x = pmv_B_x;
  368. pmv_y = pmv_B_y;
  369. }
  370. }
  371. else if (refIdxLXA == curr_ref_idx)
  372. {
  373. pmv_x = pmv_A_x;
  374. pmv_y = pmv_A_y;
  375. }
  376. }
  377. else
  378. {
  379. if (mbPartIdx == 0)
  380. {
  381. if (refIdxLXA == curr_ref_idx)
  382. {
  383. pmv_x = pmv_A_x;
  384. pmv_y = pmv_A_y;
  385. }
  386. }
  387. else if (refIdxLXC == curr_ref_idx)
  388. {
  389. pmv_x = pmv_C_x;
  390. pmv_y = pmv_C_y;
  391. }
  392. }
  393. }
  394. mv = (int16*)(currMB->mvL0 + block_x + (block_y << 2));
  395. if (encFlag) /* calculate residual MV video->mvd_l0 */
  396. {
  397. video->mvd_l0[mbPartIdx][subMbPartIdx][0] = *mv++ - pmv_x;
  398. video->mvd_l0[mbPartIdx][subMbPartIdx][1] = *mv++ - pmv_y;
  399. }
  400. else /* calculate original MV currMB->mvL0 */
  401. {
  402. pmv_x += video->mvd_l0[mbPartIdx][subMbPartIdx][0];
  403. pmv_y += video->mvd_l0[mbPartIdx][subMbPartIdx][1];
  404. for (i = 0; i < nmSubMbHeight; i++)
  405. {
  406. for (j = 0; j < nmSubMbWidth; j++)
  407. {
  408. *mv++ = pmv_x;
  409. *mv++ = pmv_y;
  410. }
  411. mv += (8 - (j << 1));
  412. }
  413. }
  414. }
  415. offset_MbPart_indx = currMB->MbPartWidth >> 4;
  416. }
  417. }