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