• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*!
2  * \copy
3  *     Copyright (c)  2009-2013, Cisco Systems
4  *     All rights reserved.
5  *
6  *     Redistribution and use in source and binary forms, with or without
7  *     modification, are permitted provided that the following conditions
8  *     are met:
9  *
10  *        * Redistributions of source code must retain the above copyright
11  *          notice, this list of conditions and the following disclaimer.
12  *
13  *        * Redistributions in binary form must reproduce the above copyright
14  *          notice, this list of conditions and the following disclaimer in
15  *          the documentation and/or other materials provided with the
16  *          distribution.
17  *
18  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26  *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28  *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  *     POSSIBILITY OF SUCH DAMAGE.
30  *
31  *
32  * \file    rec_mb.c
33  *
34  * \brief   implementation for all macroblock decoding process after mb syntax parsing and residual decoding with cavlc.
35  *
36  * \date    3/18/2009 Created
37  *
38  *************************************************************************************
39  */
40 
41 
42 #include "rec_mb.h"
43 #include "decode_slice.h"
44 
45 namespace WelsDec {
46 
WelsFillRecNeededMbInfo(PWelsDecoderContext pCtx,bool bOutput,PDqLayer pCurDqLayer)47 void WelsFillRecNeededMbInfo (PWelsDecoderContext pCtx, bool bOutput, PDqLayer pCurDqLayer) {
48   PPicture pCurPic = pCtx->pDec;
49   int32_t iLumaStride   = pCurPic->iLinesize[0];
50   int32_t iChromaStride = pCurPic->iLinesize[1];
51   int32_t iMbX = pCurDqLayer->iMbX;
52   int32_t iMbY = pCurDqLayer->iMbY;
53 
54   pCurDqLayer->iLumaStride = iLumaStride;
55   pCurDqLayer->iChromaStride = iChromaStride;
56 
57   if (bOutput) {
58     pCurDqLayer->pPred[0] = pCurPic->pData[0] + ((iMbY * iLumaStride + iMbX) << 4);
59     pCurDqLayer->pPred[1] = pCurPic->pData[1] + ((iMbY * iChromaStride + iMbX) << 3);
60     pCurDqLayer->pPred[2] = pCurPic->pData[2] + ((iMbY * iChromaStride + iMbX) << 3);
61   }
62 }
63 
RecI8x8Mb(int32_t iMbXy,PWelsDecoderContext pCtx,int16_t * pScoeffLevel,PDqLayer pDqLayer)64 int32_t RecI8x8Mb (int32_t iMbXy, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
65   RecI8x8Luma (iMbXy, pCtx, pScoeffLevel, pDqLayer);
66   RecI4x4Chroma (iMbXy, pCtx, pScoeffLevel, pDqLayer);
67   return ERR_NONE;
68 }
69 
RecI8x8Luma(int32_t iMbXy,PWelsDecoderContext pCtx,int16_t * pScoeffLevel,PDqLayer pDqLayer)70 int32_t RecI8x8Luma (int32_t iMbXy, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
71   /*****get local variable from outer variable********/
72   /*prediction info*/
73   uint8_t* pPred = pDqLayer->pPred[0];
74 
75   int32_t iLumaStride = pDqLayer->iLumaStride;
76   int32_t* pBlockOffset = pCtx->iDecBlockOffsetArray;
77   PGetIntraPred8x8Func* pGetI8x8LumaPredFunc = pCtx->pGetI8x8LumaPredFunc;
78 
79   int8_t* pIntra8x8PredMode = pDqLayer->pIntra4x4FinalMode[iMbXy]; // I_NxN
80   int16_t* pRS = pScoeffLevel;
81   /*itransform info*/
82   PIdctResAddPredFunc pIdctResAddPredFunc = pCtx->pIdctResAddPredFunc8x8;
83 
84   /*************local variable********************/
85   uint8_t i = 0;
86   bool bTLAvail[4], bTRAvail[4];
87   // Top-Right : Left : Top-Left : Top
88   bTLAvail[0] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x02);
89   bTLAvail[1] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x01);
90   bTLAvail[2] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x04);
91   bTLAvail[3] = true;
92 
93   bTRAvail[0] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x01);
94   bTRAvail[1] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x08);
95   bTRAvail[2] = true;
96   bTRAvail[3] = false;
97 
98   /*************real process*********************/
99   for (i = 0; i < 4; i++) {
100 
101     uint8_t* pPredI8x8 = pPred + pBlockOffset[i << 2];
102     uint8_t uiMode = pIntra8x8PredMode[g_kuiScan4[i << 2]];
103 
104     pGetI8x8LumaPredFunc[uiMode] (pPredI8x8, iLumaStride, bTLAvail[i], bTRAvail[i]);
105 
106     int32_t iIndex = g_kuiMbCountScan4Idx[i << 2];
107     if (pDqLayer->pNzc[iMbXy][iIndex] || pDqLayer->pNzc[iMbXy][iIndex + 1] || pDqLayer->pNzc[iMbXy][iIndex + 4]
108         || pDqLayer->pNzc[iMbXy][iIndex + 5]) {
109       int16_t* pRSI8x8 = &pRS[i << 6];
110       pIdctResAddPredFunc (pPredI8x8, iLumaStride, pRSI8x8);
111     }
112   }
113 
114   return ERR_NONE;
115 }
116 
RecI4x4Mb(int32_t iMBXY,PWelsDecoderContext pCtx,int16_t * pScoeffLevel,PDqLayer pDqLayer)117 int32_t RecI4x4Mb (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
118   RecI4x4Luma (iMBXY, pCtx, pScoeffLevel, pDqLayer);
119   RecI4x4Chroma (iMBXY, pCtx, pScoeffLevel, pDqLayer);
120   return ERR_NONE;
121 }
122 
123 
RecI4x4Luma(int32_t iMBXY,PWelsDecoderContext pCtx,int16_t * pScoeffLevel,PDqLayer pDqLayer)124 int32_t RecI4x4Luma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
125   /*****get local variable from outer variable********/
126   /*prediction info*/
127   uint8_t* pPred = pDqLayer->pPred[0];
128 
129   int32_t iLumaStride = pDqLayer->iLumaStride;
130   int32_t* pBlockOffset = pCtx->iDecBlockOffsetArray;
131   PGetIntraPredFunc* pGetI4x4LumaPredFunc = pCtx->pGetI4x4LumaPredFunc;
132 
133   int8_t* pIntra4x4PredMode = pDqLayer->pIntra4x4FinalMode[iMBXY];
134   int16_t* pRS = pScoeffLevel;
135   /*itransform info*/
136   PIdctResAddPredFunc pIdctResAddPredFunc = pCtx->pIdctResAddPredFunc;
137 
138 
139   /*************local variable********************/
140   uint8_t i = 0;
141 
142   /*************real process*********************/
143   for (i = 0; i < 16; i++) {
144 
145     uint8_t* pPredI4x4 = pPred + pBlockOffset[i];
146     uint8_t uiMode = pIntra4x4PredMode[g_kuiScan4[i]];
147 
148     pGetI4x4LumaPredFunc[uiMode] (pPredI4x4, iLumaStride);
149 
150     if (pDqLayer->pNzc[iMBXY][g_kuiMbCountScan4Idx[i]]) {
151       int16_t* pRSI4x4 = &pRS[i << 4];
152       pIdctResAddPredFunc (pPredI4x4, iLumaStride, pRSI4x4);
153     }
154   }
155 
156   return ERR_NONE;
157 }
158 
159 
RecI4x4Chroma(int32_t iMBXY,PWelsDecoderContext pCtx,int16_t * pScoeffLevel,PDqLayer pDqLayer)160 int32_t RecI4x4Chroma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
161   int32_t iChromaStride = pCtx->pCurDqLayer->pDec->iLinesize[1];
162 
163   int8_t iChromaPredMode = pDqLayer->pChromaPredMode[iMBXY];
164 
165   PGetIntraPredFunc* pGetIChromaPredFunc = pCtx->pGetIChromaPredFunc;
166 
167   uint8_t* pPred = pDqLayer->pPred[1];
168 
169   pGetIChromaPredFunc[iChromaPredMode] (pPred, iChromaStride);
170   pPred = pDqLayer->pPred[2];
171   pGetIChromaPredFunc[iChromaPredMode] (pPred, iChromaStride);
172 
173   RecChroma (iMBXY, pCtx, pScoeffLevel, pDqLayer);
174 
175   return ERR_NONE;
176 }
177 
178 
RecI16x16Mb(int32_t iMBXY,PWelsDecoderContext pCtx,int16_t * pScoeffLevel,PDqLayer pDqLayer)179 int32_t RecI16x16Mb (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
180   /*decoder use, encoder no use*/
181   int8_t iI16x16PredMode = pDqLayer->pIntraPredMode[iMBXY][7];
182   int8_t iChromaPredMode = pDqLayer->pChromaPredMode[iMBXY];
183   PGetIntraPredFunc* pGetIChromaPredFunc = pCtx->pGetIChromaPredFunc;
184   PGetIntraPredFunc* pGetI16x16LumaPredFunc = pCtx->pGetI16x16LumaPredFunc;
185   int32_t iUVStride = pCtx->pCurDqLayer->pDec->iLinesize[1];
186 
187   /*common use by decoder&encoder*/
188   int32_t iYStride = pDqLayer->iLumaStride;
189   int16_t* pRS = pScoeffLevel;
190 
191   uint8_t* pPred = pDqLayer->pPred[0];
192 
193   PIdctFourResAddPredFunc pIdctFourResAddPredFunc = pCtx->pIdctFourResAddPredFunc;
194 
195   /*decode i16x16 y*/
196   pGetI16x16LumaPredFunc[iI16x16PredMode] (pPred, iYStride);
197 
198   /*1 mb is divided 16 4x4_block to idct*/
199   const int8_t* pNzc = pDqLayer->pNzc[iMBXY];
200   pIdctFourResAddPredFunc (pPred + 0 * iYStride + 0, iYStride, pRS + 0 * 64, pNzc +  0);
201   pIdctFourResAddPredFunc (pPred + 0 * iYStride + 8, iYStride, pRS + 1 * 64, pNzc +  2);
202   pIdctFourResAddPredFunc (pPred + 8 * iYStride + 0, iYStride, pRS + 2 * 64, pNzc +  8);
203   pIdctFourResAddPredFunc (pPred + 8 * iYStride + 8, iYStride, pRS + 3 * 64, pNzc + 10);
204 
205   /*decode intra mb cb&cr*/
206   pPred = pDqLayer->pPred[1];
207   pGetIChromaPredFunc[iChromaPredMode] (pPred, iUVStride);
208   pPred = pDqLayer->pPred[2];
209   pGetIChromaPredFunc[iChromaPredMode] (pPred, iUVStride);
210   RecChroma (iMBXY, pCtx, pScoeffLevel, pDqLayer);
211 
212   return ERR_NONE;
213 }
214 
215 
216 //according to current 8*8 block ref_index to gain reference picture
GetRefPic(sMCRefMember * pMCRefMem,PWelsDecoderContext pCtx,const int8_t & iRefIdx,int32_t listIdx)217 static inline int32_t GetRefPic (sMCRefMember* pMCRefMem, PWelsDecoderContext pCtx, const int8_t& iRefIdx,
218                                  int32_t listIdx) {
219   PPicture pRefPic;
220 
221   if (iRefIdx >= 0) {
222     pRefPic = pCtx->sRefPic.pRefList[listIdx][iRefIdx];
223 
224     if (pRefPic != NULL) {
225       pMCRefMem->iSrcLineLuma = pRefPic->iLinesize[0];
226       pMCRefMem->iSrcLineChroma = pRefPic->iLinesize[1];
227 
228       pMCRefMem->pSrcY = pRefPic->pData[0];
229       pMCRefMem->pSrcU = pRefPic->pData[1];
230       pMCRefMem->pSrcV = pRefPic->pData[2];
231       if (!pMCRefMem->pSrcY || !pMCRefMem->pSrcU || !pMCRefMem->pSrcV) {
232         return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_DATA, ERR_INFO_REFERENCE_PIC_LOST);
233       }
234       return ERR_NONE;
235     }
236   }
237   return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_DATA, ERR_INFO_REFERENCE_PIC_LOST);
238 }
239 
240 
241 #ifndef MC_FLOW_SIMPLE_JUDGE
242 #define MC_FLOW_SIMPLE_JUDGE 1
243 #endif //MC_FLOW_SIMPLE_JUDGE
BaseMC(PWelsDecoderContext pCtx,sMCRefMember * pMCRefMem,const int32_t & listIdx,const int8_t & iRefIdx,int32_t iXOffset,int32_t iYOffset,SMcFunc * pMCFunc,int32_t iBlkWidth,int32_t iBlkHeight,int16_t iMVs[2])244 void BaseMC (PWelsDecoderContext pCtx, sMCRefMember* pMCRefMem, const int32_t& listIdx, const int8_t& iRefIdx,
245              int32_t iXOffset, int32_t iYOffset,
246              SMcFunc* pMCFunc,
247              int32_t iBlkWidth, int32_t iBlkHeight, int16_t iMVs[2]) {
248   int32_t iFullMVx = (iXOffset << 2) + iMVs[0]; //quarter pixel
249   int32_t iFullMVy = (iYOffset << 2) + iMVs[1];
250   iFullMVx = WELS_CLIP3 (iFullMVx, ((-PADDING_LENGTH + 2) * (1 << 2)),
251                          ((pMCRefMem->iPicWidth + PADDING_LENGTH - 19) * (1 << 2)));
252   iFullMVy = WELS_CLIP3 (iFullMVy, ((-PADDING_LENGTH + 2) * (1 << 2)),
253                          ((pMCRefMem->iPicHeight + PADDING_LENGTH - 19) * (1 << 2)));
254 
255   if (GetThreadCount (pCtx) > 1 && iRefIdx >= 0) {
256     // wait for the lines of reference macroblock (3 + 16).
257     PPicture pRefPic = pCtx->sRefPic.pRefList[listIdx][iRefIdx];
258     if (pCtx->bNewSeqBegin && (pCtx->iErrorCode & dsRefLost)) {
259       //set event if refpic is lost to prevent from infinite waiting.
260       if (!pRefPic->pReadyEvent[0].isSignaled) {
261         for (uint32_t ln = 0; ln < pCtx->sMb.iMbHeight; ++ln) {
262           SET_EVENT (&pRefPic->pReadyEvent[ln]);
263         }
264       }
265     }
266     int32_t offset = (iFullMVy >> 2) + iBlkHeight + 3 + 16;
267     if (offset > pCtx->lastReadyHeightOffset[listIdx][iRefIdx]) {
268       const int32_t down_line = WELS_MIN (offset >> 4, int32_t (pCtx->sMb.iMbHeight) - 1);
269       if (pRefPic->pReadyEvent[down_line].isSignaled != 1) {
270         WAIT_EVENT (&pRefPic->pReadyEvent[down_line], WELS_DEC_THREAD_WAIT_INFINITE);
271       }
272       pCtx->lastReadyHeightOffset[listIdx][iRefIdx] = offset;
273     }
274   }
275 
276   int32_t iSrcPixOffsetLuma = (iFullMVx >> 2) + (iFullMVy >> 2) * pMCRefMem->iSrcLineLuma;
277   int32_t iSrcPixOffsetChroma = (iFullMVx >> 3) + (iFullMVy >> 3) * pMCRefMem->iSrcLineChroma;
278 
279   int32_t iBlkWidthChroma = iBlkWidth >> 1;
280   int32_t iBlkHeightChroma = iBlkHeight >> 1;
281 
282   uint8_t* pSrcY = pMCRefMem->pSrcY + iSrcPixOffsetLuma;
283   uint8_t* pSrcU = pMCRefMem->pSrcU + iSrcPixOffsetChroma;
284   uint8_t* pSrcV = pMCRefMem->pSrcV + iSrcPixOffsetChroma;
285   uint8_t* pDstY = pMCRefMem->pDstY;
286   uint8_t* pDstU = pMCRefMem->pDstU;
287   uint8_t* pDstV = pMCRefMem->pDstV;
288 
289   pMCFunc->pMcLumaFunc (pSrcY, pMCRefMem->iSrcLineLuma, pDstY, pMCRefMem->iDstLineLuma, iFullMVx, iFullMVy, iBlkWidth,
290                         iBlkHeight);
291   pMCFunc->pMcChromaFunc (pSrcU, pMCRefMem->iSrcLineChroma, pDstU, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
292                           iBlkWidthChroma, iBlkHeightChroma);
293   pMCFunc->pMcChromaFunc (pSrcV, pMCRefMem->iSrcLineChroma, pDstV, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
294                           iBlkWidthChroma, iBlkHeightChroma);
295 
296 }
297 
WeightPrediction(PDqLayer pCurDqLayer,sMCRefMember * pMCRefMem,int32_t listIdx,int32_t iRefIdx,int32_t iBlkWidth,int32_t iBlkHeight)298 static void WeightPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, int32_t listIdx, int32_t iRefIdx,
299                               int32_t iBlkWidth,
300                               int32_t iBlkHeight) {
301 
302 
303   int32_t iLog2denom, iWoc, iOoc;
304   int32_t iPredTemp, iLineStride;
305   int32_t iPixel = 0;
306   uint8_t* pDst;
307   //luma
308   iLog2denom = pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom;
309   iWoc = pCurDqLayer->pPredWeightTable->sPredList[listIdx].iLumaWeight[iRefIdx];
310   iOoc = pCurDqLayer->pPredWeightTable->sPredList[listIdx].iLumaOffset[iRefIdx];
311   iLineStride = pMCRefMem->iDstLineLuma;
312 
313   for (int i = 0; i < iBlkHeight; i++) {
314     for (int j = 0; j < iBlkWidth; j++) {
315       iPixel = j + i * (iLineStride);
316       if (iLog2denom >= 1) {
317         iPredTemp = ((pMCRefMem->pDstY[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
318 
319         pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
320       } else {
321         iPredTemp = pMCRefMem->pDstY[iPixel] * iWoc + iOoc;
322 
323         pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
324 
325       }
326     }
327   }
328 
329 
330   //UV
331   iBlkWidth = iBlkWidth >> 1;
332   iBlkHeight = iBlkHeight >> 1;
333   iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
334   iLineStride = pMCRefMem->iDstLineChroma;
335 
336   for (int i = 0; i < 2; i++) {
337 
338 
339     //iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
340     iWoc =  pCurDqLayer->pPredWeightTable->sPredList[listIdx].iChromaWeight[iRefIdx][i];
341     iOoc = pCurDqLayer->pPredWeightTable->sPredList[listIdx].iChromaOffset[iRefIdx][i];
342     pDst = i ? pMCRefMem->pDstV : pMCRefMem->pDstU;
343     //iLineStride = pMCRefMem->iDstLineChroma;
344 
345     for (int i = 0; i < iBlkHeight ; i++) {
346       for (int j = 0; j < iBlkWidth; j++) {
347         iPixel = j + i * (iLineStride);
348         if (iLog2denom >= 1) {
349           iPredTemp = ((pDst[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
350 
351           pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
352         } else {
353           iPredTemp = pDst[iPixel] * iWoc + iOoc;
354 
355           pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
356 
357         }
358       }
359 
360     }
361 
362 
363   }
364 }
365 
BiWeightPrediction(PDqLayer pCurDqLayer,sMCRefMember * pMCRefMem,sMCRefMember * pTempMCRefMem,int32_t iRefIdx1,int32_t iRefIdx2,bool bWeightedBipredIdcIs1,int32_t iBlkWidth,int32_t iBlkHeight)366 static void BiWeightPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, sMCRefMember* pTempMCRefMem,
367                                 int32_t iRefIdx1, int32_t iRefIdx2, bool bWeightedBipredIdcIs1, int32_t iBlkWidth,
368                                 int32_t iBlkHeight) {
369   int32_t iWoc1 = 0, iOoc1 = 0, iWoc2 = 0, iOoc2 = 0;
370   int32_t iPredTemp, iLineStride;
371   int32_t iPixel = 0;
372   //luma
373   int32_t iLog2denom = pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom;
374   if (bWeightedBipredIdcIs1) {
375     iWoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaWeight[iRefIdx1];
376     iOoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaOffset[iRefIdx1];
377     iWoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iLumaWeight[iRefIdx2];
378     iOoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iLumaOffset[iRefIdx2];
379   } else {
380     iWoc1 = pCurDqLayer->pPredWeightTable->iImplicitWeight[iRefIdx1][iRefIdx2];
381     iWoc2 = 64 - iWoc1;
382   }
383   iLineStride = pMCRefMem->iDstLineLuma;
384 
385   for (int i = 0; i < iBlkHeight; i++) {
386     for (int j = 0; j < iBlkWidth; j++) {
387       iPixel = j + i * (iLineStride);
388       iPredTemp = ((pMCRefMem->pDstY[iPixel] * iWoc1 + pTempMCRefMem->pDstY[iPixel] * iWoc2 + (1 << iLog2denom)) >>
389                    (iLog2denom + 1)) + ((iOoc1 + iOoc2 + 1) >> 1);
390       pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
391     }
392   }
393 
394   //UV
395   iBlkWidth = iBlkWidth >> 1;
396   iBlkHeight = iBlkHeight >> 1;
397   iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
398   iLineStride = pMCRefMem->iDstLineChroma;
399 
400   uint8_t* pDst;
401   uint8_t* pTempDst;
402   for (int k = 0; k < 2; k++) {
403     //iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
404     if (bWeightedBipredIdcIs1) {
405       iWoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaWeight[iRefIdx1][k];
406       iOoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaOffset[iRefIdx1][k];
407       iWoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iChromaWeight[iRefIdx2][k];
408       iOoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iChromaOffset[iRefIdx2][k];
409     }
410     pDst  = k ? pMCRefMem->pDstV : pMCRefMem->pDstU;
411     pTempDst = k ? pTempMCRefMem->pDstV : pTempMCRefMem->pDstU;
412     //iLineStride = pMCRefMem->iDstLineChroma;
413 
414     for (int i = 0; i < iBlkHeight; i++) {
415       for (int j = 0; j < iBlkWidth; j++) {
416         iPixel = j + i * (iLineStride);
417         iPredTemp = ((pDst[iPixel] * iWoc1 + pTempDst[iPixel] * iWoc2 + (1 << iLog2denom)) >> (iLog2denom + 1)) + ((
418                       iOoc1 + iOoc2 + 1) >> 1);
419         pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
420       }
421     }
422   }
423 }
424 
BiPrediction(PDqLayer pCurDqLayer,sMCRefMember * pMCRefMem,sMCRefMember * pTempMCRefMem,int32_t iBlkWidth,int32_t iBlkHeight)425 static void BiPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, sMCRefMember* pTempMCRefMem, int32_t iBlkWidth,
426                           int32_t iBlkHeight) {
427   int32_t iPredTemp, iLineStride;
428   int32_t iPixel = 0;
429   //luma
430   iLineStride = pMCRefMem->iDstLineLuma;
431 
432   for (int i = 0; i < iBlkHeight; i++) {
433     for (int j = 0; j < iBlkWidth; j++) {
434       iPixel = j + i * (iLineStride);
435       iPredTemp = (pMCRefMem->pDstY[iPixel] + pTempMCRefMem->pDstY[iPixel] + 1) >> 1;
436       pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
437     }
438   }
439 
440   //UV
441   iBlkWidth = iBlkWidth >> 1;
442   iBlkHeight = iBlkHeight >> 1;
443   iLineStride = pMCRefMem->iDstLineChroma;
444 
445   uint8_t* pDst;
446   uint8_t* pTempDst;
447   for (int k = 0; k < 2; k++) {
448     pDst = k ? pMCRefMem->pDstV : pMCRefMem->pDstU;
449     pTempDst = k ? pTempMCRefMem->pDstV : pTempMCRefMem->pDstU;
450     //iLineStride = pMCRefMem->iDstLineChroma;
451 
452     for (int i = 0; i < iBlkHeight; i++) {
453       for (int j = 0; j < iBlkWidth; j++) {
454         iPixel = j + i * (iLineStride);
455         iPredTemp = (pDst[iPixel] + pTempDst[iPixel] + 1) >> 1;
456         pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
457       }
458     }
459   }
460 }
461 
GetInterPred(uint8_t * pPredY,uint8_t * pPredCb,uint8_t * pPredCr,PWelsDecoderContext pCtx)462 int32_t GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx) {
463   sMCRefMember pMCRefMem;
464   PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
465   SMcFunc* pMCFunc = &pCtx->sMcFunc;
466 
467   int32_t iMBXY = pCurDqLayer->iMbXyIndex;
468 
469   int16_t iMVs[2] = {0};
470 
471   uint32_t iMBType = pCurDqLayer->pDec->pMbType[iMBXY];
472 
473   int32_t iMBOffsetX = pCurDqLayer->iMbX << 4;
474   int32_t iMBOffsetY = pCurDqLayer->iMbY << 4;
475 
476   int32_t iDstLineLuma   = pCtx->pDec->iLinesize[0];
477   int32_t iDstLineChroma = pCtx->pDec->iLinesize[1];
478 
479   int32_t iBlk8X, iBlk8Y, iBlk4X, iBlk4Y, i, j, iIIdx, iJIdx;
480 
481   pMCRefMem.iPicWidth = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbWidth << 4);
482   pMCRefMem.iPicHeight = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbHeight << 4);
483 
484   pMCRefMem.pDstY = pPredY;
485   pMCRefMem.pDstU = pPredCb;
486   pMCRefMem.pDstV = pPredCr;
487 
488   pMCRefMem.iDstLineLuma   = iDstLineLuma;
489   pMCRefMem.iDstLineChroma = iDstLineChroma;
490 
491   int8_t iRefIndex = 0;
492 
493   switch (iMBType) {
494   case MB_TYPE_SKIP:
495   case MB_TYPE_16x16:
496     iMVs[0] = pCurDqLayer->pDec->pMv[0][iMBXY][0][0];
497     iMVs[1] = pCurDqLayer->pDec->pMv[0][iMBXY][0][1];
498     iRefIndex = pCurDqLayer->pDec->pRefIndex[0][iMBXY][0];
499     WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex, LIST_0));
500     BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
501 
502     if (pCurDqLayer->bUseWeightPredictionFlag) {
503       iRefIndex = pCurDqLayer->pDec->pRefIndex[0][iMBXY][0];
504       WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 16, 16);
505     }
506     break;
507   case MB_TYPE_16x8:
508     iMVs[0] = pCurDqLayer->pDec->pMv[0][iMBXY][0][0];
509     iMVs[1] = pCurDqLayer->pDec->pMv[0][iMBXY][0][1];
510     iRefIndex = pCurDqLayer->pDec->pRefIndex[0][iMBXY][0];
511     WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex, LIST_0));
512     BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 8, iMVs);
513 
514     if (pCurDqLayer->bUseWeightPredictionFlag) {
515       WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 16, 8);
516     }
517 
518     iMVs[0] = pCurDqLayer->pDec->pMv[0][iMBXY][8][0];
519     iMVs[1] = pCurDqLayer->pDec->pMv[0][iMBXY][8][1];
520     iRefIndex = pCurDqLayer->pDec->pRefIndex[0][iMBXY][8];
521     WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex, LIST_0));
522     pMCRefMem.pDstY = pPredY  + (iDstLineLuma << 3);
523     pMCRefMem.pDstU = pPredCb + (iDstLineChroma << 2);
524     pMCRefMem.pDstV = pPredCr + (iDstLineChroma << 2);
525     BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex, iMBOffsetX, iMBOffsetY + 8, pMCFunc, 16, 8, iMVs);
526 
527     if (pCurDqLayer->bUseWeightPredictionFlag) {
528       WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 16, 8);
529     }
530     break;
531   case MB_TYPE_8x16:
532     iMVs[0] = pCurDqLayer->pDec->pMv[0][iMBXY][0][0];
533     iMVs[1] = pCurDqLayer->pDec->pMv[0][iMBXY][0][1];
534     iRefIndex = pCurDqLayer->pDec->pRefIndex[0][iMBXY][0];
535     WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex, LIST_0));
536     BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex, iMBOffsetX, iMBOffsetY, pMCFunc, 8, 16, iMVs);
537     if (pCurDqLayer->bUseWeightPredictionFlag) {
538       WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 16);
539     }
540 
541     iMVs[0] = pCurDqLayer->pDec->pMv[0][iMBXY][2][0];
542     iMVs[1] = pCurDqLayer->pDec->pMv[0][iMBXY][2][1];
543     iRefIndex = pCurDqLayer->pDec->pRefIndex[0][iMBXY][2];
544     WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex, LIST_0));
545     pMCRefMem.pDstY = pPredY + 8;
546     pMCRefMem.pDstU = pPredCb + 4;
547     pMCRefMem.pDstV = pPredCr + 4;
548     BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex, iMBOffsetX + 8, iMBOffsetY, pMCFunc, 8, 16, iMVs);
549 
550     if (pCurDqLayer->bUseWeightPredictionFlag) {
551       WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 16);
552     }
553     break;
554   case MB_TYPE_8x8:
555   case MB_TYPE_8x8_REF0: {
556     uint32_t iSubMBType;
557     int32_t iXOffset, iYOffset;
558     uint8_t* pDstY, *pDstU, *pDstV;
559     for (i = 0; i < 4; i++) {
560       iSubMBType = pCurDqLayer->pSubMbType[iMBXY][i];
561       iBlk8X = (i & 1) << 3;
562       iBlk8Y = (i >> 1) << 3;
563       iXOffset = iMBOffsetX + iBlk8X;
564       iYOffset = iMBOffsetY + iBlk8Y;
565 
566       iIIdx = ((i >> 1) << 3) + ((i & 1) << 1);
567       iRefIndex = pCurDqLayer->pDec->pRefIndex[0][iMBXY][iIIdx];
568       WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex, LIST_0));
569       pDstY = pPredY + iBlk8X + iBlk8Y * iDstLineLuma;
570       pDstU = pPredCb + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
571       pDstV = pPredCr + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
572       pMCRefMem.pDstY = pDstY;
573       pMCRefMem.pDstU = pDstU;
574       pMCRefMem.pDstV = pDstV;
575       switch (iSubMBType) {
576       case SUB_MB_TYPE_8x8:
577         iMVs[0] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx][0];
578         iMVs[1] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx][1];
579         BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
580         if (pCurDqLayer->bUseWeightPredictionFlag) {
581 
582           WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 8);
583         }
584 
585         break;
586       case SUB_MB_TYPE_8x4:
587         iMVs[0] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx][0];
588         iMVs[1] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx][1];
589         BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
590         if (pCurDqLayer->bUseWeightPredictionFlag) {
591 
592           WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 4);
593         }
594 
595 
596         iMVs[0] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx + 4][0];
597         iMVs[1] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx + 4][1];
598         pMCRefMem.pDstY += (iDstLineLuma << 2);
599         pMCRefMem.pDstU += (iDstLineChroma << 1);
600         pMCRefMem.pDstV += (iDstLineChroma << 1);
601         BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);
602         if (pCurDqLayer->bUseWeightPredictionFlag) {
603 
604           WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 4);
605         }
606 
607         break;
608       case SUB_MB_TYPE_4x8:
609         iMVs[0] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx][0];
610         iMVs[1] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx][1];
611         BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);
612         if (pCurDqLayer->bUseWeightPredictionFlag) {
613 
614           WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 4, 8);
615         }
616 
617 
618         iMVs[0] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx + 1][0];
619         iMVs[1] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx + 1][1];
620         pMCRefMem.pDstY += 4;
621         pMCRefMem.pDstU += 2;
622         pMCRefMem.pDstV += 2;
623         BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);
624         if (pCurDqLayer->bUseWeightPredictionFlag) {
625 
626           WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 4, 8);
627         }
628 
629         break;
630       case SUB_MB_TYPE_4x4: {
631         for (j = 0; j < 4; j++) {
632           int32_t iUVLineStride;
633           iJIdx = ((j >> 1) << 2) + (j & 1);
634 
635           iBlk4X = (j & 1) << 2;
636           iBlk4Y = (j >> 1) << 2;
637 
638           iUVLineStride = (iBlk4X >> 1) + (iBlk4Y >> 1) * iDstLineChroma;
639           pMCRefMem.pDstY = pDstY + iBlk4X + iBlk4Y * iDstLineLuma;
640           pMCRefMem.pDstU = pDstU + iUVLineStride;
641           pMCRefMem.pDstV = pDstV + iUVLineStride;
642 
643           iMVs[0] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx + iJIdx][0];
644           iMVs[1] = pCurDqLayer->pDec->pMv[0][iMBXY][iIIdx + iJIdx][1];
645           BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);
646           if (pCurDqLayer->bUseWeightPredictionFlag) {
647 
648             WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 4, 4);
649           }
650 
651         }
652       }
653       break;
654       default:
655         break;
656       }
657     }
658   }
659   break;
660   default:
661     break;
662   }
663   return ERR_NONE;
664 }
665 
GetInterBPred(uint8_t * pPredYCbCr[3],uint8_t * pTempPredYCbCr[3],PWelsDecoderContext pCtx)666 int32_t GetInterBPred (uint8_t* pPredYCbCr[3], uint8_t* pTempPredYCbCr[3], PWelsDecoderContext pCtx) {
667   sMCRefMember pMCRefMem;
668   sMCRefMember pTempMCRefMem;
669 
670   PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
671   SMcFunc* pMCFunc = &pCtx->sMcFunc;
672 
673   int32_t iMBXY = pCurDqLayer->iMbXyIndex;
674 
675   int16_t iMVs[2] = { 0 };
676 
677   uint32_t iMBType = pCurDqLayer->pDec->pMbType[iMBXY];
678 
679   int32_t iMBOffsetX = pCurDqLayer->iMbX << 4;
680   int32_t iMBOffsetY = pCurDqLayer->iMbY << 4;
681 
682   int32_t iDstLineLuma = pCtx->pDec->iLinesize[0];
683   int32_t iDstLineChroma = pCtx->pDec->iLinesize[1];
684 
685 
686   pMCRefMem.iPicWidth = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbWidth << 4);
687   pMCRefMem.iPicHeight = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbHeight << 4);
688 
689   pMCRefMem.pDstY = pPredYCbCr[0];
690   pMCRefMem.pDstU = pPredYCbCr[1];
691   pMCRefMem.pDstV = pPredYCbCr[2];
692 
693   pMCRefMem.iDstLineLuma = iDstLineLuma;
694   pMCRefMem.iDstLineChroma = iDstLineChroma;
695 
696   pTempMCRefMem = pMCRefMem;
697   pTempMCRefMem.pDstY = pTempPredYCbCr[0];
698   pTempMCRefMem.pDstU = pTempPredYCbCr[1];
699   pTempMCRefMem.pDstV = pTempPredYCbCr[2];
700 
701 
702   int8_t iRefIndex0 = 0;
703   int8_t iRefIndex1 = 0;
704   int8_t iRefIndex = 0;
705 
706   bool bWeightedBipredIdcIs1 = pCurDqLayer->sLayerInfo.pPps->uiWeightedBipredIdc == 1;
707 
708   if (IS_INTER_16x16 (iMBType)) {
709     if (IS_TYPE_L0 (iMBType) && IS_TYPE_L1 (iMBType)) {
710       iMVs[0] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][0][0];
711       iMVs[1] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][0][1];
712       iRefIndex0 = pCurDqLayer->pDec->pRefIndex[LIST_0][iMBXY][0];
713       WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex0, LIST_0));
714       BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex0, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
715 
716       iMVs[0] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][0][0];
717       iMVs[1] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][0][1];
718       iRefIndex1 = pCurDqLayer->pDec->pRefIndex[LIST_1][iMBXY][0];
719       WELS_B_MB_REC_VERIFY (GetRefPic (&pTempMCRefMem, pCtx, iRefIndex1, LIST_1));
720       BaseMC (pCtx, &pTempMCRefMem, LIST_1, iRefIndex1, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
721       if (pCurDqLayer->bUseWeightedBiPredIdc) {
722         BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex0, iRefIndex1, bWeightedBipredIdcIs1, 16, 16);
723       } else {
724         BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem,  16, 16);
725       }
726     } else {
727       int32_t listIdx = (iMBType & MB_TYPE_P0L0) ? LIST_0 : LIST_1;
728       iMVs[0] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][0][0];
729       iMVs[1] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][0][1];
730       iRefIndex = pCurDqLayer->pDec->pRefIndex[listIdx][iMBXY][0];
731       WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex, listIdx));
732       BaseMC (pCtx, &pMCRefMem, listIdx, iRefIndex, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
733       if (bWeightedBipredIdcIs1) {
734         WeightPrediction (pCurDqLayer, &pMCRefMem, listIdx, iRefIndex, 16, 16);
735       }
736     }
737   } else if (IS_INTER_16x8 (iMBType)) {
738     for (int32_t i = 0; i < 2; ++i) {
739       int32_t iPartIdx = i << 3;
740       uint32_t listCount = 0;
741       int32_t lastListIdx = LIST_0;
742       for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
743         if (IS_DIR (iMBType, i, listIdx)) {
744           lastListIdx = listIdx;
745           iMVs[0] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iPartIdx][0];
746           iMVs[1] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iPartIdx][1];
747           iRefIndex = pCurDqLayer->pDec->pRefIndex[listIdx][iMBXY][iPartIdx];
748           WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex, listIdx));
749           if (i) {
750             pMCRefMem.pDstY += (iDstLineLuma << 3);
751             pMCRefMem.pDstU += (iDstLineChroma << 2);
752             pMCRefMem.pDstV += (iDstLineChroma << 2);
753           }
754           BaseMC (pCtx, &pMCRefMem, listIdx, iRefIndex, iMBOffsetX, iMBOffsetY + iPartIdx, pMCFunc, 16, 8, iMVs);
755           if (++listCount == 2) {
756             iMVs[0] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iPartIdx][0];
757             iMVs[1] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iPartIdx][1];
758             iRefIndex1 = pCurDqLayer->pDec->pRefIndex[LIST_1][iMBXY][iPartIdx];
759             WELS_B_MB_REC_VERIFY (GetRefPic (&pTempMCRefMem, pCtx, iRefIndex1, LIST_1));
760             if (i) {
761               pTempMCRefMem.pDstY += (iDstLineLuma << 3);
762               pTempMCRefMem.pDstU += (iDstLineChroma << 2);
763               pTempMCRefMem.pDstV += (iDstLineChroma << 2);
764             }
765             BaseMC (pCtx, &pTempMCRefMem, LIST_1, iRefIndex1, iMBOffsetX, iMBOffsetY + iPartIdx, pMCFunc, 16, 8, iMVs);
766             if (pCurDqLayer->bUseWeightedBiPredIdc) {
767               iRefIndex0 = pCurDqLayer->pDec->pRefIndex[LIST_0][iMBXY][iPartIdx];
768               iRefIndex1 = pCurDqLayer->pDec->pRefIndex[LIST_1][iMBXY][iPartIdx];
769               BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex0, iRefIndex1, bWeightedBipredIdcIs1, 16, 8);
770             } else {
771               BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 16, 8);
772             }
773           }
774         }
775       }
776       if (listCount == 1) {
777         if (bWeightedBipredIdcIs1) {
778           iRefIndex = pCurDqLayer->pDec->pRefIndex[lastListIdx][iMBXY][iPartIdx];
779           WeightPrediction (pCurDqLayer, &pMCRefMem, lastListIdx, iRefIndex, 16, 8);
780         }
781       }
782     }
783   } else if (IS_INTER_8x16 (iMBType)) {
784     for (int32_t i = 0; i < 2; ++i) {
785       uint32_t listCount = 0;
786       int32_t lastListIdx = LIST_0;
787       for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
788         if (IS_DIR (iMBType, i, listIdx)) {
789           lastListIdx = listIdx;
790           iMVs[0] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][i << 1][0];
791           iMVs[1] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][i << 1][1];
792           iRefIndex = pCurDqLayer->pDec->pRefIndex[listIdx][iMBXY][i << 1];
793           WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex, listIdx));
794           if (i) {
795             pMCRefMem.pDstY += 8;
796             pMCRefMem.pDstU += 4;
797             pMCRefMem.pDstV += 4;
798           }
799           BaseMC (pCtx, &pMCRefMem, listIdx, iRefIndex, iMBOffsetX + (i ? 8 : 0), iMBOffsetY, pMCFunc, 8, 16, iMVs);
800           if (++listCount == 2) {
801             iMVs[0] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][i << 1][0];
802             iMVs[1] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][i << 1][1];
803             iRefIndex1 = pCurDqLayer->pDec->pRefIndex[LIST_1][iMBXY][i << 1];
804             WELS_B_MB_REC_VERIFY (GetRefPic (&pTempMCRefMem, pCtx, iRefIndex1, LIST_1));
805             if (i) {
806               pTempMCRefMem.pDstY += 8;
807               pTempMCRefMem.pDstU += 4;
808               pTempMCRefMem.pDstV += 4;
809             }
810             BaseMC (pCtx, &pTempMCRefMem, LIST_1, iRefIndex1, iMBOffsetX + (i ? 8 : 0), iMBOffsetY, pMCFunc, 8, 16, iMVs);
811             if (pCurDqLayer->bUseWeightedBiPredIdc) {
812               iRefIndex0 = pCurDqLayer->pDec->pRefIndex[LIST_0][iMBXY][i << 1];
813               iRefIndex1 = pCurDqLayer->pDec->pRefIndex[LIST_1][iMBXY][i << 1];
814               BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex0, iRefIndex1, bWeightedBipredIdcIs1, 8, 16);
815             } else {
816               BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 8, 16);
817             }
818           }
819         }
820       }
821       if (listCount == 1) {
822         if (bWeightedBipredIdcIs1) {
823           iRefIndex = pCurDqLayer->pDec->pRefIndex[lastListIdx][iMBXY][i << 1];
824           WeightPrediction (pCurDqLayer, &pMCRefMem, lastListIdx, iRefIndex, 8, 16);
825         }
826       }
827     }
828   } else if (IS_Inter_8x8 (iMBType)) {
829     int32_t iBlk8X, iBlk8Y, iBlk4X, iBlk4Y, iIIdx, iJIdx;
830     uint32_t iSubMBType;
831     int32_t iXOffset, iYOffset;
832     uint8_t* pDstY, *pDstU, *pDstV;
833     uint8_t* pDstY2, *pDstU2, *pDstV2;
834     for (int32_t i = 0; i < 4; i++) {
835       iSubMBType = pCurDqLayer->pSubMbType[iMBXY][i];
836       iBlk8X = (i & 1) << 3;
837       iBlk8Y = (i >> 1) << 3;
838       iXOffset = iMBOffsetX + iBlk8X;
839       iYOffset = iMBOffsetY + iBlk8Y;
840 
841       iIIdx = ((i >> 1) << 3) + ((i & 1) << 1);
842 
843       pDstY = pPredYCbCr[0] + iBlk8X + iBlk8Y * iDstLineLuma;
844       pDstU = pPredYCbCr[1] + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
845       pDstV = pPredYCbCr[2] + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
846       pMCRefMem.pDstY = pDstY;
847       pMCRefMem.pDstU = pDstU;
848       pMCRefMem.pDstV = pDstV;
849 
850       pTempMCRefMem = pMCRefMem;
851       pDstY2 = pTempPredYCbCr[0] + iBlk8X + iBlk8Y * iDstLineLuma;
852       pDstU2 = pTempPredYCbCr[1] + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
853       pDstV2 = pTempPredYCbCr[2] + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
854 
855       pTempMCRefMem.pDstY = pDstY2;
856       pTempMCRefMem.pDstU = pDstU2;
857       pTempMCRefMem.pDstV = pDstV2;
858 
859       if ((IS_TYPE_L0 (iSubMBType) && IS_TYPE_L1 (iSubMBType))) {
860         iRefIndex0 = pCurDqLayer->pDec->pRefIndex[LIST_0][iMBXY][iIIdx];
861         WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex0, LIST_0));
862 
863         iRefIndex1 = pCurDqLayer->pDec->pRefIndex[LIST_1][iMBXY][iIIdx];
864         WELS_B_MB_REC_VERIFY (GetRefPic (&pTempMCRefMem, pCtx, iRefIndex1, LIST_1));
865       } else {
866         int32_t listIdx = IS_TYPE_L0 (iSubMBType) ? LIST_0 : LIST_1;
867         iRefIndex = pCurDqLayer->pDec->pRefIndex[listIdx][iMBXY][iIIdx];
868         WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, iRefIndex, listIdx));
869       }
870 
871       if (IS_SUB_8x8 (iSubMBType)) {
872         if (IS_TYPE_L0 (iSubMBType) && IS_TYPE_L1 (iSubMBType)) {
873           iMVs[0] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx][0];
874           iMVs[1] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx][1];
875           BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex0, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
876 
877           iMVs[0] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx][0];
878           iMVs[1] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx][1];
879           BaseMC (pCtx, &pTempMCRefMem, LIST_1, iRefIndex1, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
880 
881           if (pCurDqLayer->bUseWeightedBiPredIdc) {
882             BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex0, iRefIndex1, bWeightedBipredIdcIs1, 8, 8);
883           } else {
884             BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem,  8, 8);
885           }
886         } else {
887           int32_t listIdx = IS_TYPE_L0 (iSubMBType) ? LIST_0 : LIST_1;
888           iMVs[0] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx][0];
889           iMVs[1] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx][1];
890           iRefIndex = pCurDqLayer->pDec->pRefIndex[listIdx][iMBXY][iIIdx];
891           BaseMC (pCtx, &pMCRefMem, listIdx, iRefIndex, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
892           if (bWeightedBipredIdcIs1) {
893             WeightPrediction (pCurDqLayer, &pMCRefMem, listIdx, iRefIndex, 8, 8);
894           }
895         }
896       } else if (IS_SUB_8x4 (iSubMBType)) {
897         if (IS_TYPE_L0 (iSubMBType) && IS_TYPE_L1 (iSubMBType)) { //B_Bi_8x4
898           iMVs[0] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx][0];
899           iMVs[1] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx][1];
900           BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex0, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
901           iMVs[0] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx][0];
902           iMVs[1] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx][1];
903           BaseMC (pCtx, &pTempMCRefMem, LIST_1, iRefIndex1, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
904 
905           if (pCurDqLayer->bUseWeightedBiPredIdc) {
906             BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex0, iRefIndex1, bWeightedBipredIdcIs1, 8, 4);
907           } else {
908             BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem,  8, 4);
909           }
910 
911           pMCRefMem.pDstY += (iDstLineLuma << 2);
912           pMCRefMem.pDstU += (iDstLineChroma << 1);
913           pMCRefMem.pDstV += (iDstLineChroma << 1);
914           iMVs[0] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx + 4][0];
915           iMVs[1] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx + 4][1];
916           BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex0, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);
917 
918           pTempMCRefMem.pDstY += (iDstLineLuma << 2);
919           pTempMCRefMem.pDstU += (iDstLineChroma << 1);
920           pTempMCRefMem.pDstV += (iDstLineChroma << 1);
921           iMVs[0] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx + 4][0];
922           iMVs[1] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx + 4][1];
923           BaseMC (pCtx, &pTempMCRefMem, LIST_1, iRefIndex1, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);
924 
925           if (pCurDqLayer->bUseWeightedBiPredIdc) {
926             BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex0, iRefIndex1, bWeightedBipredIdcIs1, 8, 4);
927           } else {
928             BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem,  8, 4);
929           }
930         } else { //B_L0_8x4 B_L1_8x4
931           int32_t listIdx = IS_TYPE_L0 (iSubMBType) ? LIST_0 : LIST_1;
932           iMVs[0] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx][0];
933           iMVs[1] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx][1];
934           iRefIndex = pCurDqLayer->pDec->pRefIndex[listIdx][iMBXY][iIIdx];
935           BaseMC (pCtx, &pMCRefMem, listIdx, iRefIndex, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
936           pMCRefMem.pDstY += (iDstLineLuma << 2);
937           pMCRefMem.pDstU += (iDstLineChroma << 1);
938           pMCRefMem.pDstV += (iDstLineChroma << 1);
939           iMVs[0] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx + 4][0];
940           iMVs[1] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx + 4][1];
941           BaseMC (pCtx, &pMCRefMem, listIdx, iRefIndex, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);
942           if (bWeightedBipredIdcIs1) {
943             WeightPrediction (pCurDqLayer, &pMCRefMem, listIdx, iRefIndex, 8, 4);
944           }
945         }
946       } else if (IS_SUB_4x8 (iSubMBType)) {
947         if (IS_TYPE_L0 (iSubMBType) && IS_TYPE_L1 (iSubMBType)) { //B_Bi_4x8
948           iMVs[0] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx][0];
949           iMVs[1] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx][1];
950           BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex0, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);
951           iMVs[0] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx][0];
952           iMVs[1] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx][1];
953           BaseMC (pCtx, &pTempMCRefMem, LIST_1, iRefIndex1, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);
954 
955           if (pCurDqLayer->bUseWeightedBiPredIdc) {
956             BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex0, iRefIndex1, bWeightedBipredIdcIs1, 4, 8);
957           } else {
958             BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem,  4, 8);
959           }
960 
961           pMCRefMem.pDstY += 4;
962           pMCRefMem.pDstU += 2;
963           pMCRefMem.pDstV += 2;
964           iMVs[0] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx + 1][0];
965           iMVs[1] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx + 1][1];
966           BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex0, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);
967 
968           pTempMCRefMem.pDstY += 4;
969           pTempMCRefMem.pDstU += 2;
970           pTempMCRefMem.pDstV += 2;
971           iMVs[0] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx + 1][0];
972           iMVs[1] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx + 1][1];
973           BaseMC (pCtx, &pTempMCRefMem, LIST_1, iRefIndex1, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);
974 
975           if (pCurDqLayer->bUseWeightedBiPredIdc) {
976             BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex0, iRefIndex1, bWeightedBipredIdcIs1, 4, 8);
977           } else {
978             BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 4, 8);
979           }
980         } else { //B_L0_4x8 B_L1_4x8
981           int32_t listIdx = IS_TYPE_L0 (iSubMBType) ? LIST_0 : LIST_1;
982           iMVs[0] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx][0];
983           iMVs[1] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx][1];
984           iRefIndex = pCurDqLayer->pDec->pRefIndex[listIdx][iMBXY][iIIdx];
985           BaseMC (pCtx, &pMCRefMem, listIdx, iRefIndex, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);
986           pMCRefMem.pDstY += 4;
987           pMCRefMem.pDstU += 2;
988           pMCRefMem.pDstV += 2;
989           iMVs[0] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx + 1][0];
990           iMVs[1] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx + 1][1];
991           BaseMC (pCtx, &pMCRefMem, listIdx, iRefIndex, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);
992           if (bWeightedBipredIdcIs1) {
993             WeightPrediction (pCurDqLayer, &pMCRefMem, listIdx, iRefIndex, 4, 8);
994           }
995         }
996       } else if (IS_SUB_4x4 (iSubMBType)) {
997         if (IS_TYPE_L0 (iSubMBType) && IS_TYPE_L1 (iSubMBType)) {
998           for (int32_t j = 0; j < 4; j++) {
999             int32_t iUVLineStride;
1000             iJIdx = ((j >> 1) << 2) + (j & 1);
1001 
1002             iBlk4X = (j & 1) << 2;
1003             iBlk4Y = (j >> 1) << 2;
1004 
1005             iUVLineStride = (iBlk4X >> 1) + (iBlk4Y >> 1) * iDstLineChroma;
1006             pMCRefMem.pDstY = pDstY + iBlk4X + iBlk4Y * iDstLineLuma;
1007             pMCRefMem.pDstU = pDstU + iUVLineStride;
1008             pMCRefMem.pDstV = pDstV + iUVLineStride;
1009 
1010             iMVs[0] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx + iJIdx][0];
1011             iMVs[1] = pCurDqLayer->pDec->pMv[LIST_0][iMBXY][iIIdx + iJIdx][1];
1012             BaseMC (pCtx, &pMCRefMem, LIST_0, iRefIndex0, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);
1013 
1014             pTempMCRefMem.pDstY = pDstY2 + iBlk8X + iBlk8Y * iDstLineLuma;
1015             pTempMCRefMem.pDstU = pDstU2 + iUVLineStride;
1016             pTempMCRefMem.pDstV = pDstV2 + iUVLineStride;;
1017 
1018             iMVs[0] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx + iJIdx][0];
1019             iMVs[1] = pCurDqLayer->pDec->pMv[LIST_1][iMBXY][iIIdx + iJIdx][1];
1020             BaseMC (pCtx, &pTempMCRefMem, LIST_1, iRefIndex1, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);
1021 
1022             if (pCurDqLayer->bUseWeightedBiPredIdc) {
1023               BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex0, iRefIndex1, bWeightedBipredIdcIs1, 4, 4);
1024             } else {
1025               BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem,  4, 4);
1026             }
1027           }
1028         } else {
1029           int32_t listIdx = IS_TYPE_L0 (iSubMBType) ? LIST_0 : LIST_1;
1030           iRefIndex = pCurDqLayer->pDec->pRefIndex[listIdx][iMBXY][iIIdx];
1031           for (int32_t j = 0; j < 4; j++) {
1032             int32_t iUVLineStride;
1033             iJIdx = ((j >> 1) << 2) + (j & 1);
1034 
1035             iBlk4X = (j & 1) << 2;
1036             iBlk4Y = (j >> 1) << 2;
1037 
1038             iUVLineStride = (iBlk4X >> 1) + (iBlk4Y >> 1) * iDstLineChroma;
1039             pMCRefMem.pDstY = pDstY + iBlk4X + iBlk4Y * iDstLineLuma;
1040             pMCRefMem.pDstU = pDstU + iUVLineStride;
1041             pMCRefMem.pDstV = pDstV + iUVLineStride;
1042 
1043             iMVs[0] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx + iJIdx][0];
1044             iMVs[1] = pCurDqLayer->pDec->pMv[listIdx][iMBXY][iIIdx + iJIdx][1];
1045             BaseMC (pCtx, &pMCRefMem, listIdx, iRefIndex, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);
1046             if (bWeightedBipredIdcIs1) {
1047               WeightPrediction (pCurDqLayer, &pMCRefMem, listIdx, iRefIndex, 4, 4);
1048             }
1049           }
1050         }
1051       }
1052     }
1053   }
1054   return ERR_NONE;
1055 }
1056 
RecChroma(int32_t iMBXY,PWelsDecoderContext pCtx,int16_t * pScoeffLevel,PDqLayer pDqLayer)1057 int32_t RecChroma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
1058   int32_t iChromaStride = pCtx->pCurDqLayer->pDec->iLinesize[1];
1059   PIdctFourResAddPredFunc pIdctFourResAddPredFunc = pCtx->pIdctFourResAddPredFunc;
1060 
1061   uint8_t i = 0;
1062   uint8_t uiCbpC = pDqLayer->pCbp[iMBXY] >> 4;
1063 
1064   if (1 == uiCbpC || 2 == uiCbpC) {
1065     for (i = 0; i < 2; i++) {
1066       int16_t* pRS = pScoeffLevel + 256 + (i << 6);
1067       uint8_t* pPred = pDqLayer->pPred[i + 1];
1068       const int8_t* pNzc = pDqLayer->pNzc[iMBXY] + 16 + 2 * i;
1069 
1070       /*1 chroma is divided 4 4x4_block to idct*/
1071       pIdctFourResAddPredFunc (pPred, iChromaStride, pRS, pNzc);
1072     }
1073   }
1074 
1075   return ERR_NONE;
1076 }
1077 
1078 } // namespace WelsDec
1079