1
0

mp4decvop.c 82 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983
  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-2008 Intel Corporation. All Rights Reserved.
  8. //
  9. // Description: Decodes MPEG-4 bitstream.
  10. //
  11. */
  12. #include "mp4def.h"
  13. #include "mp4dec.h"
  14. #pragma warning(disable : 188) // enumerated type mixed with another type ICL
  15. void mp4_ResetVOL(mp4_Info *pInfo)
  16. {
  17. pInfo->VisualObject.VideoObject.VOPindex = 0;
  18. pInfo->VisualObject.VideoObject.prevPlaneIsB = 0;
  19. pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane.time_code = 0;
  20. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  21. pInfo->VisualObject.cFrame=0;
  22. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  23. pInfo->VisualObject.rFrame=0;
  24. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
  25. pInfo->VisualObject.nFrame=0;
  26. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.sFrame);
  27. pInfo->VisualObject.sFrame=0;
  28. }
  29. static int AllocateInitFrame(mp4_Frame* pFrame)
  30. {
  31. int32_t w, h;
  32. w = (pFrame->mbPerRow + 2 * MP4_NUM_EXT_MB) << 4;
  33. h = (pFrame->mbPerCol + 2 * MP4_NUM_EXT_MB) << 4;
  34. pFrame->mid = malloc(w * h + (w * h >> 1));
  35. if (!pFrame->mid)
  36. return 1; // out of memory
  37. ippsSet_8u(0, pFrame->mid, w * h);
  38. ippsSet_8u(128, pFrame->mid + w * h, w * h >> 1);
  39. pFrame->stepY = w;
  40. pFrame->stepCb = w >> 1;
  41. pFrame->stepCr = w >> 1;
  42. /* benski> stuff from LockFrame... */
  43. pFrame->apY = pFrame->mid;
  44. pFrame->pY = pFrame->apY + w * 16 + 16;
  45. pFrame->apCb = pFrame->apY + w * h;
  46. w >>= 1;
  47. h >>= 1;
  48. pFrame->pCb = pFrame->apCb + w * 8 + 8;
  49. pFrame->apCr = pFrame->apCb + w * h;
  50. pFrame->pCr = pFrame->apCr + w * 8 + 8;
  51. return 0;
  52. }
  53. static mp4_Status mp4_AllocInitFrame(mp4_Frame* pFrame, int32_t mbPerRow, int32_t mbPerCol)
  54. {
  55. int32_t w, h;
  56. w = (mbPerRow + 2 * MP4_NUM_EXT_MB) << 4;
  57. h = (mbPerCol + 2 * MP4_NUM_EXT_MB) << 4;
  58. pFrame->stepY = w;
  59. pFrame->apY = ippsMalloc_8u(w * h);
  60. if (!pFrame->apY)
  61. return MP4_STATUS_NO_MEM;
  62. ippsSet_8u(0, pFrame->apY, w * h);
  63. pFrame->pY = pFrame->apY + w * 16 + 16;
  64. w >>= 1;
  65. h >>= 1;
  66. pFrame->stepCb = w;
  67. pFrame->apCb = ippsMalloc_8u(w * h);
  68. if (!pFrame->apCb)
  69. return MP4_STATUS_NO_MEM;
  70. ippsSet_8u(128, pFrame->apCb, w * h);
  71. pFrame->pCb = pFrame->apCb + w * 8 + 8;
  72. pFrame->stepCr = w;
  73. pFrame->apCr = ippsMalloc_8u(w * h);
  74. if (!pFrame->apCr)
  75. return MP4_STATUS_NO_MEM;
  76. pFrame->pCr = pFrame->apCr + w * 8 + 8;
  77. ippsSet_8u(128, pFrame->apCr, w * h);
  78. return MP4_STATUS_OK;
  79. }
  80. /*
  81. // mp4_Info for decoding of Video Object Layer
  82. */
  83. mp4_Status mp4_InitVOL(mp4_Info* pInfo)
  84. {
  85. int32_t mbPerRow, mbPerCol, specSize;
  86. if (pInfo->VisualObject.VideoObject.short_video_header) {
  87. pInfo->noBVOPs = 1;
  88. } else {
  89. if (pInfo->strictSyntaxCheck) {
  90. if (pInfo->VisualObject.VideoObject.random_accessible_vol)
  91. pInfo->noPVOPs = pInfo->noBVOPs = 1;
  92. if (pInfo->VisualObject.VideoObject.type_indication == MP4_VIDEO_OBJECT_TYPE_SIMPLE ||
  93. pInfo->VisualObject.VideoObject.type_indication == MP4_VIDEO_OBJECT_TYPE_ADVANCED_REAL_TIME_SIMPLE ||
  94. pInfo->VisualObject.VideoObject.VOLControlParameters.low_delay) {
  95. pInfo->noBVOPs = 1;
  96. }
  97. }
  98. }
  99. if (pInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR)
  100. {
  101. mbPerRow = (pInfo->VisualObject.VideoObject.width + 15) >> 4;
  102. mbPerCol = (pInfo->VisualObject.VideoObject.height + 15) >> 4;
  103. // current frame
  104. // if (mp4_AllocInitFrame(&pInfo->VisualObject.cFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
  105. // return MP4_STATUS_NO_MEM;
  106. if (pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC)
  107. {
  108. // ref in past frame
  109. // if (mp4_AllocInitFrame(&pInfo->VisualObject.rFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
  110. // return MP4_STATUS_NO_MEM;
  111. // ref in future frame
  112. // if (mp4_AllocInitFrame(&pInfo->VisualObject.nFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
  113. // return MP4_STATUS_NO_MEM;
  114. // motion info (not needed for Sprites)
  115. pInfo->VisualObject.VideoObject.MBinfo = (mp4_MacroBlock*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(mp4_MacroBlock));
  116. if (!pInfo->VisualObject.VideoObject.MBinfo) return MP4_STATUS_NO_MEM;
  117. #ifdef USE_NOTCODED_STATE
  118. // not_coded MB state
  119. pInfo->VisualObject.VideoObject.ncState = ippsMalloc_8u(mbPerCol * mbPerRow);
  120. if (!pInfo->VisualObject.VideoObject.ncState) return MP4_STATUS_NO_MEM;
  121. pInfo->VisualObject.VideoObject.ncStateCleared = 0;
  122. #endif
  123. }
  124. else
  125. { // data for static sprite
  126. mbPerRow = pInfo->VisualObject.sFrame->mbPerRow = (pInfo->VisualObject.VideoObject.sprite_width + 15) >> 4;
  127. mbPerCol = pInfo->VisualObject.sFrame->mbPerCol = (pInfo->VisualObject.VideoObject.sprite_height + 15) >> 4;
  128. // if (mp4_AllocInitFrame(&pInfo->VisualObject.sFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
  129. // return MP4_STATUS_NO_MEM;
  130. }
  131. pInfo->VisualObject.VideoObject.MacroBlockPerRow = mbPerRow;
  132. pInfo->VisualObject.VideoObject.MacroBlockPerCol = mbPerCol;
  133. pInfo->VisualObject.VideoObject.MacroBlockPerVOP = mbPerRow * mbPerCol;
  134. pInfo->VisualObject.VideoObject.mbns = mp4_GetMacroBlockNumberSize(pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
  135. if (!pInfo->VisualObject.VideoObject.short_video_header)
  136. {
  137. // Intra Prediction info (not needed for SVH)
  138. pInfo->VisualObject.VideoObject.IntraPredBuff.quant = ippsMalloc_8u(mbPerRow + 1);
  139. if (!pInfo->VisualObject.VideoObject.IntraPredBuff.quant) return MP4_STATUS_NO_MEM;
  140. pInfo->VisualObject.VideoObject.IntraPredBuff.block = (mp4_IntraPredBlock*)ippsMalloc_8u((mbPerRow + 1)*6*sizeof(mp4_IntraPredBlock));
  141. if (!pInfo->VisualObject.VideoObject.IntraPredBuff.block) return MP4_STATUS_NO_MEM;
  142. {
  143. mp4_IntraPredBlock *mbCurr = pInfo->VisualObject.VideoObject.IntraPredBuff.block;
  144. mp4_IntraPredBlock *mbA = mbCurr, *mbB = pInfo->VisualObject.VideoObject.IntraPredBuff.dcB, *mbC = mbCurr + 6;
  145. int32_t j;
  146. for (j = 0; j < mbPerRow; j ++) {
  147. mbCurr[0].predA = &mbA[1]; mbCurr[0].predB = &mbB[3]; mbCurr[0].predC = &mbC[2];
  148. mbCurr[1].predA = &mbC[0]; mbCurr[1].predB = &mbC[2]; mbCurr[1].predC = &mbC[3];
  149. mbCurr[2].predA = &mbA[3]; mbCurr[2].predB = &mbA[1]; mbCurr[2].predC = &mbC[0];
  150. mbCurr[3].predA = &mbC[2]; mbCurr[3].predB = &mbC[0]; mbCurr[3].predC = &mbC[1];
  151. mbCurr[4].predA = &mbA[4]; mbCurr[4].predB = &mbB[4]; mbCurr[4].predC = &mbC[4];
  152. mbCurr[5].predA = &mbA[5]; mbCurr[5].predB = &mbB[5]; mbCurr[5].predC = &mbC[5];
  153. mbCurr += 6; mbA += 6; mbC += 6;
  154. }
  155. }
  156. if (pInfo->VisualObject.VideoObject.data_partitioned) {
  157. // DataPart info
  158. pInfo->VisualObject.VideoObject.DataPartBuff = (mp4_DataPartMacroBlock*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(mp4_DataPartMacroBlock));
  159. if (!pInfo->VisualObject.VideoObject.DataPartBuff) return MP4_STATUS_NO_MEM;
  160. }
  161. if (pInfo->VisualObject.VideoObject.interlaced) {
  162. // Field MV for B-VOP
  163. pInfo->VisualObject.VideoObject.FieldMV = (IppMotionVector*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(IppMotionVector)*2);
  164. if (!pInfo->VisualObject.VideoObject.FieldMV) return MP4_STATUS_NO_MEM;
  165. }
  166. ippiQuantInvIntraGetSize_MPEG4(&specSize);
  167. pInfo->VisualObject.VideoObject.QuantInvIntraSpec = (IppiQuantInvIntraSpec_MPEG4*)ippsMalloc_8u(specSize);
  168. ippiQuantInvIntraInit_MPEG4(pInfo->VisualObject.VideoObject.quant_type ? pInfo->VisualObject.VideoObject.intra_quant_mat : NULL, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, 8);
  169. ippiQuantInvInterGetSize_MPEG4(&specSize);
  170. pInfo->VisualObject.VideoObject.QuantInvInterSpec = (IppiQuantInvInterSpec_MPEG4*)ippsMalloc_8u(specSize);
  171. ippiQuantInvInterInit_MPEG4(pInfo->VisualObject.VideoObject.quant_type ? pInfo->VisualObject.VideoObject.nonintra_quant_mat : NULL, pInfo->VisualObject.VideoObject.QuantInvInterSpec, 8);
  172. ippiWarpGetSize_MPEG4(&specSize);
  173. pInfo->VisualObject.VideoObject.WarpSpec = (IppiWarpSpec_MPEG4*)ippsMalloc_8u(specSize);
  174. }
  175. }
  176. return MP4_STATUS_OK;
  177. }
  178. /*
  179. // Free memory allocated for mp4_Info
  180. */
  181. mp4_Status mp4_FreeVOL(mp4_Info* pInfo)
  182. {
  183. if (pInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR) {
  184. if (pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) {
  185. ippsFree(pInfo->VisualObject.VideoObject.MBinfo); pInfo->VisualObject.VideoObject.MBinfo = NULL;
  186. #ifdef USE_NOTCODED_STATE
  187. ippsFree(pInfo->VisualObject.VideoObject.ncState);
  188. #endif
  189. } else {
  190. }
  191. if (!pInfo->VisualObject.VideoObject.short_video_header) {
  192. ippsFree(pInfo->VisualObject.VideoObject.IntraPredBuff.quant); pInfo->VisualObject.VideoObject.IntraPredBuff.quant = NULL;
  193. ippsFree(pInfo->VisualObject.VideoObject.IntraPredBuff.block); pInfo->VisualObject.VideoObject.IntraPredBuff.block = NULL;
  194. if (pInfo->VisualObject.VideoObject.data_partitioned) {
  195. ippsFree(pInfo->VisualObject.VideoObject.DataPartBuff); pInfo->VisualObject.VideoObject.DataPartBuff = NULL;
  196. }
  197. if (pInfo->VisualObject.VideoObject.interlaced) {
  198. ippsFree(pInfo->VisualObject.VideoObject.FieldMV); pInfo->VisualObject.VideoObject.FieldMV = NULL;
  199. }
  200. ippsFree(pInfo->VisualObject.VideoObject.QuantInvIntraSpec); pInfo->VisualObject.VideoObject.QuantInvIntraSpec = NULL;
  201. ippsFree(pInfo->VisualObject.VideoObject.QuantInvInterSpec); pInfo->VisualObject.VideoObject.QuantInvInterSpec = NULL;
  202. ippsFree(pInfo->VisualObject.VideoObject.WarpSpec); pInfo->VisualObject.VideoObject.WarpSpec = NULL;
  203. }
  204. }
  205. return MP4_STATUS_OK;
  206. }
  207. mp4_Status mp4_DecodeMVD(mp4_Info *pInfo, int32_t *mvdx, int32_t *mvdy, int32_t fcode)
  208. {
  209. const mp4_VLC1 *pTab;
  210. int32_t mvd, sign;
  211. uint32_t code;
  212. int32_t factor = fcode - 1;
  213. /* decode MVDx */
  214. code = mp4_ShowBits(pInfo, 12);
  215. if (code >= 128)
  216. pTab = mp4_MVD_B12_2 + ((code - 128) >> 5);
  217. else if (code >= 2)
  218. pTab = mp4_MVD_B12_1 + (code - 2);
  219. else {
  220. mp4_Error("Error: decoding MVD");
  221. return MP4_STATUS_ERROR;
  222. }
  223. mvd = pTab->code;
  224. mp4_FlushBits(pInfo, pTab->len);
  225. if (mvd) {
  226. sign = mp4_GetBit(pInfo);
  227. if (factor) {
  228. code = mp4_GetBits9(pInfo, factor);
  229. mvd = ((mvd - 1) << factor) + code + 1;
  230. }
  231. if (sign)
  232. mvd = -mvd;
  233. }
  234. *mvdx = mvd;
  235. /* decode MVDy */
  236. code = mp4_ShowBits(pInfo, 12);
  237. if (code >= 128)
  238. pTab = mp4_MVD_B12_2 + ((code - 128) >> 5);
  239. else if (code >= 2)
  240. pTab = mp4_MVD_B12_1 + (code - 2);
  241. else {
  242. mp4_Error("Error: decoding MVD");
  243. return MP4_STATUS_ERROR;
  244. }
  245. mvd = pTab->code;
  246. mp4_FlushBits(pInfo, pTab->len);
  247. if (mvd) {
  248. sign = mp4_GetBit(pInfo);
  249. if (factor) {
  250. code = mp4_GetBits9(pInfo, factor);
  251. mvd = ((mvd - 1) << factor) + code + 1;
  252. }
  253. if (sign)
  254. mvd = -mvd;
  255. }
  256. *mvdy = mvd;
  257. return MP4_STATUS_OK;
  258. }
  259. mp4_Status mp4_DecodeMV(mp4_Info *pInfo, IppMotionVector *mv, int32_t fcode)
  260. {
  261. int32_t mvdx, mvdy, range, range2, dx, dy;
  262. if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, fcode) != MP4_STATUS_OK)
  263. return MP4_STATUS_ERROR;
  264. range = 16 << fcode;
  265. range2 = range + range;
  266. dx = mv->dx + mvdx;
  267. if (dx < -range)
  268. dx += range2;
  269. else if (dx >= range)
  270. dx -= range2;
  271. mv->dx = (int16_t)dx;
  272. dy = mv->dy + mvdy;
  273. if (dy < -range)
  274. dy += range2;
  275. else if (dy >= range)
  276. dy -= range2;
  277. mv->dy = (int16_t)dy;
  278. return MP4_STATUS_OK;
  279. }
  280. mp4_Status mp4_Decode4MV(mp4_Info *pInfo, IppMotionVector *mv, int32_t fcode)
  281. {
  282. int32_t i, mvdx, mvdy, range, range2, dx, dy;
  283. range = 16 << fcode;
  284. range2 = range + range;
  285. for (i = 0; i < 4; i ++) {
  286. if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, fcode) != MP4_STATUS_OK)
  287. return MP4_STATUS_ERROR;
  288. dx = mv[i].dx + mvdx;
  289. if (dx < -range)
  290. dx += range2;
  291. else if (dx >= range)
  292. dx -= range2;
  293. mv[i].dx = (int16_t)dx;
  294. dy = mv[i].dy + mvdy;
  295. if (dy < -range)
  296. dy += range2;
  297. else if (dy >= range)
  298. dy -= range2;
  299. mv[i].dy = (int16_t)dy;
  300. }
  301. return MP4_STATUS_OK;
  302. }
  303. mp4_Status mp4_DecodeMV_Direct(mp4_Info *pInfo, IppMotionVector mvC[4], IppMotionVector mvForw[4], IppMotionVector mvBack[4], int32_t TRB, int32_t TRD, int32_t modb, int32_t comb_type)
  304. {
  305. int32_t mvdx, mvdy, i;
  306. if (modb == 2) {
  307. if (comb_type != IPPVC_MBTYPE_INTER4V) {
  308. mvForw[0].dx = mvForw[1].dx = mvForw[2].dx = mvForw[3].dx = (int16_t)((TRB * mvC[0].dx) / TRD);
  309. mvForw[0].dy = mvForw[1].dy = mvForw[2].dy = mvForw[3].dy = (int16_t)((TRB * mvC[0].dy) / TRD);
  310. mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (int16_t)(((TRB - TRD) * mvC[0].dx) / TRD);
  311. mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (int16_t)(((TRB - TRD) * mvC[0].dy) / TRD);
  312. } else
  313. for (i = 0; i < 4; i ++) {
  314. mvForw[i].dx = (int16_t)((TRB * mvC[i].dx) / TRD);
  315. mvForw[i].dy = (int16_t)((TRB * mvC[i].dy) / TRD);
  316. mvBack[i].dx = (int16_t)(((TRB - TRD) * mvC[i].dx) / TRD);
  317. mvBack[i].dy = (int16_t)(((TRB - TRD) * mvC[i].dy) / TRD);
  318. }
  319. } else {
  320. if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, 1) != MP4_STATUS_OK)
  321. return MP4_STATUS_ERROR;
  322. if (comb_type != IPPVC_MBTYPE_INTER4V) {
  323. mvForw[0].dx = mvForw[1].dx = mvForw[2].dx = mvForw[3].dx = (int16_t)((TRB * mvC[0].dx) / TRD + mvdx);
  324. mvForw[0].dy = mvForw[1].dy = mvForw[2].dy = mvForw[3].dy = (int16_t)((TRB * mvC[0].dy) / TRD + mvdy);
  325. if (mvdx == 0)
  326. mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (int16_t)(((TRB - TRD) * mvC[0].dx) / TRD);
  327. else
  328. mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (int16_t)(mvForw[0].dx - mvC[0].dx);
  329. if (mvdy == 0)
  330. mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (int16_t)(((TRB - TRD) * mvC[0].dy) / TRD);
  331. else
  332. mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (int16_t)(mvForw[0].dy - mvC[0].dy);
  333. } else
  334. for (i = 0; i < 4; i++) {
  335. mvForw[i].dx = (int16_t)((TRB * mvC[i].dx) / TRD + mvdx);
  336. mvForw[i].dy = (int16_t)((TRB * mvC[i].dy) / TRD + mvdy);
  337. if (mvdx == 0)
  338. mvBack[i].dx = (int16_t)(((TRB - TRD) * mvC[i].dx) / TRD);
  339. else
  340. mvBack[i].dx = (int16_t)(mvForw[i].dx - mvC[i].dx);
  341. if (mvdy == 0)
  342. mvBack[i].dy = (int16_t)(((TRB - TRD) * mvC[i].dy) / TRD);
  343. else
  344. mvBack[i].dy = (int16_t)(mvForw[i].dy - mvC[i].dy);
  345. }
  346. }
  347. return MP4_STATUS_OK;
  348. }
  349. mp4_Status mp4_DecodeMV_DirectField(mp4_Info *pInfo, int32_t mb_ftfr, int32_t mb_fbfr, IppMotionVector *mvTop, IppMotionVector *mvBottom, IppMotionVector *mvForwTop, IppMotionVector *mvForwBottom, IppMotionVector *mvBackTop, IppMotionVector *mvBackBottom, int32_t TRB, int32_t TRD, int32_t modb)
  350. {
  351. // field direct mode
  352. int32_t TRDt, TRDb, TRBt, TRBb, deltaTop, deltaBottom, mvdx, mvdy;
  353. deltaTop = mb_ftfr;
  354. deltaBottom = mb_fbfr - 1;
  355. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.top_field_first) {
  356. deltaTop = -deltaTop;
  357. deltaBottom = -deltaBottom;
  358. }
  359. TRDt = mp4_DivRoundInf(TRD, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaTop;
  360. TRDb = mp4_DivRoundInf(TRD, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaBottom;
  361. TRBt = mp4_DivRoundInf(TRB, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaTop;
  362. TRBb = mp4_DivRoundInf(TRB, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaBottom;
  363. if (modb == 2) {
  364. // delta == 0
  365. mvdx = mvdy = 0;
  366. } else {
  367. if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, 1) != MP4_STATUS_OK)
  368. return MP4_STATUS_ERROR;
  369. }
  370. mvForwTop->dx = (int16_t)((TRBt * mvTop->dx) / TRDt + mvdx);
  371. if (mvdx == 0)
  372. mvBackTop->dx = (int16_t)(((TRBt - TRDt) * mvTop->dx) / TRDt);
  373. else
  374. mvBackTop->dx = (int16_t)(mvForwTop->dx - mvTop->dx);
  375. mvForwTop->dy = (int16_t)((TRBt * mvTop->dy * 2) / TRDt + mvdy);
  376. if (mvdy == 0)
  377. mvBackTop->dy = (int16_t)(((TRBt - TRDt) * mvTop->dy * 2) / TRDt);
  378. else
  379. mvBackTop->dy = (int16_t)(mvForwTop->dy - mvTop->dy * 2);
  380. mvForwBottom->dx = (int16_t)((TRBb * mvBottom->dx) / TRDb + mvdx);
  381. if (mvdx == 0)
  382. mvBackBottom->dx = (int16_t)(((TRBb - TRDb) * mvBottom->dx) / TRDb);
  383. else
  384. mvBackBottom->dx = (int16_t)(mvForwBottom->dx - mvBottom->dx);
  385. mvForwBottom->dy = (int16_t)((TRBb * mvBottom->dy * 2) / TRDb + mvdy);
  386. if (mvdy == 0)
  387. mvBackBottom->dy = (int16_t)(((TRBb - TRDb) * mvBottom->dy * 2) / TRDb);
  388. else
  389. mvBackBottom->dy = (int16_t)(mvForwBottom->dy - mvBottom->dy * 2);
  390. mvForwTop->dy >>= 1;
  391. mvBackTop->dy >>= 1;
  392. mvForwBottom->dy >>= 1;
  393. mvBackBottom->dy >>= 1;
  394. return MP4_STATUS_OK;
  395. }
  396. /*static*/ void mp4_ExpandFrameReplicate(uint8_t *pSrcDstPlane, int32_t frameWidth, int32_t frameHeight, int32_t expandPels, int32_t step)
  397. {
  398. uint8_t *pDst1, *pDst2, *pSrc1, *pSrc2;
  399. int32_t i, j;
  400. uint32_t t1, t2;
  401. pDst1 = pSrcDstPlane + step * expandPels;
  402. pDst2 = pDst1 + frameWidth + expandPels;
  403. if (expandPels == 8) {
  404. for (i = 0; i < frameHeight; i ++) {
  405. t1 = pDst1[8] + (pDst1[8] << 8);
  406. t2 = pDst2[-1] + (pDst2[-1] << 8);
  407. t1 = (t1 << 16) + t1;
  408. t2 = (t2 << 16) + t2;
  409. ((uint32_t*)pDst1)[0] = t1;
  410. ((uint32_t*)pDst1)[1] = t1;
  411. ((uint32_t*)pDst2)[0] = t2;
  412. ((uint32_t*)pDst2)[1] = t2;
  413. pDst1 += step;
  414. pDst2 += step;
  415. }
  416. } else if (expandPels == 16) {
  417. for (i = 0; i < frameHeight; i ++) {
  418. t1 = pDst1[16] + (pDst1[16] << 8);
  419. t2 = pDst2[-1] + (pDst2[-1] << 8);
  420. t1 = (t1 << 16) + t1;
  421. t2 = (t2 << 16) + t2;
  422. ((uint32_t*)pDst1)[0] = t1;
  423. ((uint32_t*)pDst1)[1] = t1;
  424. ((uint32_t*)pDst1)[2] = t1;
  425. ((uint32_t*)pDst1)[3] = t1;
  426. ((uint32_t*)pDst2)[0] = t2;
  427. ((uint32_t*)pDst2)[1] = t2;
  428. ((uint32_t*)pDst2)[2] = t2;
  429. ((uint32_t*)pDst2)[3] = t2;
  430. pDst1 += step;
  431. pDst2 += step;
  432. }
  433. } else {
  434. for (i = 0; i < frameHeight; i ++) {
  435. ippsSet_8u(pDst1[expandPels], pDst1, expandPels);
  436. ippsSet_8u(pDst2[-1], pDst2, expandPels);
  437. pDst1 += step;
  438. pDst2 += step;
  439. }
  440. }
  441. pDst1 = pSrcDstPlane;
  442. pSrc1 = pSrcDstPlane + expandPels * step;
  443. pDst2 = pSrc1 + frameHeight * step;
  444. pSrc2 = pDst2 - step;
  445. j = frameWidth + 2 * expandPels;
  446. for (i = 0; i < expandPels; i ++) {
  447. ippsCopy_8u(pSrc1, pDst1, j);
  448. ippsCopy_8u(pSrc2, pDst2, j);
  449. pDst1 += step;
  450. pDst2 += step;
  451. }
  452. }
  453. void mp4_PadFrame(mp4_Info* pInfo)
  454. {
  455. #if 0
  456. /*
  457. // padding VOP (for not complete blocks padd by
  458. // 0 for DivX(tm) 5.0 AVI streams
  459. // 128 for QuickTime(tm) MP4 streams
  460. // replication for other
  461. */
  462. int32_t wL, hL, wC, hC, i;
  463. //if (pInfo->VisualObject.VideoObject.short_video_header)
  464. // return;
  465. wL = pInfo->VisualObject.VideoObject.width;
  466. hL = pInfo->VisualObject.VideoObject.height;
  467. wC = pInfo->VisualObject.VideoObject.width >> 1;
  468. hC = pInfo->VisualObject.VideoObject.height >> 1;
  469. if ((pInfo->VisualObject.VideoObject.width & 15 || pInfo->VisualObject.VideoObject.height & 15) &&
  470. ((pInfo->ftype == 1 && pInfo->ftype_f == 0) || (pInfo->ftype == 2 && pInfo->ftype_f == 1))) {
  471. uint8_t pad = (uint8_t)(pInfo->ftype == 1 ? 128 : 0);
  472. if (pInfo->VisualObject.VideoObject.width & 15) {
  473. uint8_t *p;
  474. // pad one col
  475. p = pInfo->VisualObject.cFrame.pY + pInfo->VisualObject.VideoObject.width;
  476. for (i = 0; i < pInfo->VisualObject.VideoObject.height; i ++) {
  477. *p = pad;
  478. p += pInfo->VisualObject.cFrame.stepY;
  479. }
  480. p = pInfo->VisualObject.cFrame.pCb + (pInfo->VisualObject.VideoObject.width >> 1);
  481. for (i = 0; i < pInfo->VisualObject.VideoObject.height >> 1; i ++) {
  482. *p = pad;
  483. p += pInfo->VisualObject.cFrame.stepCb;
  484. }
  485. p = pInfo->VisualObject.cFrame.pCr + (pInfo->VisualObject.VideoObject.width >> 1);
  486. for (i = 0; i < pInfo->VisualObject.VideoObject.height >> 1; i ++) {
  487. *p = pad;
  488. p += pInfo->VisualObject.cFrame.stepCr;
  489. }
  490. wL ++;
  491. wC ++;
  492. }
  493. if (pInfo->VisualObject.VideoObject.height & 15) {
  494. // pad one row
  495. ippsSet_8u(pad, pInfo->VisualObject.cFrame.pY + pInfo->VisualObject.cFrame.stepY * pInfo->VisualObject.VideoObject.height, pInfo->VisualObject.VideoObject.width);
  496. ippsSet_8u(pad, pInfo->VisualObject.cFrame.pCb + pInfo->VisualObject.cFrame.stepCb * (pInfo->VisualObject.VideoObject.height >> 1), pInfo->VisualObject.VideoObject.width >> 1);
  497. ippsSet_8u(pad, pInfo->VisualObject.cFrame.pCr + pInfo->VisualObject.cFrame.stepCr * (pInfo->VisualObject.VideoObject.height >> 1), pInfo->VisualObject.VideoObject.width >> 1);
  498. hL ++;
  499. hC ++;
  500. }
  501. }
  502. #else
  503. /*
  504. // padding VOP for not complete blocks
  505. // replication from macroblock boundary for DIVX and MP4 and from frame boundary for other
  506. */
  507. int32_t wL, hL, wC, hC;
  508. if ((pInfo->ftype == 1 && pInfo->ftype_f == 0) || (pInfo->ftype == 2 && pInfo->ftype_f == 1)) {
  509. wL = pInfo->VisualObject.VideoObject.MacroBlockPerRow * 16;
  510. hL = pInfo->VisualObject.VideoObject.MacroBlockPerCol * 16;
  511. } else {
  512. wL = pInfo->VisualObject.VideoObject.width;
  513. hL = pInfo->VisualObject.VideoObject.height;
  514. }
  515. wC = wL >> 1;
  516. hC = hL >> 1;
  517. #endif
  518. mp4_ExpandFrameReplicate(pInfo->VisualObject.cFrame->apY, wL, hL, 16 * MP4_NUM_EXT_MB, pInfo->VisualObject.cFrame->stepY);
  519. mp4_ExpandFrameReplicate(pInfo->VisualObject.cFrame->apCb, wC, hC, 8 * MP4_NUM_EXT_MB, pInfo->VisualObject.cFrame->stepCb);
  520. mp4_ExpandFrameReplicate(pInfo->VisualObject.cFrame->apCr, wC, hC, 8 * MP4_NUM_EXT_MB, pInfo->VisualObject.cFrame->stepCr);
  521. }
  522. mp4_Status mp4_DecodeVideoObjectPlane(mp4_Info* pInfo)
  523. {
  524. mp4_Status status = MP4_STATUS_OK;
  525. Ipp64s vop_time;
  526. // set VOP time
  527. if (pInfo->VisualObject.VideoObject.short_video_header)
  528. {
  529. vop_time = pInfo->VisualObject.VideoObject.vop_sync_time + pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.temporal_reference * 1001;
  530. if (pInfo->VisualObject.cFrame && pInfo->VisualObject.cFrame->time > vop_time)
  531. {
  532. pInfo->VisualObject.VideoObject.vop_sync_time += 256 * 1001;
  533. vop_time += 256 * 1001;
  534. }
  535. }
  536. else
  537. {
  538. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B)
  539. {
  540. vop_time = pInfo->VisualObject.VideoObject.vop_sync_time_b + pInfo->VisualObject.VideoObject.VideoObjectPlane.modulo_time_base * pInfo->VisualObject.VideoObject.vop_time_increment_resolution + pInfo->VisualObject.VideoObject.VideoObjectPlane.time_increment;
  541. }
  542. else
  543. {
  544. if (pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane.time_code > pInfo->VisualObject.VideoObject.vop_sync_time)
  545. pInfo->VisualObject.VideoObject.vop_sync_time = pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane.time_code;
  546. vop_time = pInfo->VisualObject.VideoObject.vop_sync_time + pInfo->VisualObject.VideoObject.VideoObjectPlane.modulo_time_base * pInfo->VisualObject.VideoObject.vop_time_increment_resolution + pInfo->VisualObject.VideoObject.VideoObjectPlane.time_increment;
  547. if (pInfo->VisualObject.VideoObject.vop_sync_time_b < pInfo->VisualObject.VideoObject.vop_sync_time)
  548. pInfo->VisualObject.VideoObject.vop_sync_time_b = pInfo->VisualObject.VideoObject.vop_sync_time;
  549. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.modulo_time_base != 0) {
  550. pInfo->VisualObject.VideoObject.vop_sync_time = vop_time - pInfo->VisualObject.VideoObject.VideoObjectPlane.time_increment;
  551. }
  552. }
  553. }
  554. // if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded || vop_time != pInfo->VisualObject.rFrame.time) {
  555. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded ||
  556. ( (!pInfo->VisualObject.cFrame || vop_time != pInfo->VisualObject.cFrame->time) &&
  557. (!pInfo->VisualObject.rFrame || vop_time != pInfo->VisualObject.rFrame->time) &&
  558. (!pInfo->VisualObject.nFrame || vop_time != pInfo->VisualObject.nFrame->time)
  559. ))
  560. {
  561. switch (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type)
  562. {
  563. case MP4_VOP_TYPE_I :
  564. // set new video frame
  565. if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_STATIC)
  566. {
  567. // TODO: verify
  568. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.sFrame);
  569. pInfo->VisualObject.sFrame = pInfo->VisualObject.cFrame;
  570. pInfo->VisualObject.cFrame = 0;
  571. }
  572. else
  573. {
  574. if (pInfo->noPVOPs)
  575. {
  576. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  577. pInfo->VisualObject.cFrame=0;
  578. }
  579. else if (pInfo->noBVOPs)
  580. {
  581. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  582. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  583. pInfo->VisualObject.rFrame = pInfo->VisualObject.cFrame;
  584. pInfo->VisualObject.cFrame = 0;
  585. }
  586. else
  587. {
  588. if (pInfo->VisualObject.VideoObject.VOPindex > 0)
  589. {
  590. if (pInfo->VisualObject.VideoObject.prevPlaneIsB)
  591. {
  592. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  593. pInfo->VisualObject.cFrame = 0;
  594. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
  595. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  596. pInfo->VisualObject.rFrame = pInfo->VisualObject.nFrame;
  597. pInfo->VisualObject.nFrame = 0;
  598. pInfo->VisualObject.VideoObject.prevPlaneIsB=0;
  599. }
  600. else
  601. {
  602. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  603. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  604. pInfo->VisualObject.rFrame = pInfo->VisualObject.cFrame;
  605. pInfo->VisualObject.cFrame = 0;
  606. }
  607. }
  608. }
  609. }
  610. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded)
  611. {
  612. if (pInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR)
  613. {
  614. status = mp4_DecodeVOP_I(pInfo);
  615. } //f else
  616. //f status = mp4_DecodeVOP_I_Shape(pInfo);
  617. if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_STATIC && pInfo->VisualObject.VideoObject.VOPindex == 0)
  618. {
  619. // TODO: verify (was: mp4_SWAP(mp4_Frame, pInfo->VisualObject.sFrame, pInfo->VisualObject.cFrame);
  620. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.sFrame);
  621. pInfo->VisualObject.sFrame = pInfo->VisualObject.cFrame;
  622. pInfo->VisualObject.cFrame = 0;
  623. mp4_ExpandFrameReplicate(pInfo->VisualObject.sFrame->apY, pInfo->VisualObject.VideoObject.sprite_width, pInfo->VisualObject.VideoObject.sprite_height, 16, pInfo->VisualObject.sFrame->stepY);
  624. mp4_ExpandFrameReplicate(pInfo->VisualObject.sFrame->apCb, pInfo->VisualObject.VideoObject.sprite_width >> 1, pInfo->VisualObject.VideoObject.sprite_height >> 1, 8, pInfo->VisualObject.sFrame->stepCb);
  625. mp4_ExpandFrameReplicate(pInfo->VisualObject.sFrame->apCr, pInfo->VisualObject.VideoObject.sprite_width >> 1, pInfo->VisualObject.VideoObject.sprite_height >> 1, 8, pInfo->VisualObject.sFrame->stepCr);
  626. } else {
  627. mp4_PadFrame(pInfo);
  628. }
  629. // set past and future time for B-VOP
  630. pInfo->VisualObject.VideoObject.rTime = pInfo->VisualObject.VideoObject.nTime;
  631. pInfo->VisualObject.VideoObject.nTime = vop_time;
  632. #ifdef USE_NOTCODED_STATE
  633. // Clear not_coded MB state
  634. if ((pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) && pInfo->VisualObject.VideoObject.obmc_disable && !pInfo->VisualObject.VideoObject.ncStateCleared) {
  635. ippsZero_8u(pInfo->VisualObject.VideoObject.ncState, pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
  636. pInfo->VisualObject.VideoObject.ncStateCleared = 1;
  637. }
  638. #endif
  639. }
  640. mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_I);
  641. break;
  642. case MP4_VOP_TYPE_P :
  643. // set new video frame
  644. if (pInfo->noBVOPs)
  645. {
  646. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  647. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  648. pInfo->VisualObject.rFrame = pInfo->VisualObject.cFrame;
  649. pInfo->VisualObject.cFrame = 0;
  650. }
  651. else
  652. {
  653. if (pInfo->VisualObject.VideoObject.VOPindex > 0)
  654. {
  655. if (pInfo->VisualObject.VideoObject.prevPlaneIsB)
  656. {
  657. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  658. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  659. pInfo->VisualObject.cFrame=0;
  660. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
  661. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  662. pInfo->VisualObject.rFrame = pInfo->VisualObject.nFrame;
  663. pInfo->VisualObject.nFrame = 0;
  664. pInfo->VisualObject.VideoObject.prevPlaneIsB = 0;
  665. }
  666. else
  667. {
  668. if (pInfo->VisualObject.cFrame)
  669. {
  670. int w, h;
  671. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  672. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  673. pInfo->VisualObject.rFrame = pInfo->VisualObject.cFrame;
  674. pInfo->VisualObject.cFrame=0;
  675. pInfo->VisualObject.cFrame = CreateFrame(&pInfo->VisualObject);
  676. w = (pInfo->VisualObject.cFrame->mbPerRow + 2 * MP4_NUM_EXT_MB) << 4;
  677. h = (pInfo->VisualObject.cFrame->mbPerCol + 2 * MP4_NUM_EXT_MB) << 4;
  678. memcpy(pInfo->VisualObject.cFrame->mid, pInfo->VisualObject.rFrame->mid, w * h + (w * h >> 1));
  679. }
  680. }
  681. }
  682. }
  683. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded)
  684. {
  685. status = mp4_DecodeVOP_P(pInfo);
  686. mp4_PadFrame(pInfo);
  687. // set past and future time for B-VOP
  688. pInfo->VisualObject.VideoObject.rTime = pInfo->VisualObject.VideoObject.nTime;
  689. pInfo->VisualObject.VideoObject.nTime = vop_time;
  690. }
  691. mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_P);
  692. #ifdef USE_NOTCODED_STATE
  693. pInfo->VisualObject.VideoObject.ncStateCleared = 0;
  694. #endif
  695. break;
  696. case MP4_VOP_TYPE_B :
  697. status = MP4_STATUS_OK;
  698. // after reset it is need to skip first B-frames
  699. //if (pInfo->VisualObject.VideoObject.VOPindex >= 2)
  700. //DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  701. if (!pInfo->VisualObject.VideoObject.prevPlaneIsB)
  702. {
  703. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
  704. pInfo->VisualObject.nFrame = pInfo->VisualObject.cFrame;
  705. pInfo->VisualObject.cFrame = 0;
  706. pInfo->VisualObject.VideoObject.prevPlaneIsB = 1;
  707. }
  708. else
  709. {
  710. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  711. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  712. pInfo->VisualObject.cFrame=0;
  713. }
  714. if (pInfo->VisualObject.VideoObject.VOPindex < 2)
  715. {
  716. // if we don't have both reference frames
  717. if (pInfo->ftype == 2)
  718. {
  719. //repeat last frame for AVI timing reasons
  720. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
  721. if (pInfo->VisualObject.nFrame)
  722. pInfo->VisualObject.nFrame->outputted = 0;
  723. }
  724. mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_B);
  725. break;
  726. }
  727. // set Tframe for direct interlaced mode
  728. if (!pInfo->VisualObject.VideoObject.Tframe)
  729. pInfo->VisualObject.VideoObject.Tframe = (int32_t)(vop_time - pInfo->VisualObject.rFrame->time);
  730. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded)
  731. {
  732. pInfo->VisualObject.VideoObject.TRB = (int32_t)(vop_time - pInfo->VisualObject.VideoObject.rTime);
  733. pInfo->VisualObject.VideoObject.TRD = (int32_t)(pInfo->VisualObject.VideoObject.nTime - pInfo->VisualObject.VideoObject.rTime);
  734. // defense from bad streams when B-VOPs are before Past and/or Future
  735. if (pInfo->VisualObject.VideoObject.TRB <= 0)
  736. pInfo->VisualObject.VideoObject.TRB = 1;
  737. if (pInfo->VisualObject.VideoObject.TRD <= 0)
  738. pInfo->VisualObject.VideoObject.TRD = 2;
  739. if (pInfo->VisualObject.VideoObject.TRD <= pInfo->VisualObject.VideoObject.TRB)
  740. {
  741. pInfo->VisualObject.VideoObject.TRB = 1;
  742. pInfo->VisualObject.VideoObject.TRD = 2;
  743. }
  744. if (pInfo->VisualObject.VideoObject.Tframe >= pInfo->VisualObject.VideoObject.TRD)
  745. pInfo->VisualObject.VideoObject.Tframe = pInfo->VisualObject.VideoObject.TRB;
  746. status = mp4_DecodeVOP_B(pInfo);
  747. }
  748. mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_B);
  749. break;
  750. case MP4_VOP_TYPE_S :
  751. // set new video frame
  752. if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_GMC)
  753. {
  754. if (pInfo->VisualObject.VideoObject.VOPindex > 0)
  755. {
  756. if (pInfo->VisualObject.VideoObject.prevPlaneIsB)
  757. {
  758. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  759. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  760. pInfo->VisualObject.cFrame=0;
  761. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
  762. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  763. pInfo->VisualObject.rFrame = pInfo->VisualObject.nFrame;
  764. pInfo->VisualObject.nFrame = 0;
  765. pInfo->VisualObject.VideoObject.prevPlaneIsB = 0;
  766. }
  767. else
  768. {
  769. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  770. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  771. pInfo->VisualObject.rFrame = pInfo->VisualObject.cFrame;
  772. pInfo->VisualObject.cFrame = 0;
  773. }
  774. }
  775. }
  776. else
  777. {
  778. DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  779. ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
  780. pInfo->VisualObject.cFrame=0;
  781. }
  782. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded)
  783. {
  784. status = mp4_DecodeVOP_S(pInfo);
  785. if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_GMC)
  786. {
  787. mp4_PadFrame(pInfo);
  788. // set past and future time for B-VOP
  789. pInfo->VisualObject.VideoObject.rTime = pInfo->VisualObject.VideoObject.nTime;
  790. pInfo->VisualObject.VideoObject.nTime = vop_time;
  791. }
  792. #ifdef USE_NOTCODED_STATE
  793. // Clear not_coded MB state
  794. if ((pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) && pInfo->VisualObject.VideoObject.obmc_disable && !pInfo->VisualObject.VideoObject.ncStateCleared)
  795. {
  796. ippsZero_8u(pInfo->VisualObject.VideoObject.ncState, pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
  797. pInfo->VisualObject.VideoObject.ncStateCleared = 1;
  798. }
  799. #endif
  800. }
  801. mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_S);
  802. break;
  803. }
  804. if (!pInfo->VisualObject.VideoObject.VideoObjectPlane.coded)
  805. {
  806. //pInfo->VisualObject.rFrame->outputted = 0;
  807. //pInfo->VisualObject.cFrame = pInfo->VisualObject.rFrame;
  808. //pInfo->VisualObject.rFrame=0;
  809. //DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
  810. //ippsCopy_8u(pInfo->VisualObject.rFrame->apY, pInfo->VisualObject.cFrame->apY, pInfo->VisualObject.cFrame->stepY * ((pInfo->VisualObject.VideoObject.MacroBlockPerCol + 2) << 4));
  811. //ippsCopy_8u(pInfo->VisualObject.rFrame->apCb, pInfo->VisualObject.cFrame->apCb, pInfo->VisualObject.cFrame->stepCb * ((pInfo->VisualObject.VideoObject.MacroBlockPerCol + 2) << 3));
  812. //ippsCopy_8u(pInfo->VisualObject.rFrame->apCr, pInfo->VisualObject.cFrame->apCr, pInfo->VisualObject.cFrame->stepCr * ((pInfo->VisualObject.VideoObject.MacroBlockPerCol + 2) << 3));
  813. #ifdef USE_NOTCODED_STATE
  814. ippsSet_8u(1, pInfo->VisualObject.VideoObject.ncState, pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
  815. pInfo->VisualObject.VideoObject.ncStateCleared = 0;
  816. #endif
  817. }
  818. mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP);
  819. }
  820. if (pInfo->VisualObject.cFrame)
  821. {
  822. // save current VOP type
  823. pInfo->VisualObject.cFrame->type = pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type;
  824. // save current VOP time
  825. pInfo->VisualObject.cFrame->time = vop_time;
  826. }
  827. return status;
  828. }
  829. /*
  830. // Intra DC and AC reconstruction for SVH macroblock
  831. */
  832. mp4_Status mp4_DecodeIntraMB_SVH(mp4_Info *pInfo, int32_t pat, int32_t quant, uint8_t *pR[], int32_t stepR[])
  833. {
  834. __ALIGN16(int16_t, coeff, 64);
  835. int32_t blockNum, pm = 32, lnz;
  836. for (blockNum = 0; blockNum < 6; blockNum ++) {
  837. if (ippiReconstructCoeffsIntra_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pat & pm, quant, 0, IPPVC_SCAN_ZIGZAG, 0) != ippStsNoErr) {
  838. mp4_Error("Error: decoding coefficients of Inter block");
  839. return MP4_STATUS_ERROR;
  840. }
  841. if (lnz > 0) {
  842. ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
  843. } else {
  844. mp4_Set8x8_8u(pR[blockNum], stepR[blockNum], (uint8_t)((coeff[0] + 4) >> 3));
  845. }
  846. if (pat & pm) {
  847. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
  848. } else {
  849. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
  850. }
  851. pm >>= 1;
  852. }
  853. return MP4_STATUS_OK;
  854. }
  855. mp4_Status mp4_DecodeInterMB_SVH(mp4_Info *pInfo, int16_t *coeffMB, int32_t quant, int32_t pat)
  856. {
  857. int32_t i, lnz, pm = 32;
  858. int16_t *coeff = coeffMB;
  859. for (i = 0; i < 6; i ++) {
  860. if ((pat) & pm) {
  861. if (ippiReconstructCoeffsInter_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, quant, 0) != ippStsNoErr) {
  862. mp4_Error("Error: decoding coefficients of Inter block");
  863. return MP4_STATUS_ERROR;
  864. }
  865. if (lnz != 0) {
  866. if ((lnz <= 4) && (coeff[16] == 0))
  867. ippiDCT8x8Inv_2x2_16s_C1I(coeff);
  868. else if ((lnz <= 13) && (coeff[32] == 0))
  869. ippiDCT8x8Inv_4x4_16s_C1I(coeff);
  870. else
  871. ippiDCT8x8Inv_16s_C1I(coeff);
  872. } else {
  873. mp4_Set64_16s((int16_t)((coeff[0] + 4) >> 3), coeff);
  874. }
  875. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_C);
  876. } else {
  877. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
  878. }
  879. pm >>= 1;
  880. coeff += 64;
  881. }
  882. return MP4_STATUS_OK;
  883. }
  884. /*
  885. // Intra DC and AC reconstruction for macroblock
  886. */
  887. mp4_Status mp4_DecodeIntraMB(mp4_Info *pInfo, int32_t x, int32_t pat, int32_t quant, int32_t dcVLC, int32_t ac_pred_flag, uint8_t *pR[], int32_t stepR[])
  888. {
  889. __ALIGN16(int16_t, coeff, 64);
  890. int32_t blockNum, lnz, predDir, scan, dc, dcA, dcB, dcC, dcP, k, nz, predQuantA, predQuantC, dcScaler, pm = 32;
  891. int16_t *predAcA, *predAcC, sDC = 0;
  892. mp4_IntraPredBlock *bCurr;
  893. for (blockNum = 0; blockNum < 6; blockNum ++) {
  894. // find prediction direction
  895. bCurr = &pInfo->VisualObject.VideoObject.IntraPredBuff.block[6*x+blockNum];
  896. dcA = bCurr->predA->dct_dc >= 0 ? bCurr->predA->dct_dc : 1024;
  897. dcB = bCurr->predB->dct_dc >= 0 ? bCurr->predB->dct_dc : 1024;
  898. dcC = bCurr->predC->dct_dc >= 0 ? bCurr->predC->dct_dc : 1024;
  899. if (mp4_ABS(dcA - dcB) < mp4_ABS(dcB - dcC)) {
  900. predDir = IPPVC_SCAN_HORIZONTAL;
  901. dcP = dcC;
  902. } else {
  903. predDir = IPPVC_SCAN_VERTICAL;
  904. dcP = dcA;
  905. }
  906. scan = IPPVC_SCAN_ZIGZAG;
  907. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag)
  908. scan = IPPVC_SCAN_VERTICAL;
  909. else if (ac_pred_flag)
  910. scan = predDir;
  911. // decode coeffs
  912. if (dcVLC) {
  913. if (ippiDecodeDCIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA) != ippStsNoErr) {
  914. mp4_Error("Error: decoding DC coefficient of Intra block");
  915. return MP4_STATUS_ERROR;
  916. }
  917. }
  918. if (pat & pm) {
  919. if (ippiDecodeCoeffsIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, 0, dcVLC, scan) != ippStsNoErr) {
  920. mp4_Error("Error: decoding coefficients of Intra block");
  921. return MP4_STATUS_ERROR;
  922. }
  923. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
  924. } else {
  925. if (dcVLC)
  926. sDC = coeff[0];
  927. mp4_Zero64_16s(coeff);
  928. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
  929. lnz = 0;
  930. if (dcVLC)
  931. coeff[0] = sDC;
  932. }
  933. // predict DC
  934. dcScaler = (blockNum < 4) ? mp4_DCScalerLuma[quant] : mp4_DCScalerChroma[quant];
  935. dc = coeff[0] + mp4_DivIntraDC(dcP, dcScaler);
  936. mp4_CLIP(dc, -2048, 2047);
  937. coeff[0] = (int16_t)dc;
  938. // predict AC
  939. nz = 0;
  940. if (ac_pred_flag) {
  941. if (predDir == IPPVC_SCAN_HORIZONTAL && (bCurr->predC->dct_dc >= 0)) {
  942. predAcC = bCurr->predC->dct_acC;
  943. predQuantC = (blockNum == 2 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1];
  944. if (predQuantC == quant)
  945. for (k = 1; k < 8; k ++) {
  946. coeff[k] = (int16_t)(coeff[k] + predAcC[k]);
  947. if (coeff[k]) {
  948. mp4_CLIP(coeff[k], -2048, 2047);
  949. nz = 1;
  950. }
  951. }
  952. else
  953. for (k = 1; k < 8; k ++) {
  954. coeff[k] = (int16_t)(coeff[k] + mp4_DivIntraAC(predAcC[k] * predQuantC, quant));
  955. if (coeff[k]) {
  956. mp4_CLIP(coeff[k], -2048, 2047);
  957. nz = 1;
  958. }
  959. }
  960. } else if (predDir == IPPVC_SCAN_VERTICAL && (bCurr->predA->dct_dc >= 0)) {
  961. predAcA = bCurr->predA->dct_acA;
  962. predQuantA = (blockNum == 1 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x];
  963. if (predQuantA == quant)
  964. for (k = 1; k < 8; k ++) {
  965. coeff[k*8] = (int16_t)(coeff[k*8] + predAcA[k]);
  966. if (coeff[k*8]) {
  967. mp4_CLIP(coeff[k*8], -2048, 2047);
  968. nz = 1;
  969. }
  970. }
  971. else
  972. for (k = 1; k < 8; k ++) {
  973. coeff[k*8] = (int16_t)(coeff[k*8] + mp4_DivIntraAC(predAcA[k] * predQuantA, quant));
  974. if (coeff[k*8]) {
  975. mp4_CLIP(coeff[k*8], -2048, 2047);
  976. nz = 1;
  977. }
  978. }
  979. }
  980. }
  981. // copy predicted AC for future Prediction
  982. for (k = 1; k < 8; k ++) {
  983. bCurr[6].dct_acC[k] = coeff[k];
  984. bCurr[6].dct_acA[k] = coeff[k*8];
  985. }
  986. if ((nz | lnz) || (pInfo->VisualObject.VideoObject.quant_type == 1)) {
  987. ippiQuantInvIntra_MPEG4_16s_C1I(coeff, 63, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, quant, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA);
  988. ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
  989. } else {
  990. k = coeff[0] * dcScaler;
  991. mp4_CLIP(k, -2048, 2047);
  992. coeff[0] = (int16_t)k;
  993. k = (k + 4) >> 3;
  994. mp4_CLIP(k, 0, 255);
  995. mp4_Set8x8_8u(pR[blockNum], stepR[blockNum], (uint8_t)k);
  996. }
  997. // copy DC for future Prediction
  998. if (blockNum >= 3)
  999. pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[blockNum].dct_dc = bCurr[6].dct_dc;
  1000. bCurr[6].dct_dc = coeff[0];
  1001. // copy quant
  1002. if (blockNum == 5)
  1003. pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1] = (uint8_t)quant;
  1004. pm >>= 1;
  1005. }
  1006. return MP4_STATUS_OK;
  1007. }
  1008. /*
  1009. // Intra DC and AC reconstruction for DP macroblock
  1010. */
  1011. mp4_Status mp4_DecodeIntraMB_DP(mp4_Info *pInfo, int16_t dct_dc[], int32_t x, int32_t pat, int32_t quant, int32_t dcVLC, int32_t ac_pred_flag, uint8_t *pR[], int32_t stepR[])
  1012. {
  1013. __ALIGN16(int16_t, coeff, 64);
  1014. int32_t blockNum, lnz, predDir, scan, dc, dcA, dcB, dcC, dcP, k, nz, predQuantA, predQuantC, dcScaler, pm = 32;
  1015. int16_t *predAcA, *predAcC;
  1016. mp4_IntraPredBlock *bCurr;
  1017. for (blockNum = 0; blockNum < 6; blockNum ++) {
  1018. // find prediction direction
  1019. bCurr = &pInfo->VisualObject.VideoObject.IntraPredBuff.block[6*x+blockNum];
  1020. dcA = bCurr->predA->dct_dc >= 0 ? bCurr->predA->dct_dc : 1024;
  1021. dcB = bCurr->predB->dct_dc >= 0 ? bCurr->predB->dct_dc : 1024;
  1022. dcC = bCurr->predC->dct_dc >= 0 ? bCurr->predC->dct_dc : 1024;
  1023. if (mp4_ABS(dcA - dcB) < mp4_ABS(dcB - dcC)) {
  1024. predDir = IPPVC_SCAN_HORIZONTAL;
  1025. dcP = dcC;
  1026. } else {
  1027. predDir = IPPVC_SCAN_VERTICAL;
  1028. dcP = dcA;
  1029. }
  1030. scan = (ac_pred_flag) ? predDir : IPPVC_SCAN_ZIGZAG;
  1031. // decode coeffs
  1032. if (pat & pm) {
  1033. if (ippiDecodeCoeffsIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pInfo->VisualObject.VideoObject.reversible_vlc, dcVLC, scan) != ippStsNoErr) {
  1034. mp4_Error("Error: decoding coefficients of Intra block");
  1035. return MP4_STATUS_ERROR;
  1036. }
  1037. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
  1038. } else {
  1039. mp4_Zero64_16s(coeff);
  1040. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
  1041. lnz = 0;
  1042. }
  1043. if (dcVLC)
  1044. coeff[0] = dct_dc[blockNum];
  1045. // predict DC
  1046. dcScaler = (blockNum < 4) ? mp4_DCScalerLuma[quant] : mp4_DCScalerChroma[quant];
  1047. dc = coeff[0] + mp4_DivIntraDC(dcP, dcScaler);
  1048. mp4_CLIP(dc, -2048, 2047);
  1049. coeff[0] = (int16_t)dc;
  1050. // predict AC
  1051. nz = 0;
  1052. if (ac_pred_flag) {
  1053. if (predDir == IPPVC_SCAN_HORIZONTAL && (bCurr->predC->dct_dc >= 0)) {
  1054. predAcC = bCurr->predC->dct_acC;
  1055. predQuantC = (blockNum == 2 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1];
  1056. if (predQuantC == quant)
  1057. for (k = 1; k < 8; k ++) {
  1058. coeff[k] = (int16_t)(coeff[k] + predAcC[k]); // clip ??
  1059. if (coeff[k]) {
  1060. mp4_CLIP(coeff[k], -2048, 2047);
  1061. nz = 1;
  1062. }
  1063. }
  1064. else
  1065. for (k = 1; k < 8; k ++) {
  1066. coeff[k] = (int16_t)(coeff[k] + mp4_DivIntraAC(predAcC[k] * predQuantC, quant));
  1067. if (coeff[k]) {
  1068. mp4_CLIP(coeff[k], -2048, 2047);
  1069. nz = 1;
  1070. }
  1071. }
  1072. } else if (predDir == IPPVC_SCAN_VERTICAL && (bCurr->predA->dct_dc >= 0)) {
  1073. predAcA = bCurr->predA->dct_acA;
  1074. predQuantA = (blockNum == 1 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x];
  1075. if (predQuantA == quant)
  1076. for (k = 1; k < 8; k ++) {
  1077. coeff[k*8] = (int16_t)(coeff[k*8] + predAcA[k]);
  1078. if (coeff[k*8]) {
  1079. mp4_CLIP(coeff[k*8], -2048, 2047);
  1080. nz = 1;
  1081. }
  1082. }
  1083. else
  1084. for (k = 1; k < 8; k ++) {
  1085. coeff[k*8] = (int16_t)(coeff[k*8] + mp4_DivIntraAC(predAcA[k] * predQuantA, quant));
  1086. if (coeff[k*8]) {
  1087. mp4_CLIP(coeff[k*8], -2048, 2047);
  1088. nz = 1;
  1089. }
  1090. }
  1091. }
  1092. }
  1093. // copy predicted AC for future Prediction
  1094. for (k = 1; k < 8; k ++) {
  1095. bCurr[6].dct_acC[k] = coeff[k];
  1096. bCurr[6].dct_acA[k] = coeff[k*8];
  1097. }
  1098. if ((nz | lnz) || (pInfo->VisualObject.VideoObject.quant_type == 1)) {
  1099. ippiQuantInvIntra_MPEG4_16s_C1I(coeff, 63, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, quant, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA);
  1100. ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
  1101. } else {
  1102. k = coeff[0] * dcScaler;
  1103. mp4_CLIP(k, -2048, 2047);
  1104. coeff[0] = (int16_t)k;
  1105. k = (k + 4) >> 3;
  1106. mp4_CLIP(k, 0, 255);
  1107. mp4_Set8x8_8u(pR[blockNum], stepR[blockNum], (uint8_t)k);
  1108. }
  1109. // copy DC for future Prediction
  1110. if (blockNum >= 3)
  1111. pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[blockNum].dct_dc = bCurr[6].dct_dc;
  1112. bCurr[6].dct_dc = coeff[0];
  1113. // copy quant
  1114. if (blockNum == 5)
  1115. pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1] = (uint8_t)quant;
  1116. pm >>= 1;
  1117. }
  1118. return MP4_STATUS_OK;
  1119. }
  1120. /*
  1121. // Intra DC and AC reconstruction for macroblock (w/o iDCT)
  1122. */
  1123. mp4_Status mp4_ReconstructCoeffsIntraMB(mp4_Info *pInfo, int32_t x, int32_t pat, int32_t quant, int32_t dcVLC, int32_t ac_pred_flag, int16_t *coeffMB, int32_t lastNZ[])
  1124. {
  1125. int32_t blockNum, lnz, predDir, scan, dc, dcA, dcB, dcC, dcP, k, nz, predQuantA, predQuantC, dcScaler, pm = 32;
  1126. int16_t *predAcA, *predAcC, sDC = 0, *coeff = coeffMB;
  1127. mp4_IntraPredBlock *bCurr;
  1128. for (blockNum = 0; blockNum < 6; blockNum ++) {
  1129. // find prediction direction
  1130. bCurr = &pInfo->VisualObject.VideoObject.IntraPredBuff.block[6*x+blockNum];
  1131. dcA = bCurr->predA->dct_dc >= 0 ? bCurr->predA->dct_dc : 1024;
  1132. dcB = bCurr->predB->dct_dc >= 0 ? bCurr->predB->dct_dc : 1024;
  1133. dcC = bCurr->predC->dct_dc >= 0 ? bCurr->predC->dct_dc : 1024;
  1134. if (mp4_ABS(dcA - dcB) < mp4_ABS(dcB - dcC)) {
  1135. predDir = IPPVC_SCAN_HORIZONTAL;
  1136. dcP = dcC;
  1137. } else {
  1138. predDir = IPPVC_SCAN_VERTICAL;
  1139. dcP = dcA;
  1140. }
  1141. scan = IPPVC_SCAN_ZIGZAG;
  1142. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag)
  1143. scan = IPPVC_SCAN_VERTICAL;
  1144. else if (ac_pred_flag)
  1145. scan = predDir;
  1146. // decode coeffs
  1147. if (dcVLC) {
  1148. if (ippiDecodeDCIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA) != ippStsNoErr) {
  1149. mp4_Error("Error: decoding DC coefficient of Intra block");
  1150. return MP4_STATUS_ERROR;
  1151. }
  1152. }
  1153. if (pat & pm) {
  1154. if (ippiDecodeCoeffsIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, 0, dcVLC, scan) != ippStsNoErr) {
  1155. mp4_Error("Error: decoding coefficients of Intra block");
  1156. return MP4_STATUS_ERROR;
  1157. }
  1158. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
  1159. } else {
  1160. if (dcVLC)
  1161. sDC = coeff[0];
  1162. mp4_Zero64_16s(coeff);
  1163. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
  1164. lnz = 0;
  1165. if (dcVLC)
  1166. coeff[0] = sDC;
  1167. }
  1168. // predict DC
  1169. dcScaler = (blockNum < 4) ? mp4_DCScalerLuma[quant] : mp4_DCScalerChroma[quant];
  1170. dc = coeff[0] + mp4_DivIntraDC(dcP, dcScaler);
  1171. mp4_CLIP(dc, -2048, 2047);
  1172. coeff[0] = (int16_t)dc;
  1173. // predict AC
  1174. nz = 0;
  1175. if (ac_pred_flag) {
  1176. if (predDir == IPPVC_SCAN_HORIZONTAL && (bCurr->predC->dct_dc >= 0)) {
  1177. predAcC = bCurr->predC->dct_acC;
  1178. predQuantC = (blockNum == 2 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1];
  1179. if (predQuantC == quant)
  1180. for (k = 1; k < 8; k ++) {
  1181. coeff[k] = (int16_t)(coeff[k] + predAcC[k]);
  1182. if (coeff[k]) {
  1183. mp4_CLIP(coeff[k], -2048, 2047);
  1184. nz = 1;
  1185. }
  1186. }
  1187. else
  1188. for (k = 1; k < 8; k ++) {
  1189. coeff[k] = (int16_t)(coeff[k] + mp4_DivIntraAC(predAcC[k] * predQuantC, quant));
  1190. if (coeff[k]) {
  1191. mp4_CLIP(coeff[k], -2048, 2047);
  1192. nz = 1;
  1193. }
  1194. }
  1195. } else if (predDir == IPPVC_SCAN_VERTICAL && (bCurr->predA->dct_dc >= 0)) {
  1196. predAcA = bCurr->predA->dct_acA;
  1197. predQuantA = (blockNum == 1 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x];
  1198. if (predQuantA == quant)
  1199. for (k = 1; k < 8; k ++) {
  1200. coeff[k*8] = (int16_t)(coeff[k*8] + predAcA[k]);
  1201. if (coeff[k*8]) {
  1202. mp4_CLIP(coeff[k*8], -2048, 2047);
  1203. nz = 1;
  1204. }
  1205. }
  1206. else
  1207. for (k = 1; k < 8; k ++) {
  1208. coeff[k*8] = (int16_t)(coeff[k*8] + mp4_DivIntraAC(predAcA[k] * predQuantA, quant));
  1209. if (coeff[k*8]) {
  1210. mp4_CLIP(coeff[k*8], -2048, 2047);
  1211. nz = 1;
  1212. }
  1213. }
  1214. }
  1215. }
  1216. // copy predicted AC for future Prediction
  1217. for (k = 1; k < 8; k ++) {
  1218. bCurr[6].dct_acC[k] = coeff[k];
  1219. bCurr[6].dct_acA[k] = coeff[k*8];
  1220. }
  1221. if ((nz | lnz) || (pInfo->VisualObject.VideoObject.quant_type == 1)) {
  1222. ippiQuantInvIntra_MPEG4_16s_C1I(coeff, 63, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, quant, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA);
  1223. lnz = 63;
  1224. } else {
  1225. k = coeff[0] * dcScaler;
  1226. mp4_CLIP(k, -2048, 2047);
  1227. coeff[0] = (int16_t)k;
  1228. }
  1229. // copy DC for future Prediction
  1230. if (blockNum >= 3)
  1231. pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[blockNum].dct_dc = bCurr[6].dct_dc;
  1232. bCurr[6].dct_dc = coeff[0];
  1233. // copy quant
  1234. if (blockNum == 5)
  1235. pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1] = (uint8_t)quant;
  1236. lastNZ[blockNum] = lnz;
  1237. pm >>= 1;
  1238. coeff += 64;
  1239. }
  1240. return MP4_STATUS_OK;
  1241. }
  1242. mp4_Status mp4_DecodeInterMB(mp4_Info *pInfo, int16_t *coeffMB, int32_t quant, int32_t pat, int32_t scan)
  1243. {
  1244. int32_t i, lnz, pm = 32;
  1245. int16_t *coeff = coeffMB;
  1246. for (i = 0; i < 6; i ++) {
  1247. if ((pat) & pm) {
  1248. if (ippiReconstructCoeffsInter_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pInfo->VisualObject.VideoObject.reversible_vlc, scan, pInfo->VisualObject.VideoObject.QuantInvInterSpec, quant) != ippStsNoErr) {
  1249. mp4_Error("Error: decoding coefficients of Inter block");
  1250. return MP4_STATUS_ERROR;
  1251. }
  1252. if (pInfo->VisualObject.VideoObject.quant_type == 0 || (coeff[63] == 0)) {
  1253. if (lnz != 0) {
  1254. if (scan == IPPVC_SCAN_ZIGZAG) {
  1255. if ((lnz <= 4) && (coeff[16] == 0))
  1256. ippiDCT8x8Inv_2x2_16s_C1I(coeff);
  1257. else if ((lnz <= 13) && (coeff[32] == 0))
  1258. ippiDCT8x8Inv_4x4_16s_C1I(coeff);
  1259. else
  1260. ippiDCT8x8Inv_16s_C1I(coeff);
  1261. } else { // IPPVC_SCAN_VERTICAL
  1262. if ((lnz <= 5) && (coeff[16] == 0) && (coeff[24] == 0))
  1263. ippiDCT8x8Inv_2x2_16s_C1I(coeff);
  1264. else if (lnz <= 9)
  1265. ippiDCT8x8Inv_4x4_16s_C1I(coeff);
  1266. else
  1267. ippiDCT8x8Inv_16s_C1I(coeff);
  1268. }
  1269. } else {
  1270. mp4_Set64_16s((int16_t)((coeff[0] + 4) >> 3), coeff);
  1271. }
  1272. } else {
  1273. ippiDCT8x8Inv_16s_C1I(coeff);
  1274. }
  1275. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_C);
  1276. } else {
  1277. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
  1278. }
  1279. pm >>= 1;
  1280. coeff += 64;
  1281. }
  1282. return MP4_STATUS_OK;
  1283. }
  1284. void mp4_DCTInvCoeffsInterMB(mp4_Info *pInfo, int16_t *coeffMB, int32_t lastNZ[], int32_t pat, int32_t scan)
  1285. {
  1286. int32_t i, lnz, pm = 32;
  1287. int16_t *coeff = coeffMB;
  1288. for (i = 0; i < 6; i ++) {
  1289. if ((pat) & pm) {
  1290. if (pInfo->VisualObject.VideoObject.quant_type == 0 || (coeff[63] == 0)) {
  1291. lnz = lastNZ[i];
  1292. if (lnz != 0) {
  1293. if (scan == IPPVC_SCAN_ZIGZAG) {
  1294. if ((lnz <= 4) && (coeff[16] == 0))
  1295. ippiDCT8x8Inv_2x2_16s_C1I(coeff);
  1296. else if ((lnz <= 13) && (coeff[32] == 0))
  1297. ippiDCT8x8Inv_4x4_16s_C1I(coeff);
  1298. else
  1299. ippiDCT8x8Inv_16s_C1I(coeff);
  1300. } else { // IPPVC_SCAN_VERTICAL
  1301. if ((lnz <= 5) && (coeff[16] == 0) && (coeff[24] == 0))
  1302. ippiDCT8x8Inv_2x2_16s_C1I(coeff);
  1303. else if (lnz <= 9)
  1304. ippiDCT8x8Inv_4x4_16s_C1I(coeff);
  1305. else
  1306. ippiDCT8x8Inv_16s_C1I(coeff);
  1307. }
  1308. } else {
  1309. mp4_Set64_16s((int16_t)((coeff[0] + 4) >> 3), coeff);
  1310. }
  1311. } else {
  1312. ippiDCT8x8Inv_16s_C1I(coeff);
  1313. }
  1314. }
  1315. pm >>= 1;
  1316. coeff += 64;
  1317. }
  1318. }
  1319. /*
  1320. // decode mcbpc and set MBtype and ChromaPattern
  1321. */
  1322. mp4_Status mp4_DecodeMCBPC_P(mp4_Info* pInfo, int32_t *mbType, int32_t *mbPattern, int32_t stat)
  1323. {
  1324. uint32_t code;
  1325. int32_t type, pattern;
  1326. code = mp4_ShowBits9(pInfo, 9);
  1327. if (code >= 256) {
  1328. type = IPPVC_MBTYPE_INTER;
  1329. pattern = 0;
  1330. mp4_FlushBits(pInfo, 1);
  1331. } else {
  1332. type = mp4_PVOPmb_type[code];
  1333. pattern = mp4_PVOPmb_cbpc[code];
  1334. mp4_FlushBits(pInfo, mp4_PVOPmb_bits[code]);
  1335. }
  1336. if (code == 0) {
  1337. mp4_Error("Error: decoding MCBPC");
  1338. return MP4_STATUS_ERROR;
  1339. }
  1340. *mbType = type;
  1341. *mbPattern = pattern;
  1342. if (stat) {
  1343. if (type == IPPVC_MBTYPE_INTER)
  1344. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER);
  1345. else if (type == IPPVC_MBTYPE_INTER_Q)
  1346. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER_Q);
  1347. else if (type == IPPVC_MBTYPE_INTRA)
  1348. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTRA);
  1349. else if (type == IPPVC_MBTYPE_INTRA_Q)
  1350. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTRA_Q);
  1351. else if (type == IPPVC_MBTYPE_INTER4V)
  1352. mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER4V);
  1353. }
  1354. return MP4_STATUS_OK;
  1355. }
  1356. mp4_Status mp4_PredictDecode1MV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, int32_t y, int32_t x)
  1357. {
  1358. IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr;
  1359. int32_t mbInRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
  1360. int32_t fcode = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
  1361. int32_t resync_marker_disable = pInfo->VisualObject.VideoObject.resync_marker_disable;
  1362. // block 0
  1363. mvCurr = MBcurr[0].mv;
  1364. mvLeft = MBcurr[-1].mv;
  1365. mvTop = MBcurr[-mbInRow].mv;
  1366. mvRight = MBcurr[-mbInRow+1].mv;
  1367. if (resync_marker_disable) {
  1368. if ((y | x) == 0) {
  1369. mvCurr[0].dx = mvCurr[0].dy = 0;
  1370. } else if (x == 0) {
  1371. mvCurr[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
  1372. mvCurr[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
  1373. } else if (y == 0) {
  1374. mvCurr[0] = mvLeft[1];
  1375. } else if (x == mbInRow - 1) {
  1376. mvCurr[0].dx = mp4_Median(0, mvLeft[1].dx, mvTop[2].dx);
  1377. mvCurr[0].dy = mp4_Median(0, mvLeft[1].dy, mvTop[2].dy);
  1378. } else {
  1379. mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
  1380. mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
  1381. }
  1382. } else {
  1383. int32_t validLeft, validTop, validRight;
  1384. if (x > 0)
  1385. validLeft = MBcurr[-1].validPred;
  1386. else
  1387. validLeft = 0;
  1388. if (y > 0)
  1389. validTop = MBcurr[-mbInRow].validPred;
  1390. else
  1391. validTop = 0;
  1392. if ((y > 0) && (x < mbInRow - 1))
  1393. validRight = MBcurr[-mbInRow+1].validPred;
  1394. else
  1395. validRight = 0;
  1396. switch ((validLeft << 2) | (validTop << 1) | validRight) {
  1397. case 7:
  1398. mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
  1399. mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
  1400. break;
  1401. case 6:
  1402. mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, 0);
  1403. mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, 0);
  1404. break;
  1405. case 5:
  1406. mvCurr[0].dx = mp4_Median(mvLeft[1].dx, 0, mvRight[2].dx);
  1407. mvCurr[0].dy = mp4_Median(mvLeft[1].dy, 0, mvRight[2].dy);
  1408. break;
  1409. case 4:
  1410. mvCurr[0] = mvLeft[1];
  1411. break;
  1412. case 3:
  1413. mvCurr[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
  1414. mvCurr[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
  1415. break;
  1416. case 2:
  1417. mvCurr[0] = mvTop[2];
  1418. break;
  1419. case 1:
  1420. mvCurr[0] = mvRight[2];
  1421. break;
  1422. default:
  1423. mvCurr[0].dx = mvCurr[0].dy = 0;
  1424. break;
  1425. }
  1426. }
  1427. return mp4_DecodeMV(pInfo, mvCurr, fcode);
  1428. }
  1429. mp4_Status mp4_PredictDecode4MV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, int32_t y, int32_t x)
  1430. {
  1431. IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr;
  1432. int32_t mbInRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
  1433. int32_t fcode = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
  1434. int32_t resync_marker_disable = pInfo->VisualObject.VideoObject.resync_marker_disable;
  1435. mvCurr = MBcurr[0].mv;
  1436. mvLeft = MBcurr[-1].mv;
  1437. mvTop = MBcurr[-mbInRow].mv;
  1438. mvRight = MBcurr[-mbInRow+1].mv;
  1439. if (resync_marker_disable) {
  1440. // block 0
  1441. if ((y | x) == 0) {
  1442. mvCurr[0].dx = mvCurr[0].dy = 0;
  1443. } else if (x == 0) {
  1444. mvCurr[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
  1445. mvCurr[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
  1446. } else if (y == 0) {
  1447. mvCurr[0] = mvLeft[1];
  1448. } else if (x == mbInRow - 1) {
  1449. mvCurr[0].dx = mp4_Median(0, mvLeft[1].dx, mvTop[2].dx);
  1450. mvCurr[0].dy = mp4_Median(0, mvLeft[1].dy, mvTop[2].dy);
  1451. } else {
  1452. mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
  1453. mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
  1454. }
  1455. if (mp4_DecodeMV(pInfo, mvCurr, fcode) != MP4_STATUS_OK)
  1456. return MP4_STATUS_ERROR;
  1457. // block 1
  1458. if (y == 0) {
  1459. mvCurr[1] = mvCurr[0];
  1460. } else if (x == mbInRow - 1) {
  1461. mvCurr[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, 0);
  1462. mvCurr[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, 0);
  1463. } else {
  1464. mvCurr[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
  1465. mvCurr[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
  1466. }
  1467. if (mp4_DecodeMV(pInfo, mvCurr+1, fcode) != MP4_STATUS_OK)
  1468. return MP4_STATUS_ERROR;
  1469. // block 2
  1470. if (x == 0) {
  1471. mvCurr[2].dx = mp4_Median(0, mvCurr[0].dx, mvCurr[1].dx);
  1472. mvCurr[2].dy = mp4_Median(0, mvCurr[0].dy, mvCurr[1].dy);
  1473. } else {
  1474. mvCurr[2].dx = mp4_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
  1475. mvCurr[2].dy = mp4_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
  1476. }
  1477. if (mp4_DecodeMV(pInfo, mvCurr+2, fcode) != MP4_STATUS_OK)
  1478. return MP4_STATUS_ERROR;
  1479. // block 3
  1480. mvCurr[3].dx = mp4_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
  1481. mvCurr[3].dy = mp4_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
  1482. if (mp4_DecodeMV(pInfo, mvCurr+3, fcode) != MP4_STATUS_OK)
  1483. return MP4_STATUS_ERROR;
  1484. } else {
  1485. int32_t validLeft, validTop, validRight;
  1486. if (x > 0)
  1487. validLeft = MBcurr[-1].validPred;
  1488. else
  1489. validLeft = 0;
  1490. if (y > 0)
  1491. validTop = MBcurr[-mbInRow].validPred;
  1492. else
  1493. validTop = 0;
  1494. if ((y > 0) && (x < mbInRow - 1))
  1495. validRight = MBcurr[-mbInRow+1].validPred;
  1496. else
  1497. validRight = 0;
  1498. // block 0
  1499. switch ((validLeft << 2) | (validTop << 1) | validRight) {
  1500. case 7:
  1501. mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
  1502. mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
  1503. break;
  1504. case 6:
  1505. mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, 0);
  1506. mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, 0);
  1507. break;
  1508. case 5:
  1509. mvCurr[0].dx = mp4_Median(mvLeft[1].dx, 0, mvRight[2].dx);
  1510. mvCurr[0].dy = mp4_Median(mvLeft[1].dy, 0, mvRight[2].dy);
  1511. break;
  1512. case 4:
  1513. mvCurr[0] = mvLeft[1];
  1514. break;
  1515. case 3:
  1516. mvCurr[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
  1517. mvCurr[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
  1518. break;
  1519. case 2:
  1520. mvCurr[0] = mvTop[2];
  1521. break;
  1522. case 1:
  1523. mvCurr[0] = mvRight[2];
  1524. break;
  1525. default:
  1526. mvCurr[0].dx = mvCurr[0].dy = 0;
  1527. break;
  1528. }
  1529. if (mp4_DecodeMV(pInfo, mvCurr, fcode) != MP4_STATUS_OK)
  1530. return MP4_STATUS_ERROR;
  1531. // block 1
  1532. switch ((validTop << 1) | validRight) {
  1533. case 3:
  1534. mvCurr[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
  1535. mvCurr[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
  1536. break;
  1537. case 2:
  1538. mvCurr[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, 0);
  1539. mvCurr[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, 0);
  1540. break;
  1541. case 1:
  1542. mvCurr[1].dx = mp4_Median(mvCurr[0].dx, 0, mvRight[2].dx);
  1543. mvCurr[1].dy = mp4_Median(mvCurr[0].dy, 0, mvRight[2].dy);
  1544. break;
  1545. default:
  1546. mvCurr[1] = mvCurr[0];
  1547. break;
  1548. }
  1549. if (mp4_DecodeMV(pInfo, mvCurr+1, fcode) != MP4_STATUS_OK)
  1550. return MP4_STATUS_ERROR;
  1551. // block 2
  1552. if (validLeft) {
  1553. mvCurr[2].dx = mp4_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
  1554. mvCurr[2].dy = mp4_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
  1555. } else {
  1556. mvCurr[2].dx = mp4_Median(0, mvCurr[0].dx, mvCurr[1].dx);
  1557. mvCurr[2].dy = mp4_Median(0, mvCurr[0].dy, mvCurr[1].dy);
  1558. }
  1559. if (mp4_DecodeMV(pInfo, mvCurr+2, fcode) != MP4_STATUS_OK)
  1560. return MP4_STATUS_ERROR;
  1561. // block 3
  1562. mvCurr[3].dx = mp4_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
  1563. mvCurr[3].dy = mp4_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
  1564. if (mp4_DecodeMV(pInfo, mvCurr+3, fcode) != MP4_STATUS_OK)
  1565. return MP4_STATUS_ERROR;
  1566. }
  1567. return MP4_STATUS_OK;
  1568. }
  1569. mp4_Status mp4_PredictDecodeFMV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, int32_t y, int32_t x, IppMotionVector *mvT, IppMotionVector *mvB)
  1570. {
  1571. IppMotionVector mvLeft = {0, 0}, mvTop = {0, 0}, mvRight = {0, 0}, mvPred;
  1572. int32_t mbInRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
  1573. int32_t fcode = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
  1574. int32_t resync_marker_disable = pInfo->VisualObject.VideoObject.resync_marker_disable;
  1575. if (x > 0) {
  1576. mvLeft = MBcurr[-1].mv[1];
  1577. mvLeft.dy = (int16_t)mp4_Div2(mvLeft.dy);
  1578. }
  1579. if (y > 0) {
  1580. mvTop = MBcurr[-mbInRow].mv[2];
  1581. mvTop.dy = (int16_t)mp4_Div2(mvTop.dy);
  1582. if (x < (mbInRow - 1)) {
  1583. mvRight = MBcurr[-mbInRow+1].mv[2];
  1584. mvRight.dy = (int16_t)mp4_Div2(mvRight.dy);
  1585. }
  1586. }
  1587. if (resync_marker_disable) {
  1588. if ((y | x) == 0) {
  1589. mvPred.dx = mvPred.dy = 0;
  1590. } else if (x == 0) {
  1591. mvPred.dx = mp4_Median(0, mvTop.dx, mvRight.dx);
  1592. mvPred.dy = mp4_Median(0, mvTop.dy, mvRight.dy);
  1593. } else if (y == 0) {
  1594. mvPred = mvLeft;
  1595. } else if (x == mbInRow - 1) {
  1596. mvPred.dx = mp4_Median(0, mvLeft.dx, mvTop.dx);
  1597. mvPred.dy = mp4_Median(0, mvLeft.dy, mvTop.dy);
  1598. } else {
  1599. mvPred.dx = mp4_Median(mvLeft.dx, mvTop.dx, mvRight.dx);
  1600. mvPred.dy = mp4_Median(mvLeft.dy, mvTop.dy, mvRight.dy);
  1601. }
  1602. } else {
  1603. int32_t validLeft, validTop, validRight;
  1604. if (x > 0)
  1605. validLeft = MBcurr[-1].validPred;
  1606. else
  1607. validLeft = 0;
  1608. if (y > 0)
  1609. validTop = MBcurr[-mbInRow].validPred;
  1610. else
  1611. validTop = 0;
  1612. if ((y > 0) && (x < mbInRow - 1))
  1613. validRight = MBcurr[-mbInRow+1].validPred;
  1614. else
  1615. validRight = 0;
  1616. switch ((validLeft << 2) | (validTop << 1) | validRight) {
  1617. case 7:
  1618. mvPred.dx = mp4_Median(mvLeft.dx, mvTop.dx, mvRight.dx);
  1619. mvPred.dy = mp4_Median(mvLeft.dy, mvTop.dy, mvRight.dy);
  1620. break;
  1621. case 6:
  1622. mvPred.dx = mp4_Median(mvLeft.dx, mvTop.dx, 0);
  1623. mvPred.dy = mp4_Median(mvLeft.dy, mvTop.dy, 0);
  1624. break;
  1625. case 5:
  1626. mvPred.dx = mp4_Median(mvLeft.dx, 0, mvRight.dx);
  1627. mvPred.dy = mp4_Median(mvLeft.dy, 0, mvRight.dy);
  1628. break;
  1629. case 4:
  1630. mvPred = mvLeft;
  1631. break;
  1632. case 3:
  1633. mvPred.dx = mp4_Median(0, mvTop.dx, mvRight.dx);
  1634. mvPred.dy = mp4_Median(0, mvTop.dy, mvRight.dy);
  1635. break;
  1636. case 2:
  1637. mvPred = mvTop;
  1638. break;
  1639. case 1:
  1640. mvPred = mvRight;
  1641. break;
  1642. default:
  1643. mvPred.dx = mvPred.dy = 0;
  1644. break;
  1645. }
  1646. }
  1647. *mvT = mvPred;
  1648. if (mp4_DecodeMV(pInfo, mvT, fcode) != MP4_STATUS_OK)
  1649. return MP4_STATUS_ERROR;
  1650. *mvB = mvPred;
  1651. if (mp4_DecodeMV(pInfo, mvB, fcode) != MP4_STATUS_OK)
  1652. return MP4_STATUS_ERROR;
  1653. // update MV buffer for future prediction
  1654. MBcurr->mv[0].dx = MBcurr->mv[1].dx = MBcurr->mv[2].dx = MBcurr->mv[3].dx = (int16_t)mp4_Div2Round(mvT->dx + mvB->dx);
  1655. MBcurr->mv[0].dy = MBcurr->mv[1].dy = MBcurr->mv[2].dy = MBcurr->mv[3].dy = (int16_t)(mvT->dy + mvB->dy);
  1656. return MP4_STATUS_OK;
  1657. }
  1658. void mp4_OBMC(mp4_Info *pInfo, mp4_MacroBlock *pMBinfo, IppMotionVector *mvCur, int32_t colNum, int32_t rowNum, IppiRect limitRectL, uint8_t *pYc, int32_t stepYc, uint8_t *pYr, int32_t stepYr, int32_t cbpy, int16_t *coeffMB, int32_t dct_type)
  1659. {
  1660. IppMotionVector mvOBMCL, mvOBMCU, mvOBMCR, mvOBMCB, *mvLeft, *mvUpper, *mvRight;
  1661. int32_t mbPerRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow, dx, dy, rt;
  1662. // get Right MV
  1663. if (colNum == mbPerRow - 1)
  1664. mvRight = &mvCur[1];
  1665. else if (pMBinfo[1].type >= IPPVC_MBTYPE_INTRA)
  1666. mvRight = &mvCur[1];
  1667. else
  1668. mvRight = pMBinfo[1].mv;
  1669. // get Left MV
  1670. if (colNum == 0)
  1671. mvLeft = mvCur - 1;
  1672. else if (pMBinfo[-1].type >= IPPVC_MBTYPE_INTRA)
  1673. mvLeft = mvCur - 1;
  1674. else
  1675. mvLeft = pMBinfo[-1].mv;
  1676. // get Upper MV
  1677. if (rowNum == 0)
  1678. mvUpper = mvCur - 2;
  1679. else if (pMBinfo[-mbPerRow].type >= IPPVC_MBTYPE_INTRA)
  1680. mvUpper = mvCur - 2;
  1681. else
  1682. mvUpper = pMBinfo[-mbPerRow].mv;
  1683. dx = colNum * 16;
  1684. dy = rowNum * 16;
  1685. rt = pInfo->VisualObject.VideoObject.VideoObjectPlane.rounding_type;
  1686. if (pInfo->VisualObject.VideoObject.quarter_sample) {
  1687. mp4_LimitMVQ(&mvLeft[1], &mvOBMCL, &limitRectL, dx, dy, 8);
  1688. mp4_LimitMVQ(&mvUpper[2], &mvOBMCU, &limitRectL, dx, dy, 8);
  1689. mp4_LimitMVQ(&mvCur[1], &mvOBMCR, &limitRectL, dx, dy, 8);
  1690. mp4_LimitMVQ(&mvCur[2], &mvOBMCB, &limitRectL, dx, dy, 8);
  1691. ippiOBMC8x8QP_MPEG4_8u_C1R(pYr, stepYr, pYc, stepYc, &mvCur[0], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
  1692. mp4_LimitMVQ(&mvCur[0], &mvOBMCL, &limitRectL, dx+8, dy, 8);
  1693. mp4_LimitMVQ(&mvUpper[3], &mvOBMCU, &limitRectL, dx+8, dy, 8);
  1694. mp4_LimitMVQ(&mvRight[0], &mvOBMCR, &limitRectL, dx+8, dy, 8);
  1695. mp4_LimitMVQ(&mvCur[3], &mvOBMCB, &limitRectL, dx+8, dy, 8);
  1696. ippiOBMC8x8QP_MPEG4_8u_C1R(pYr+8, stepYr, pYc+8, stepYc, &mvCur[1], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
  1697. mp4_LimitMVQ(&mvLeft[3], &mvOBMCL, &limitRectL, dx, dy+8, 8);
  1698. mp4_LimitMVQ(&mvCur[0], &mvOBMCU, &limitRectL, dx, dy+8, 8);
  1699. mp4_LimitMVQ(&mvCur[3], &mvOBMCR, &limitRectL, dx, dy+8, 8);
  1700. ippiOBMC8x8QP_MPEG4_8u_C1R(pYr+stepYr*8, stepYr, pYc+stepYc*8, stepYc, &mvCur[2], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[2], rt);
  1701. mp4_LimitMVQ(&mvCur[2], &mvOBMCL, &limitRectL, dx+8, dy+8, 8);
  1702. mp4_LimitMVQ(&mvCur[1], &mvOBMCU, &limitRectL, dx+8, dy+8, 8);
  1703. mp4_LimitMVQ(&mvRight[2], &mvOBMCR, &limitRectL, dx+8, dy+8, 8);
  1704. ippiOBMC8x8QP_MPEG4_8u_C1R(pYr+8+stepYr*8, stepYr, pYc+8+stepYc*8, stepYc, &mvCur[3], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[3], rt);
  1705. } else {
  1706. mp4_LimitMV(&mvLeft[1], &mvOBMCL, &limitRectL, dx, dy, 8);
  1707. mp4_LimitMV(&mvUpper[2], &mvOBMCU, &limitRectL, dx, dy, 8);
  1708. mp4_LimitMV(&mvCur[1], &mvOBMCR, &limitRectL, dx, dy, 8);
  1709. mp4_LimitMV(&mvCur[2], &mvOBMCB, &limitRectL, dx, dy, 8);
  1710. ippiOBMC8x8HP_MPEG4_8u_C1R(pYr, stepYr, pYc, stepYc, &mvCur[0], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
  1711. mp4_LimitMV(&mvCur[0], &mvOBMCL, &limitRectL, dx+8, dy, 8);
  1712. mp4_LimitMV(&mvUpper[3], &mvOBMCU, &limitRectL, dx+8, dy, 8);
  1713. mp4_LimitMV(&mvRight[0], &mvOBMCR, &limitRectL, dx+8, dy, 8);
  1714. mp4_LimitMV(&mvCur[3], &mvOBMCB, &limitRectL, dx+8, dy, 8);
  1715. ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+8, stepYr, pYc+8, stepYc, &mvCur[1], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
  1716. mp4_LimitMV(&mvLeft[3], &mvOBMCL, &limitRectL, dx, dy+8, 8);
  1717. mp4_LimitMV(&mvCur[0], &mvOBMCU, &limitRectL, dx, dy+8, 8);
  1718. mp4_LimitMV(&mvCur[3], &mvOBMCR, &limitRectL, dx, dy+8, 8);
  1719. ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+stepYr*8, stepYr, pYc+stepYc*8, stepYc, &mvCur[2], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[2], rt);
  1720. mp4_LimitMV(&mvCur[2], &mvOBMCL, &limitRectL, dx+8, dy+8, 8);
  1721. mp4_LimitMV(&mvCur[1], &mvOBMCU, &limitRectL, dx+8, dy+8, 8);
  1722. mp4_LimitMV(&mvRight[2], &mvOBMCR, &limitRectL, dx+8, dy+8, 8);
  1723. ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+8+stepYr*8, stepYr, pYc+8+stepYc*8, stepYc, &mvCur[3], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[3], rt);
  1724. }
  1725. if (!dct_type) {
  1726. mp4_AddResidual(cbpy & 8, pYc, stepYc, coeffMB);
  1727. mp4_AddResidual(cbpy & 4, pYc+8, stepYc, coeffMB+64);
  1728. mp4_AddResidual(cbpy & 2, pYc+stepYc*8, stepYc, coeffMB+128);
  1729. mp4_AddResidual(cbpy & 1, pYc+stepYc*8+8, stepYc, coeffMB+192);
  1730. } else {
  1731. mp4_AddResidual(cbpy & 8, pYc, stepYc*2, coeffMB);
  1732. mp4_AddResidual(cbpy & 4, pYc+8, stepYc*2, coeffMB+64);
  1733. mp4_AddResidual(cbpy & 2, pYc+stepYc, stepYc*2, coeffMB+128);
  1734. mp4_AddResidual(cbpy & 1, pYc+stepYc+8, stepYc*2, coeffMB+192);
  1735. }
  1736. }
  1737. void mp4_CopyMacroBlocks(const mp4_Frame *rFrame, mp4_Frame *cFrame, int32_t mbPerRow, int32_t rowNum, int32_t colNum, int32_t n)
  1738. {
  1739. int32_t i, stepYr, stepYc, stepCbr, stepCbc, stepCrr, stepCrc;
  1740. uint8_t *pYc, *pCbc, *pCrc, *pYr, *pCbr, *pCrr;
  1741. if (n <= 0)
  1742. return;
  1743. stepYc = cFrame->stepY;
  1744. stepCbc = cFrame->stepCb;
  1745. stepCrc = cFrame->stepCr;
  1746. stepYr = rFrame->stepY;
  1747. stepCbr = rFrame->stepCb;
  1748. stepCrr = rFrame->stepCr;
  1749. pYc = cFrame->pY + (rowNum * stepYc + colNum) * 16;
  1750. pCbc = cFrame->pCb + (rowNum * stepCbc + colNum) * 8;
  1751. pCrc = cFrame->pCr + (rowNum * stepCrc + colNum) * 8;
  1752. pYr = rFrame->pY + (rowNum * stepYr + colNum) * 16;
  1753. pCbr = rFrame->pCb + (rowNum * stepCbr + colNum) * 8;
  1754. pCrr = rFrame->pCr + (rowNum * stepCrr + colNum) * 8;
  1755. for (i = rowNum * mbPerRow + colNum; i < rowNum * mbPerRow + colNum + n; i ++) {
  1756. ippiCopy16x16_8u_C1R(pYr, stepYr, pYc, stepYc);
  1757. ippiCopy8x8_8u_C1R(pCbr, stepCbr, pCbc, stepCbc);
  1758. ippiCopy8x8_8u_C1R(pCrr, stepCrr, pCrc, stepCrc);
  1759. if ((i + 1) % mbPerRow == 0) {
  1760. pYc += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
  1761. pCbc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbc << 3) - stepCbc;
  1762. pCrc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrc << 3) - stepCrc;
  1763. pYr += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYr << 4) - stepYr;
  1764. pCbr += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbr << 3) - stepCbr;
  1765. pCrr += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrr << 3) - stepCrr;
  1766. } else {
  1767. pYc += 16; pCrc += 8; pCbc += 8;
  1768. pYr += 16; pCrr += 8; pCbr += 8;
  1769. }
  1770. }
  1771. }
  1772. // added by benski
  1773. mp4_Frame *CreateFrame(mp4_VisualObject *object)
  1774. {
  1775. if (object->frame_cache)
  1776. {
  1777. mp4_Frame *ret = object->frame_cache;
  1778. object->frame_cache = ret->next;
  1779. ret->next = 0;
  1780. ret->reference_count = 1;
  1781. return ret;
  1782. }
  1783. else
  1784. {
  1785. mp4_Frame *ret = (mp4_Frame *)calloc(1, sizeof(mp4_Frame));
  1786. ret->reference_count = 1;
  1787. ret->sprite = 0;
  1788. ret->mbPerRow = (object->VideoObject.width + 15) >> 4;
  1789. ret->mbPerCol = (object->VideoObject.height + 15) >> 4;
  1790. AllocateInitFrame(ret);
  1791. return ret;
  1792. }
  1793. }
  1794. mp4_Frame *CreateSpriteFrame(mp4_VisualObject *object)
  1795. {
  1796. if (object->sprite_cache)
  1797. {
  1798. mp4_Frame *ret = object->sprite_cache;
  1799. object->sprite_cache = ret->next;
  1800. ret->next = 0;
  1801. ret->reference_count = 1;
  1802. return ret;
  1803. }
  1804. else
  1805. {
  1806. mp4_Frame *ret = (mp4_Frame *)calloc(1, sizeof(mp4_Frame));
  1807. ret->reference_count = 1;
  1808. ret->sprite = 1;
  1809. ret->mbPerRow = (object->VideoObject.sprite_width + 15) >> 4;
  1810. ret->mbPerCol = (object->VideoObject.sprite_height + 15) >> 4;
  1811. AllocateInitFrame(ret);
  1812. return ret;
  1813. }
  1814. }
  1815. /* to delete
  1816. free(decoder->dec.VisualObject.cFrame.mid);
  1817. decoder->dec.VisualObject.cFrame.mid = 0;
  1818. */
  1819. void ReleaseFrame(mp4_VisualObject *object, mp4_Frame *frame)
  1820. {
  1821. if (frame && --frame->reference_count == 0)
  1822. {
  1823. if (frame->outputted == 0)
  1824. {
  1825. // DebugBreak();
  1826. }
  1827. frame->outputted = 0;
  1828. if (frame->sprite)
  1829. {
  1830. frame->next = object->sprite_cache;
  1831. object->sprite_cache = frame;
  1832. }
  1833. else
  1834. {
  1835. frame->next = object->frame_cache;
  1836. object->frame_cache = frame;
  1837. }
  1838. }
  1839. }
  1840. mp4_Frame *GetDisplayFrame(mp4_VisualObject *object)
  1841. {
  1842. mp4_Frame *ret = object->display_frames;
  1843. if (ret)
  1844. {
  1845. object->display_frames = ret->next;
  1846. ret->next = 0;
  1847. }
  1848. return ret;
  1849. }
  1850. void DisplayFrame(mp4_VisualObject *object, mp4_Frame *frame)
  1851. {
  1852. if (frame)
  1853. {
  1854. mp4_Frame *tail = object->display_frames;
  1855. if (frame->outputted)
  1856. {
  1857. DebugBreak();
  1858. }
  1859. frame->outputted = 1;
  1860. frame->reference_count++;
  1861. if (tail)
  1862. {
  1863. while (tail->next)
  1864. {
  1865. tail = tail->next;
  1866. }
  1867. tail->next = frame;
  1868. frame->next = 0;
  1869. }
  1870. else
  1871. {
  1872. object->display_frames = frame;
  1873. frame->next = 0;
  1874. }
  1875. }
  1876. }
  1877. void FreeCache(mp4_VisualObject *object)
  1878. {
  1879. while (object->display_frames)
  1880. {
  1881. mp4_Frame *frame = object->display_frames;
  1882. object->display_frames = frame->next;
  1883. free(frame->mid);
  1884. free(frame);
  1885. }
  1886. while (object->frame_cache)
  1887. {
  1888. mp4_Frame *frame = object->frame_cache;
  1889. object->frame_cache = frame->next;
  1890. free(frame->mid);
  1891. free(frame);
  1892. }
  1893. while (object->sprite_cache)
  1894. {
  1895. mp4_Frame *frame = object->frame_cache;
  1896. object->frame_cache = frame->next;
  1897. free(frame->mid);
  1898. free(frame);
  1899. }
  1900. }