123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983 |
- /* ///////////////////////////////////////////////////////////////////////
- //
- // INTEL CORPORATION PROPRIETARY INFORMATION
- // This software is supplied under the terms of a license agreement or
- // nondisclosure agreement with Intel Corporation and may not be copied
- // or disclosed except in accordance with the terms of that agreement.
- // Copyright (c) 2001-2008 Intel Corporation. All Rights Reserved.
- //
- // Description: Decodes MPEG-4 bitstream.
- //
- */
- #include "mp4def.h"
- #include "mp4dec.h"
- #pragma warning(disable : 188) // enumerated type mixed with another type ICL
- void mp4_ResetVOL(mp4_Info *pInfo)
- {
- pInfo->VisualObject.VideoObject.VOPindex = 0;
- pInfo->VisualObject.VideoObject.prevPlaneIsB = 0;
- pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane.time_code = 0;
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- pInfo->VisualObject.cFrame=0;
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- pInfo->VisualObject.rFrame=0;
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
- pInfo->VisualObject.nFrame=0;
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.sFrame);
- pInfo->VisualObject.sFrame=0;
- }
- static int AllocateInitFrame(mp4_Frame* pFrame)
- {
- int32_t w, h;
- w = (pFrame->mbPerRow + 2 * MP4_NUM_EXT_MB) << 4;
- h = (pFrame->mbPerCol + 2 * MP4_NUM_EXT_MB) << 4;
- pFrame->mid = malloc(w * h + (w * h >> 1));
- if (!pFrame->mid)
- return 1; // out of memory
- ippsSet_8u(0, pFrame->mid, w * h);
- ippsSet_8u(128, pFrame->mid + w * h, w * h >> 1);
- pFrame->stepY = w;
- pFrame->stepCb = w >> 1;
- pFrame->stepCr = w >> 1;
- /* benski> stuff from LockFrame... */
- pFrame->apY = pFrame->mid;
- pFrame->pY = pFrame->apY + w * 16 + 16;
- pFrame->apCb = pFrame->apY + w * h;
- w >>= 1;
- h >>= 1;
- pFrame->pCb = pFrame->apCb + w * 8 + 8;
- pFrame->apCr = pFrame->apCb + w * h;
- pFrame->pCr = pFrame->apCr + w * 8 + 8;
- return 0;
- }
- static mp4_Status mp4_AllocInitFrame(mp4_Frame* pFrame, int32_t mbPerRow, int32_t mbPerCol)
- {
- int32_t w, h;
- w = (mbPerRow + 2 * MP4_NUM_EXT_MB) << 4;
- h = (mbPerCol + 2 * MP4_NUM_EXT_MB) << 4;
- pFrame->stepY = w;
- pFrame->apY = ippsMalloc_8u(w * h);
- if (!pFrame->apY)
- return MP4_STATUS_NO_MEM;
- ippsSet_8u(0, pFrame->apY, w * h);
- pFrame->pY = pFrame->apY + w * 16 + 16;
- w >>= 1;
- h >>= 1;
- pFrame->stepCb = w;
- pFrame->apCb = ippsMalloc_8u(w * h);
- if (!pFrame->apCb)
- return MP4_STATUS_NO_MEM;
- ippsSet_8u(128, pFrame->apCb, w * h);
- pFrame->pCb = pFrame->apCb + w * 8 + 8;
- pFrame->stepCr = w;
- pFrame->apCr = ippsMalloc_8u(w * h);
- if (!pFrame->apCr)
- return MP4_STATUS_NO_MEM;
- pFrame->pCr = pFrame->apCr + w * 8 + 8;
- ippsSet_8u(128, pFrame->apCr, w * h);
- return MP4_STATUS_OK;
- }
- /*
- // mp4_Info for decoding of Video Object Layer
- */
- mp4_Status mp4_InitVOL(mp4_Info* pInfo)
- {
- int32_t mbPerRow, mbPerCol, specSize;
- if (pInfo->VisualObject.VideoObject.short_video_header) {
- pInfo->noBVOPs = 1;
- } else {
- if (pInfo->strictSyntaxCheck) {
- if (pInfo->VisualObject.VideoObject.random_accessible_vol)
- pInfo->noPVOPs = pInfo->noBVOPs = 1;
- if (pInfo->VisualObject.VideoObject.type_indication == MP4_VIDEO_OBJECT_TYPE_SIMPLE ||
- pInfo->VisualObject.VideoObject.type_indication == MP4_VIDEO_OBJECT_TYPE_ADVANCED_REAL_TIME_SIMPLE ||
- pInfo->VisualObject.VideoObject.VOLControlParameters.low_delay) {
- pInfo->noBVOPs = 1;
- }
- }
- }
- if (pInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR)
- {
- mbPerRow = (pInfo->VisualObject.VideoObject.width + 15) >> 4;
- mbPerCol = (pInfo->VisualObject.VideoObject.height + 15) >> 4;
- // current frame
- // if (mp4_AllocInitFrame(&pInfo->VisualObject.cFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
- // return MP4_STATUS_NO_MEM;
- if (pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC)
- {
- // ref in past frame
- // if (mp4_AllocInitFrame(&pInfo->VisualObject.rFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
- // return MP4_STATUS_NO_MEM;
- // ref in future frame
- // if (mp4_AllocInitFrame(&pInfo->VisualObject.nFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
- // return MP4_STATUS_NO_MEM;
- // motion info (not needed for Sprites)
- pInfo->VisualObject.VideoObject.MBinfo = (mp4_MacroBlock*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(mp4_MacroBlock));
- if (!pInfo->VisualObject.VideoObject.MBinfo) return MP4_STATUS_NO_MEM;
- #ifdef USE_NOTCODED_STATE
- // not_coded MB state
- pInfo->VisualObject.VideoObject.ncState = ippsMalloc_8u(mbPerCol * mbPerRow);
- if (!pInfo->VisualObject.VideoObject.ncState) return MP4_STATUS_NO_MEM;
- pInfo->VisualObject.VideoObject.ncStateCleared = 0;
- #endif
- }
- else
- { // data for static sprite
- mbPerRow = pInfo->VisualObject.sFrame->mbPerRow = (pInfo->VisualObject.VideoObject.sprite_width + 15) >> 4;
- mbPerCol = pInfo->VisualObject.sFrame->mbPerCol = (pInfo->VisualObject.VideoObject.sprite_height + 15) >> 4;
- // if (mp4_AllocInitFrame(&pInfo->VisualObject.sFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
- // return MP4_STATUS_NO_MEM;
- }
- pInfo->VisualObject.VideoObject.MacroBlockPerRow = mbPerRow;
- pInfo->VisualObject.VideoObject.MacroBlockPerCol = mbPerCol;
- pInfo->VisualObject.VideoObject.MacroBlockPerVOP = mbPerRow * mbPerCol;
- pInfo->VisualObject.VideoObject.mbns = mp4_GetMacroBlockNumberSize(pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
- if (!pInfo->VisualObject.VideoObject.short_video_header)
- {
- // Intra Prediction info (not needed for SVH)
- pInfo->VisualObject.VideoObject.IntraPredBuff.quant = ippsMalloc_8u(mbPerRow + 1);
- if (!pInfo->VisualObject.VideoObject.IntraPredBuff.quant) return MP4_STATUS_NO_MEM;
- pInfo->VisualObject.VideoObject.IntraPredBuff.block = (mp4_IntraPredBlock*)ippsMalloc_8u((mbPerRow + 1)*6*sizeof(mp4_IntraPredBlock));
- if (!pInfo->VisualObject.VideoObject.IntraPredBuff.block) return MP4_STATUS_NO_MEM;
- {
- mp4_IntraPredBlock *mbCurr = pInfo->VisualObject.VideoObject.IntraPredBuff.block;
- mp4_IntraPredBlock *mbA = mbCurr, *mbB = pInfo->VisualObject.VideoObject.IntraPredBuff.dcB, *mbC = mbCurr + 6;
- int32_t j;
- for (j = 0; j < mbPerRow; j ++) {
- mbCurr[0].predA = &mbA[1]; mbCurr[0].predB = &mbB[3]; mbCurr[0].predC = &mbC[2];
- mbCurr[1].predA = &mbC[0]; mbCurr[1].predB = &mbC[2]; mbCurr[1].predC = &mbC[3];
- mbCurr[2].predA = &mbA[3]; mbCurr[2].predB = &mbA[1]; mbCurr[2].predC = &mbC[0];
- mbCurr[3].predA = &mbC[2]; mbCurr[3].predB = &mbC[0]; mbCurr[3].predC = &mbC[1];
- mbCurr[4].predA = &mbA[4]; mbCurr[4].predB = &mbB[4]; mbCurr[4].predC = &mbC[4];
- mbCurr[5].predA = &mbA[5]; mbCurr[5].predB = &mbB[5]; mbCurr[5].predC = &mbC[5];
- mbCurr += 6; mbA += 6; mbC += 6;
- }
- }
- if (pInfo->VisualObject.VideoObject.data_partitioned) {
- // DataPart info
- pInfo->VisualObject.VideoObject.DataPartBuff = (mp4_DataPartMacroBlock*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(mp4_DataPartMacroBlock));
- if (!pInfo->VisualObject.VideoObject.DataPartBuff) return MP4_STATUS_NO_MEM;
- }
- if (pInfo->VisualObject.VideoObject.interlaced) {
- // Field MV for B-VOP
- pInfo->VisualObject.VideoObject.FieldMV = (IppMotionVector*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(IppMotionVector)*2);
- if (!pInfo->VisualObject.VideoObject.FieldMV) return MP4_STATUS_NO_MEM;
- }
- ippiQuantInvIntraGetSize_MPEG4(&specSize);
- pInfo->VisualObject.VideoObject.QuantInvIntraSpec = (IppiQuantInvIntraSpec_MPEG4*)ippsMalloc_8u(specSize);
- ippiQuantInvIntraInit_MPEG4(pInfo->VisualObject.VideoObject.quant_type ? pInfo->VisualObject.VideoObject.intra_quant_mat : NULL, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, 8);
- ippiQuantInvInterGetSize_MPEG4(&specSize);
- pInfo->VisualObject.VideoObject.QuantInvInterSpec = (IppiQuantInvInterSpec_MPEG4*)ippsMalloc_8u(specSize);
- ippiQuantInvInterInit_MPEG4(pInfo->VisualObject.VideoObject.quant_type ? pInfo->VisualObject.VideoObject.nonintra_quant_mat : NULL, pInfo->VisualObject.VideoObject.QuantInvInterSpec, 8);
- ippiWarpGetSize_MPEG4(&specSize);
- pInfo->VisualObject.VideoObject.WarpSpec = (IppiWarpSpec_MPEG4*)ippsMalloc_8u(specSize);
- }
- }
- return MP4_STATUS_OK;
- }
- /*
- // Free memory allocated for mp4_Info
- */
- mp4_Status mp4_FreeVOL(mp4_Info* pInfo)
- {
- if (pInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR) {
- if (pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) {
- ippsFree(pInfo->VisualObject.VideoObject.MBinfo); pInfo->VisualObject.VideoObject.MBinfo = NULL;
- #ifdef USE_NOTCODED_STATE
- ippsFree(pInfo->VisualObject.VideoObject.ncState);
- #endif
- } else {
- }
- if (!pInfo->VisualObject.VideoObject.short_video_header) {
- ippsFree(pInfo->VisualObject.VideoObject.IntraPredBuff.quant); pInfo->VisualObject.VideoObject.IntraPredBuff.quant = NULL;
- ippsFree(pInfo->VisualObject.VideoObject.IntraPredBuff.block); pInfo->VisualObject.VideoObject.IntraPredBuff.block = NULL;
- if (pInfo->VisualObject.VideoObject.data_partitioned) {
- ippsFree(pInfo->VisualObject.VideoObject.DataPartBuff); pInfo->VisualObject.VideoObject.DataPartBuff = NULL;
- }
- if (pInfo->VisualObject.VideoObject.interlaced) {
- ippsFree(pInfo->VisualObject.VideoObject.FieldMV); pInfo->VisualObject.VideoObject.FieldMV = NULL;
- }
- ippsFree(pInfo->VisualObject.VideoObject.QuantInvIntraSpec); pInfo->VisualObject.VideoObject.QuantInvIntraSpec = NULL;
- ippsFree(pInfo->VisualObject.VideoObject.QuantInvInterSpec); pInfo->VisualObject.VideoObject.QuantInvInterSpec = NULL;
- ippsFree(pInfo->VisualObject.VideoObject.WarpSpec); pInfo->VisualObject.VideoObject.WarpSpec = NULL;
- }
- }
- return MP4_STATUS_OK;
- }
- mp4_Status mp4_DecodeMVD(mp4_Info *pInfo, int32_t *mvdx, int32_t *mvdy, int32_t fcode)
- {
- const mp4_VLC1 *pTab;
- int32_t mvd, sign;
- uint32_t code;
- int32_t factor = fcode - 1;
- /* decode MVDx */
- code = mp4_ShowBits(pInfo, 12);
- if (code >= 128)
- pTab = mp4_MVD_B12_2 + ((code - 128) >> 5);
- else if (code >= 2)
- pTab = mp4_MVD_B12_1 + (code - 2);
- else {
- mp4_Error("Error: decoding MVD");
- return MP4_STATUS_ERROR;
- }
- mvd = pTab->code;
- mp4_FlushBits(pInfo, pTab->len);
- if (mvd) {
- sign = mp4_GetBit(pInfo);
- if (factor) {
- code = mp4_GetBits9(pInfo, factor);
- mvd = ((mvd - 1) << factor) + code + 1;
- }
- if (sign)
- mvd = -mvd;
- }
- *mvdx = mvd;
- /* decode MVDy */
- code = mp4_ShowBits(pInfo, 12);
- if (code >= 128)
- pTab = mp4_MVD_B12_2 + ((code - 128) >> 5);
- else if (code >= 2)
- pTab = mp4_MVD_B12_1 + (code - 2);
- else {
- mp4_Error("Error: decoding MVD");
- return MP4_STATUS_ERROR;
- }
- mvd = pTab->code;
- mp4_FlushBits(pInfo, pTab->len);
- if (mvd) {
- sign = mp4_GetBit(pInfo);
- if (factor) {
- code = mp4_GetBits9(pInfo, factor);
- mvd = ((mvd - 1) << factor) + code + 1;
- }
- if (sign)
- mvd = -mvd;
- }
- *mvdy = mvd;
- return MP4_STATUS_OK;
- }
- mp4_Status mp4_DecodeMV(mp4_Info *pInfo, IppMotionVector *mv, int32_t fcode)
- {
- int32_t mvdx, mvdy, range, range2, dx, dy;
- if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- range = 16 << fcode;
- range2 = range + range;
- dx = mv->dx + mvdx;
- if (dx < -range)
- dx += range2;
- else if (dx >= range)
- dx -= range2;
- mv->dx = (int16_t)dx;
- dy = mv->dy + mvdy;
- if (dy < -range)
- dy += range2;
- else if (dy >= range)
- dy -= range2;
- mv->dy = (int16_t)dy;
- return MP4_STATUS_OK;
- }
- mp4_Status mp4_Decode4MV(mp4_Info *pInfo, IppMotionVector *mv, int32_t fcode)
- {
- int32_t i, mvdx, mvdy, range, range2, dx, dy;
- range = 16 << fcode;
- range2 = range + range;
- for (i = 0; i < 4; i ++) {
- if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- dx = mv[i].dx + mvdx;
- if (dx < -range)
- dx += range2;
- else if (dx >= range)
- dx -= range2;
- mv[i].dx = (int16_t)dx;
- dy = mv[i].dy + mvdy;
- if (dy < -range)
- dy += range2;
- else if (dy >= range)
- dy -= range2;
- mv[i].dy = (int16_t)dy;
- }
- return MP4_STATUS_OK;
- }
- 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)
- {
- int32_t mvdx, mvdy, i;
- if (modb == 2) {
- if (comb_type != IPPVC_MBTYPE_INTER4V) {
- mvForw[0].dx = mvForw[1].dx = mvForw[2].dx = mvForw[3].dx = (int16_t)((TRB * mvC[0].dx) / TRD);
- mvForw[0].dy = mvForw[1].dy = mvForw[2].dy = mvForw[3].dy = (int16_t)((TRB * mvC[0].dy) / TRD);
- mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (int16_t)(((TRB - TRD) * mvC[0].dx) / TRD);
- mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (int16_t)(((TRB - TRD) * mvC[0].dy) / TRD);
- } else
- for (i = 0; i < 4; i ++) {
- mvForw[i].dx = (int16_t)((TRB * mvC[i].dx) / TRD);
- mvForw[i].dy = (int16_t)((TRB * mvC[i].dy) / TRD);
- mvBack[i].dx = (int16_t)(((TRB - TRD) * mvC[i].dx) / TRD);
- mvBack[i].dy = (int16_t)(((TRB - TRD) * mvC[i].dy) / TRD);
- }
- } else {
- if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, 1) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- if (comb_type != IPPVC_MBTYPE_INTER4V) {
- mvForw[0].dx = mvForw[1].dx = mvForw[2].dx = mvForw[3].dx = (int16_t)((TRB * mvC[0].dx) / TRD + mvdx);
- mvForw[0].dy = mvForw[1].dy = mvForw[2].dy = mvForw[3].dy = (int16_t)((TRB * mvC[0].dy) / TRD + mvdy);
- if (mvdx == 0)
- mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (int16_t)(((TRB - TRD) * mvC[0].dx) / TRD);
- else
- mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (int16_t)(mvForw[0].dx - mvC[0].dx);
- if (mvdy == 0)
- mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (int16_t)(((TRB - TRD) * mvC[0].dy) / TRD);
- else
- mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (int16_t)(mvForw[0].dy - mvC[0].dy);
- } else
- for (i = 0; i < 4; i++) {
- mvForw[i].dx = (int16_t)((TRB * mvC[i].dx) / TRD + mvdx);
- mvForw[i].dy = (int16_t)((TRB * mvC[i].dy) / TRD + mvdy);
- if (mvdx == 0)
- mvBack[i].dx = (int16_t)(((TRB - TRD) * mvC[i].dx) / TRD);
- else
- mvBack[i].dx = (int16_t)(mvForw[i].dx - mvC[i].dx);
- if (mvdy == 0)
- mvBack[i].dy = (int16_t)(((TRB - TRD) * mvC[i].dy) / TRD);
- else
- mvBack[i].dy = (int16_t)(mvForw[i].dy - mvC[i].dy);
- }
- }
- return MP4_STATUS_OK;
- }
- 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)
- {
- // field direct mode
- int32_t TRDt, TRDb, TRBt, TRBb, deltaTop, deltaBottom, mvdx, mvdy;
- deltaTop = mb_ftfr;
- deltaBottom = mb_fbfr - 1;
- if (pInfo->VisualObject.VideoObject.VideoObjectPlane.top_field_first) {
- deltaTop = -deltaTop;
- deltaBottom = -deltaBottom;
- }
- TRDt = mp4_DivRoundInf(TRD, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaTop;
- TRDb = mp4_DivRoundInf(TRD, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaBottom;
- TRBt = mp4_DivRoundInf(TRB, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaTop;
- TRBb = mp4_DivRoundInf(TRB, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaBottom;
- if (modb == 2) {
- // delta == 0
- mvdx = mvdy = 0;
- } else {
- if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, 1) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- }
- mvForwTop->dx = (int16_t)((TRBt * mvTop->dx) / TRDt + mvdx);
- if (mvdx == 0)
- mvBackTop->dx = (int16_t)(((TRBt - TRDt) * mvTop->dx) / TRDt);
- else
- mvBackTop->dx = (int16_t)(mvForwTop->dx - mvTop->dx);
- mvForwTop->dy = (int16_t)((TRBt * mvTop->dy * 2) / TRDt + mvdy);
- if (mvdy == 0)
- mvBackTop->dy = (int16_t)(((TRBt - TRDt) * mvTop->dy * 2) / TRDt);
- else
- mvBackTop->dy = (int16_t)(mvForwTop->dy - mvTop->dy * 2);
- mvForwBottom->dx = (int16_t)((TRBb * mvBottom->dx) / TRDb + mvdx);
- if (mvdx == 0)
- mvBackBottom->dx = (int16_t)(((TRBb - TRDb) * mvBottom->dx) / TRDb);
- else
- mvBackBottom->dx = (int16_t)(mvForwBottom->dx - mvBottom->dx);
- mvForwBottom->dy = (int16_t)((TRBb * mvBottom->dy * 2) / TRDb + mvdy);
- if (mvdy == 0)
- mvBackBottom->dy = (int16_t)(((TRBb - TRDb) * mvBottom->dy * 2) / TRDb);
- else
- mvBackBottom->dy = (int16_t)(mvForwBottom->dy - mvBottom->dy * 2);
- mvForwTop->dy >>= 1;
- mvBackTop->dy >>= 1;
- mvForwBottom->dy >>= 1;
- mvBackBottom->dy >>= 1;
- return MP4_STATUS_OK;
- }
- /*static*/ void mp4_ExpandFrameReplicate(uint8_t *pSrcDstPlane, int32_t frameWidth, int32_t frameHeight, int32_t expandPels, int32_t step)
- {
- uint8_t *pDst1, *pDst2, *pSrc1, *pSrc2;
- int32_t i, j;
- uint32_t t1, t2;
- pDst1 = pSrcDstPlane + step * expandPels;
- pDst2 = pDst1 + frameWidth + expandPels;
- if (expandPels == 8) {
- for (i = 0; i < frameHeight; i ++) {
- t1 = pDst1[8] + (pDst1[8] << 8);
- t2 = pDst2[-1] + (pDst2[-1] << 8);
- t1 = (t1 << 16) + t1;
- t2 = (t2 << 16) + t2;
- ((uint32_t*)pDst1)[0] = t1;
- ((uint32_t*)pDst1)[1] = t1;
- ((uint32_t*)pDst2)[0] = t2;
- ((uint32_t*)pDst2)[1] = t2;
- pDst1 += step;
- pDst2 += step;
- }
- } else if (expandPels == 16) {
- for (i = 0; i < frameHeight; i ++) {
- t1 = pDst1[16] + (pDst1[16] << 8);
- t2 = pDst2[-1] + (pDst2[-1] << 8);
- t1 = (t1 << 16) + t1;
- t2 = (t2 << 16) + t2;
- ((uint32_t*)pDst1)[0] = t1;
- ((uint32_t*)pDst1)[1] = t1;
- ((uint32_t*)pDst1)[2] = t1;
- ((uint32_t*)pDst1)[3] = t1;
- ((uint32_t*)pDst2)[0] = t2;
- ((uint32_t*)pDst2)[1] = t2;
- ((uint32_t*)pDst2)[2] = t2;
- ((uint32_t*)pDst2)[3] = t2;
- pDst1 += step;
- pDst2 += step;
- }
- } else {
- for (i = 0; i < frameHeight; i ++) {
- ippsSet_8u(pDst1[expandPels], pDst1, expandPels);
- ippsSet_8u(pDst2[-1], pDst2, expandPels);
- pDst1 += step;
- pDst2 += step;
- }
- }
- pDst1 = pSrcDstPlane;
- pSrc1 = pSrcDstPlane + expandPels * step;
- pDst2 = pSrc1 + frameHeight * step;
- pSrc2 = pDst2 - step;
- j = frameWidth + 2 * expandPels;
- for (i = 0; i < expandPels; i ++) {
- ippsCopy_8u(pSrc1, pDst1, j);
- ippsCopy_8u(pSrc2, pDst2, j);
- pDst1 += step;
- pDst2 += step;
- }
- }
- void mp4_PadFrame(mp4_Info* pInfo)
- {
- #if 0
- /*
- // padding VOP (for not complete blocks padd by
- // 0 for DivX(tm) 5.0 AVI streams
- // 128 for QuickTime(tm) MP4 streams
- // replication for other
- */
- int32_t wL, hL, wC, hC, i;
- //if (pInfo->VisualObject.VideoObject.short_video_header)
- // return;
- wL = pInfo->VisualObject.VideoObject.width;
- hL = pInfo->VisualObject.VideoObject.height;
- wC = pInfo->VisualObject.VideoObject.width >> 1;
- hC = pInfo->VisualObject.VideoObject.height >> 1;
- if ((pInfo->VisualObject.VideoObject.width & 15 || pInfo->VisualObject.VideoObject.height & 15) &&
- ((pInfo->ftype == 1 && pInfo->ftype_f == 0) || (pInfo->ftype == 2 && pInfo->ftype_f == 1))) {
- uint8_t pad = (uint8_t)(pInfo->ftype == 1 ? 128 : 0);
- if (pInfo->VisualObject.VideoObject.width & 15) {
- uint8_t *p;
- // pad one col
- p = pInfo->VisualObject.cFrame.pY + pInfo->VisualObject.VideoObject.width;
- for (i = 0; i < pInfo->VisualObject.VideoObject.height; i ++) {
- *p = pad;
- p += pInfo->VisualObject.cFrame.stepY;
- }
- p = pInfo->VisualObject.cFrame.pCb + (pInfo->VisualObject.VideoObject.width >> 1);
- for (i = 0; i < pInfo->VisualObject.VideoObject.height >> 1; i ++) {
- *p = pad;
- p += pInfo->VisualObject.cFrame.stepCb;
- }
- p = pInfo->VisualObject.cFrame.pCr + (pInfo->VisualObject.VideoObject.width >> 1);
- for (i = 0; i < pInfo->VisualObject.VideoObject.height >> 1; i ++) {
- *p = pad;
- p += pInfo->VisualObject.cFrame.stepCr;
- }
- wL ++;
- wC ++;
- }
- if (pInfo->VisualObject.VideoObject.height & 15) {
- // pad one row
- ippsSet_8u(pad, pInfo->VisualObject.cFrame.pY + pInfo->VisualObject.cFrame.stepY * pInfo->VisualObject.VideoObject.height, pInfo->VisualObject.VideoObject.width);
- ippsSet_8u(pad, pInfo->VisualObject.cFrame.pCb + pInfo->VisualObject.cFrame.stepCb * (pInfo->VisualObject.VideoObject.height >> 1), pInfo->VisualObject.VideoObject.width >> 1);
- ippsSet_8u(pad, pInfo->VisualObject.cFrame.pCr + pInfo->VisualObject.cFrame.stepCr * (pInfo->VisualObject.VideoObject.height >> 1), pInfo->VisualObject.VideoObject.width >> 1);
- hL ++;
- hC ++;
- }
- }
- #else
- /*
- // padding VOP for not complete blocks
- // replication from macroblock boundary for DIVX and MP4 and from frame boundary for other
- */
- int32_t wL, hL, wC, hC;
- if ((pInfo->ftype == 1 && pInfo->ftype_f == 0) || (pInfo->ftype == 2 && pInfo->ftype_f == 1)) {
- wL = pInfo->VisualObject.VideoObject.MacroBlockPerRow * 16;
- hL = pInfo->VisualObject.VideoObject.MacroBlockPerCol * 16;
- } else {
- wL = pInfo->VisualObject.VideoObject.width;
- hL = pInfo->VisualObject.VideoObject.height;
- }
- wC = wL >> 1;
- hC = hL >> 1;
- #endif
- mp4_ExpandFrameReplicate(pInfo->VisualObject.cFrame->apY, wL, hL, 16 * MP4_NUM_EXT_MB, pInfo->VisualObject.cFrame->stepY);
- mp4_ExpandFrameReplicate(pInfo->VisualObject.cFrame->apCb, wC, hC, 8 * MP4_NUM_EXT_MB, pInfo->VisualObject.cFrame->stepCb);
- mp4_ExpandFrameReplicate(pInfo->VisualObject.cFrame->apCr, wC, hC, 8 * MP4_NUM_EXT_MB, pInfo->VisualObject.cFrame->stepCr);
- }
- mp4_Status mp4_DecodeVideoObjectPlane(mp4_Info* pInfo)
- {
- mp4_Status status = MP4_STATUS_OK;
- Ipp64s vop_time;
- // set VOP time
- if (pInfo->VisualObject.VideoObject.short_video_header)
- {
- vop_time = pInfo->VisualObject.VideoObject.vop_sync_time + pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.temporal_reference * 1001;
- if (pInfo->VisualObject.cFrame && pInfo->VisualObject.cFrame->time > vop_time)
- {
- pInfo->VisualObject.VideoObject.vop_sync_time += 256 * 1001;
- vop_time += 256 * 1001;
- }
- }
- else
- {
- if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B)
- {
- 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;
- }
- else
- {
- if (pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane.time_code > pInfo->VisualObject.VideoObject.vop_sync_time)
- pInfo->VisualObject.VideoObject.vop_sync_time = pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane.time_code;
- 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;
- if (pInfo->VisualObject.VideoObject.vop_sync_time_b < pInfo->VisualObject.VideoObject.vop_sync_time)
- pInfo->VisualObject.VideoObject.vop_sync_time_b = pInfo->VisualObject.VideoObject.vop_sync_time;
- if (pInfo->VisualObject.VideoObject.VideoObjectPlane.modulo_time_base != 0) {
- pInfo->VisualObject.VideoObject.vop_sync_time = vop_time - pInfo->VisualObject.VideoObject.VideoObjectPlane.time_increment;
- }
- }
- }
- // if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded || vop_time != pInfo->VisualObject.rFrame.time) {
- if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded ||
- ( (!pInfo->VisualObject.cFrame || vop_time != pInfo->VisualObject.cFrame->time) &&
- (!pInfo->VisualObject.rFrame || vop_time != pInfo->VisualObject.rFrame->time) &&
- (!pInfo->VisualObject.nFrame || vop_time != pInfo->VisualObject.nFrame->time)
- ))
- {
- switch (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type)
- {
- case MP4_VOP_TYPE_I :
- // set new video frame
- if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_STATIC)
- {
- // TODO: verify
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.sFrame);
- pInfo->VisualObject.sFrame = pInfo->VisualObject.cFrame;
- pInfo->VisualObject.cFrame = 0;
- }
- else
- {
- if (pInfo->noPVOPs)
- {
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- pInfo->VisualObject.cFrame=0;
- }
- else if (pInfo->noBVOPs)
- {
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- pInfo->VisualObject.rFrame = pInfo->VisualObject.cFrame;
- pInfo->VisualObject.cFrame = 0;
- }
- else
- {
- if (pInfo->VisualObject.VideoObject.VOPindex > 0)
- {
- if (pInfo->VisualObject.VideoObject.prevPlaneIsB)
- {
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- pInfo->VisualObject.cFrame = 0;
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- pInfo->VisualObject.rFrame = pInfo->VisualObject.nFrame;
- pInfo->VisualObject.nFrame = 0;
- pInfo->VisualObject.VideoObject.prevPlaneIsB=0;
- }
- else
- {
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- pInfo->VisualObject.rFrame = pInfo->VisualObject.cFrame;
- pInfo->VisualObject.cFrame = 0;
- }
- }
- }
- }
- if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded)
- {
- if (pInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR)
- {
- status = mp4_DecodeVOP_I(pInfo);
- } //f else
- //f status = mp4_DecodeVOP_I_Shape(pInfo);
- if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_STATIC && pInfo->VisualObject.VideoObject.VOPindex == 0)
- {
- // TODO: verify (was: mp4_SWAP(mp4_Frame, pInfo->VisualObject.sFrame, pInfo->VisualObject.cFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.sFrame);
- pInfo->VisualObject.sFrame = pInfo->VisualObject.cFrame;
- pInfo->VisualObject.cFrame = 0;
- mp4_ExpandFrameReplicate(pInfo->VisualObject.sFrame->apY, pInfo->VisualObject.VideoObject.sprite_width, pInfo->VisualObject.VideoObject.sprite_height, 16, pInfo->VisualObject.sFrame->stepY);
- mp4_ExpandFrameReplicate(pInfo->VisualObject.sFrame->apCb, pInfo->VisualObject.VideoObject.sprite_width >> 1, pInfo->VisualObject.VideoObject.sprite_height >> 1, 8, pInfo->VisualObject.sFrame->stepCb);
- mp4_ExpandFrameReplicate(pInfo->VisualObject.sFrame->apCr, pInfo->VisualObject.VideoObject.sprite_width >> 1, pInfo->VisualObject.VideoObject.sprite_height >> 1, 8, pInfo->VisualObject.sFrame->stepCr);
- } else {
- mp4_PadFrame(pInfo);
- }
- // set past and future time for B-VOP
- pInfo->VisualObject.VideoObject.rTime = pInfo->VisualObject.VideoObject.nTime;
- pInfo->VisualObject.VideoObject.nTime = vop_time;
- #ifdef USE_NOTCODED_STATE
- // Clear not_coded MB state
- if ((pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) && pInfo->VisualObject.VideoObject.obmc_disable && !pInfo->VisualObject.VideoObject.ncStateCleared) {
- ippsZero_8u(pInfo->VisualObject.VideoObject.ncState, pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
- pInfo->VisualObject.VideoObject.ncStateCleared = 1;
- }
- #endif
- }
- mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_I);
- break;
- case MP4_VOP_TYPE_P :
- // set new video frame
- if (pInfo->noBVOPs)
- {
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- pInfo->VisualObject.rFrame = pInfo->VisualObject.cFrame;
- pInfo->VisualObject.cFrame = 0;
- }
- else
- {
- if (pInfo->VisualObject.VideoObject.VOPindex > 0)
- {
- if (pInfo->VisualObject.VideoObject.prevPlaneIsB)
- {
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- pInfo->VisualObject.cFrame=0;
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- pInfo->VisualObject.rFrame = pInfo->VisualObject.nFrame;
- pInfo->VisualObject.nFrame = 0;
- pInfo->VisualObject.VideoObject.prevPlaneIsB = 0;
- }
- else
- {
- if (pInfo->VisualObject.cFrame)
- {
- int w, h;
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- pInfo->VisualObject.rFrame = pInfo->VisualObject.cFrame;
- pInfo->VisualObject.cFrame=0;
- pInfo->VisualObject.cFrame = CreateFrame(&pInfo->VisualObject);
- w = (pInfo->VisualObject.cFrame->mbPerRow + 2 * MP4_NUM_EXT_MB) << 4;
- h = (pInfo->VisualObject.cFrame->mbPerCol + 2 * MP4_NUM_EXT_MB) << 4;
- memcpy(pInfo->VisualObject.cFrame->mid, pInfo->VisualObject.rFrame->mid, w * h + (w * h >> 1));
- }
- }
- }
- }
- if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded)
- {
- status = mp4_DecodeVOP_P(pInfo);
- mp4_PadFrame(pInfo);
- // set past and future time for B-VOP
- pInfo->VisualObject.VideoObject.rTime = pInfo->VisualObject.VideoObject.nTime;
- pInfo->VisualObject.VideoObject.nTime = vop_time;
- }
- mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_P);
- #ifdef USE_NOTCODED_STATE
- pInfo->VisualObject.VideoObject.ncStateCleared = 0;
- #endif
- break;
- case MP4_VOP_TYPE_B :
- status = MP4_STATUS_OK;
- // after reset it is need to skip first B-frames
- //if (pInfo->VisualObject.VideoObject.VOPindex >= 2)
- //DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- if (!pInfo->VisualObject.VideoObject.prevPlaneIsB)
- {
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
- pInfo->VisualObject.nFrame = pInfo->VisualObject.cFrame;
- pInfo->VisualObject.cFrame = 0;
- pInfo->VisualObject.VideoObject.prevPlaneIsB = 1;
- }
- else
- {
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- pInfo->VisualObject.cFrame=0;
- }
- if (pInfo->VisualObject.VideoObject.VOPindex < 2)
- {
- // if we don't have both reference frames
- if (pInfo->ftype == 2)
- {
- //repeat last frame for AVI timing reasons
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
- if (pInfo->VisualObject.nFrame)
- pInfo->VisualObject.nFrame->outputted = 0;
- }
- mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_B);
- break;
- }
- // set Tframe for direct interlaced mode
- if (!pInfo->VisualObject.VideoObject.Tframe)
- pInfo->VisualObject.VideoObject.Tframe = (int32_t)(vop_time - pInfo->VisualObject.rFrame->time);
- if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded)
- {
- pInfo->VisualObject.VideoObject.TRB = (int32_t)(vop_time - pInfo->VisualObject.VideoObject.rTime);
- pInfo->VisualObject.VideoObject.TRD = (int32_t)(pInfo->VisualObject.VideoObject.nTime - pInfo->VisualObject.VideoObject.rTime);
- // defense from bad streams when B-VOPs are before Past and/or Future
- if (pInfo->VisualObject.VideoObject.TRB <= 0)
- pInfo->VisualObject.VideoObject.TRB = 1;
- if (pInfo->VisualObject.VideoObject.TRD <= 0)
- pInfo->VisualObject.VideoObject.TRD = 2;
- if (pInfo->VisualObject.VideoObject.TRD <= pInfo->VisualObject.VideoObject.TRB)
- {
- pInfo->VisualObject.VideoObject.TRB = 1;
- pInfo->VisualObject.VideoObject.TRD = 2;
- }
- if (pInfo->VisualObject.VideoObject.Tframe >= pInfo->VisualObject.VideoObject.TRD)
- pInfo->VisualObject.VideoObject.Tframe = pInfo->VisualObject.VideoObject.TRB;
- status = mp4_DecodeVOP_B(pInfo);
- }
- mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_B);
- break;
- case MP4_VOP_TYPE_S :
- // set new video frame
- if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_GMC)
- {
- if (pInfo->VisualObject.VideoObject.VOPindex > 0)
- {
- if (pInfo->VisualObject.VideoObject.prevPlaneIsB)
- {
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- pInfo->VisualObject.cFrame=0;
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.nFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- pInfo->VisualObject.rFrame = pInfo->VisualObject.nFrame;
- pInfo->VisualObject.nFrame = 0;
- pInfo->VisualObject.VideoObject.prevPlaneIsB = 0;
- }
- else
- {
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- pInfo->VisualObject.rFrame = pInfo->VisualObject.cFrame;
- pInfo->VisualObject.cFrame = 0;
- }
- }
- }
- else
- {
- DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- ReleaseFrame(&pInfo->VisualObject, pInfo->VisualObject.cFrame);
- pInfo->VisualObject.cFrame=0;
- }
- if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded)
- {
- status = mp4_DecodeVOP_S(pInfo);
- if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_GMC)
- {
- mp4_PadFrame(pInfo);
- // set past and future time for B-VOP
- pInfo->VisualObject.VideoObject.rTime = pInfo->VisualObject.VideoObject.nTime;
- pInfo->VisualObject.VideoObject.nTime = vop_time;
- }
- #ifdef USE_NOTCODED_STATE
- // Clear not_coded MB state
- if ((pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) && pInfo->VisualObject.VideoObject.obmc_disable && !pInfo->VisualObject.VideoObject.ncStateCleared)
- {
- ippsZero_8u(pInfo->VisualObject.VideoObject.ncState, pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
- pInfo->VisualObject.VideoObject.ncStateCleared = 1;
- }
- #endif
- }
- mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_S);
- break;
- }
- if (!pInfo->VisualObject.VideoObject.VideoObjectPlane.coded)
- {
- //pInfo->VisualObject.rFrame->outputted = 0;
- //pInfo->VisualObject.cFrame = pInfo->VisualObject.rFrame;
- //pInfo->VisualObject.rFrame=0;
- //DisplayFrame(&pInfo->VisualObject, pInfo->VisualObject.rFrame);
- //ippsCopy_8u(pInfo->VisualObject.rFrame->apY, pInfo->VisualObject.cFrame->apY, pInfo->VisualObject.cFrame->stepY * ((pInfo->VisualObject.VideoObject.MacroBlockPerCol + 2) << 4));
- //ippsCopy_8u(pInfo->VisualObject.rFrame->apCb, pInfo->VisualObject.cFrame->apCb, pInfo->VisualObject.cFrame->stepCb * ((pInfo->VisualObject.VideoObject.MacroBlockPerCol + 2) << 3));
- //ippsCopy_8u(pInfo->VisualObject.rFrame->apCr, pInfo->VisualObject.cFrame->apCr, pInfo->VisualObject.cFrame->stepCr * ((pInfo->VisualObject.VideoObject.MacroBlockPerCol + 2) << 3));
- #ifdef USE_NOTCODED_STATE
- ippsSet_8u(1, pInfo->VisualObject.VideoObject.ncState, pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
- pInfo->VisualObject.VideoObject.ncStateCleared = 0;
- #endif
- }
- mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP);
- }
- if (pInfo->VisualObject.cFrame)
- {
- // save current VOP type
- pInfo->VisualObject.cFrame->type = pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type;
- // save current VOP time
- pInfo->VisualObject.cFrame->time = vop_time;
- }
- return status;
- }
- /*
- // Intra DC and AC reconstruction for SVH macroblock
- */
- mp4_Status mp4_DecodeIntraMB_SVH(mp4_Info *pInfo, int32_t pat, int32_t quant, uint8_t *pR[], int32_t stepR[])
- {
- __ALIGN16(int16_t, coeff, 64);
- int32_t blockNum, pm = 32, lnz;
- for (blockNum = 0; blockNum < 6; blockNum ++) {
- if (ippiReconstructCoeffsIntra_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pat & pm, quant, 0, IPPVC_SCAN_ZIGZAG, 0) != ippStsNoErr) {
- mp4_Error("Error: decoding coefficients of Inter block");
- return MP4_STATUS_ERROR;
- }
- if (lnz > 0) {
- ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
- } else {
- mp4_Set8x8_8u(pR[blockNum], stepR[blockNum], (uint8_t)((coeff[0] + 4) >> 3));
- }
- if (pat & pm) {
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
- } else {
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
- }
- pm >>= 1;
- }
- return MP4_STATUS_OK;
- }
- mp4_Status mp4_DecodeInterMB_SVH(mp4_Info *pInfo, int16_t *coeffMB, int32_t quant, int32_t pat)
- {
- int32_t i, lnz, pm = 32;
- int16_t *coeff = coeffMB;
- for (i = 0; i < 6; i ++) {
- if ((pat) & pm) {
- if (ippiReconstructCoeffsInter_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, quant, 0) != ippStsNoErr) {
- mp4_Error("Error: decoding coefficients of Inter block");
- return MP4_STATUS_ERROR;
- }
- if (lnz != 0) {
- if ((lnz <= 4) && (coeff[16] == 0))
- ippiDCT8x8Inv_2x2_16s_C1I(coeff);
- else if ((lnz <= 13) && (coeff[32] == 0))
- ippiDCT8x8Inv_4x4_16s_C1I(coeff);
- else
- ippiDCT8x8Inv_16s_C1I(coeff);
- } else {
- mp4_Set64_16s((int16_t)((coeff[0] + 4) >> 3), coeff);
- }
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_C);
- } else {
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
- }
- pm >>= 1;
- coeff += 64;
- }
- return MP4_STATUS_OK;
- }
- /*
- // Intra DC and AC reconstruction for macroblock
- */
- 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[])
- {
- __ALIGN16(int16_t, coeff, 64);
- int32_t blockNum, lnz, predDir, scan, dc, dcA, dcB, dcC, dcP, k, nz, predQuantA, predQuantC, dcScaler, pm = 32;
- int16_t *predAcA, *predAcC, sDC = 0;
- mp4_IntraPredBlock *bCurr;
- for (blockNum = 0; blockNum < 6; blockNum ++) {
- // find prediction direction
- bCurr = &pInfo->VisualObject.VideoObject.IntraPredBuff.block[6*x+blockNum];
- dcA = bCurr->predA->dct_dc >= 0 ? bCurr->predA->dct_dc : 1024;
- dcB = bCurr->predB->dct_dc >= 0 ? bCurr->predB->dct_dc : 1024;
- dcC = bCurr->predC->dct_dc >= 0 ? bCurr->predC->dct_dc : 1024;
- if (mp4_ABS(dcA - dcB) < mp4_ABS(dcB - dcC)) {
- predDir = IPPVC_SCAN_HORIZONTAL;
- dcP = dcC;
- } else {
- predDir = IPPVC_SCAN_VERTICAL;
- dcP = dcA;
- }
- scan = IPPVC_SCAN_ZIGZAG;
- if (pInfo->VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag)
- scan = IPPVC_SCAN_VERTICAL;
- else if (ac_pred_flag)
- scan = predDir;
- // decode coeffs
- if (dcVLC) {
- if (ippiDecodeDCIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA) != ippStsNoErr) {
- mp4_Error("Error: decoding DC coefficient of Intra block");
- return MP4_STATUS_ERROR;
- }
- }
- if (pat & pm) {
- if (ippiDecodeCoeffsIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, 0, dcVLC, scan) != ippStsNoErr) {
- mp4_Error("Error: decoding coefficients of Intra block");
- return MP4_STATUS_ERROR;
- }
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
- } else {
- if (dcVLC)
- sDC = coeff[0];
- mp4_Zero64_16s(coeff);
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
- lnz = 0;
- if (dcVLC)
- coeff[0] = sDC;
- }
- // predict DC
- dcScaler = (blockNum < 4) ? mp4_DCScalerLuma[quant] : mp4_DCScalerChroma[quant];
- dc = coeff[0] + mp4_DivIntraDC(dcP, dcScaler);
- mp4_CLIP(dc, -2048, 2047);
- coeff[0] = (int16_t)dc;
- // predict AC
- nz = 0;
- if (ac_pred_flag) {
- if (predDir == IPPVC_SCAN_HORIZONTAL && (bCurr->predC->dct_dc >= 0)) {
- predAcC = bCurr->predC->dct_acC;
- predQuantC = (blockNum == 2 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1];
- if (predQuantC == quant)
- for (k = 1; k < 8; k ++) {
- coeff[k] = (int16_t)(coeff[k] + predAcC[k]);
- if (coeff[k]) {
- mp4_CLIP(coeff[k], -2048, 2047);
- nz = 1;
- }
- }
- else
- for (k = 1; k < 8; k ++) {
- coeff[k] = (int16_t)(coeff[k] + mp4_DivIntraAC(predAcC[k] * predQuantC, quant));
- if (coeff[k]) {
- mp4_CLIP(coeff[k], -2048, 2047);
- nz = 1;
- }
- }
- } else if (predDir == IPPVC_SCAN_VERTICAL && (bCurr->predA->dct_dc >= 0)) {
- predAcA = bCurr->predA->dct_acA;
- predQuantA = (blockNum == 1 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x];
- if (predQuantA == quant)
- for (k = 1; k < 8; k ++) {
- coeff[k*8] = (int16_t)(coeff[k*8] + predAcA[k]);
- if (coeff[k*8]) {
- mp4_CLIP(coeff[k*8], -2048, 2047);
- nz = 1;
- }
- }
- else
- for (k = 1; k < 8; k ++) {
- coeff[k*8] = (int16_t)(coeff[k*8] + mp4_DivIntraAC(predAcA[k] * predQuantA, quant));
- if (coeff[k*8]) {
- mp4_CLIP(coeff[k*8], -2048, 2047);
- nz = 1;
- }
- }
- }
- }
- // copy predicted AC for future Prediction
- for (k = 1; k < 8; k ++) {
- bCurr[6].dct_acC[k] = coeff[k];
- bCurr[6].dct_acA[k] = coeff[k*8];
- }
- if ((nz | lnz) || (pInfo->VisualObject.VideoObject.quant_type == 1)) {
- ippiQuantInvIntra_MPEG4_16s_C1I(coeff, 63, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, quant, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA);
- ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
- } else {
- k = coeff[0] * dcScaler;
- mp4_CLIP(k, -2048, 2047);
- coeff[0] = (int16_t)k;
- k = (k + 4) >> 3;
- mp4_CLIP(k, 0, 255);
- mp4_Set8x8_8u(pR[blockNum], stepR[blockNum], (uint8_t)k);
- }
- // copy DC for future Prediction
- if (blockNum >= 3)
- pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[blockNum].dct_dc = bCurr[6].dct_dc;
- bCurr[6].dct_dc = coeff[0];
- // copy quant
- if (blockNum == 5)
- pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1] = (uint8_t)quant;
- pm >>= 1;
- }
- return MP4_STATUS_OK;
- }
- /*
- // Intra DC and AC reconstruction for DP macroblock
- */
- 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[])
- {
- __ALIGN16(int16_t, coeff, 64);
- int32_t blockNum, lnz, predDir, scan, dc, dcA, dcB, dcC, dcP, k, nz, predQuantA, predQuantC, dcScaler, pm = 32;
- int16_t *predAcA, *predAcC;
- mp4_IntraPredBlock *bCurr;
- for (blockNum = 0; blockNum < 6; blockNum ++) {
- // find prediction direction
- bCurr = &pInfo->VisualObject.VideoObject.IntraPredBuff.block[6*x+blockNum];
- dcA = bCurr->predA->dct_dc >= 0 ? bCurr->predA->dct_dc : 1024;
- dcB = bCurr->predB->dct_dc >= 0 ? bCurr->predB->dct_dc : 1024;
- dcC = bCurr->predC->dct_dc >= 0 ? bCurr->predC->dct_dc : 1024;
- if (mp4_ABS(dcA - dcB) < mp4_ABS(dcB - dcC)) {
- predDir = IPPVC_SCAN_HORIZONTAL;
- dcP = dcC;
- } else {
- predDir = IPPVC_SCAN_VERTICAL;
- dcP = dcA;
- }
- scan = (ac_pred_flag) ? predDir : IPPVC_SCAN_ZIGZAG;
- // decode coeffs
- if (pat & pm) {
- if (ippiDecodeCoeffsIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pInfo->VisualObject.VideoObject.reversible_vlc, dcVLC, scan) != ippStsNoErr) {
- mp4_Error("Error: decoding coefficients of Intra block");
- return MP4_STATUS_ERROR;
- }
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
- } else {
- mp4_Zero64_16s(coeff);
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
- lnz = 0;
- }
- if (dcVLC)
- coeff[0] = dct_dc[blockNum];
- // predict DC
- dcScaler = (blockNum < 4) ? mp4_DCScalerLuma[quant] : mp4_DCScalerChroma[quant];
- dc = coeff[0] + mp4_DivIntraDC(dcP, dcScaler);
- mp4_CLIP(dc, -2048, 2047);
- coeff[0] = (int16_t)dc;
- // predict AC
- nz = 0;
- if (ac_pred_flag) {
- if (predDir == IPPVC_SCAN_HORIZONTAL && (bCurr->predC->dct_dc >= 0)) {
- predAcC = bCurr->predC->dct_acC;
- predQuantC = (blockNum == 2 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1];
- if (predQuantC == quant)
- for (k = 1; k < 8; k ++) {
- coeff[k] = (int16_t)(coeff[k] + predAcC[k]); // clip ??
- if (coeff[k]) {
- mp4_CLIP(coeff[k], -2048, 2047);
- nz = 1;
- }
- }
- else
- for (k = 1; k < 8; k ++) {
- coeff[k] = (int16_t)(coeff[k] + mp4_DivIntraAC(predAcC[k] * predQuantC, quant));
- if (coeff[k]) {
- mp4_CLIP(coeff[k], -2048, 2047);
- nz = 1;
- }
- }
- } else if (predDir == IPPVC_SCAN_VERTICAL && (bCurr->predA->dct_dc >= 0)) {
- predAcA = bCurr->predA->dct_acA;
- predQuantA = (blockNum == 1 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x];
- if (predQuantA == quant)
- for (k = 1; k < 8; k ++) {
- coeff[k*8] = (int16_t)(coeff[k*8] + predAcA[k]);
- if (coeff[k*8]) {
- mp4_CLIP(coeff[k*8], -2048, 2047);
- nz = 1;
- }
- }
- else
- for (k = 1; k < 8; k ++) {
- coeff[k*8] = (int16_t)(coeff[k*8] + mp4_DivIntraAC(predAcA[k] * predQuantA, quant));
- if (coeff[k*8]) {
- mp4_CLIP(coeff[k*8], -2048, 2047);
- nz = 1;
- }
- }
- }
- }
- // copy predicted AC for future Prediction
- for (k = 1; k < 8; k ++) {
- bCurr[6].dct_acC[k] = coeff[k];
- bCurr[6].dct_acA[k] = coeff[k*8];
- }
- if ((nz | lnz) || (pInfo->VisualObject.VideoObject.quant_type == 1)) {
- ippiQuantInvIntra_MPEG4_16s_C1I(coeff, 63, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, quant, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA);
- ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
- } else {
- k = coeff[0] * dcScaler;
- mp4_CLIP(k, -2048, 2047);
- coeff[0] = (int16_t)k;
- k = (k + 4) >> 3;
- mp4_CLIP(k, 0, 255);
- mp4_Set8x8_8u(pR[blockNum], stepR[blockNum], (uint8_t)k);
- }
- // copy DC for future Prediction
- if (blockNum >= 3)
- pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[blockNum].dct_dc = bCurr[6].dct_dc;
- bCurr[6].dct_dc = coeff[0];
- // copy quant
- if (blockNum == 5)
- pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1] = (uint8_t)quant;
- pm >>= 1;
- }
- return MP4_STATUS_OK;
- }
- /*
- // Intra DC and AC reconstruction for macroblock (w/o iDCT)
- */
- 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[])
- {
- int32_t blockNum, lnz, predDir, scan, dc, dcA, dcB, dcC, dcP, k, nz, predQuantA, predQuantC, dcScaler, pm = 32;
- int16_t *predAcA, *predAcC, sDC = 0, *coeff = coeffMB;
- mp4_IntraPredBlock *bCurr;
- for (blockNum = 0; blockNum < 6; blockNum ++) {
- // find prediction direction
- bCurr = &pInfo->VisualObject.VideoObject.IntraPredBuff.block[6*x+blockNum];
- dcA = bCurr->predA->dct_dc >= 0 ? bCurr->predA->dct_dc : 1024;
- dcB = bCurr->predB->dct_dc >= 0 ? bCurr->predB->dct_dc : 1024;
- dcC = bCurr->predC->dct_dc >= 0 ? bCurr->predC->dct_dc : 1024;
- if (mp4_ABS(dcA - dcB) < mp4_ABS(dcB - dcC)) {
- predDir = IPPVC_SCAN_HORIZONTAL;
- dcP = dcC;
- } else {
- predDir = IPPVC_SCAN_VERTICAL;
- dcP = dcA;
- }
- scan = IPPVC_SCAN_ZIGZAG;
- if (pInfo->VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag)
- scan = IPPVC_SCAN_VERTICAL;
- else if (ac_pred_flag)
- scan = predDir;
- // decode coeffs
- if (dcVLC) {
- if (ippiDecodeDCIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA) != ippStsNoErr) {
- mp4_Error("Error: decoding DC coefficient of Intra block");
- return MP4_STATUS_ERROR;
- }
- }
- if (pat & pm) {
- if (ippiDecodeCoeffsIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, 0, dcVLC, scan) != ippStsNoErr) {
- mp4_Error("Error: decoding coefficients of Intra block");
- return MP4_STATUS_ERROR;
- }
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
- } else {
- if (dcVLC)
- sDC = coeff[0];
- mp4_Zero64_16s(coeff);
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
- lnz = 0;
- if (dcVLC)
- coeff[0] = sDC;
- }
- // predict DC
- dcScaler = (blockNum < 4) ? mp4_DCScalerLuma[quant] : mp4_DCScalerChroma[quant];
- dc = coeff[0] + mp4_DivIntraDC(dcP, dcScaler);
- mp4_CLIP(dc, -2048, 2047);
- coeff[0] = (int16_t)dc;
- // predict AC
- nz = 0;
- if (ac_pred_flag) {
- if (predDir == IPPVC_SCAN_HORIZONTAL && (bCurr->predC->dct_dc >= 0)) {
- predAcC = bCurr->predC->dct_acC;
- predQuantC = (blockNum == 2 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1];
- if (predQuantC == quant)
- for (k = 1; k < 8; k ++) {
- coeff[k] = (int16_t)(coeff[k] + predAcC[k]);
- if (coeff[k]) {
- mp4_CLIP(coeff[k], -2048, 2047);
- nz = 1;
- }
- }
- else
- for (k = 1; k < 8; k ++) {
- coeff[k] = (int16_t)(coeff[k] + mp4_DivIntraAC(predAcC[k] * predQuantC, quant));
- if (coeff[k]) {
- mp4_CLIP(coeff[k], -2048, 2047);
- nz = 1;
- }
- }
- } else if (predDir == IPPVC_SCAN_VERTICAL && (bCurr->predA->dct_dc >= 0)) {
- predAcA = bCurr->predA->dct_acA;
- predQuantA = (blockNum == 1 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x];
- if (predQuantA == quant)
- for (k = 1; k < 8; k ++) {
- coeff[k*8] = (int16_t)(coeff[k*8] + predAcA[k]);
- if (coeff[k*8]) {
- mp4_CLIP(coeff[k*8], -2048, 2047);
- nz = 1;
- }
- }
- else
- for (k = 1; k < 8; k ++) {
- coeff[k*8] = (int16_t)(coeff[k*8] + mp4_DivIntraAC(predAcA[k] * predQuantA, quant));
- if (coeff[k*8]) {
- mp4_CLIP(coeff[k*8], -2048, 2047);
- nz = 1;
- }
- }
- }
- }
- // copy predicted AC for future Prediction
- for (k = 1; k < 8; k ++) {
- bCurr[6].dct_acC[k] = coeff[k];
- bCurr[6].dct_acA[k] = coeff[k*8];
- }
- if ((nz | lnz) || (pInfo->VisualObject.VideoObject.quant_type == 1)) {
- ippiQuantInvIntra_MPEG4_16s_C1I(coeff, 63, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, quant, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA);
- lnz = 63;
- } else {
- k = coeff[0] * dcScaler;
- mp4_CLIP(k, -2048, 2047);
- coeff[0] = (int16_t)k;
- }
- // copy DC for future Prediction
- if (blockNum >= 3)
- pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[blockNum].dct_dc = bCurr[6].dct_dc;
- bCurr[6].dct_dc = coeff[0];
- // copy quant
- if (blockNum == 5)
- pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1] = (uint8_t)quant;
- lastNZ[blockNum] = lnz;
- pm >>= 1;
- coeff += 64;
- }
- return MP4_STATUS_OK;
- }
- mp4_Status mp4_DecodeInterMB(mp4_Info *pInfo, int16_t *coeffMB, int32_t quant, int32_t pat, int32_t scan)
- {
- int32_t i, lnz, pm = 32;
- int16_t *coeff = coeffMB;
- for (i = 0; i < 6; i ++) {
- if ((pat) & pm) {
- if (ippiReconstructCoeffsInter_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pInfo->VisualObject.VideoObject.reversible_vlc, scan, pInfo->VisualObject.VideoObject.QuantInvInterSpec, quant) != ippStsNoErr) {
- mp4_Error("Error: decoding coefficients of Inter block");
- return MP4_STATUS_ERROR;
- }
- if (pInfo->VisualObject.VideoObject.quant_type == 0 || (coeff[63] == 0)) {
- if (lnz != 0) {
- if (scan == IPPVC_SCAN_ZIGZAG) {
- if ((lnz <= 4) && (coeff[16] == 0))
- ippiDCT8x8Inv_2x2_16s_C1I(coeff);
- else if ((lnz <= 13) && (coeff[32] == 0))
- ippiDCT8x8Inv_4x4_16s_C1I(coeff);
- else
- ippiDCT8x8Inv_16s_C1I(coeff);
- } else { // IPPVC_SCAN_VERTICAL
- if ((lnz <= 5) && (coeff[16] == 0) && (coeff[24] == 0))
- ippiDCT8x8Inv_2x2_16s_C1I(coeff);
- else if (lnz <= 9)
- ippiDCT8x8Inv_4x4_16s_C1I(coeff);
- else
- ippiDCT8x8Inv_16s_C1I(coeff);
- }
- } else {
- mp4_Set64_16s((int16_t)((coeff[0] + 4) >> 3), coeff);
- }
- } else {
- ippiDCT8x8Inv_16s_C1I(coeff);
- }
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_C);
- } else {
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
- }
- pm >>= 1;
- coeff += 64;
- }
- return MP4_STATUS_OK;
- }
- void mp4_DCTInvCoeffsInterMB(mp4_Info *pInfo, int16_t *coeffMB, int32_t lastNZ[], int32_t pat, int32_t scan)
- {
- int32_t i, lnz, pm = 32;
- int16_t *coeff = coeffMB;
- for (i = 0; i < 6; i ++) {
- if ((pat) & pm) {
- if (pInfo->VisualObject.VideoObject.quant_type == 0 || (coeff[63] == 0)) {
- lnz = lastNZ[i];
- if (lnz != 0) {
- if (scan == IPPVC_SCAN_ZIGZAG) {
- if ((lnz <= 4) && (coeff[16] == 0))
- ippiDCT8x8Inv_2x2_16s_C1I(coeff);
- else if ((lnz <= 13) && (coeff[32] == 0))
- ippiDCT8x8Inv_4x4_16s_C1I(coeff);
- else
- ippiDCT8x8Inv_16s_C1I(coeff);
- } else { // IPPVC_SCAN_VERTICAL
- if ((lnz <= 5) && (coeff[16] == 0) && (coeff[24] == 0))
- ippiDCT8x8Inv_2x2_16s_C1I(coeff);
- else if (lnz <= 9)
- ippiDCT8x8Inv_4x4_16s_C1I(coeff);
- else
- ippiDCT8x8Inv_16s_C1I(coeff);
- }
- } else {
- mp4_Set64_16s((int16_t)((coeff[0] + 4) >> 3), coeff);
- }
- } else {
- ippiDCT8x8Inv_16s_C1I(coeff);
- }
- }
- pm >>= 1;
- coeff += 64;
- }
- }
- /*
- // decode mcbpc and set MBtype and ChromaPattern
- */
- mp4_Status mp4_DecodeMCBPC_P(mp4_Info* pInfo, int32_t *mbType, int32_t *mbPattern, int32_t stat)
- {
- uint32_t code;
- int32_t type, pattern;
- code = mp4_ShowBits9(pInfo, 9);
- if (code >= 256) {
- type = IPPVC_MBTYPE_INTER;
- pattern = 0;
- mp4_FlushBits(pInfo, 1);
- } else {
- type = mp4_PVOPmb_type[code];
- pattern = mp4_PVOPmb_cbpc[code];
- mp4_FlushBits(pInfo, mp4_PVOPmb_bits[code]);
- }
- if (code == 0) {
- mp4_Error("Error: decoding MCBPC");
- return MP4_STATUS_ERROR;
- }
- *mbType = type;
- *mbPattern = pattern;
- if (stat) {
- if (type == IPPVC_MBTYPE_INTER)
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER);
- else if (type == IPPVC_MBTYPE_INTER_Q)
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER_Q);
- else if (type == IPPVC_MBTYPE_INTRA)
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTRA);
- else if (type == IPPVC_MBTYPE_INTRA_Q)
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTRA_Q);
- else if (type == IPPVC_MBTYPE_INTER4V)
- mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER4V);
- }
- return MP4_STATUS_OK;
- }
- mp4_Status mp4_PredictDecode1MV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, int32_t y, int32_t x)
- {
- IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr;
- int32_t mbInRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
- int32_t fcode = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
- int32_t resync_marker_disable = pInfo->VisualObject.VideoObject.resync_marker_disable;
- // block 0
- mvCurr = MBcurr[0].mv;
- mvLeft = MBcurr[-1].mv;
- mvTop = MBcurr[-mbInRow].mv;
- mvRight = MBcurr[-mbInRow+1].mv;
- if (resync_marker_disable) {
- if ((y | x) == 0) {
- mvCurr[0].dx = mvCurr[0].dy = 0;
- } else if (x == 0) {
- mvCurr[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
- mvCurr[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
- } else if (y == 0) {
- mvCurr[0] = mvLeft[1];
- } else if (x == mbInRow - 1) {
- mvCurr[0].dx = mp4_Median(0, mvLeft[1].dx, mvTop[2].dx);
- mvCurr[0].dy = mp4_Median(0, mvLeft[1].dy, mvTop[2].dy);
- } else {
- mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
- mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
- }
- } else {
- int32_t validLeft, validTop, validRight;
- if (x > 0)
- validLeft = MBcurr[-1].validPred;
- else
- validLeft = 0;
- if (y > 0)
- validTop = MBcurr[-mbInRow].validPred;
- else
- validTop = 0;
- if ((y > 0) && (x < mbInRow - 1))
- validRight = MBcurr[-mbInRow+1].validPred;
- else
- validRight = 0;
- switch ((validLeft << 2) | (validTop << 1) | validRight) {
- case 7:
- mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
- mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
- break;
- case 6:
- mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, 0);
- mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, 0);
- break;
- case 5:
- mvCurr[0].dx = mp4_Median(mvLeft[1].dx, 0, mvRight[2].dx);
- mvCurr[0].dy = mp4_Median(mvLeft[1].dy, 0, mvRight[2].dy);
- break;
- case 4:
- mvCurr[0] = mvLeft[1];
- break;
- case 3:
- mvCurr[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
- mvCurr[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
- break;
- case 2:
- mvCurr[0] = mvTop[2];
- break;
- case 1:
- mvCurr[0] = mvRight[2];
- break;
- default:
- mvCurr[0].dx = mvCurr[0].dy = 0;
- break;
- }
- }
- return mp4_DecodeMV(pInfo, mvCurr, fcode);
- }
- mp4_Status mp4_PredictDecode4MV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, int32_t y, int32_t x)
- {
- IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr;
- int32_t mbInRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
- int32_t fcode = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
- int32_t resync_marker_disable = pInfo->VisualObject.VideoObject.resync_marker_disable;
- mvCurr = MBcurr[0].mv;
- mvLeft = MBcurr[-1].mv;
- mvTop = MBcurr[-mbInRow].mv;
- mvRight = MBcurr[-mbInRow+1].mv;
- if (resync_marker_disable) {
- // block 0
- if ((y | x) == 0) {
- mvCurr[0].dx = mvCurr[0].dy = 0;
- } else if (x == 0) {
- mvCurr[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
- mvCurr[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
- } else if (y == 0) {
- mvCurr[0] = mvLeft[1];
- } else if (x == mbInRow - 1) {
- mvCurr[0].dx = mp4_Median(0, mvLeft[1].dx, mvTop[2].dx);
- mvCurr[0].dy = mp4_Median(0, mvLeft[1].dy, mvTop[2].dy);
- } else {
- mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
- mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
- }
- if (mp4_DecodeMV(pInfo, mvCurr, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- // block 1
- if (y == 0) {
- mvCurr[1] = mvCurr[0];
- } else if (x == mbInRow - 1) {
- mvCurr[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, 0);
- mvCurr[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, 0);
- } else {
- mvCurr[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
- mvCurr[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
- }
- if (mp4_DecodeMV(pInfo, mvCurr+1, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- // block 2
- if (x == 0) {
- mvCurr[2].dx = mp4_Median(0, mvCurr[0].dx, mvCurr[1].dx);
- mvCurr[2].dy = mp4_Median(0, mvCurr[0].dy, mvCurr[1].dy);
- } else {
- mvCurr[2].dx = mp4_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
- mvCurr[2].dy = mp4_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
- }
- if (mp4_DecodeMV(pInfo, mvCurr+2, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- // block 3
- mvCurr[3].dx = mp4_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
- mvCurr[3].dy = mp4_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
- if (mp4_DecodeMV(pInfo, mvCurr+3, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- } else {
- int32_t validLeft, validTop, validRight;
- if (x > 0)
- validLeft = MBcurr[-1].validPred;
- else
- validLeft = 0;
- if (y > 0)
- validTop = MBcurr[-mbInRow].validPred;
- else
- validTop = 0;
- if ((y > 0) && (x < mbInRow - 1))
- validRight = MBcurr[-mbInRow+1].validPred;
- else
- validRight = 0;
- // block 0
- switch ((validLeft << 2) | (validTop << 1) | validRight) {
- case 7:
- mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
- mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
- break;
- case 6:
- mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, 0);
- mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, 0);
- break;
- case 5:
- mvCurr[0].dx = mp4_Median(mvLeft[1].dx, 0, mvRight[2].dx);
- mvCurr[0].dy = mp4_Median(mvLeft[1].dy, 0, mvRight[2].dy);
- break;
- case 4:
- mvCurr[0] = mvLeft[1];
- break;
- case 3:
- mvCurr[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
- mvCurr[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
- break;
- case 2:
- mvCurr[0] = mvTop[2];
- break;
- case 1:
- mvCurr[0] = mvRight[2];
- break;
- default:
- mvCurr[0].dx = mvCurr[0].dy = 0;
- break;
- }
- if (mp4_DecodeMV(pInfo, mvCurr, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- // block 1
- switch ((validTop << 1) | validRight) {
- case 3:
- mvCurr[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
- mvCurr[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
- break;
- case 2:
- mvCurr[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, 0);
- mvCurr[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, 0);
- break;
- case 1:
- mvCurr[1].dx = mp4_Median(mvCurr[0].dx, 0, mvRight[2].dx);
- mvCurr[1].dy = mp4_Median(mvCurr[0].dy, 0, mvRight[2].dy);
- break;
- default:
- mvCurr[1] = mvCurr[0];
- break;
- }
- if (mp4_DecodeMV(pInfo, mvCurr+1, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- // block 2
- if (validLeft) {
- mvCurr[2].dx = mp4_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
- mvCurr[2].dy = mp4_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
- } else {
- mvCurr[2].dx = mp4_Median(0, mvCurr[0].dx, mvCurr[1].dx);
- mvCurr[2].dy = mp4_Median(0, mvCurr[0].dy, mvCurr[1].dy);
- }
- if (mp4_DecodeMV(pInfo, mvCurr+2, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- // block 3
- mvCurr[3].dx = mp4_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
- mvCurr[3].dy = mp4_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
- if (mp4_DecodeMV(pInfo, mvCurr+3, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- }
- return MP4_STATUS_OK;
- }
- mp4_Status mp4_PredictDecodeFMV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, int32_t y, int32_t x, IppMotionVector *mvT, IppMotionVector *mvB)
- {
- IppMotionVector mvLeft = {0, 0}, mvTop = {0, 0}, mvRight = {0, 0}, mvPred;
- int32_t mbInRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
- int32_t fcode = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
- int32_t resync_marker_disable = pInfo->VisualObject.VideoObject.resync_marker_disable;
- if (x > 0) {
- mvLeft = MBcurr[-1].mv[1];
- mvLeft.dy = (int16_t)mp4_Div2(mvLeft.dy);
- }
- if (y > 0) {
- mvTop = MBcurr[-mbInRow].mv[2];
- mvTop.dy = (int16_t)mp4_Div2(mvTop.dy);
- if (x < (mbInRow - 1)) {
- mvRight = MBcurr[-mbInRow+1].mv[2];
- mvRight.dy = (int16_t)mp4_Div2(mvRight.dy);
- }
- }
- if (resync_marker_disable) {
- if ((y | x) == 0) {
- mvPred.dx = mvPred.dy = 0;
- } else if (x == 0) {
- mvPred.dx = mp4_Median(0, mvTop.dx, mvRight.dx);
- mvPred.dy = mp4_Median(0, mvTop.dy, mvRight.dy);
- } else if (y == 0) {
- mvPred = mvLeft;
- } else if (x == mbInRow - 1) {
- mvPred.dx = mp4_Median(0, mvLeft.dx, mvTop.dx);
- mvPred.dy = mp4_Median(0, mvLeft.dy, mvTop.dy);
- } else {
- mvPred.dx = mp4_Median(mvLeft.dx, mvTop.dx, mvRight.dx);
- mvPred.dy = mp4_Median(mvLeft.dy, mvTop.dy, mvRight.dy);
- }
- } else {
- int32_t validLeft, validTop, validRight;
- if (x > 0)
- validLeft = MBcurr[-1].validPred;
- else
- validLeft = 0;
- if (y > 0)
- validTop = MBcurr[-mbInRow].validPred;
- else
- validTop = 0;
- if ((y > 0) && (x < mbInRow - 1))
- validRight = MBcurr[-mbInRow+1].validPred;
- else
- validRight = 0;
- switch ((validLeft << 2) | (validTop << 1) | validRight) {
- case 7:
- mvPred.dx = mp4_Median(mvLeft.dx, mvTop.dx, mvRight.dx);
- mvPred.dy = mp4_Median(mvLeft.dy, mvTop.dy, mvRight.dy);
- break;
- case 6:
- mvPred.dx = mp4_Median(mvLeft.dx, mvTop.dx, 0);
- mvPred.dy = mp4_Median(mvLeft.dy, mvTop.dy, 0);
- break;
- case 5:
- mvPred.dx = mp4_Median(mvLeft.dx, 0, mvRight.dx);
- mvPred.dy = mp4_Median(mvLeft.dy, 0, mvRight.dy);
- break;
- case 4:
- mvPred = mvLeft;
- break;
- case 3:
- mvPred.dx = mp4_Median(0, mvTop.dx, mvRight.dx);
- mvPred.dy = mp4_Median(0, mvTop.dy, mvRight.dy);
- break;
- case 2:
- mvPred = mvTop;
- break;
- case 1:
- mvPred = mvRight;
- break;
- default:
- mvPred.dx = mvPred.dy = 0;
- break;
- }
- }
- *mvT = mvPred;
- if (mp4_DecodeMV(pInfo, mvT, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- *mvB = mvPred;
- if (mp4_DecodeMV(pInfo, mvB, fcode) != MP4_STATUS_OK)
- return MP4_STATUS_ERROR;
- // update MV buffer for future prediction
- MBcurr->mv[0].dx = MBcurr->mv[1].dx = MBcurr->mv[2].dx = MBcurr->mv[3].dx = (int16_t)mp4_Div2Round(mvT->dx + mvB->dx);
- MBcurr->mv[0].dy = MBcurr->mv[1].dy = MBcurr->mv[2].dy = MBcurr->mv[3].dy = (int16_t)(mvT->dy + mvB->dy);
- return MP4_STATUS_OK;
- }
- 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)
- {
- IppMotionVector mvOBMCL, mvOBMCU, mvOBMCR, mvOBMCB, *mvLeft, *mvUpper, *mvRight;
- int32_t mbPerRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow, dx, dy, rt;
- // get Right MV
- if (colNum == mbPerRow - 1)
- mvRight = &mvCur[1];
- else if (pMBinfo[1].type >= IPPVC_MBTYPE_INTRA)
- mvRight = &mvCur[1];
- else
- mvRight = pMBinfo[1].mv;
- // get Left MV
- if (colNum == 0)
- mvLeft = mvCur - 1;
- else if (pMBinfo[-1].type >= IPPVC_MBTYPE_INTRA)
- mvLeft = mvCur - 1;
- else
- mvLeft = pMBinfo[-1].mv;
- // get Upper MV
- if (rowNum == 0)
- mvUpper = mvCur - 2;
- else if (pMBinfo[-mbPerRow].type >= IPPVC_MBTYPE_INTRA)
- mvUpper = mvCur - 2;
- else
- mvUpper = pMBinfo[-mbPerRow].mv;
- dx = colNum * 16;
- dy = rowNum * 16;
- rt = pInfo->VisualObject.VideoObject.VideoObjectPlane.rounding_type;
- if (pInfo->VisualObject.VideoObject.quarter_sample) {
- mp4_LimitMVQ(&mvLeft[1], &mvOBMCL, &limitRectL, dx, dy, 8);
- mp4_LimitMVQ(&mvUpper[2], &mvOBMCU, &limitRectL, dx, dy, 8);
- mp4_LimitMVQ(&mvCur[1], &mvOBMCR, &limitRectL, dx, dy, 8);
- mp4_LimitMVQ(&mvCur[2], &mvOBMCB, &limitRectL, dx, dy, 8);
- ippiOBMC8x8QP_MPEG4_8u_C1R(pYr, stepYr, pYc, stepYc, &mvCur[0], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
- mp4_LimitMVQ(&mvCur[0], &mvOBMCL, &limitRectL, dx+8, dy, 8);
- mp4_LimitMVQ(&mvUpper[3], &mvOBMCU, &limitRectL, dx+8, dy, 8);
- mp4_LimitMVQ(&mvRight[0], &mvOBMCR, &limitRectL, dx+8, dy, 8);
- mp4_LimitMVQ(&mvCur[3], &mvOBMCB, &limitRectL, dx+8, dy, 8);
- ippiOBMC8x8QP_MPEG4_8u_C1R(pYr+8, stepYr, pYc+8, stepYc, &mvCur[1], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
- mp4_LimitMVQ(&mvLeft[3], &mvOBMCL, &limitRectL, dx, dy+8, 8);
- mp4_LimitMVQ(&mvCur[0], &mvOBMCU, &limitRectL, dx, dy+8, 8);
- mp4_LimitMVQ(&mvCur[3], &mvOBMCR, &limitRectL, dx, dy+8, 8);
- ippiOBMC8x8QP_MPEG4_8u_C1R(pYr+stepYr*8, stepYr, pYc+stepYc*8, stepYc, &mvCur[2], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[2], rt);
- mp4_LimitMVQ(&mvCur[2], &mvOBMCL, &limitRectL, dx+8, dy+8, 8);
- mp4_LimitMVQ(&mvCur[1], &mvOBMCU, &limitRectL, dx+8, dy+8, 8);
- mp4_LimitMVQ(&mvRight[2], &mvOBMCR, &limitRectL, dx+8, dy+8, 8);
- ippiOBMC8x8QP_MPEG4_8u_C1R(pYr+8+stepYr*8, stepYr, pYc+8+stepYc*8, stepYc, &mvCur[3], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[3], rt);
- } else {
- mp4_LimitMV(&mvLeft[1], &mvOBMCL, &limitRectL, dx, dy, 8);
- mp4_LimitMV(&mvUpper[2], &mvOBMCU, &limitRectL, dx, dy, 8);
- mp4_LimitMV(&mvCur[1], &mvOBMCR, &limitRectL, dx, dy, 8);
- mp4_LimitMV(&mvCur[2], &mvOBMCB, &limitRectL, dx, dy, 8);
- ippiOBMC8x8HP_MPEG4_8u_C1R(pYr, stepYr, pYc, stepYc, &mvCur[0], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
- mp4_LimitMV(&mvCur[0], &mvOBMCL, &limitRectL, dx+8, dy, 8);
- mp4_LimitMV(&mvUpper[3], &mvOBMCU, &limitRectL, dx+8, dy, 8);
- mp4_LimitMV(&mvRight[0], &mvOBMCR, &limitRectL, dx+8, dy, 8);
- mp4_LimitMV(&mvCur[3], &mvOBMCB, &limitRectL, dx+8, dy, 8);
- ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+8, stepYr, pYc+8, stepYc, &mvCur[1], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
- mp4_LimitMV(&mvLeft[3], &mvOBMCL, &limitRectL, dx, dy+8, 8);
- mp4_LimitMV(&mvCur[0], &mvOBMCU, &limitRectL, dx, dy+8, 8);
- mp4_LimitMV(&mvCur[3], &mvOBMCR, &limitRectL, dx, dy+8, 8);
- ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+stepYr*8, stepYr, pYc+stepYc*8, stepYc, &mvCur[2], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[2], rt);
- mp4_LimitMV(&mvCur[2], &mvOBMCL, &limitRectL, dx+8, dy+8, 8);
- mp4_LimitMV(&mvCur[1], &mvOBMCU, &limitRectL, dx+8, dy+8, 8);
- mp4_LimitMV(&mvRight[2], &mvOBMCR, &limitRectL, dx+8, dy+8, 8);
- ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+8+stepYr*8, stepYr, pYc+8+stepYc*8, stepYc, &mvCur[3], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[3], rt);
- }
- if (!dct_type) {
- mp4_AddResidual(cbpy & 8, pYc, stepYc, coeffMB);
- mp4_AddResidual(cbpy & 4, pYc+8, stepYc, coeffMB+64);
- mp4_AddResidual(cbpy & 2, pYc+stepYc*8, stepYc, coeffMB+128);
- mp4_AddResidual(cbpy & 1, pYc+stepYc*8+8, stepYc, coeffMB+192);
- } else {
- mp4_AddResidual(cbpy & 8, pYc, stepYc*2, coeffMB);
- mp4_AddResidual(cbpy & 4, pYc+8, stepYc*2, coeffMB+64);
- mp4_AddResidual(cbpy & 2, pYc+stepYc, stepYc*2, coeffMB+128);
- mp4_AddResidual(cbpy & 1, pYc+stepYc+8, stepYc*2, coeffMB+192);
- }
- }
- void mp4_CopyMacroBlocks(const mp4_Frame *rFrame, mp4_Frame *cFrame, int32_t mbPerRow, int32_t rowNum, int32_t colNum, int32_t n)
- {
- int32_t i, stepYr, stepYc, stepCbr, stepCbc, stepCrr, stepCrc;
- uint8_t *pYc, *pCbc, *pCrc, *pYr, *pCbr, *pCrr;
- if (n <= 0)
- return;
- stepYc = cFrame->stepY;
- stepCbc = cFrame->stepCb;
- stepCrc = cFrame->stepCr;
- stepYr = rFrame->stepY;
- stepCbr = rFrame->stepCb;
- stepCrr = rFrame->stepCr;
- pYc = cFrame->pY + (rowNum * stepYc + colNum) * 16;
- pCbc = cFrame->pCb + (rowNum * stepCbc + colNum) * 8;
- pCrc = cFrame->pCr + (rowNum * stepCrc + colNum) * 8;
- pYr = rFrame->pY + (rowNum * stepYr + colNum) * 16;
- pCbr = rFrame->pCb + (rowNum * stepCbr + colNum) * 8;
- pCrr = rFrame->pCr + (rowNum * stepCrr + colNum) * 8;
- for (i = rowNum * mbPerRow + colNum; i < rowNum * mbPerRow + colNum + n; i ++) {
- ippiCopy16x16_8u_C1R(pYr, stepYr, pYc, stepYc);
- ippiCopy8x8_8u_C1R(pCbr, stepCbr, pCbc, stepCbc);
- ippiCopy8x8_8u_C1R(pCrr, stepCrr, pCrc, stepCrc);
- if ((i + 1) % mbPerRow == 0) {
- pYc += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
- pCbc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbc << 3) - stepCbc;
- pCrc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrc << 3) - stepCrc;
- pYr += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYr << 4) - stepYr;
- pCbr += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbr << 3) - stepCbr;
- pCrr += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrr << 3) - stepCrr;
- } else {
- pYc += 16; pCrc += 8; pCbc += 8;
- pYr += 16; pCrr += 8; pCbr += 8;
- }
- }
- }
- // added by benski
- mp4_Frame *CreateFrame(mp4_VisualObject *object)
- {
- if (object->frame_cache)
- {
- mp4_Frame *ret = object->frame_cache;
- object->frame_cache = ret->next;
- ret->next = 0;
- ret->reference_count = 1;
- return ret;
- }
- else
- {
- mp4_Frame *ret = (mp4_Frame *)calloc(1, sizeof(mp4_Frame));
- ret->reference_count = 1;
- ret->sprite = 0;
- ret->mbPerRow = (object->VideoObject.width + 15) >> 4;
- ret->mbPerCol = (object->VideoObject.height + 15) >> 4;
- AllocateInitFrame(ret);
- return ret;
- }
- }
- mp4_Frame *CreateSpriteFrame(mp4_VisualObject *object)
- {
- if (object->sprite_cache)
- {
- mp4_Frame *ret = object->sprite_cache;
- object->sprite_cache = ret->next;
- ret->next = 0;
- ret->reference_count = 1;
- return ret;
- }
- else
- {
- mp4_Frame *ret = (mp4_Frame *)calloc(1, sizeof(mp4_Frame));
- ret->reference_count = 1;
- ret->sprite = 1;
- ret->mbPerRow = (object->VideoObject.sprite_width + 15) >> 4;
- ret->mbPerCol = (object->VideoObject.sprite_height + 15) >> 4;
- AllocateInitFrame(ret);
- return ret;
- }
- }
- /* to delete
- free(decoder->dec.VisualObject.cFrame.mid);
- decoder->dec.VisualObject.cFrame.mid = 0;
- */
- void ReleaseFrame(mp4_VisualObject *object, mp4_Frame *frame)
- {
- if (frame && --frame->reference_count == 0)
- {
- if (frame->outputted == 0)
- {
- // DebugBreak();
- }
- frame->outputted = 0;
- if (frame->sprite)
- {
- frame->next = object->sprite_cache;
- object->sprite_cache = frame;
- }
- else
- {
- frame->next = object->frame_cache;
- object->frame_cache = frame;
- }
- }
- }
- mp4_Frame *GetDisplayFrame(mp4_VisualObject *object)
- {
- mp4_Frame *ret = object->display_frames;
- if (ret)
- {
- object->display_frames = ret->next;
- ret->next = 0;
- }
- return ret;
- }
- void DisplayFrame(mp4_VisualObject *object, mp4_Frame *frame)
- {
- if (frame)
- {
- mp4_Frame *tail = object->display_frames;
- if (frame->outputted)
- {
- DebugBreak();
- }
- frame->outputted = 1;
- frame->reference_count++;
- if (tail)
- {
- while (tail->next)
- {
- tail = tail->next;
- }
- tail->next = frame;
- frame->next = 0;
- }
- else
- {
- object->display_frames = frame;
- frame->next = 0;
- }
- }
- }
- void FreeCache(mp4_VisualObject *object)
- {
- while (object->display_frames)
- {
- mp4_Frame *frame = object->display_frames;
- object->display_frames = frame->next;
- free(frame->mid);
- free(frame);
- }
- while (object->frame_cache)
- {
- mp4_Frame *frame = object->frame_cache;
- object->frame_cache = frame->next;
- free(frame->mid);
- free(frame);
- }
- while (object->sprite_cache)
- {
- mp4_Frame *frame = object->frame_cache;
- object->frame_cache = frame->next;
- free(frame->mid);
- free(frame);
- }
- }
|