History

B-frame decoding support for Main and High Profile with two test cases.

xiaotianshi2 committed 8 years ago

Commit 657d2171 parent e3e838355 files · +17936 −13825Browse files

Showing the changes to codec/decoder/core/src/rec_mb.cpp (1 of 55 files). Show all

Unified · Split

codec/decoder/core/src/rec_mb.cpp+1040−559
@@ -1,559 +1,1040 @@
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−
47−void WelsFillRecNeededMbInfo (PWelsDecoderContext pCtx, bool bOutput, PDqLayer pCurLayer) {
48− PPicture pCurPic = pCtx->pDec;
49− int32_t iLumaStride = pCurPic->iLinesize[0];
50− int32_t iChromaStride = pCurPic->iLinesize[1];
51− int32_t iMbX = pCurLayer->iMbX;
52− int32_t iMbY = pCurLayer->iMbY;
53−
54− pCurLayer->iLumaStride = iLumaStride;
55− pCurLayer->iChromaStride = iChromaStride;
56−
57− if (bOutput) {
58− pCurLayer->pPred[0] = pCurPic->pData[0] + ((iMbY * iLumaStride + iMbX) << 4);
59− pCurLayer->pPred[1] = pCurPic->pData[1] + ((iMbY * iChromaStride + iMbX) << 3);
60− pCurLayer->pPred[2] = pCurPic->pData[2] + ((iMbY * iChromaStride + iMbX) << 3);
61− }
62−}
63−
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−
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−
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−
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−
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−
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
217−static inline void GetRefPic (sMCRefMember* pMCRefMem, PWelsDecoderContext pCtx, int8_t* pRefIdxList,
218− int32_t iIndex) {
219− PPicture pRefPic;
220−
221− int8_t iRefIdx = pRefIdxList[iIndex];
222− pRefPic = pCtx->sRefPic.pRefList[LIST_0][iRefIdx];
223−
224− pMCRefMem->iSrcLineLuma = pRefPic->iLinesize[0];
225− pMCRefMem->iSrcLineChroma = pRefPic->iLinesize[1];
226−
227− pMCRefMem->pSrcY = pRefPic->pData[0];
228− pMCRefMem->pSrcU = pRefPic->pData[1];
229− pMCRefMem->pSrcV = pRefPic->pData[2];
230−}
231−
232−
233−#ifndef MC_FLOW_SIMPLE_JUDGE
234−#define MC_FLOW_SIMPLE_JUDGE 1
235−#endif //MC_FLOW_SIMPLE_JUDGE
236−void BaseMC (sMCRefMember* pMCRefMem, int32_t iXOffset, int32_t iYOffset, SMcFunc* pMCFunc,
237− int32_t iBlkWidth, int32_t iBlkHeight, int16_t iMVs[2]) {
238− int32_t iFullMVx = (iXOffset << 2) + iMVs[0]; //quarter pixel
239− int32_t iFullMVy = (iYOffset << 2) + iMVs[1];
240− iFullMVx = WELS_CLIP3 (iFullMVx, ((-PADDING_LENGTH + 2) * (1 << 2)),
241− ((pMCRefMem->iPicWidth + PADDING_LENGTH - 19) * (1 << 2)));
242− iFullMVy = WELS_CLIP3 (iFullMVy, ((-PADDING_LENGTH + 2) * (1 << 2)),
243− ((pMCRefMem->iPicHeight + PADDING_LENGTH - 19) * (1 << 2)));
244−
245− int32_t iSrcPixOffsetLuma = (iFullMVx >> 2) + (iFullMVy >> 2) * pMCRefMem->iSrcLineLuma;
246− int32_t iSrcPixOffsetChroma = (iFullMVx >> 3) + (iFullMVy >> 3) * pMCRefMem->iSrcLineChroma;
247−
248− int32_t iBlkWidthChroma = iBlkWidth >> 1;
249− int32_t iBlkHeightChroma = iBlkHeight >> 1;
250−
251− uint8_t* pSrcY = pMCRefMem->pSrcY + iSrcPixOffsetLuma;
252− uint8_t* pSrcU = pMCRefMem->pSrcU + iSrcPixOffsetChroma;
253− uint8_t* pSrcV = pMCRefMem->pSrcV + iSrcPixOffsetChroma;
254− uint8_t* pDstY = pMCRefMem->pDstY;
255− uint8_t* pDstU = pMCRefMem->pDstU;
256− uint8_t* pDstV = pMCRefMem->pDstV;
257−
258− pMCFunc->pMcLumaFunc (pSrcY, pMCRefMem->iSrcLineLuma, pDstY, pMCRefMem->iDstLineLuma, iFullMVx, iFullMVy, iBlkWidth,
259− iBlkHeight);
260− pMCFunc->pMcChromaFunc (pSrcU, pMCRefMem->iSrcLineChroma, pDstU, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
261− iBlkWidthChroma, iBlkHeightChroma);
262− pMCFunc->pMcChromaFunc (pSrcV, pMCRefMem->iSrcLineChroma, pDstV, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
263− iBlkWidthChroma, iBlkHeightChroma);
264−
265−}
266−
267−void WeightPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, int32_t iRefIdx, int32_t iBlkWidth,
268− int32_t iBlkHeight) {
269−
270−
271− int32_t iLog2denom, iWoc, iOoc;
272− int32_t iPredTemp, iLineStride;
273− int32_t iPixel = 0;
274− uint8_t* pDst;
275− //luma
276− iLog2denom = pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom;
277− iWoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaWeight[iRefIdx];
278− iOoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaOffset[iRefIdx];
279− iLineStride = pMCRefMem->iDstLineLuma;
280−
281− for (int i = 0; i < iBlkHeight; i++) {
282− for (int j = 0; j < iBlkWidth; j++) {
283− iPixel = j + i * (iLineStride);
284− if (iLog2denom >= 1) {
285− iPredTemp = ((pMCRefMem->pDstY[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
286−
287− pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
288− } else {
289− iPredTemp = pMCRefMem->pDstY[iPixel] * iWoc + iOoc;
290−
291− pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
292−
293− }
294− }
295− }
296−
297−
298− //UV
299− iBlkWidth = iBlkWidth >> 1;
300− iBlkHeight = iBlkHeight >> 1;
301− iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
302− iLineStride = pMCRefMem->iDstLineChroma;
303−
304− for (int i = 0; i < 2; i++) {
305−
306−
307− //iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
308− iWoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaWeight[iRefIdx][i];
309− iOoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaOffset[iRefIdx][i];
310− pDst = i ? pMCRefMem->pDstV : pMCRefMem->pDstU;
311− //iLineStride = pMCRefMem->iDstLineChroma;
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 = ((pDst[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
318−
319− pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
320− } else {
321− iPredTemp = pDst[iPixel] * iWoc + iOoc;
322−
323− pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
324−
325− }
326− }
327−
328− }
329−
330−
331− }
332−}
333−
334−
335−void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx) {
336− sMCRefMember pMCRefMem;
337− PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
338− SMcFunc* pMCFunc = &pCtx->sMcFunc;
339−
340− int32_t iMBXY = pCurDqLayer->iMbXyIndex;
341−
342− int16_t iMVs[2] = {0};
343−
344− int32_t iMBType = pCurDqLayer->pMbType[iMBXY];
345−
346− int32_t iMBOffsetX = pCurDqLayer->iMbX << 4;
347− int32_t iMBOffsetY = pCurDqLayer->iMbY << 4;
348−
349− int32_t iDstLineLuma = pCtx->pDec->iLinesize[0];
350− int32_t iDstLineChroma = pCtx->pDec->iLinesize[1];
351−
352− int32_t iBlk8X, iBlk8Y, iBlk4X, iBlk4Y, i, j, iIIdx, iJIdx;
353−
354− pMCRefMem.iPicWidth = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbWidth << 4);
355− pMCRefMem.iPicHeight = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbHeight << 4);
356−
357− pMCRefMem.pDstY = pPredY;
358− pMCRefMem.pDstU = pPredCb;
359− pMCRefMem.pDstV = pPredCr;
360−
361− pMCRefMem.iDstLineLuma = iDstLineLuma;
362− pMCRefMem.iDstLineChroma = iDstLineChroma;
363−
364− int32_t iRefIndex = 0;
365−
366− switch (iMBType) {
367− case MB_TYPE_SKIP:
368− case MB_TYPE_16x16:
369− iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
370− iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
371− GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);
372− BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
373−
374− if (pCurDqLayer->bUseWeightPredictionFlag) {
375− iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
376− WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 16);
377− }
378− break;
379− case MB_TYPE_16x8:
380− iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
381− iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
382− GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);
383− BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 8, iMVs);
384−
385− if (pCurDqLayer->bUseWeightPredictionFlag) {
386− iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
387− WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 8);
388− }
389−
390− iMVs[0] = pCurDqLayer->pMv[0][iMBXY][8][0];
391− iMVs[1] = pCurDqLayer->pMv[0][iMBXY][8][1];
392− GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 8);
393− pMCRefMem.pDstY = pPredY + (iDstLineLuma << 3);
394− pMCRefMem.pDstU = pPredCb + (iDstLineChroma << 2);
395− pMCRefMem.pDstV = pPredCr + (iDstLineChroma << 2);
396− BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY + 8, pMCFunc, 16, 8, iMVs);
397−
398− if (pCurDqLayer->bUseWeightPredictionFlag) {
399− iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][8];
400− WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 8);
401− }
402− break;
403− case MB_TYPE_8x16:
404− iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
405− iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
406− GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);
407− BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 8, 16, iMVs);
408− if (pCurDqLayer->bUseWeightPredictionFlag) {
409− iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
410− WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 16);
411− }
412−
413− iMVs[0] = pCurDqLayer->pMv[0][iMBXY][2][0];
414− iMVs[1] = pCurDqLayer->pMv[0][iMBXY][2][1];
415− GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 2);
416− pMCRefMem.pDstY = pPredY + 8;
417− pMCRefMem.pDstU = pPredCb + 4;
418− pMCRefMem.pDstV = pPredCr + 4;
419− BaseMC (&pMCRefMem, iMBOffsetX + 8, iMBOffsetY, pMCFunc, 8, 16, iMVs);
420−
421− if (pCurDqLayer->bUseWeightPredictionFlag) {
422− iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][2];
423− WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 16);
424− }
425− break;
426− case MB_TYPE_8x8:
427− case MB_TYPE_8x8_REF0: {
428− uint32_t iSubMBType;
429− int32_t iXOffset, iYOffset;
430− uint8_t* pDstY, *pDstU, *pDstV;
431− for (i = 0; i < 4; i++) {
432− iSubMBType = pCurDqLayer->pSubMbType[iMBXY][i];
433− iBlk8X = (i & 1) << 3;
434− iBlk8Y = (i >> 1) << 3;
435− iXOffset = iMBOffsetX + iBlk8X;
436− iYOffset = iMBOffsetY + iBlk8Y;
437−
438− iIIdx = ((i >> 1) << 3) + ((i & 1) << 1);
439− GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], iIIdx);
440− iRefIndex = pCurDqLayer->bUseWeightPredictionFlag ? pCurDqLayer->pRefIndex[0][iMBXY][iIIdx] : 0;
441−
442− pDstY = pPredY + iBlk8X + iBlk8Y * iDstLineLuma;
443− pDstU = pPredCb + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
444− pDstV = pPredCr + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
445− pMCRefMem.pDstY = pDstY;
446− pMCRefMem.pDstU = pDstU;
447− pMCRefMem.pDstV = pDstV;
448− switch (iSubMBType) {
449− case SUB_MB_TYPE_8x8:
450− iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
451− iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
452− BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
453− if (pCurDqLayer->bUseWeightPredictionFlag) {
454−
455− WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 8);
456− }
457−
458− break;
459− case SUB_MB_TYPE_8x4:
460− iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
461− iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
462− BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
463− if (pCurDqLayer->bUseWeightPredictionFlag) {
464−
465− WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 4);
466− }
467−
468−
469− iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 4][0];
470− iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 4][1];
471− pMCRefMem.pDstY += (iDstLineLuma << 2);
472− pMCRefMem.pDstU += (iDstLineChroma << 1);
473− pMCRefMem.pDstV += (iDstLineChroma << 1);
474− BaseMC (&pMCRefMem, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);
475− if (pCurDqLayer->bUseWeightPredictionFlag) {
476−
477− WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 4);
478− }
479−
480− break;
481− case SUB_MB_TYPE_4x8:
482− iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
483− iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
484− BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);
485− if (pCurDqLayer->bUseWeightPredictionFlag) {
486−
487− WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 8);
488− }
489−
490−
491− iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 1][0];
492− iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 1][1];
493− pMCRefMem.pDstY += 4;
494− pMCRefMem.pDstU += 2;
495− pMCRefMem.pDstV += 2;
496− BaseMC (&pMCRefMem, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);
497− if (pCurDqLayer->bUseWeightPredictionFlag) {
498−
499− WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 8);
500− }
501−
502− break;
503− case SUB_MB_TYPE_4x4: {
504− for (j = 0; j < 4; j++) {
505− int32_t iUVLineStride;
506− iJIdx = ((j >> 1) << 2) + (j & 1);
507−
508− iBlk4X = (j & 1) << 2;
509− iBlk4Y = (j >> 1) << 2;
510−
511− iUVLineStride = (iBlk4X >> 1) + (iBlk4Y >> 1) * iDstLineChroma;
512− pMCRefMem.pDstY = pDstY + iBlk4X + iBlk4Y * iDstLineLuma;
513− pMCRefMem.pDstU = pDstU + iUVLineStride;
514− pMCRefMem.pDstV = pDstV + iUVLineStride;
515−
516− iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + iJIdx][0];
517− iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + iJIdx][1];
518− BaseMC (&pMCRefMem, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);
519− if (pCurDqLayer->bUseWeightPredictionFlag) {
520−
521− WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 4);
522− }
523−
524− }
525− }
526− break;
527− default:
528− break;
529− }
530− }
531− }
532− break;
533− default:
534− break;
535− }
536−}
537−
538−int32_t RecChroma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
539− int32_t iChromaStride = pCtx->pCurDqLayer->pDec->iLinesize[1];
540− PIdctFourResAddPredFunc pIdctFourResAddPredFunc = pCtx->pIdctFourResAddPredFunc;
541−
542− uint8_t i = 0;
543− uint8_t uiCbpC = pDqLayer->pCbp[iMBXY] >> 4;
544−
545− if (1 == uiCbpC || 2 == uiCbpC) {
546− for (i = 0; i < 2; i++) {
547− int16_t* pRS = pScoeffLevel + 256 + (i << 6);
548− uint8_t* pPred = pDqLayer->pPred[i + 1];
549− const int8_t* pNzc = pDqLayer->pNzc[iMBXY] + 16 + 2 * i;
550−
551− /*1 chroma is divided 4 4x4_block to idct*/
552− pIdctFourResAddPredFunc (pPred, iChromaStride, pRS, pNzc);
553− }
554− }
555−
556− return ERR_NONE;
557−}
558−
559−} // namespace WelsDec
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+
47+void WelsFillRecNeededMbInfo (PWelsDecoderContext pCtx, bool bOutput, PDqLayer pCurLayer) {
48+ PPicture pCurPic = pCtx->pDec;
49+ int32_t iLumaStride = pCurPic->iLinesize[0];
50+ int32_t iChromaStride = pCurPic->iLinesize[1];
51+ int32_t iMbX = pCurLayer->iMbX;
52+ int32_t iMbY = pCurLayer->iMbY;
53+
54+ pCurLayer->iLumaStride = iLumaStride;
55+ pCurLayer->iChromaStride = iChromaStride;
56+
57+ if (bOutput) {
58+ pCurLayer->pPred[0] = pCurPic->pData[0] + ((iMbY * iLumaStride + iMbX) << 4);
59+ pCurLayer->pPred[1] = pCurPic->pData[1] + ((iMbY * iChromaStride + iMbX) << 3);
60+ pCurLayer->pPred[2] = pCurPic->pData[2] + ((iMbY * iChromaStride + iMbX) << 3);
61+ }
62+}
63+
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+
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+
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+
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+
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+
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
217+static inline void GetRefPic (sMCRefMember* pMCRefMem, PWelsDecoderContext pCtx, int8_t* pRefIdxList,
218+ int32_t iIndex, int32_t listIdx) {
219+ PPicture pRefPic;
220+
221+ int8_t iRefIdx = pRefIdxList[iIndex];
222+ pRefPic = pCtx->sRefPic.pRefList[listIdx][iRefIdx];
223+
224+ pMCRefMem->iSrcLineLuma = pRefPic->iLinesize[0];
225+ pMCRefMem->iSrcLineChroma = pRefPic->iLinesize[1];
226+
227+ pMCRefMem->pSrcY = pRefPic->pData[0];
228+ pMCRefMem->pSrcU = pRefPic->pData[1];
229+ pMCRefMem->pSrcV = pRefPic->pData[2];
230+}
231+
232+
233+#ifndef MC_FLOW_SIMPLE_JUDGE
234+#define MC_FLOW_SIMPLE_JUDGE 1
235+#endif //MC_FLOW_SIMPLE_JUDGE
236+void BaseMC (sMCRefMember* pMCRefMem, int32_t iXOffset, int32_t iYOffset, SMcFunc* pMCFunc,
237+ int32_t iBlkWidth, int32_t iBlkHeight, int16_t iMVs[2]) {
238+ int32_t iFullMVx = (iXOffset << 2) + iMVs[0]; //quarter pixel
239+ int32_t iFullMVy = (iYOffset << 2) + iMVs[1];
240+ iFullMVx = WELS_CLIP3 (iFullMVx, ((-PADDING_LENGTH + 2) * (1 << 2)),
241+ ((pMCRefMem->iPicWidth + PADDING_LENGTH - 19) * (1 << 2)));
242+ iFullMVy = WELS_CLIP3 (iFullMVy, ((-PADDING_LENGTH + 2) * (1 << 2)),
243+ ((pMCRefMem->iPicHeight + PADDING_LENGTH - 19) * (1 << 2)));
244+
245+ int32_t iSrcPixOffsetLuma = (iFullMVx >> 2) + (iFullMVy >> 2) * pMCRefMem->iSrcLineLuma;
246+ int32_t iSrcPixOffsetChroma = (iFullMVx >> 3) + (iFullMVy >> 3) * pMCRefMem->iSrcLineChroma;
247+
248+ int32_t iBlkWidthChroma = iBlkWidth >> 1;
249+ int32_t iBlkHeightChroma = iBlkHeight >> 1;
250+
251+ uint8_t* pSrcY = pMCRefMem->pSrcY + iSrcPixOffsetLuma;
252+ uint8_t* pSrcU = pMCRefMem->pSrcU + iSrcPixOffsetChroma;
253+ uint8_t* pSrcV = pMCRefMem->pSrcV + iSrcPixOffsetChroma;
254+ uint8_t* pDstY = pMCRefMem->pDstY;
255+ uint8_t* pDstU = pMCRefMem->pDstU;
256+ uint8_t* pDstV = pMCRefMem->pDstV;
257+
258+ pMCFunc->pMcLumaFunc (pSrcY, pMCRefMem->iSrcLineLuma, pDstY, pMCRefMem->iDstLineLuma, iFullMVx, iFullMVy, iBlkWidth,
259+ iBlkHeight);
260+ pMCFunc->pMcChromaFunc (pSrcU, pMCRefMem->iSrcLineChroma, pDstU, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
261+ iBlkWidthChroma, iBlkHeightChroma);
262+ pMCFunc->pMcChromaFunc (pSrcV, pMCRefMem->iSrcLineChroma, pDstV, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
263+ iBlkWidthChroma, iBlkHeightChroma);
264+
265+}
266+
267+static void WeightPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, int32_t listIdx, int32_t iRefIdx,
268+ int32_t iBlkWidth,
269+ int32_t iBlkHeight) {
270+
271+
272+ int32_t iLog2denom, iWoc, iOoc;
273+ int32_t iPredTemp, iLineStride;
274+ int32_t iPixel = 0;
275+ uint8_t* pDst;
276+ //luma
277+ iLog2denom = pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom;
278+ iWoc = pCurDqLayer->pPredWeightTable->sPredList[listIdx].iLumaWeight[iRefIdx];
279+ iOoc = pCurDqLayer->pPredWeightTable->sPredList[listIdx].iLumaOffset[iRefIdx];
280+ iLineStride = pMCRefMem->iDstLineLuma;
281+
282+ for (int i = 0; i < iBlkHeight; i++) {
283+ for (int j = 0; j < iBlkWidth; j++) {
284+ iPixel = j + i * (iLineStride);
285+ if (iLog2denom >= 1) {
286+ iPredTemp = ((pMCRefMem->pDstY[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
287+
288+ pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
289+ } else {
290+ iPredTemp = pMCRefMem->pDstY[iPixel] * iWoc + iOoc;
291+
292+ pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
293+
294+ }
295+ }
296+ }
297+
298+
299+ //UV
300+ iBlkWidth = iBlkWidth >> 1;
301+ iBlkHeight = iBlkHeight >> 1;
302+ iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
303+ iLineStride = pMCRefMem->iDstLineChroma;
304+
305+ for (int i = 0; i < 2; i++) {
306+
307+
308+ //iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
309+ iWoc = pCurDqLayer->pPredWeightTable->sPredList[listIdx].iChromaWeight[iRefIdx][i];
310+ iOoc = pCurDqLayer->pPredWeightTable->sPredList[listIdx].iChromaOffset[iRefIdx][i];
311+ pDst = i ? pMCRefMem->pDstV : pMCRefMem->pDstU;
312+ //iLineStride = pMCRefMem->iDstLineChroma;
313+
314+ for (int i = 0; i < iBlkHeight ; i++) {
315+ for (int j = 0; j < iBlkWidth; j++) {
316+ iPixel = j + i * (iLineStride);
317+ if (iLog2denom >= 1) {
318+ iPredTemp = ((pDst[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
319+
320+ pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
321+ } else {
322+ iPredTemp = pDst[iPixel] * iWoc + iOoc;
323+
324+ pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
325+
326+ }
327+ }
328+
329+ }
330+
331+
332+ }
333+}
334+
335+static void BiWeightPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, sMCRefMember* pTempMCRefMem,
336+ int32_t iRefIdx1, int32_t iRefIdx2, bool bWeightedBipredIdcIs1, int32_t iBlkWidth,
337+ int32_t iBlkHeight) {
338+ int32_t iWoc1 = 0, iOoc1 = 0, iWoc2 = 0, iOoc2 = 0;
339+ int32_t iPredTemp, iLineStride;
340+ int32_t iPixel = 0;
341+ //luma
342+ int32_t iLog2denom = pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom;
343+ if (bWeightedBipredIdcIs1) {
344+ iWoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaWeight[iRefIdx1];
345+ iOoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaOffset[iRefIdx1];
346+ iWoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iLumaWeight[iRefIdx2];
347+ iOoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iLumaOffset[iRefIdx2];
348+ } else {
349+ iWoc1 = pCurDqLayer->pPredWeightTable->iImplicitWeight[iRefIdx1][iRefIdx2];
350+ iWoc2 = 64 - iWoc1;
351+ }
352+ iLineStride = pMCRefMem->iDstLineLuma;
353+
354+ for (int i = 0; i < iBlkHeight; i++) {
355+ for (int j = 0; j < iBlkWidth; j++) {
356+ iPixel = j + i * (iLineStride);
357+ iPredTemp = ((pMCRefMem->pDstY[iPixel] * iWoc1 + pTempMCRefMem->pDstY[iPixel] * iWoc2 + (1 << iLog2denom)) >>
358+ (iLog2denom + 1)) + ((iOoc1 + iOoc2 + 1) >> 1);
359+ pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
360+ }
361+ }
362+
363+ //UV
364+ iBlkWidth = iBlkWidth >> 1;
365+ iBlkHeight = iBlkHeight >> 1;
366+ iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
367+ iLineStride = pMCRefMem->iDstLineChroma;
368+
369+ uint8_t* pDst;
370+ uint8_t* pTempDst;
371+ for (int k = 0; k < 2; k++) {
372+ //iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
373+ if (bWeightedBipredIdcIs1) {
374+ iWoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaWeight[iRefIdx1][k];
375+ iOoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaOffset[iRefIdx1][k];
376+ iWoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iChromaWeight[iRefIdx2][k];
377+ iOoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iChromaOffset[iRefIdx2][k];
378+ }
379+ pDst = k ? pMCRefMem->pDstV : pMCRefMem->pDstU;
380+ pTempDst = k ? pTempMCRefMem->pDstV : pTempMCRefMem->pDstU;
381+ //iLineStride = pMCRefMem->iDstLineChroma;
382+
383+ for (int i = 0; i < iBlkHeight; i++) {
384+ for (int j = 0; j < iBlkWidth; j++) {
385+ iPixel = j + i * (iLineStride);
386+ iPredTemp = ((pDst[iPixel] * iWoc1 + pTempDst[iPixel] * iWoc2 + (1 << iLog2denom)) >> (iLog2denom + 1)) + ((
387+ iOoc1 + iOoc2 + 1) >> 1);
388+ pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
389+ }
390+ }
391+ }
392+}
393+
394+static void BiPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, sMCRefMember* pTempMCRefMem, int32_t iBlkWidth,
395+ int32_t iBlkHeight) {
396+ int32_t iPredTemp, iLineStride;
397+ int32_t iPixel = 0;
398+ //luma
399+ iLineStride = pMCRefMem->iDstLineLuma;
400+
401+ for (int i = 0; i < iBlkHeight; i++) {
402+ for (int j = 0; j < iBlkWidth; j++) {
403+ iPixel = j + i * (iLineStride);
404+ iPredTemp = (pMCRefMem->pDstY[iPixel] + pTempMCRefMem->pDstY[iPixel] + 1) >> 1;
405+ pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
406+ }
407+ }
408+
409+ //UV
410+ iBlkWidth = iBlkWidth >> 1;
411+ iBlkHeight = iBlkHeight >> 1;
412+ iLineStride = pMCRefMem->iDstLineChroma;
413+
414+ uint8_t* pDst;
415+ uint8_t* pTempDst;
416+ for (int k = 0; k < 2; k++) {
417+ pDst = k ? pMCRefMem->pDstV : pMCRefMem->pDstU;
418+ pTempDst = k ? pTempMCRefMem->pDstV : pTempMCRefMem->pDstU;
419+ //iLineStride = pMCRefMem->iDstLineChroma;
420+
421+ for (int i = 0; i < iBlkHeight; i++) {
422+ for (int j = 0; j < iBlkWidth; j++) {
423+ iPixel = j + i * (iLineStride);
424+ iPredTemp = (pDst[iPixel] + pTempDst[iPixel] + 1) >> 1;
425+ pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
426+ }
427+ }
428+ }
429+}
430+
431+void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx) {
432+ sMCRefMember pMCRefMem;
433+ PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
434+ SMcFunc* pMCFunc = &pCtx->sMcFunc;
435+
436+ int32_t iMBXY = pCurDqLayer->iMbXyIndex;
437+
438+ int16_t iMVs[2] = {0};
439+
440+ uint32_t iMBType = pCurDqLayer->pMbType[iMBXY];
441+
442+ int32_t iMBOffsetX = pCurDqLayer->iMbX << 4;
443+ int32_t iMBOffsetY = pCurDqLayer->iMbY << 4;
444+
445+ int32_t iDstLineLuma = pCtx->pDec->iLinesize[0];
446+ int32_t iDstLineChroma = pCtx->pDec->iLinesize[1];
447+
448+ int32_t iBlk8X, iBlk8Y, iBlk4X, iBlk4Y, i, j, iIIdx, iJIdx;
449+
450+ pMCRefMem.iPicWidth = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbWidth << 4);
451+ pMCRefMem.iPicHeight = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbHeight << 4);
452+
453+ pMCRefMem.pDstY = pPredY;
454+ pMCRefMem.pDstU = pPredCb;
455+ pMCRefMem.pDstV = pPredCr;
456+
457+ pMCRefMem.iDstLineLuma = iDstLineLuma;
458+ pMCRefMem.iDstLineChroma = iDstLineChroma;
459+
460+ int32_t iRefIndex = 0;
461+
462+ switch (iMBType) {
463+ case MB_TYPE_SKIP:
464+ case MB_TYPE_16x16:
465+ iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
466+ iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
467+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0);
468+ BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
469+
470+ if (pCurDqLayer->bUseWeightPredictionFlag) {
471+ iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
472+ WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 16, 16);
473+ }
474+ break;
475+ case MB_TYPE_16x8:
476+ iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
477+ iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
478+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0);
479+ BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 8, iMVs);
480+
481+ if (pCurDqLayer->bUseWeightPredictionFlag) {
482+ iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
483+ WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 16, 8);
484+ }
485+
486+ iMVs[0] = pCurDqLayer->pMv[0][iMBXY][8][0];
487+ iMVs[1] = pCurDqLayer->pMv[0][iMBXY][8][1];
488+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 8, LIST_0);
489+ pMCRefMem.pDstY = pPredY + (iDstLineLuma << 3);
490+ pMCRefMem.pDstU = pPredCb + (iDstLineChroma << 2);
491+ pMCRefMem.pDstV = pPredCr + (iDstLineChroma << 2);
492+ BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY + 8, pMCFunc, 16, 8, iMVs);
493+
494+ if (pCurDqLayer->bUseWeightPredictionFlag) {
495+ iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][8];
496+ WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 16, 8);
497+ }
498+ break;
499+ case MB_TYPE_8x16:
500+ iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
501+ iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
502+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0);
503+ BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 8, 16, iMVs);
504+ if (pCurDqLayer->bUseWeightPredictionFlag) {
505+ iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
506+ WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 16);
507+ }
508+
509+ iMVs[0] = pCurDqLayer->pMv[0][iMBXY][2][0];
510+ iMVs[1] = pCurDqLayer->pMv[0][iMBXY][2][1];
511+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 2, LIST_0);
512+ pMCRefMem.pDstY = pPredY + 8;
513+ pMCRefMem.pDstU = pPredCb + 4;
514+ pMCRefMem.pDstV = pPredCr + 4;
515+ BaseMC (&pMCRefMem, iMBOffsetX + 8, iMBOffsetY, pMCFunc, 8, 16, iMVs);
516+
517+ if (pCurDqLayer->bUseWeightPredictionFlag) {
518+ iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][2];
519+ WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 16);
520+ }
521+ break;
522+ case MB_TYPE_8x8:
523+ case MB_TYPE_8x8_REF0: {
524+ uint32_t iSubMBType;
525+ int32_t iXOffset, iYOffset;
526+ uint8_t* pDstY, *pDstU, *pDstV;
527+ for (i = 0; i < 4; i++) {
528+ iSubMBType = pCurDqLayer->pSubMbType[iMBXY][i];
529+ iBlk8X = (i & 1) << 3;
530+ iBlk8Y = (i >> 1) << 3;
531+ iXOffset = iMBOffsetX + iBlk8X;
532+ iYOffset = iMBOffsetY + iBlk8Y;
533+
534+ iIIdx = ((i >> 1) << 3) + ((i & 1) << 1);
535+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], iIIdx, LIST_0);
536+ iRefIndex = pCurDqLayer->bUseWeightPredictionFlag ? pCurDqLayer->pRefIndex[0][iMBXY][iIIdx] : 0;
537+
538+ pDstY = pPredY + iBlk8X + iBlk8Y * iDstLineLuma;
539+ pDstU = pPredCb + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
540+ pDstV = pPredCr + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
541+ pMCRefMem.pDstY = pDstY;
542+ pMCRefMem.pDstU = pDstU;
543+ pMCRefMem.pDstV = pDstV;
544+ switch (iSubMBType) {
545+ case SUB_MB_TYPE_8x8:
546+ iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
547+ iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
548+ BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
549+ if (pCurDqLayer->bUseWeightPredictionFlag) {
550+
551+ WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 8);
552+ }
553+
554+ break;
555+ case SUB_MB_TYPE_8x4:
556+ iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
557+ iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
558+ BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
559+ if (pCurDqLayer->bUseWeightPredictionFlag) {
560+
561+ WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 4);
562+ }
563+
564+
565+ iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 4][0];
566+ iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 4][1];
567+ pMCRefMem.pDstY += (iDstLineLuma << 2);
568+ pMCRefMem.pDstU += (iDstLineChroma << 1);
569+ pMCRefMem.pDstV += (iDstLineChroma << 1);
570+ BaseMC (&pMCRefMem, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);
571+ if (pCurDqLayer->bUseWeightPredictionFlag) {
572+
573+ WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 4);
574+ }
575+
576+ break;
577+ case SUB_MB_TYPE_4x8:
578+ iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
579+ iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
580+ BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);
581+ if (pCurDqLayer->bUseWeightPredictionFlag) {
582+
583+ WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 4, 8);
584+ }
585+
586+
587+ iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 1][0];
588+ iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 1][1];
589+ pMCRefMem.pDstY += 4;
590+ pMCRefMem.pDstU += 2;
591+ pMCRefMem.pDstV += 2;
592+ BaseMC (&pMCRefMem, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);
593+ if (pCurDqLayer->bUseWeightPredictionFlag) {
594+
595+ WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 4, 8);
596+ }
597+
598+ break;
599+ case SUB_MB_TYPE_4x4: {
600+ for (j = 0; j < 4; j++) {
601+ int32_t iUVLineStride;
602+ iJIdx = ((j >> 1) << 2) + (j & 1);
603+
604+ iBlk4X = (j & 1) << 2;
605+ iBlk4Y = (j >> 1) << 2;
606+
607+ iUVLineStride = (iBlk4X >> 1) + (iBlk4Y >> 1) * iDstLineChroma;
608+ pMCRefMem.pDstY = pDstY + iBlk4X + iBlk4Y * iDstLineLuma;
609+ pMCRefMem.pDstU = pDstU + iUVLineStride;
610+ pMCRefMem.pDstV = pDstV + iUVLineStride;
611+
612+ iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + iJIdx][0];
613+ iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + iJIdx][1];
614+ BaseMC (&pMCRefMem, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);
615+ if (pCurDqLayer->bUseWeightPredictionFlag) {
616+
617+ WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 4, 4);
618+ }
619+
620+ }
621+ }
622+ break;
623+ default:
624+ break;
625+ }
626+ }
627+ }
628+ break;
629+ default:
630+ break;
631+ }
632+}
633+
634+void GetInterBPred (uint8_t* pPredYCbCr[3], uint8_t* pTempPredYCbCr[3], PWelsDecoderContext pCtx) {
635+ sMCRefMember pMCRefMem;
636+ sMCRefMember pTempMCRefMem;
637+
638+ PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
639+ SMcFunc* pMCFunc = &pCtx->sMcFunc;
640+
641+ int32_t iMBXY = pCurDqLayer->iMbXyIndex;
642+
643+ int16_t iMVs[2] = { 0 };
644+
645+ uint32_t iMBType = pCurDqLayer->pMbType[iMBXY];
646+
647+ int32_t iMBOffsetX = pCurDqLayer->iMbX << 4;
648+ int32_t iMBOffsetY = pCurDqLayer->iMbY << 4;
649+
650+ int32_t iDstLineLuma = pCtx->pDec->iLinesize[0];
651+ int32_t iDstLineChroma = pCtx->pDec->iLinesize[1];
652+
653+
654+ pMCRefMem.iPicWidth = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbWidth << 4);
655+ pMCRefMem.iPicHeight = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbHeight << 4);
656+
657+ pMCRefMem.pDstY = pPredYCbCr[0];
658+ pMCRefMem.pDstU = pPredYCbCr[1];
659+ pMCRefMem.pDstV = pPredYCbCr[2];
660+
661+ pMCRefMem.iDstLineLuma = iDstLineLuma;
662+ pMCRefMem.iDstLineChroma = iDstLineChroma;
663+
664+ pTempMCRefMem = pMCRefMem;
665+ pTempMCRefMem.pDstY = pTempPredYCbCr[0];
666+ pTempMCRefMem.pDstU = pTempPredYCbCr[1];
667+ pTempMCRefMem.pDstV = pTempPredYCbCr[2];
668+
669+
670+ int32_t iRefIndex1 = 0;
671+ int32_t iRefIndex2 = 0;
672+
673+ bool bWeightedBipredIdcIs1 = pCurDqLayer->sLayerInfo.pPps->uiWeightedBipredIdc == 1;
674+
675+ if (IS_INTER_16x16 (iMBType)) {
676+ if (IS_TYPE_L0 (iMBType) && IS_TYPE_L1 (iMBType)) {
677+ iMVs[0] = pCurDqLayer->pMv[LIST_0][iMBXY][0][0];
678+ iMVs[1] = pCurDqLayer->pMv[LIST_0][iMBXY][0][1];
679+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[LIST_0][iMBXY], 0, LIST_0);
680+ BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
681+
682+ iMVs[0] = pCurDqLayer->pMv[LIST_1][iMBXY][0][0];
683+ iMVs[1] = pCurDqLayer->pMv[LIST_1][iMBXY][0][1];
684+ GetRefPic (&pTempMCRefMem, pCtx, pCurDqLayer->pRefIndex[LIST_1][iMBXY], 0, LIST_1);
685+ BaseMC (&pTempMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
686+ iRefIndex1 = pCurDqLayer->pRefIndex[LIST_0][iMBXY][0];
687+ iRefIndex2 = pCurDqLayer->pRefIndex[LIST_1][iMBXY][0];
688+ if (pCurDqLayer->bUseWeightedBiPredIdc) {
689+ BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex1, iRefIndex2, bWeightedBipredIdcIs1, 16, 16);
690+ } else {
691+ BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 16, 16);
692+ }
693+ } else {
694+ int32_t listIdx = (iMBType & MB_TYPE_P0L0) ? LIST_0 : LIST_1;
695+ iMVs[0] = pCurDqLayer->pMv[listIdx][iMBXY][0][0];
696+ iMVs[1] = pCurDqLayer->pMv[listIdx][iMBXY][0][1];
697+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[listIdx][iMBXY], 0, listIdx);
698+ BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
699+ if (bWeightedBipredIdcIs1) {
700+ int32_t iRefIndex = pCurDqLayer->pRefIndex[listIdx][iMBXY][0];
701+ WeightPrediction (pCurDqLayer, &pMCRefMem, listIdx, iRefIndex, 16, 16);
702+ }
703+ }
704+ } else if (IS_INTER_16x8 (iMBType)) {
705+ for (int32_t i = 0; i < 2; ++i) {
706+ int32_t iPartIdx = i << 3;
707+ uint32_t listCount = 0;
708+ int32_t lastListIdx = LIST_0;
709+ for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
710+ if (IS_DIR (iMBType, i, listIdx)) {
711+ lastListIdx = listIdx;
712+ iMVs[0] = pCurDqLayer->pMv[listIdx][iMBXY][iPartIdx][0];
713+ iMVs[1] = pCurDqLayer->pMv[listIdx][iMBXY][iPartIdx][1];
714+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[listIdx][iMBXY], iPartIdx, listIdx);
715+ if (i) {
716+ pMCRefMem.pDstY += (iDstLineLuma << 3);
717+ pMCRefMem.pDstU += (iDstLineChroma << 2);
718+ pMCRefMem.pDstV += (iDstLineChroma << 2);
719+ }
720+ BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY + iPartIdx, pMCFunc, 16, 8, iMVs);
721+ if (++listCount == 2) {
722+ iMVs[0] = pCurDqLayer->pMv[LIST_1][iMBXY][iPartIdx][0];
723+ iMVs[1] = pCurDqLayer->pMv[LIST_1][iMBXY][iPartIdx][1];
724+ GetRefPic (&pTempMCRefMem, pCtx, pCurDqLayer->pRefIndex[LIST_1][iMBXY], iPartIdx, LIST_1);
725+ if (i) {
726+ pTempMCRefMem.pDstY += (iDstLineLuma << 3);
727+ pTempMCRefMem.pDstU += (iDstLineChroma << 2);
728+ pTempMCRefMem.pDstV += (iDstLineChroma << 2);
729+ }
730+ BaseMC (&pTempMCRefMem, iMBOffsetX, iMBOffsetY + iPartIdx, pMCFunc, 16, 8, iMVs);
731+ if (pCurDqLayer->bUseWeightedBiPredIdc) {
732+ iRefIndex1 = pCurDqLayer->pRefIndex[LIST_0][iMBXY][iPartIdx];
733+ iRefIndex2 = pCurDqLayer->pRefIndex[LIST_1][iMBXY][iPartIdx];
734+ BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex1, iRefIndex2, bWeightedBipredIdcIs1, 16, 8);
735+ } else {
736+ BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 16, 8);
737+ }
738+ }
739+ }
740+ }
741+ if (listCount == 1) {
742+ if (bWeightedBipredIdcIs1) {
743+ int32_t iRefIndex = pCurDqLayer->pRefIndex[lastListIdx][iMBXY][iPartIdx];
744+ WeightPrediction (pCurDqLayer, &pMCRefMem, lastListIdx, iRefIndex, 16, 8);
745+ }
746+ }
747+ }
748+ } else if (IS_INTER_8x16 (iMBType)) {
749+ for (int32_t i = 0; i < 2; ++i) {
750+ uint32_t listCount = 0;
751+ int32_t lastListIdx = LIST_0;
752+ for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
753+ if (IS_DIR (iMBType, i, listIdx)) {
754+ lastListIdx = listIdx;
755+ iMVs[0] = pCurDqLayer->pMv[listIdx][iMBXY][i << 1][0];
756+ iMVs[1] = pCurDqLayer->pMv[listIdx][iMBXY][i << 1][1];
757+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[listIdx][iMBXY], i << 1, listIdx);
758+ if (i) {
759+ pMCRefMem.pDstY += 8;
760+ pMCRefMem.pDstU += 4;
761+ pMCRefMem.pDstV += 4;
762+ }
763+ BaseMC (&pMCRefMem, iMBOffsetX + (i ? 8 : 0), iMBOffsetY, pMCFunc, 8, 16, iMVs);
764+ if (++listCount == 2) {
765+ iMVs[0] = pCurDqLayer->pMv[LIST_1][iMBXY][i << 1][0];
766+ iMVs[1] = pCurDqLayer->pMv[LIST_1][iMBXY][i << 1][1];
767+ GetRefPic (&pTempMCRefMem, pCtx, pCurDqLayer->pRefIndex[LIST_1][iMBXY], i << 1, LIST_1);
768+ if (i) {
769+ pTempMCRefMem.pDstY += 8;
770+ pTempMCRefMem.pDstU += 4;
771+ pTempMCRefMem.pDstV += 4;
772+ }
773+ BaseMC (&pTempMCRefMem, iMBOffsetX + (i ? 8 : 0), iMBOffsetY, pMCFunc, 8, 16, iMVs);
774+ if (pCurDqLayer->bUseWeightedBiPredIdc) {
775+ iRefIndex1 = pCurDqLayer->pRefIndex[LIST_0][iMBXY][i << 1];
776+ iRefIndex2 = pCurDqLayer->pRefIndex[LIST_1][iMBXY][i << 1];
777+ BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex1, iRefIndex2, bWeightedBipredIdcIs1, 8, 16);
778+ } else {
779+ BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 8, 16);
780+ }
781+ }
782+ }
783+ }
784+ if (listCount == 1) {
785+ if (bWeightedBipredIdcIs1) {
786+ int32_t iRefIndex = pCurDqLayer->pRefIndex[lastListIdx][iMBXY][i << 1];
787+ WeightPrediction (pCurDqLayer, &pMCRefMem, lastListIdx, iRefIndex, 8, 16);
788+ }
789+ }
790+ }
791+ } else if (IS_Inter_8x8 (iMBType)) {
792+ int32_t iBlk8X, iBlk8Y, iBlk4X, iBlk4Y, iIIdx, iJIdx;
793+ uint32_t iSubMBType;
794+ int32_t iXOffset, iYOffset;
795+ uint8_t* pDstY, *pDstU, *pDstV;
796+ uint8_t* pDstY2, *pDstU2, *pDstV2;
797+ for (int32_t i = 0; i < 4; i++) {
798+ iSubMBType = pCurDqLayer->pSubMbType[iMBXY][i];
799+ iBlk8X = (i & 1) << 3;
800+ iBlk8Y = (i >> 1) << 3;
801+ iXOffset = iMBOffsetX + iBlk8X;
802+ iYOffset = iMBOffsetY + iBlk8Y;
803+
804+ iIIdx = ((i >> 1) << 3) + ((i & 1) << 1);
805+
806+ pDstY = pPredYCbCr[0] + iBlk8X + iBlk8Y * iDstLineLuma;
807+ pDstU = pPredYCbCr[1] + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
808+ pDstV = pPredYCbCr[2] + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
809+ pMCRefMem.pDstY = pDstY;
810+ pMCRefMem.pDstU = pDstU;
811+ pMCRefMem.pDstV = pDstV;
812+
813+ pTempMCRefMem = pMCRefMem;
814+ pDstY2 = pTempPredYCbCr[0] + iBlk8X + iBlk8Y * iDstLineLuma;
815+ pDstU2 = pTempPredYCbCr[1] + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
816+ pDstV2 = pTempPredYCbCr[2] + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
817+
818+ pTempMCRefMem.pDstY = pDstY2;
819+ pTempMCRefMem.pDstU = pDstU2;
820+ pTempMCRefMem.pDstV = pDstV2;
821+
822+ if ((IS_TYPE_L0 (iSubMBType) && IS_TYPE_L1 (iSubMBType))) {
823+ iRefIndex1 = pCurDqLayer->pRefIndex[LIST_0][iMBXY][iIIdx];
824+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[LIST_0][iMBXY], iIIdx, LIST_0);
825+
826+ iRefIndex2 = pCurDqLayer->pRefIndex[LIST_1][iMBXY][iIIdx];
827+ GetRefPic (&pTempMCRefMem, pCtx, pCurDqLayer->pRefIndex[LIST_1][iMBXY], iIIdx, LIST_1);
828+ } else {
829+ int32_t listIdx = IS_TYPE_L0 (iSubMBType) ? LIST_0 : LIST_1;
830+ iRefIndex1 = pCurDqLayer->pRefIndex[listIdx][iMBXY][iIIdx];
831+ GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[listIdx][iMBXY], iIIdx, listIdx);
832+ }
833+
834+ if (IS_SUB_8x8 (iSubMBType)) {
835+ if (IS_TYPE_L0 (iSubMBType) && IS_TYPE_L1 (iSubMBType)) {
836+ iMVs[0] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx][0];
837+ iMVs[1] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx][1];
838+ BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
839+
840+ iMVs[0] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx][0];
841+ iMVs[1] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx][1];
842+ BaseMC (&pTempMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
843+
844+ if (pCurDqLayer->bUseWeightedBiPredIdc) {
845+ BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex1, iRefIndex2, bWeightedBipredIdcIs1, 8, 8);
846+ } else {
847+ BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 8, 8);
848+ }
849+ } else {
850+ int32_t listIdx = IS_TYPE_L0 (iSubMBType) ? LIST_0 : LIST_1;
851+ iMVs[0] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx][0];
852+ iMVs[1] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx][1];
853+ BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
854+ if (bWeightedBipredIdcIs1) {
855+ int32_t iRefIndex = pCurDqLayer->pRefIndex[listIdx][iMBXY][iIIdx];
856+ WeightPrediction (pCurDqLayer, &pMCRefMem, listIdx, iRefIndex, 8, 8);
857+ }
858+ }
859+ } else if (IS_SUB_8x4 (iSubMBType)) {
860+ if (IS_TYPE_L0 (iSubMBType) && IS_TYPE_L1 (iSubMBType)) { //B_Bi_8x4
861+ iMVs[0] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx][0];
862+ iMVs[1] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx][1];
863+ BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
864+ iMVs[0] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx][0];
865+ iMVs[1] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx][1];
866+ BaseMC (&pTempMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
867+
868+ if (pCurDqLayer->bUseWeightedBiPredIdc) {
869+ BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex1, iRefIndex2, bWeightedBipredIdcIs1, 8, 4);
870+ } else {
871+ BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 8, 4);
872+ }
873+
874+ pMCRefMem.pDstY += (iDstLineLuma << 2);
875+ pMCRefMem.pDstU += (iDstLineChroma << 1);
876+ pMCRefMem.pDstV += (iDstLineChroma << 1);
877+ iMVs[0] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx + 4][0];
878+ iMVs[1] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx + 4][1];
879+ BaseMC (&pMCRefMem, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);
880+
881+ pTempMCRefMem.pDstY += (iDstLineLuma << 2);
882+ pTempMCRefMem.pDstU += (iDstLineChroma << 1);
883+ pTempMCRefMem.pDstV += (iDstLineChroma << 1);
884+ iMVs[0] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx + 4][0];
885+ iMVs[1] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx + 4][1];
886+ BaseMC (&pTempMCRefMem, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);
887+
888+ if (pCurDqLayer->bUseWeightedBiPredIdc) {
889+ BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex1, iRefIndex2, bWeightedBipredIdcIs1, 8, 4);
890+ } else {
891+ BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 8, 4);
892+ }
893+ } else { //B_L0_8x4 B_L1_8x4
894+ int32_t listIdx = IS_TYPE_L0 (iSubMBType) ? LIST_0 : LIST_1;
895+ iMVs[0] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx][0];
896+ iMVs[1] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx][1];
897+ BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
898+ pMCRefMem.pDstY += (iDstLineLuma << 2);
899+ pMCRefMem.pDstU += (iDstLineChroma << 1);
900+ pMCRefMem.pDstV += (iDstLineChroma << 1);
901+ iMVs[0] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx + 4][0];
902+ iMVs[1] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx + 4][1];
903+ BaseMC (&pMCRefMem, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);
904+ if (bWeightedBipredIdcIs1) {
905+ int32_t iRefIndex = pCurDqLayer->pRefIndex[listIdx][iMBXY][iIIdx];
906+ WeightPrediction (pCurDqLayer, &pMCRefMem, listIdx, iRefIndex, 8, 4);
907+ }
908+ }
909+ } else if (IS_SUB_4x8 (iSubMBType)) {
910+ if (IS_TYPE_L0 (iSubMBType) && IS_TYPE_L1 (iSubMBType)) { //B_Bi_4x8
911+ iMVs[0] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx][0];
912+ iMVs[1] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx][1];
913+ BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);
914+ iMVs[0] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx][0];
915+ iMVs[1] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx][1];
916+ BaseMC (&pTempMCRefMem, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);
917+
918+ if (pCurDqLayer->bUseWeightedBiPredIdc) {
919+ BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex1, iRefIndex2, bWeightedBipredIdcIs1, 4, 8);
920+ } else {
921+ BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 4, 8);
922+ }
923+
924+ pMCRefMem.pDstY += 4;
925+ pMCRefMem.pDstU += 2;
926+ pMCRefMem.pDstV += 2;
927+ iMVs[0] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx + 1][0];
928+ iMVs[1] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx + 1][1];
929+ BaseMC (&pMCRefMem, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);
930+
931+ pTempMCRefMem.pDstY += 4;
932+ pTempMCRefMem.pDstU += 2;
933+ pTempMCRefMem.pDstV += 2;
934+ iMVs[0] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx + 1][0];
935+ iMVs[1] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx + 1][1];
936+ BaseMC (&pTempMCRefMem, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);
937+
938+ if (pCurDqLayer->bUseWeightedBiPredIdc) {
939+ BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex1, iRefIndex2, bWeightedBipredIdcIs1, 4, 8);
940+ } else {
941+ BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 4, 8);
942+ }
943+ } else { //B_L0_4x8 B_L1_4x8
944+ int32_t listIdx = IS_TYPE_L0 (iSubMBType) ? LIST_0 : LIST_1;
945+ iMVs[0] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx][0];
946+ iMVs[1] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx][1];
947+ BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);
948+ pMCRefMem.pDstY += 4;
949+ pMCRefMem.pDstU += 2;
950+ pMCRefMem.pDstV += 2;
951+ iMVs[0] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx + 1][0];
952+ iMVs[1] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx + 1][1];
953+ BaseMC (&pMCRefMem, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);
954+ if (bWeightedBipredIdcIs1) {
955+ int32_t iRefIndex = pCurDqLayer->pRefIndex[listIdx][iMBXY][iIIdx];
956+ WeightPrediction (pCurDqLayer, &pMCRefMem, listIdx, iRefIndex, 4, 8);
957+ }
958+ }
959+ } else if (IS_SUB_4x4 (iSubMBType)) {
960+ if (IS_TYPE_L0 (iSubMBType) && IS_TYPE_L1 (iSubMBType)) {
961+ for (int32_t j = 0; j < 4; j++) {
962+ int32_t iUVLineStride;
963+ iJIdx = ((j >> 1) << 2) + (j & 1);
964+
965+ iBlk4X = (j & 1) << 2;
966+ iBlk4Y = (j >> 1) << 2;
967+
968+ iUVLineStride = (iBlk4X >> 1) + (iBlk4Y >> 1) * iDstLineChroma;
969+ pMCRefMem.pDstY = pDstY + iBlk4X + iBlk4Y * iDstLineLuma;
970+ pMCRefMem.pDstU = pDstU + iUVLineStride;
971+ pMCRefMem.pDstV = pDstV + iUVLineStride;
972+
973+ iMVs[0] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx + iJIdx][0];
974+ iMVs[1] = pCurDqLayer->pMv[LIST_0][iMBXY][iIIdx + iJIdx][1];
975+ BaseMC (&pMCRefMem, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);
976+
977+ pTempMCRefMem.pDstY = pDstY2 + iBlk8X + iBlk8Y * iDstLineLuma;
978+ pTempMCRefMem.pDstU = pDstU2 + iUVLineStride;
979+ pTempMCRefMem.pDstV = pDstV2 + iUVLineStride;;
980+
981+ iMVs[0] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx + iJIdx][0];
982+ iMVs[1] = pCurDqLayer->pMv[LIST_1][iMBXY][iIIdx + iJIdx][1];
983+ BaseMC (&pTempMCRefMem, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);
984+
985+ if (pCurDqLayer->bUseWeightedBiPredIdc) {
986+ BiWeightPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, iRefIndex1, iRefIndex2, bWeightedBipredIdcIs1, 4, 4);
987+ } else {
988+ BiPrediction (pCurDqLayer, &pMCRefMem, &pTempMCRefMem, 4, 4);
989+ }
990+ }
991+ } else {
992+ int32_t listIdx = IS_TYPE_L0 (iSubMBType) ? LIST_0 : LIST_1;
993+ int32_t iRefIndex = pCurDqLayer->pRefIndex[listIdx][iMBXY][iIIdx];
994+ for (int32_t j = 0; j < 4; j++) {
995+ int32_t iUVLineStride;
996+ iJIdx = ((j >> 1) << 2) + (j & 1);
997+
998+ iBlk4X = (j & 1) << 2;
999+ iBlk4Y = (j >> 1) << 2;
1000+
1001+ iUVLineStride = (iBlk4X >> 1) + (iBlk4Y >> 1) * iDstLineChroma;
1002+ pMCRefMem.pDstY = pDstY + iBlk4X + iBlk4Y * iDstLineLuma;
1003+ pMCRefMem.pDstU = pDstU + iUVLineStride;
1004+ pMCRefMem.pDstV = pDstV + iUVLineStride;
1005+
1006+ iMVs[0] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx + iJIdx][0];
1007+ iMVs[1] = pCurDqLayer->pMv[listIdx][iMBXY][iIIdx + iJIdx][1];
1008+ BaseMC (&pMCRefMem, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);
1009+ if (bWeightedBipredIdcIs1) {
1010+ WeightPrediction (pCurDqLayer, &pMCRefMem, listIdx, iRefIndex, 4, 4);
1011+ }
1012+ }
1013+ }
1014+ }
1015+ }
1016+ }
1017+}
1018+
1019+int32_t RecChroma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
1020+ int32_t iChromaStride = pCtx->pCurDqLayer->pDec->iLinesize[1];
1021+ PIdctFourResAddPredFunc pIdctFourResAddPredFunc = pCtx->pIdctFourResAddPredFunc;
1022+
1023+ uint8_t i = 0;
1024+ uint8_t uiCbpC = pDqLayer->pCbp[iMBXY] >> 4;
1025+
1026+ if (1 == uiCbpC || 2 == uiCbpC) {
1027+ for (i = 0; i < 2; i++) {
1028+ int16_t* pRS = pScoeffLevel + 256 + (i << 6);
1029+ uint8_t* pPred = pDqLayer->pPred[i + 1];
1030+ const int8_t* pNzc = pDqLayer->pNzc[iMBXY] + 16 + 2 * i;
1031+
1032+ /*1 chroma is divided 4 4x4_block to idct*/
1033+ pIdctFourResAddPredFunc (pPred, iChromaStride, pRS, pNzc);
1034+ }
1035+ }
1036+
1037+ return ERR_NONE;
1038+}
1039+
1040+} // namespace WelsDec

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t