1
0

mp4decvopb.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. /* ///////////////////////////////////////////////////////////////////////
  2. //
  3. // INTEL CORPORATION PROPRIETARY INFORMATION
  4. // This software is supplied under the terms of a license agreement or
  5. // nondisclosure agreement with Intel Corporation and may not be copied
  6. // or disclosed except in accordance with the terms of that agreement.
  7. // Copyright (c) 2001-2007 Intel Corporation. All Rights Reserved.
  8. //
  9. // Description: Decodes B-VOPs
  10. //
  11. */
  12. #include "mp4def.h"
  13. #include "mp4dec.h"
  14. /*
  15. // Purpose: decode MPEG-4 BVOP
  16. */
  17. mp4_Status mp4_DecodeVOP_B(mp4_Info* pInfo)
  18. {
  19. __ALIGN16(int16_t, coeffMB, 64*6);
  20. __ALIGN16(uint8_t, tmpMB, 64*4);
  21. uint32_t code;
  22. uint8_t *pYc, *pCbc, *pCrc, *pYp, *pCbp, *pCrp, *pYn, *pCbn, *pCrn, *pc, *pr, *pn;
  23. int32_t stepYp, stepYc, stepYn, stepCbp, stepCbc, stepCbn, stepCrp, stepCrc, stepCrn, mbPerRow, mbPerCol;
  24. int32_t dx, dy, TRB, TRD, quant, mbCurr, mbInVideoPacket, colNum, rowNum;
  25. IppiRect limitRectL, limitRectC;
  26. int32_t quarter_sample, modb, mb_type, cbpb, dct_type, field_prediction, rvlc = 0, scan;
  27. int32_t mb_ftfr, mb_fbfr, mb_btfr, mb_bbfr, fcode_forward, fcode_backward;
  28. mp4_MacroBlock *pMBinfo;
  29. mp4_Status sts;
  30. sts = MP4_STATUS_OK;
  31. if (!pInfo->VisualObject.cFrame)
  32. pInfo->VisualObject.cFrame = CreateFrame(&pInfo->VisualObject);
  33. stepYc = pInfo->VisualObject.cFrame->stepY;
  34. stepYp = pInfo->VisualObject.rFrame->stepY;
  35. stepYn = pInfo->VisualObject.nFrame->stepY;
  36. stepCbc = pInfo->VisualObject.cFrame->stepCb;
  37. stepCbp = pInfo->VisualObject.rFrame->stepCb;
  38. stepCbn = pInfo->VisualObject.nFrame->stepCb;
  39. stepCrc = pInfo->VisualObject.cFrame->stepCr;
  40. stepCrp = pInfo->VisualObject.rFrame->stepCr;
  41. stepCrn = pInfo->VisualObject.nFrame->stepCr;
  42. pYc = pInfo->VisualObject.cFrame->pY;
  43. pCbc = pInfo->VisualObject.cFrame->pCb;
  44. pCrc = pInfo->VisualObject.cFrame->pCr;
  45. pYp = pInfo->VisualObject.rFrame->pY;
  46. pCbp = pInfo->VisualObject.rFrame->pCb;
  47. pCrp = pInfo->VisualObject.rFrame->pCr;
  48. pYn = pInfo->VisualObject.nFrame->pY;
  49. pCbn = pInfo->VisualObject.nFrame->pCb;
  50. pCrn = pInfo->VisualObject.nFrame->pCr;
  51. quarter_sample = pInfo->VisualObject.VideoObject.quarter_sample;
  52. scan = pInfo->VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag ? IPPVC_SCAN_VERTICAL : IPPVC_SCAN_ZIGZAG;
  53. fcode_forward = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
  54. fcode_backward = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_backward;
  55. // Bounding rectangles for MV limitation
  56. limitRectL.x = - 16 * MP4_NUM_EXT_MB;
  57. limitRectL.y = - 16 * MP4_NUM_EXT_MB;
  58. limitRectL.width = pInfo->VisualObject.VideoObject.width + 16 * 2 * MP4_NUM_EXT_MB;
  59. limitRectL.height = pInfo->VisualObject.VideoObject.height + 16 * 2 * MP4_NUM_EXT_MB;
  60. limitRectC.x = -8 * MP4_NUM_EXT_MB;
  61. limitRectC.y = -8 * MP4_NUM_EXT_MB;
  62. limitRectC.width = (pInfo->VisualObject.VideoObject.width >> 1) + 8 * 2 * MP4_NUM_EXT_MB;
  63. limitRectC.height = (pInfo->VisualObject.VideoObject.height >> 1) + 8 * 2 * MP4_NUM_EXT_MB;
  64. quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant;
  65. mbPerRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
  66. mbPerCol = pInfo->VisualObject.VideoObject.MacroBlockPerCol;
  67. mbCurr = colNum = rowNum = 0;
  68. TRD = pInfo->VisualObject.VideoObject.TRD;
  69. TRB = pInfo->VisualObject.VideoObject.TRB;
  70. pMBinfo = pInfo->VisualObject.VideoObject.MBinfo;
  71. // decode interlaced B-VOP
  72. if (pInfo->VisualObject.VideoObject.interlaced) {
  73. IppMotionVector mvCbCrF, mvCbCrB, mvForwT, mvBackT, mvForwB, mvBackB, mvForw[4], mvBack[4], mvCbCrFFT, mvCbCrFFB, mvCbCrBFT, mvCbCrBFB, *mvField = pInfo->VisualObject.VideoObject.FieldMV;
  74. // warning "variable may be used without having been initialized"
  75. mvCbCrF.dx = mvCbCrF.dy = mvCbCrB.dx = mvCbCrB.dy = mvCbCrFFT.dx = mvCbCrFFT.dy = mvCbCrFFB.dx = mvCbCrFFB.dy = mvCbCrBFT.dx = mvCbCrBFT.dy = mvCbCrBFB.dx = mvCbCrBFB.dy = 0;
  76. mb_ftfr = mb_fbfr = mb_btfr = mb_bbfr = 0;
  77. for (;;) {
  78. mbInVideoPacket = 0;
  79. // reset MV predictors at new VideoPacket
  80. mvForwT.dx = mvForwT.dy = mvBackT.dx = mvBackT.dy = mvForwB.dx = mvForwB.dy = mvBackB.dx = mvBackB.dy = 0;
  81. // decode B-VOP macroblocks
  82. for (;;) {
  83. if (pMBinfo->not_coded) {
  84. ippiCopy16x16_8u_C1R(pYp, stepYp, pYc, stepYc);
  85. ippiCopy8x8_8u_C1R(pCbp, stepCbp, pCbc, stepCbc);
  86. ippiCopy8x8_8u_C1R(pCrp, stepCrp, pCrc, stepCrc);
  87. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_NOTCODED);
  88. } else {
  89. cbpb = 0;
  90. if (mp4_GetBit(pInfo)) {
  91. modb = 2;
  92. mb_type = IPPVC_MBTYPE_DIRECT;
  93. } else {
  94. modb = mp4_GetBit(pInfo);
  95. // decode mb_type
  96. code = mp4_ShowBits9(pInfo, 4);
  97. if (code != 0) {
  98. mb_type = mp4_BVOPmb_type[code].code;
  99. mp4_FlushBits(pInfo, mp4_BVOPmb_type[code].len);
  100. } else {
  101. mp4_Error("Error when decode mb_type of B-VOP macroblock");
  102. goto Err_1;
  103. }
  104. if (modb == 0)
  105. cbpb = mp4_GetBits9(pInfo, 6);
  106. if (mb_type != IPPVC_MBTYPE_DIRECT && cbpb != 0)
  107. mp4_UpdateQuant_B(pInfo, quant);
  108. }
  109. dct_type = 0;
  110. field_prediction = 0;
  111. if (cbpb != 0)
  112. dct_type = mp4_GetBit(pInfo);
  113. if (mb_type != IPPVC_MBTYPE_DIRECT) {
  114. field_prediction = mp4_GetBit(pInfo);
  115. if (field_prediction) {
  116. if (mb_type != IPPVC_MBTYPE_BACKWARD) {
  117. mb_ftfr = mp4_GetBit(pInfo);
  118. mb_fbfr = mp4_GetBit(pInfo);
  119. }
  120. if (mb_type != IPPVC_MBTYPE_FORWARD) {
  121. mb_btfr = mp4_GetBit(pInfo);
  122. mb_bbfr = mp4_GetBit(pInfo);
  123. }
  124. }
  125. }
  126. // coordinates of current MB for limitation
  127. dx = colNum * 16;
  128. dy = rowNum * 16;
  129. if (mb_type == IPPVC_MBTYPE_FORWARD) {
  130. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_FORWARD);
  131. if (!field_prediction) {
  132. if (mp4_DecodeMV(pInfo, &mvForwT, fcode_forward) != MP4_STATUS_OK)
  133. goto Err_1;
  134. if (quarter_sample) {
  135. mp4_LimitMVQ(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
  136. mp4_ComputeChromaMVQ(&mvForw[0], &mvCbCrF);
  137. mp4_Copy16x16QP_8u(pYp, stepYp, pYc, stepYc, &mvForw[0], 0);
  138. } else {
  139. mp4_LimitMV(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
  140. mp4_ComputeChromaMV(&mvForw[0], &mvCbCrF);
  141. mp4_Copy16x16HP_8u(pYp, stepYp, pYc, stepYc, &mvForw[0], 0);
  142. }
  143. //mvForw[1] = mvForw[2] = mvForw[3] = mvForw[0];
  144. mvForwB = mvForwT;
  145. } else {
  146. mvForwT.dy = (int16_t)mp4_Div2(mvForwT.dy);
  147. if (mp4_DecodeMV(pInfo, &mvForwT, fcode_forward) != MP4_STATUS_OK)
  148. goto Err_1;
  149. mvForwB.dy = (int16_t)mp4_Div2(mvForwB.dy);
  150. if (mp4_DecodeMV(pInfo, &mvForwB, fcode_forward) != MP4_STATUS_OK)
  151. goto Err_1;
  152. if (quarter_sample) {
  153. mp4_LimitFMVQ(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
  154. mp4_Copy16x8QP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
  155. mvForw[0].dx = (int16_t)mp4_Div2(mvForw[0].dx);
  156. mvForw[0].dy = (int16_t)(mp4_Div2(mvForw[0].dy*2) >> 1);
  157. mp4_LimitFMVQ(&mvForwB, &mvForw[2], &limitRectL, dx, dy, 16);
  158. mp4_Copy16x8QP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
  159. mvForw[2].dx = (int16_t)mp4_Div2(mvForw[2].dx);
  160. mvForw[2].dy = (int16_t)(mp4_Div2(mvForw[2].dy*2) >> 1);
  161. } else {
  162. mp4_LimitFMV(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
  163. mp4_Copy16x8HP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
  164. mp4_LimitFMV(&mvForwB, &mvForw[2], &limitRectL, dx, dy, 16);
  165. mp4_Copy16x8HP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
  166. }
  167. mvForwT.dy <<= 1;
  168. mvForwB.dy <<= 1;
  169. //mvForw[1] = mvForw[0];
  170. //mvForw[3] = mvForw[2];
  171. mp4_ComputeChromaMV(&mvForw[0], &mvCbCrFFT);
  172. mp4_ComputeChromaMV(&mvForw[2], &mvCbCrFFB);
  173. }
  174. if (mp4_DecodeInterMB(pInfo, coeffMB, quant, cbpb, scan) != MP4_STATUS_OK)
  175. goto Err_1;
  176. if (!dct_type) {
  177. mp4_AddResidual(cbpb & 32, pYc, stepYc, coeffMB);
  178. mp4_AddResidual(cbpb & 16, pYc+8, stepYc, coeffMB+64);
  179. mp4_AddResidual(cbpb & 8, pYc+stepYc*8, stepYc, coeffMB+128);
  180. mp4_AddResidual(cbpb & 4, pYc+stepYc*8+8, stepYc, coeffMB+192);
  181. } else {
  182. mp4_AddResidual(cbpb & 32, pYc, stepYc*2, coeffMB);
  183. mp4_AddResidual(cbpb & 16, pYc+8, stepYc*2, coeffMB+64);
  184. mp4_AddResidual(cbpb & 8, pYc+stepYc, stepYc*2, coeffMB+128);
  185. mp4_AddResidual(cbpb & 4, pYc+stepYc+8, stepYc*2, coeffMB+192);
  186. }
  187. if (!field_prediction) {
  188. mp4_MC_HP(cbpb & 2, pCbp, stepCbp, pCbc, stepCbc, coeffMB+256, &mvCbCrF, 0);
  189. mp4_MC_HP(cbpb & 1, pCrp, stepCrp, pCrc, stepCrc, coeffMB+320, &mvCbCrF, 0);
  190. } else {
  191. mp4_Copy8x4HP_8u(pCbp+(mb_ftfr ? stepCbp : 0), stepCbp*2, pCbc, stepCbc*2, &mvCbCrFFT, 0);
  192. mp4_Copy8x4HP_8u(pCrp+(mb_ftfr ? stepCrp : 0), stepCrp*2, pCrc, stepCrc*2, &mvCbCrFFT, 0);
  193. mp4_Copy8x4HP_8u(pCbp+(mb_fbfr ? stepCbp : 0), stepCbp*2, pCbc+stepCbc, stepCbc*2, &mvCbCrFFB, 0);
  194. mp4_Copy8x4HP_8u(pCrp+(mb_fbfr ? stepCrp : 0), stepCrp*2, pCrc+stepCrc, stepCrc*2, &mvCbCrFFB, 0);
  195. mp4_AddResidual(cbpb & 2, pCbc, stepCbc, coeffMB+256);
  196. mp4_AddResidual(cbpb & 1, pCrc, stepCrc, coeffMB+320);
  197. }
  198. } else if (mb_type == IPPVC_MBTYPE_BACKWARD) {
  199. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_BACKWARD);
  200. if (!field_prediction) {
  201. if (mp4_DecodeMV(pInfo, &mvBackT, fcode_backward) != MP4_STATUS_OK)
  202. goto Err_1;
  203. if (quarter_sample) {
  204. mp4_LimitMVQ(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
  205. mp4_ComputeChromaMVQ(&mvBack[0], &mvCbCrB);
  206. mp4_Copy16x16QP_8u(pYn, stepYn, pYc, stepYc, &mvBack[0], 0);
  207. } else {
  208. mp4_LimitMV(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
  209. mp4_ComputeChromaMV(&mvBack[0], &mvCbCrB);
  210. mp4_Copy16x16HP_8u(pYn, stepYn, pYc, stepYc, &mvBack[0], 0);
  211. }
  212. //mvBack[1] = mvBack[2] = mvBack[3] = mvBack[0];
  213. mvBackB = mvBackT;
  214. } else {
  215. mvBackT.dy = (int16_t)mp4_Div2(mvBackT.dy);
  216. if (mp4_DecodeMV(pInfo, &mvBackT, fcode_backward) != MP4_STATUS_OK)
  217. goto Err_1;
  218. mvBackB.dy = (int16_t)mp4_Div2(mvBackB.dy);
  219. if (mp4_DecodeMV(pInfo, &mvBackB, fcode_backward) != MP4_STATUS_OK)
  220. goto Err_1;
  221. if (quarter_sample) {
  222. mp4_LimitFMVQ(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
  223. mp4_Copy16x8QP_8u(pYn+(mb_btfr ? stepYn : 0), stepYn*2, pYc, stepYc*2, &mvBack[0], 0);
  224. mvBack[0].dx = (int16_t)mp4_Div2(mvBack[0].dx);
  225. mvBack[0].dy = (int16_t)(mp4_Div2(mvBack[0].dy*2) >> 1);
  226. mp4_LimitFMVQ(&mvBackB, &mvBack[2], &limitRectL, dx, dy, 16);
  227. mp4_Copy16x8QP_8u(pYn+(mb_bbfr ? stepYn : 0), stepYn*2, pYc+stepYc, stepYc*2, &mvBack[2], 0);
  228. mvBack[2].dx = (int16_t)mp4_Div2(mvBack[2].dx);
  229. mvBack[2].dy = (int16_t)(mp4_Div2(mvBack[2].dy*2) >> 1);
  230. } else {
  231. mp4_LimitFMV(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
  232. mp4_Copy16x8HP_8u(pYn+(mb_btfr ? stepYn : 0), stepYn*2, pYc, stepYc*2, &mvBack[0], 0);
  233. mp4_LimitFMV(&mvBackB, &mvBack[2], &limitRectL, dx, dy, 16);
  234. mp4_Copy16x8HP_8u(pYn+(mb_bbfr ? stepYn : 0), stepYn*2, pYc+stepYc, stepYc*2, &mvBack[2], 0);
  235. }
  236. mvBackT.dy <<= 1;
  237. mvBackB.dy <<= 1;
  238. //mvBack[1] = mvBack[0];
  239. //mvBack[3] = mvBack[2];
  240. mp4_ComputeChromaMV(&mvBack[0], &mvCbCrBFT);
  241. mp4_ComputeChromaMV(&mvBack[2], &mvCbCrBFB);
  242. }
  243. if (mp4_DecodeInterMB(pInfo, coeffMB, quant, cbpb, scan) != MP4_STATUS_OK)
  244. goto Err_1;
  245. if (!dct_type) {
  246. mp4_AddResidual(cbpb & 32, pYc, stepYc, coeffMB);
  247. mp4_AddResidual(cbpb & 16, pYc+8, stepYc, coeffMB+64);
  248. mp4_AddResidual(cbpb & 8, pYc+stepYc*8, stepYc, coeffMB+128);
  249. mp4_AddResidual(cbpb & 4, pYc+stepYc*8+8, stepYc, coeffMB+192);
  250. } else {
  251. mp4_AddResidual(cbpb & 32, pYc, stepYc*2, coeffMB);
  252. mp4_AddResidual(cbpb & 16, pYc+8, stepYc*2, coeffMB+64);
  253. mp4_AddResidual(cbpb & 8, pYc+stepYc, stepYc*2, coeffMB+128);
  254. mp4_AddResidual(cbpb & 4, pYc+stepYc+8, stepYc*2, coeffMB+192);
  255. }
  256. if (!field_prediction) {
  257. mp4_MC_HP(cbpb & 2, pCbn, stepCbn, pCbc, stepCbc, coeffMB+256, &mvCbCrB, 0);
  258. mp4_MC_HP(cbpb & 1, pCrn, stepCrn, pCrc, stepCrc, coeffMB+320, &mvCbCrB, 0);
  259. } else {
  260. mp4_Copy8x4HP_8u(pCbn+(mb_btfr ? stepCbn : 0), stepCbn*2, pCbc, stepCbc*2, &mvCbCrBFT, 0);
  261. mp4_Copy8x4HP_8u(pCrn+(mb_btfr ? stepCrn : 0), stepCrn*2, pCrc, stepCrc*2, &mvCbCrBFT, 0);
  262. mp4_Copy8x4HP_8u(pCbn+(mb_bbfr ? stepCbn : 0), stepCbn*2, pCbc+stepCbc, stepCbc*2, &mvCbCrBFB, 0);
  263. mp4_Copy8x4HP_8u(pCrn+(mb_bbfr ? stepCrn : 0), stepCrn*2, pCrc+stepCrc, stepCrc*2, &mvCbCrBFB, 0);
  264. mp4_AddResidual(cbpb & 2, pCbc, stepCbc, coeffMB+256);
  265. mp4_AddResidual(cbpb & 1, pCrc, stepCrc, coeffMB+320);
  266. }
  267. } else if (mb_type == IPPVC_MBTYPE_INTERPOLATE) {
  268. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTERPOLATE);
  269. if (!field_prediction) {
  270. if (mp4_DecodeMV(pInfo, &mvForwT, fcode_forward) != MP4_STATUS_OK)
  271. goto Err_1;
  272. if (mp4_DecodeMV(pInfo, &mvBackT, fcode_backward) != MP4_STATUS_OK)
  273. goto Err_1;
  274. if (quarter_sample) {
  275. mp4_LimitMVQ(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
  276. mp4_ComputeChromaMVQ(&mvForw[0], &mvCbCrF);
  277. mp4_Copy16x16QP_8u(pYp, stepYp, pYc, stepYc, &mvForw[0], 0);
  278. mp4_LimitMVQ(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
  279. mp4_ComputeChromaMVQ(&mvBack[0], &mvCbCrB);
  280. mp4_Copy16x16QP_8u(pYn, stepYn, tmpMB, 16, &mvBack[0], 0);
  281. } else {
  282. mp4_LimitMV(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
  283. mp4_ComputeChromaMV(&mvForw[0], &mvCbCrF);
  284. mp4_Copy16x16HP_8u(pYp, stepYp, pYc, stepYc, &mvForw[0], 0);
  285. mp4_LimitMV(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
  286. mp4_ComputeChromaMV(&mvBack[0], &mvCbCrB);
  287. mp4_Copy16x16HP_8u(pYn, stepYn, tmpMB, 16, &mvBack[0], 0);
  288. }
  289. //mvForw[1] = mvForw[2] = mvForw[3] = mvForw[0];
  290. mvForwB = mvForwT;
  291. //mvBack[1] = mvBack[2] = mvBack[3] = mvBack[0];
  292. mvBackB = mvBackT;
  293. } else {
  294. mvForwT.dy = (int16_t)mp4_Div2(mvForwT.dy);
  295. if (mp4_DecodeMV(pInfo, &mvForwT, fcode_forward) != MP4_STATUS_OK)
  296. goto Err_1;
  297. mvForwB.dy = (int16_t)mp4_Div2(mvForwB.dy);
  298. if (mp4_DecodeMV(pInfo, &mvForwB, fcode_forward) != MP4_STATUS_OK)
  299. goto Err_1;
  300. mvBackT.dy = (int16_t)mp4_Div2(mvBackT.dy);
  301. if (mp4_DecodeMV(pInfo, &mvBackT, fcode_backward) != MP4_STATUS_OK)
  302. goto Err_1;
  303. mvBackB.dy = (int16_t)mp4_Div2(mvBackB.dy);
  304. if (mp4_DecodeMV(pInfo, &mvBackB, fcode_backward) != MP4_STATUS_OK)
  305. goto Err_1;
  306. if (quarter_sample) {
  307. mp4_LimitFMVQ(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
  308. mp4_Copy16x8QP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
  309. mvForw[0].dx = (int16_t)mp4_Div2(mvForw[0].dx);
  310. mvForw[0].dy = (int16_t)(mp4_Div2(mvForw[0].dy*2) >> 1);
  311. mp4_LimitFMVQ(&mvForwB, &mvForw[2], &limitRectL, dx, dy, 16);
  312. mp4_Copy16x8QP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
  313. mvForw[2].dx = (int16_t)mp4_Div2(mvForw[2].dx);
  314. mvForw[2].dy = (int16_t)(mp4_Div2(mvForw[2].dy*2) >> 1);
  315. mp4_LimitFMVQ(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
  316. mp4_Copy16x8QP_8u(pYn+(mb_btfr ? stepYn : 0), stepYn*2, tmpMB, 32, &mvBack[0], 0);
  317. mvBack[0].dx = (int16_t)mp4_Div2(mvBack[0].dx);
  318. mvBack[0].dy = (int16_t)(mp4_Div2(mvBack[0].dy*2) >> 1);
  319. mp4_LimitFMVQ(&mvBackB, &mvBack[2], &limitRectL, dx, dy, 16);
  320. mp4_Copy16x8QP_8u(pYn+(mb_bbfr ? stepYn : 0), stepYn*2, tmpMB+16, 32, &mvBack[2], 0);
  321. mvBack[2].dx = (int16_t)mp4_Div2(mvBack[2].dx);
  322. mvBack[2].dy = (int16_t)(mp4_Div2(mvBack[2].dy*2) >> 1);
  323. } else {
  324. mp4_LimitFMV(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
  325. mp4_Copy16x8HP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
  326. mp4_LimitFMV(&mvForwB, &mvForw[2], &limitRectL, dx, dy, 16);
  327. mp4_Copy16x8HP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
  328. mp4_LimitFMV(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
  329. mp4_Copy16x8HP_8u(pYn+(mb_btfr ? stepYn : 0), stepYn*2, tmpMB, 32, &mvBack[0], 0);
  330. mp4_LimitFMV(&mvBackB, &mvBack[2], &limitRectL, dx, dy, 16);
  331. mp4_Copy16x8HP_8u(pYn+(mb_bbfr ? stepYn : 0), stepYn*2, tmpMB+16, 32, &mvBack[2], 0);
  332. }
  333. mvForwT.dy <<= 1;
  334. mvForwB.dy <<= 1;
  335. mvBackT.dy <<= 1;
  336. mvBackB.dy <<= 1;
  337. //mvForw[1] = mvForw[0];
  338. //mvForw[3] = mvForw[2];
  339. //mvBack[1] = mvBack[0];
  340. //mvBack[3] = mvBack[2];
  341. mp4_ComputeChromaMV(&mvForw[0], &mvCbCrFFT);
  342. mp4_ComputeChromaMV(&mvForw[2], &mvCbCrFFB);
  343. mp4_ComputeChromaMV(&mvBack[0], &mvCbCrBFT);
  344. mp4_ComputeChromaMV(&mvBack[2], &mvCbCrBFB);
  345. }
  346. ippiAverage16x16_8u_C1IR(tmpMB, 16, pYc, stepYc);
  347. if (mp4_DecodeInterMB(pInfo, coeffMB, quant, cbpb, scan) != MP4_STATUS_OK)
  348. goto Err_1;
  349. if (!dct_type) {
  350. mp4_AddResidual(cbpb & 32, pYc, stepYc, coeffMB);
  351. mp4_AddResidual(cbpb & 16, pYc+8, stepYc, coeffMB+64);
  352. mp4_AddResidual(cbpb & 8, pYc+stepYc*8, stepYc, coeffMB+128);
  353. mp4_AddResidual(cbpb & 4, pYc+stepYc*8+8, stepYc, coeffMB+192);
  354. } else {
  355. mp4_AddResidual(cbpb & 32, pYc, stepYc*2, coeffMB);
  356. mp4_AddResidual(cbpb & 16, pYc+8, stepYc*2, coeffMB+64);
  357. mp4_AddResidual(cbpb & 8, pYc+stepYc, stepYc*2, coeffMB+128);
  358. mp4_AddResidual(cbpb & 4, pYc+stepYc+8, stepYc*2, coeffMB+192);
  359. }
  360. if (!field_prediction) {
  361. mp4_Copy8x8HP_8u(pCbp, stepCbp, pCbc, stepCbc, &mvCbCrF, 0);
  362. mp4_Copy8x8HP_8u(pCrp, stepCrp, pCrc, stepCrc, &mvCbCrF, 0);
  363. mp4_Copy8x8HP_8u(pCbn, stepCbn, tmpMB, 8, &mvCbCrB, 0);
  364. mp4_Copy8x8HP_8u(pCrn, stepCrn, tmpMB+64, 8, &mvCbCrB, 0);
  365. } else {
  366. mp4_Copy8x4HP_8u(pCbp+(mb_ftfr ? stepCbp : 0), stepCbp*2, pCbc, stepCbc*2, &mvCbCrFFT, 0);
  367. mp4_Copy8x4HP_8u(pCrp+(mb_ftfr ? stepCrp : 0), stepCrp*2, pCrc, stepCrc*2, &mvCbCrFFT, 0);
  368. mp4_Copy8x4HP_8u(pCbp+(mb_fbfr ? stepCbp : 0), stepCbp*2, pCbc+stepCbc, stepCbc*2, &mvCbCrFFB, 0);
  369. mp4_Copy8x4HP_8u(pCrp+(mb_fbfr ? stepCrp : 0), stepCrp*2, pCrc+stepCrc, stepCrc*2, &mvCbCrFFB, 0);
  370. mp4_Copy8x4HP_8u(pCbn+(mb_btfr ? stepCbn : 0), stepCbn*2, tmpMB, 16, &mvCbCrBFT, 0);
  371. mp4_Copy8x4HP_8u(pCrn+(mb_btfr ? stepCrn : 0), stepCrn*2, tmpMB+64, 16, &mvCbCrBFT, 0);
  372. mp4_Copy8x4HP_8u(pCbn+(mb_bbfr ? stepCbn : 0), stepCbn*2, tmpMB+8, 16, &mvCbCrBFB, 0);
  373. mp4_Copy8x4HP_8u(pCrn+(mb_bbfr ? stepCrn : 0), stepCrn*2, tmpMB+64+8, 16, &mvCbCrBFB, 0);
  374. }
  375. ippiAverage8x8_8u_C1IR(tmpMB, 8, pCbc, stepCbc);
  376. ippiAverage8x8_8u_C1IR(tmpMB+64, 8, pCrc, stepCrc);
  377. mp4_AddResidual(cbpb & 2, pCbc, stepCbc, coeffMB+256);
  378. mp4_AddResidual(cbpb & 1, pCrc, stepCrc, coeffMB+320);
  379. } else { // IPPVC_MBTYPE_DIRECT
  380. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_DIRECT);
  381. field_prediction = pMBinfo->field_info & 1;
  382. if (!field_prediction) {
  383. // frame direct mode
  384. if (mp4_DecodeMV_Direct(pInfo, pMBinfo->mv, mvForw, mvBack, TRB, TRD, modb, pMBinfo->type) != MP4_STATUS_OK)
  385. goto Err_1;
  386. if (quarter_sample) {
  387. mp4_ComputeChroma4MVQ(mvForw, &mvCbCrF);
  388. mp4_Limit4MVQ(mvForw, mvForw, &limitRectL, dx, dy, 8);
  389. mp4_ComputeChroma4MVQ(mvBack, &mvCbCrB);
  390. mp4_Limit4MVQ(mvBack, mvBack, &limitRectL, dx, dy, 8);
  391. pc = pYc;
  392. pr = pYp;
  393. pn = pYn;
  394. mp4_Copy8x8QP_8u(pr, stepYp, pc, stepYc, &mvForw[0], 0);
  395. mp4_Copy8x8QP_8u(pn, stepYn, tmpMB, 16, &mvBack[0], 0);
  396. mp4_Copy8x8QP_8u(pr+8, stepYp, pc+8, stepYc, &mvForw[1], 0);
  397. mp4_Copy8x8QP_8u(pn+8, stepYn, tmpMB+8, 16, &mvBack[1], 0);
  398. pc = pYc + stepYc * 8;
  399. pr = pYp + stepYp * 8;
  400. pn = pYn + stepYn * 8;
  401. mp4_Copy8x8QP_8u(pr, stepYp, pc, stepYc, &mvForw[2], 0);
  402. mp4_Copy8x8QP_8u(pn, stepYn, tmpMB+128, 16, &mvBack[2], 0);
  403. mp4_Copy8x8QP_8u(pr+8, stepYp, pc+8, stepYc, &mvForw[3], 0);
  404. mp4_Copy8x8QP_8u(pn+8, stepYn, tmpMB+136, 16, &mvBack[3], 0);
  405. } else {
  406. mp4_ComputeChroma4MV(mvForw, &mvCbCrF);
  407. mp4_Limit4MV(mvForw, mvForw, &limitRectL, dx, dy, 8);
  408. mp4_ComputeChroma4MV(mvBack, &mvCbCrB);
  409. mp4_Limit4MV(mvBack, mvBack, &limitRectL, dx, dy, 8);
  410. pc = pYc;
  411. pr = pYp;
  412. pn = pYn;
  413. mp4_Copy8x8HP_8u(pr, stepYp, pc, stepYc, &mvForw[0], 0);
  414. mp4_Copy8x8HP_8u(pn, stepYn, tmpMB, 16, &mvBack[0], 0);
  415. mp4_Copy8x8HP_8u(pr+8, stepYp, pc+8, stepYc, &mvForw[1], 0);
  416. mp4_Copy8x8HP_8u(pn+8, stepYn, tmpMB+8, 16, &mvBack[1], 0);
  417. pc = pYc + stepYc * 8;
  418. pr = pYp + stepYp * 8;
  419. pn = pYn + stepYn * 8;
  420. mp4_Copy8x8HP_8u(pr, stepYp, pc, stepYc, &mvForw[2], 0);
  421. mp4_Copy8x8HP_8u(pn, stepYn, tmpMB+128, 16, &mvBack[2], 0);
  422. mp4_Copy8x8HP_8u(pr+8, stepYp, pc+8, stepYc, &mvForw[3], 0);
  423. mp4_Copy8x8HP_8u(pn+8, stepYn, tmpMB+136, 16, &mvBack[3], 0);
  424. }
  425. mp4_LimitMV(&mvCbCrF, &mvCbCrF, &limitRectC, dx >> 1, dy >> 1, 8);
  426. mp4_LimitMV(&mvCbCrB, &mvCbCrB, &limitRectC, dx >> 1, dy >> 1, 8);
  427. } else {
  428. mb_ftfr = (pMBinfo->field_info >> 1) & 1;
  429. mb_fbfr = (pMBinfo->field_info >> 2) & 1;
  430. if (mp4_DecodeMV_DirectField(pInfo, mb_ftfr, mb_fbfr, &mvField[0], &mvField[1], &mvForw[0], &mvForw[2], &mvBack[0], &mvBack[2], TRB, TRD, modb) != MP4_STATUS_OK)
  431. goto Err_1;
  432. if (quarter_sample) {
  433. mp4_LimitFMVQ(&mvForw[0], &mvForw[0], &limitRectL, dx, dy, 16);
  434. mp4_LimitFMVQ(&mvForw[2], &mvForw[2], &limitRectL, dx, dy, 16);
  435. mp4_LimitFMVQ(&mvBack[0], &mvBack[0], &limitRectL, dx, dy, 16);
  436. mp4_LimitFMVQ(&mvBack[2], &mvBack[2], &limitRectL, dx, dy, 16);
  437. mp4_Copy16x8QP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
  438. mp4_Copy16x8QP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
  439. mp4_Copy16x8QP_8u(pYn/*+stepYn*mb_btfr*/, stepYn*2, tmpMB, 32, &mvBack[0], 0);
  440. mp4_Copy16x8QP_8u(pYn+stepYn/**mb_bbfr*/, stepYn*2, tmpMB+16, 32, &mvBack[2], 0);
  441. mvForw[0].dx = (int16_t)mp4_Div2(mvForw[0].dx);
  442. mvForw[0].dy = (int16_t)(mp4_Div2(mvForw[0].dy*2) >> 1);
  443. mvForw[2].dx = (int16_t)mp4_Div2(mvForw[2].dx);
  444. mvForw[2].dy = (int16_t)(mp4_Div2(mvForw[2].dy*2) >> 1);
  445. mvBack[0].dx = (int16_t)mp4_Div2(mvBack[0].dx);
  446. mvBack[0].dy = (int16_t)(mp4_Div2(mvBack[0].dy*2) >> 1);
  447. mvBack[2].dx = (int16_t)mp4_Div2(mvBack[2].dx);
  448. mvBack[2].dy = (int16_t)(mp4_Div2(mvBack[2].dy*2) >> 1);
  449. } else {
  450. mp4_LimitFMV(&mvForw[0], &mvForw[0], &limitRectL, dx, dy, 16);
  451. mp4_LimitFMV(&mvForw[2], &mvForw[2], &limitRectL, dx, dy, 16);
  452. mp4_LimitFMV(&mvBack[0], &mvBack[0], &limitRectL, dx, dy, 16);
  453. mp4_LimitFMV(&mvBack[2], &mvBack[2], &limitRectL, dx, dy, 16);
  454. mp4_Copy16x8HP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
  455. mp4_Copy16x8HP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
  456. mp4_Copy16x8HP_8u(pYn/*+stepYn*mb_btfr*/, stepYn*2, tmpMB, 32, &mvBack[0], 0);
  457. mp4_Copy16x8HP_8u(pYn+stepYn/**mb_bbfr*/, stepYn*2, tmpMB+16, 32, &mvBack[2], 0);
  458. }
  459. mp4_ComputeChromaMV(&mvForw[0], &mvCbCrFFT);
  460. mp4_ComputeChromaMV(&mvForw[2], &mvCbCrFFB);
  461. mp4_ComputeChromaMV(&mvBack[0], &mvCbCrBFT);
  462. mp4_ComputeChromaMV(&mvBack[2], &mvCbCrBFB);
  463. }
  464. ippiAverage16x16_8u_C1IR(tmpMB, 16, pYc, stepYc);
  465. if (mp4_DecodeInterMB(pInfo, coeffMB, quant, cbpb, scan) != MP4_STATUS_OK)
  466. goto Err_1;
  467. if (!dct_type) {
  468. mp4_AddResidual(cbpb & 32, pYc, stepYc, coeffMB);
  469. mp4_AddResidual(cbpb & 16, pYc+8, stepYc, coeffMB+64);
  470. mp4_AddResidual(cbpb & 8, pYc+stepYc*8, stepYc, coeffMB+128);
  471. mp4_AddResidual(cbpb & 4, pYc+stepYc*8+8, stepYc, coeffMB+192);
  472. } else {
  473. mp4_AddResidual(cbpb & 32, pYc, stepYc*2, coeffMB);
  474. mp4_AddResidual(cbpb & 16, pYc+8, stepYc*2, coeffMB+64);
  475. mp4_AddResidual(cbpb & 8, pYc+stepYc, stepYc*2, coeffMB+128);
  476. mp4_AddResidual(cbpb & 4, pYc+stepYc+8, stepYc*2, coeffMB+192);
  477. }
  478. if (!field_prediction) {
  479. mp4_Copy8x8HP_8u(pCbp, stepCbp, pCbc, stepCbc, &mvCbCrF, 0);
  480. mp4_Copy8x8HP_8u(pCrp, stepCrp, pCrc, stepCrc, &mvCbCrF, 0);
  481. mp4_Copy8x8HP_8u(pCbn, stepCbn, tmpMB, 8, &mvCbCrB, 0);
  482. mp4_Copy8x8HP_8u(pCrn, stepCrn, tmpMB+64, 8, &mvCbCrB, 0);
  483. } else {
  484. mp4_Copy8x4HP_8u(pCbp+(mb_ftfr ? stepCbp : 0), stepCbp*2, pCbc, stepCbc*2, &mvCbCrFFT, 0);
  485. mp4_Copy8x4HP_8u(pCrp+(mb_ftfr ? stepCrp : 0), stepCrp*2, pCrc, stepCrc*2, &mvCbCrFFT, 0);
  486. mp4_Copy8x4HP_8u(pCbp+(mb_fbfr ? stepCbp : 0), stepCbp*2, pCbc+stepCbc, stepCbc*2, &mvCbCrFFB, 0);
  487. mp4_Copy8x4HP_8u(pCrp+(mb_fbfr ? stepCrp : 0), stepCrp*2, pCrc+stepCrc, stepCrc*2, &mvCbCrFFB, 0);
  488. mp4_Copy8x4HP_8u(pCbn/*+(mb_btfr ? stepCbn : 0)*/, stepCbn*2, tmpMB, 16, &mvCbCrBFT, 0);
  489. mp4_Copy8x4HP_8u(pCrn/*+(mb_btfr ? stepCrn : 0)*/, stepCrn*2, tmpMB+64, 16, &mvCbCrBFT, 0);
  490. mp4_Copy8x4HP_8u(pCbn+/*(mb_bbfr ? */stepCbn/* : 0)*/, stepCbn*2, tmpMB+8, 16, &mvCbCrBFB, 0);
  491. mp4_Copy8x4HP_8u(pCrn+/*(mb_bbfr ? */stepCrn/* : 0)*/, stepCrn*2, tmpMB+64+8, 16, &mvCbCrBFB, 0);
  492. }
  493. ippiAverage8x8_8u_C1IR(tmpMB, 8, pCbc, stepCbc);
  494. ippiAverage8x8_8u_C1IR(tmpMB+64, 8, pCrc, stepCrc);
  495. mp4_AddResidual(cbpb & 2, pCbc, stepCbc, coeffMB+256);
  496. mp4_AddResidual(cbpb & 1, pCrc, stepCrc, coeffMB+320);
  497. }
  498. }
  499. //mbCurr ++;
  500. mbInVideoPacket ++;
  501. colNum ++;
  502. pMBinfo ++;
  503. mvField += 2;
  504. if (colNum == mbPerRow) {
  505. colNum = 0;
  506. rowNum ++;
  507. if (rowNum == mbPerCol)
  508. return sts;
  509. pYc += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
  510. pCbc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbc << 3) - stepCbc;
  511. pCrc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrc << 3) - stepCrc;
  512. pYp += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYp << 4) - stepYp;
  513. pCbp += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbp << 3) - stepCbp;
  514. pCrp += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrp << 3) - stepCrp;
  515. pYn += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYn << 4) - stepYn;
  516. pCbn += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbn << 3) - stepCbn;
  517. pCrn += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrn << 3) - stepCrn;
  518. // reset MV predictors at new row
  519. mvForwT.dx = mvForwT.dy = mvBackT.dx = mvBackT.dy = mvForwB.dx = mvForwB.dy = mvBackB.dx = mvBackB.dy = 0;
  520. } else {
  521. pYc += 16; pCrc += 8; pCbc += 8;
  522. pYp += 16; pCrp += 8; pCbp += 8;
  523. pYn += 16; pCrn += 8; pCbn += 8;
  524. }
  525. if (!pInfo->VisualObject.VideoObject.resync_marker_disable) {
  526. int32_t found;
  527. ErrRet_1:
  528. if (mp4_CheckDecodeVideoPacket(pInfo, &found) == MP4_STATUS_OK) {
  529. if (found) {
  530. quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant_scale;
  531. mbCurr = pInfo->VisualObject.VideoObject.VideoObjectPlane.macroblock_num;
  532. mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, mbCurr - rowNum * mbPerRow - colNum);
  533. rowNum = mbCurr / mbPerRow;
  534. colNum = mbCurr % mbPerRow;
  535. pYc = pInfo->VisualObject.cFrame->pY + (rowNum * stepYc + colNum) * 16; pCbc = pInfo->VisualObject.cFrame->pCb + (rowNum * stepCbc + colNum) * 8; pCrc = pInfo->VisualObject.cFrame->pCr + (rowNum * stepCrc + colNum) * 8;
  536. pYp = pInfo->VisualObject.rFrame->pY + (rowNum * stepYp + colNum) * 16; pCbp = pInfo->VisualObject.rFrame->pCb + (rowNum * stepCbp + colNum) * 8; pCrp = pInfo->VisualObject.rFrame->pCr + (rowNum * stepCrp + colNum) * 8;
  537. pYn = pInfo->VisualObject.nFrame->pY + (rowNum * stepYn + colNum) * 16; pCbn = pInfo->VisualObject.nFrame->pCb + (rowNum * stepCbn + colNum) * 8; pCrn = pInfo->VisualObject.nFrame->pCr + (rowNum * stepCrn + colNum) * 8;
  538. pMBinfo = pInfo->VisualObject.VideoObject.MBinfo + mbCurr;
  539. break;
  540. }
  541. } else
  542. goto Err_1;
  543. }
  544. }
  545. }
  546. Err_1:
  547. sts = MP4_STATUS_ERROR;
  548. if (pInfo->stopOnErr)
  549. return sts;
  550. if (pInfo->VisualObject.VideoObject.resync_marker_disable || !mp4_SeekResyncMarker(pInfo))
  551. {
  552. mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, pInfo->VisualObject.VideoObject.MacroBlockPerVOP - rowNum * mbPerRow - colNum);
  553. return sts;
  554. }
  555. goto ErrRet_1;
  556. }
  557. // decode usual B-VOP
  558. for (;;) {
  559. IppMotionVector mvCbCrF, mvCbCrB, mvForw, mvBack, mvForwLim, mvBackLim;
  560. mbInVideoPacket = 0;
  561. // reset MV predictors at new VideoPacket
  562. mvForw.dx = mvForw.dy = mvBack.dx = mvBack.dy = 0;
  563. // decode B-VOP macroblocks
  564. for (;;) {
  565. if (pMBinfo->not_coded) {
  566. ippiCopy16x16_8u_C1R(pYp, stepYp, pYc, stepYc);
  567. ippiCopy8x8_8u_C1R(pCbp, stepCbp, pCbc, stepCbc);
  568. ippiCopy8x8_8u_C1R(pCrp, stepCrp, pCrc, stepCrc);
  569. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_NOTCODED);
  570. } else {
  571. cbpb = 0;
  572. if (mp4_GetBit(pInfo)) {
  573. modb = 2;
  574. mb_type = IPPVC_MBTYPE_DIRECT;
  575. } else {
  576. modb = mp4_GetBit(pInfo);
  577. // decode mb_type
  578. code = mp4_ShowBits9(pInfo, 4);
  579. if (code != 0) {
  580. mb_type = mp4_BVOPmb_type[code].code;
  581. mp4_FlushBits(pInfo, mp4_BVOPmb_type[code].len);
  582. } else {
  583. mp4_Error("Error when decode mb_type of B-VOP macroblock");
  584. goto Err_2;
  585. }
  586. if (modb == 0)
  587. cbpb = mp4_GetBits9(pInfo, 6);
  588. if (mb_type != IPPVC_MBTYPE_DIRECT && cbpb != 0)
  589. mp4_UpdateQuant_B(pInfo, quant);
  590. }
  591. // coordinates of current MB for limitation
  592. dx = colNum * 16;
  593. dy = rowNum * 16;
  594. if (mb_type == IPPVC_MBTYPE_FORWARD) {
  595. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_FORWARD);
  596. if (mp4_DecodeMV(pInfo, &mvForw, fcode_forward) != MP4_STATUS_OK)
  597. goto Err_2;
  598. if (quarter_sample) {
  599. mp4_LimitMVQ(&mvForw, &mvForwLim, &limitRectL, dx, dy, 16);
  600. mp4_ComputeChromaMVQ(&mvForwLim, &mvCbCrF);
  601. mp4_Copy16x16QP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim, 0);
  602. mp4_DecodeReconBlockInter_MPEG4(cbpb & 32, pYc, stepYc, Err_2);
  603. mp4_DecodeReconBlockInter_MPEG4(cbpb & 16, pYc+8, stepYc, Err_2);
  604. mp4_DecodeReconBlockInter_MPEG4(cbpb & 8, pYc+8*stepYc, stepYc, Err_2);
  605. mp4_DecodeReconBlockInter_MPEG4(cbpb & 4, pYc+8*stepYc+8, stepYc, Err_2);
  606. } else {
  607. mp4_LimitMV(&mvForw, &mvForwLim, &limitRectL, dx, dy, 16);
  608. mp4_ComputeChromaMV(&mvForwLim, &mvCbCrF);
  609. if (cbpb & 60) {
  610. mp4_DecodeMCBlockInter_MPEG4(cbpb & 32, pYp, stepYp, pYc, stepYc, mvForwLim, 0, Err_2);
  611. mp4_DecodeMCBlockInter_MPEG4(cbpb & 16, pYp+8, stepYp, pYc+8, stepYc, mvForwLim, 0, Err_2);
  612. mp4_DecodeMCBlockInter_MPEG4(cbpb & 8, pYp+8*stepYp, stepYp, pYc+8*stepYc, stepYc, mvForwLim, 0, Err_2);
  613. mp4_DecodeMCBlockInter_MPEG4(cbpb & 4, pYp+8*stepYp+8, stepYp, pYc+8*stepYc+8, stepYc, mvForwLim, 0, Err_2);
  614. } else {
  615. mp4_Copy16x16HP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim, 0);
  616. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
  617. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
  618. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
  619. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
  620. }
  621. }
  622. mp4_DecodeMCBlockInter_MPEG4(cbpb & 2, pCbp, stepCbp, pCbc, stepCbc, mvCbCrF, 0, Err_2);
  623. mp4_DecodeMCBlockInter_MPEG4(cbpb & 1, pCrp, stepCrp, pCrc, stepCrc, mvCbCrF, 0, Err_2);
  624. } else if (mb_type == IPPVC_MBTYPE_BACKWARD) {
  625. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_BACKWARD);
  626. if (mp4_DecodeMV(pInfo, &mvBack, fcode_backward) != MP4_STATUS_OK)
  627. goto Err_2;
  628. if (quarter_sample) {
  629. mp4_LimitMVQ(&mvBack, &mvBackLim, &limitRectL, dx, dy, 16);
  630. mp4_ComputeChromaMVQ(&mvBackLim, &mvCbCrB);
  631. mp4_Copy16x16QP_8u(pYn, stepYn, pYc, stepYc, &mvBackLim, 0);
  632. mp4_DecodeReconBlockInter_MPEG4(cbpb & 32, pYc, stepYc, Err_2);
  633. mp4_DecodeReconBlockInter_MPEG4(cbpb & 16, pYc+8, stepYc, Err_2);
  634. mp4_DecodeReconBlockInter_MPEG4(cbpb & 8, pYc+8*stepYc, stepYc, Err_2);
  635. mp4_DecodeReconBlockInter_MPEG4(cbpb & 4, pYc+8*stepYc+8, stepYc, Err_2);
  636. } else {
  637. mp4_LimitMV(&mvBack, &mvBackLim, &limitRectL, dx, dy, 16);
  638. mp4_ComputeChromaMV(&mvBackLim, &mvCbCrB);
  639. if (cbpb & 60) {
  640. mp4_DecodeMCBlockInter_MPEG4(cbpb & 32, pYn, stepYn, pYc, stepYc, mvBackLim, 0, Err_2);
  641. mp4_DecodeMCBlockInter_MPEG4(cbpb & 16, pYn+8, stepYn, pYc+8, stepYc, mvBackLim, 0, Err_2);
  642. mp4_DecodeMCBlockInter_MPEG4(cbpb & 8, pYn+8*stepYn, stepYp, pYc+8*stepYc, stepYc, mvBackLim, 0, Err_2);
  643. mp4_DecodeMCBlockInter_MPEG4(cbpb & 4, pYn+8*stepYn+8, stepYp, pYc+8*stepYc+8, stepYc, mvBackLim, 0, Err_2);
  644. } else {
  645. mp4_Copy16x16HP_8u(pYn, stepYn, pYc, stepYc, &mvBackLim, 0);
  646. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
  647. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
  648. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
  649. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
  650. }
  651. }
  652. mp4_DecodeMCBlockInter_MPEG4(cbpb & 2, pCbn, stepCbn, pCbc, stepCbc, mvCbCrB, 0, Err_2);
  653. mp4_DecodeMCBlockInter_MPEG4(cbpb & 1, pCrn, stepCrn, pCrc, stepCrc, mvCbCrB, 0, Err_2);
  654. }
  655. else if (mb_type == IPPVC_MBTYPE_INTERPOLATE)
  656. {
  657. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTERPOLATE);
  658. if (mp4_DecodeMV(pInfo, &mvForw, fcode_forward) != MP4_STATUS_OK)
  659. goto Err_2;
  660. if (mp4_DecodeMV(pInfo, &mvBack, fcode_backward) != MP4_STATUS_OK)
  661. goto Err_2;
  662. if (quarter_sample)
  663. {
  664. mp4_LimitMVQ(&mvForw, &mvForwLim, &limitRectL, dx, dy, 16);
  665. mp4_ComputeChromaMVQ(&mvForwLim, &mvCbCrF);
  666. mp4_Copy16x16QP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim, 0);
  667. mp4_LimitMVQ(&mvBack, &mvBackLim, &limitRectL, dx, dy, 16);
  668. mp4_ComputeChromaMVQ(&mvBackLim, &mvCbCrB);
  669. mp4_Copy16x16QP_8u(pYn, stepYn, tmpMB, 16, &mvBackLim, 0);
  670. }
  671. else
  672. {
  673. mp4_LimitMV(&mvForw, &mvForwLim, &limitRectL, dx, dy, 16);
  674. mp4_ComputeChromaMV(&mvForwLim, &mvCbCrF);
  675. mp4_Copy16x16HP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim, 0);
  676. mp4_LimitMV(&mvBack, &mvBackLim, &limitRectL, dx, dy, 16);
  677. mp4_ComputeChromaMV(&mvBackLim, &mvCbCrB);
  678. mp4_Copy16x16HP_8u(pYn, stepYn, tmpMB, 16, &mvBackLim, 0);
  679. }
  680. ippiAverage16x16_8u_C1IR(tmpMB, 16, pYc, stepYc);
  681. mp4_DecodeReconBlockInter_MPEG4(cbpb & 32, pYc, stepYc, Err_2);
  682. mp4_DecodeReconBlockInter_MPEG4(cbpb & 16, pYc+8, stepYc, Err_2);
  683. mp4_DecodeReconBlockInter_MPEG4(cbpb & 8, pYc+8*stepYc, stepYc, Err_2);
  684. mp4_DecodeReconBlockInter_MPEG4(cbpb & 4, pYc+8*stepYc+8, stepYc, Err_2);
  685. mp4_Copy8x8HP_8u(pCbp, stepCbp, pCbc, stepCbc, &mvCbCrF, 0);
  686. mp4_Copy8x8HP_8u(pCbn, stepCbn, tmpMB, 8, &mvCbCrB, 0);
  687. ippiAverage8x8_8u_C1IR(tmpMB, 8, pCbc, stepCbc);
  688. mp4_DecodeReconBlockInter_MPEG4(cbpb & 2, pCbc, stepCbc, Err_2);
  689. mp4_Copy8x8HP_8u(pCrp, stepCrp, pCrc, stepCrc, &mvCbCrF, 0);
  690. mp4_Copy8x8HP_8u(pCrn, stepCrn, tmpMB, 8, &mvCbCrB, 0);
  691. ippiAverage8x8_8u_C1IR(tmpMB, 8, pCrc, stepCrc);
  692. mp4_DecodeReconBlockInter_MPEG4(cbpb & 1, pCrc, stepCrc, Err_2);
  693. }
  694. else
  695. { // IPPVC_MBTYPE_DIRECT
  696. IppMotionVector mvForw[4], mvBack[4], mvForwLim[4], mvBackLim[4];
  697. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_DIRECT);
  698. //f MVs of collocated block of recently decoded I or P frame used in Direct mode
  699. if (mp4_DecodeMV_Direct(pInfo, pMBinfo->mv, mvForw, mvBack, TRB, TRD, modb, pMBinfo->type) != MP4_STATUS_OK)
  700. goto Err_2;
  701. if (quarter_sample)
  702. {
  703. mp4_Limit4MVQ(mvForw, mvForwLim, &limitRectL, dx, dy, 8);
  704. mp4_ComputeChroma4MVQ(mvForw, &mvCbCrF);
  705. mp4_Limit4MVQ(mvBack, mvBackLim, &limitRectL, dx, dy, 8);
  706. mp4_ComputeChroma4MVQ(mvBack, &mvCbCrB);
  707. mp4_Copy8x8QP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim[0], 0);
  708. mp4_Copy8x8QP_8u(pYn, stepYn, tmpMB, 16, &mvBackLim[0], 0);
  709. mp4_Copy8x8QP_8u(pYp+8, stepYp, pYc+8, stepYc, &mvForwLim[1], 0);
  710. mp4_Copy8x8QP_8u(pYn+8, stepYn, tmpMB+8, 16, &mvBackLim[1], 0);
  711. mp4_Copy8x8QP_8u(pYp+8*stepYp, stepYp, pYc+8*stepYc, stepYc, &mvForwLim[2], 0);
  712. mp4_Copy8x8QP_8u(pYn+8*stepYn, stepYn, tmpMB+8*16, 16, &mvBackLim[2], 0);
  713. mp4_Copy8x8QP_8u(pYp+8*stepYp+8, stepYp, pYc+8*stepYc+8, stepYc, &mvForwLim[3], 0);
  714. mp4_Copy8x8QP_8u(pYn+8*stepYn+8, stepYn, tmpMB+8*16+8, 16, &mvBackLim[3], 0);
  715. }
  716. else
  717. {
  718. if (pMBinfo->type == IPPVC_MBTYPE_INTER4V) {
  719. mp4_Limit4MV(mvForw, mvForwLim, &limitRectL, dx, dy, 8);
  720. mp4_ComputeChroma4MV(mvForw, &mvCbCrF);
  721. mp4_Limit4MV(mvBack, mvBackLim, &limitRectL, dx, dy, 8);
  722. mp4_ComputeChroma4MV(mvBack, &mvCbCrB);
  723. mp4_Copy8x8HP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim[0], 0);
  724. mp4_Copy8x8HP_8u(pYn, stepYn, tmpMB, 16, &mvBackLim[0], 0);
  725. mp4_Copy8x8HP_8u(pYp+8, stepYp, pYc+8, stepYc, &mvForwLim[1], 0);
  726. mp4_Copy8x8HP_8u(pYn+8, stepYn, tmpMB+8, 16, &mvBackLim[1], 0);
  727. mp4_Copy8x8HP_8u(pYp+8*stepYp, stepYp, pYc+8*stepYc, stepYc, &mvForwLim[2], 0);
  728. mp4_Copy8x8HP_8u(pYn+8*stepYn, stepYn, tmpMB+8*16, 16, &mvBackLim[2], 0);
  729. mp4_Copy8x8HP_8u(pYp+8*stepYp+8, stepYp, pYc+8*stepYc+8, stepYc, &mvForwLim[3], 0);
  730. mp4_Copy8x8HP_8u(pYn+8*stepYn+8, stepYn, tmpMB+8*16+8, 16, &mvBackLim[3], 0);
  731. }
  732. else
  733. {
  734. mp4_LimitMV(mvForw, mvForwLim, &limitRectL, dx, dy, 16);
  735. mp4_ComputeChromaMV(mvForwLim, &mvCbCrF);
  736. mp4_LimitMV(mvBack, mvBackLim, &limitRectL, dx, dy, 16);
  737. mp4_ComputeChromaMV(mvBackLim, &mvCbCrB);
  738. mp4_Copy16x16HP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim[0], 0);
  739. mp4_Copy16x16HP_8u(pYn, stepYn, tmpMB, 16, &mvBackLim[0], 0);
  740. }
  741. }
  742. ippiAverage16x16_8u_C1IR(tmpMB, 16, pYc, stepYc);
  743. mp4_DecodeReconBlockInter_MPEG4(cbpb & 32, pYc, stepYc, Err_2);
  744. mp4_DecodeReconBlockInter_MPEG4(cbpb & 16, pYc+8, stepYc, Err_2);
  745. mp4_DecodeReconBlockInter_MPEG4(cbpb & 8, pYc+8*stepYc, stepYc, Err_2);
  746. mp4_DecodeReconBlockInter_MPEG4(cbpb & 4, pYc+8*stepYc+8, stepYc, Err_2);
  747. mp4_LimitMV(&mvCbCrF, &mvCbCrF, &limitRectC, dx >> 1, dy >> 1, 8);
  748. mp4_LimitMV(&mvCbCrB, &mvCbCrB, &limitRectC, dx >> 1, dy >> 1, 8);
  749. mp4_Copy8x8HP_8u(pCbp, stepCbp, pCbc, stepCbc, &mvCbCrF, 0);
  750. mp4_Copy8x8HP_8u(pCbn, stepCbn, tmpMB, 8, &mvCbCrB, 0);
  751. ippiAverage8x8_8u_C1IR(tmpMB, 8, pCbc, stepCbc);
  752. mp4_DecodeReconBlockInter_MPEG4(cbpb & 2, pCbc, stepCbc, Err_2);
  753. mp4_Copy8x8HP_8u(pCrp, stepCrp, pCrc, stepCrc, &mvCbCrF, 0);
  754. mp4_Copy8x8HP_8u(pCrn, stepCrn, tmpMB, 8, &mvCbCrB, 0);
  755. ippiAverage8x8_8u_C1IR(tmpMB, 8, pCrc, stepCrc);
  756. mp4_DecodeReconBlockInter_MPEG4(cbpb & 1, pCrc, stepCrc, Err_2);
  757. }
  758. }
  759. //mbCurr ++;
  760. mbInVideoPacket ++;
  761. colNum ++;
  762. pMBinfo ++;
  763. if (colNum == mbPerRow)
  764. {
  765. colNum = 0;
  766. rowNum ++;
  767. if (rowNum == mbPerCol)
  768. return sts;
  769. pYc += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
  770. pCbc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbc << 3) - stepCbc;
  771. pCrc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrc << 3) - stepCrc;
  772. pYp += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYp << 4) - stepYp;
  773. pCbp += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbp << 3) - stepCbp;
  774. pCrp += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrp << 3) - stepCrp;
  775. pYn += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYn << 4) - stepYn;
  776. pCbn += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbn << 3) - stepCbn;
  777. pCrn += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrn << 3) - stepCrn;
  778. // reset MV predictors at new row
  779. mvForw.dx = mvForw.dy = mvBack.dx = mvBack.dy = 0;
  780. }
  781. else
  782. {
  783. pYc += 16; pCrc += 8; pCbc += 8;
  784. pYp += 16; pCrp += 8; pCbp += 8;
  785. pYn += 16; pCrn += 8; pCbn += 8;
  786. }
  787. if (!pInfo->VisualObject.VideoObject.resync_marker_disable)
  788. {
  789. int32_t found;
  790. ErrRet_2:
  791. if (mp4_CheckDecodeVideoPacket(pInfo, &found) == MP4_STATUS_OK)
  792. {
  793. if (found)
  794. {
  795. quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant_scale;
  796. mbCurr = pInfo->VisualObject.VideoObject.VideoObjectPlane.macroblock_num;
  797. mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, mbCurr - rowNum * mbPerRow - colNum);
  798. rowNum = mbCurr / mbPerRow;
  799. colNum = mbCurr % mbPerRow;
  800. pYc = pInfo->VisualObject.cFrame->pY + (rowNum * stepYc + colNum) * 16; pCbc = pInfo->VisualObject.cFrame->pCb + (rowNum * stepCbc + colNum) * 8; pCrc = pInfo->VisualObject.cFrame->pCr + (rowNum * stepCrc + colNum) * 8;
  801. pYp = pInfo->VisualObject.rFrame->pY + (rowNum * stepYp + colNum) * 16; pCbp = pInfo->VisualObject.rFrame->pCb + (rowNum * stepCbp + colNum) * 8; pCrp = pInfo->VisualObject.rFrame->pCr + (rowNum * stepCrp + colNum) * 8;
  802. pYn = pInfo->VisualObject.nFrame->pY + (rowNum * stepYn + colNum) * 16; pCbn = pInfo->VisualObject.nFrame->pCb + (rowNum * stepCbn + colNum) * 8; pCrn = pInfo->VisualObject.nFrame->pCr + (rowNum * stepCrn + colNum) * 8;
  803. pMBinfo = pInfo->VisualObject.VideoObject.MBinfo + mbCurr;
  804. break;
  805. }
  806. }
  807. else
  808. goto Err_2;
  809. }
  810. }
  811. }
  812. Err_2:
  813. sts = MP4_STATUS_ERROR;
  814. if (pInfo->stopOnErr)
  815. return sts;
  816. if (pInfo->VisualObject.VideoObject.resync_marker_disable || !mp4_SeekResyncMarker(pInfo))
  817. {
  818. mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, pInfo->VisualObject.VideoObject.MacroBlockPerVOP - rowNum * mbPerRow - colNum);
  819. return sts;
  820. }
  821. goto ErrRet_2;
  822. }