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/*!1/*!
2 * \copy2 * \copy
3 * Copyright (c) 2009-2013, Cisco Systems3 * Copyright (c) 2009-2013, Cisco Systems
4 * All rights reserved.4 * All rights reserved.
5 *5 *
6 * Redistribution and use in source and binary forms, with or without6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions7 * modification, are permitted provided that the following conditions
8 * are met:8 * are met:
9 *9 *
10 * * Redistributions of source code must retain the above copyright10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.11 * notice, this list of conditions and the following disclaimer.
12 *12 *
13 * * Redistributions in binary form must reproduce the above copyright13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the15 * the documentation and/or other materials provided with the
16 * distribution.16 * distribution.
17 *17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.29 * POSSIBILITY OF SUCH DAMAGE.
30 *30 *
31 *31 *
32 * \file rec_mb.c32 * \file rec_mb.c
33 *33 *
34 * \brief implementation for all macroblock decoding process after mb syntax parsing and residual decoding with cavlc.34 * \brief implementation for all macroblock decoding process after mb syntax parsing and residual decoding with cavlc.
35 *35 *
36 * \date 3/18/2009 Created36 * \date 3/18/2009 Created
37 *37 *
38 *************************************************************************************38 *************************************************************************************
39 */39 */
40 40
41 41
42#include "rec_mb.h"42#include "rec_mb.h"
43#include "decode_slice.h"43#include "decode_slice.h"
44 44
45namespace WelsDec {45namespace WelsDec {
46 46
47void WelsFillRecNeededMbInfo (PWelsDecoderContext pCtx, bool bOutput, PDqLayer pCurLayer) {47void WelsFillRecNeededMbInfo (PWelsDecoderContext pCtx, bool bOutput, PDqLayer pCurLayer) {
48 PPicture pCurPic = pCtx->pDec;48 PPicture pCurPic = pCtx->pDec;
49 int32_t iLumaStride = pCurPic->iLinesize[0];49 int32_t iLumaStride = pCurPic->iLinesize[0];
50 int32_t iChromaStride = pCurPic->iLinesize[1];50 int32_t iChromaStride = pCurPic->iLinesize[1];
51 int32_t iMbX = pCurLayer->iMbX;51 int32_t iMbX = pCurLayer->iMbX;
52 int32_t iMbY = pCurLayer->iMbY;52 int32_t iMbY = pCurLayer->iMbY;
53 53
54 pCurLayer->iLumaStride = iLumaStride;54 pCurLayer->iLumaStride = iLumaStride;
55 pCurLayer->iChromaStride = iChromaStride;55 pCurLayer->iChromaStride = iChromaStride;
56 56
57 if (bOutput) {57 if (bOutput) {
58 pCurLayer->pPred[0] = pCurPic->pData[0] + ((iMbY * iLumaStride + iMbX) << 4);58 pCurLayer->pPred[0] = pCurPic->pData[0] + ((iMbY * iLumaStride + iMbX) << 4);
59 pCurLayer->pPred[1] = pCurPic->pData[1] + ((iMbY * iChromaStride + iMbX) << 3);59 pCurLayer->pPred[1] = pCurPic->pData[1] + ((iMbY * iChromaStride + iMbX) << 3);
60 pCurLayer->pPred[2] = pCurPic->pData[2] + ((iMbY * iChromaStride + iMbX) << 3);60 pCurLayer->pPred[2] = pCurPic->pData[2] + ((iMbY * iChromaStride + iMbX) << 3);
61 }61 }
62}62}
63 63
64int32_t RecI8x8Mb (int32_t iMbXy, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {64int32_t RecI8x8Mb (int32_t iMbXy, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
65 RecI8x8Luma (iMbXy, pCtx, pScoeffLevel, pDqLayer);65 RecI8x8Luma (iMbXy, pCtx, pScoeffLevel, pDqLayer);
66 RecI4x4Chroma (iMbXy, pCtx, pScoeffLevel, pDqLayer);66 RecI4x4Chroma (iMbXy, pCtx, pScoeffLevel, pDqLayer);
67 return ERR_NONE;67 return ERR_NONE;
68}68}
69 69
70int32_t RecI8x8Luma (int32_t iMbXy, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {70int32_t RecI8x8Luma (int32_t iMbXy, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
71 /*****get local variable from outer variable********/71 /*****get local variable from outer variable********/
72 /*prediction info*/72 /*prediction info*/
73 uint8_t* pPred = pDqLayer->pPred[0];73 uint8_t* pPred = pDqLayer->pPred[0];
74 74
75 int32_t iLumaStride = pDqLayer->iLumaStride;75 int32_t iLumaStride = pDqLayer->iLumaStride;
76 int32_t* pBlockOffset = pCtx->iDecBlockOffsetArray;76 int32_t* pBlockOffset = pCtx->iDecBlockOffsetArray;
77 PGetIntraPred8x8Func* pGetI8x8LumaPredFunc = pCtx->pGetI8x8LumaPredFunc;77 PGetIntraPred8x8Func* pGetI8x8LumaPredFunc = pCtx->pGetI8x8LumaPredFunc;
78 78
79 int8_t* pIntra8x8PredMode = pDqLayer->pIntra4x4FinalMode[iMbXy]; // I_NxN79 int8_t* pIntra8x8PredMode = pDqLayer->pIntra4x4FinalMode[iMbXy]; // I_NxN
80 int16_t* pRS = pScoeffLevel;80 int16_t* pRS = pScoeffLevel;
81 /*itransform info*/81 /*itransform info*/
82 PIdctResAddPredFunc pIdctResAddPredFunc = pCtx->pIdctResAddPredFunc8x8;82 PIdctResAddPredFunc pIdctResAddPredFunc = pCtx->pIdctResAddPredFunc8x8;
83 83
84 /*************local variable********************/84 /*************local variable********************/
85 uint8_t i = 0;85 uint8_t i = 0;
86 bool bTLAvail[4], bTRAvail[4];86 bool bTLAvail[4], bTRAvail[4];
87 // Top-Right : Left : Top-Left : Top87 // Top-Right : Left : Top-Left : Top
88 bTLAvail[0] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x02);88 bTLAvail[0] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x02);
89 bTLAvail[1] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x01);89 bTLAvail[1] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x01);
90 bTLAvail[2] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x04);90 bTLAvail[2] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x04);
91 bTLAvail[3] = true;91 bTLAvail[3] = true;
92 92
93 bTRAvail[0] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x01);93 bTRAvail[0] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x01);
94 bTRAvail[1] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x08);94 bTRAvail[1] = !! (pDqLayer->pIntraNxNAvailFlag[iMbXy] & 0x08);
95 bTRAvail[2] = true;95 bTRAvail[2] = true;
96 bTRAvail[3] = false;96 bTRAvail[3] = false;
97 97
98 /*************real process*********************/98 /*************real process*********************/
99 for (i = 0; i < 4; i++) {99 for (i = 0; i < 4; i++) {
100 100
101 uint8_t* pPredI8x8 = pPred + pBlockOffset[i << 2];101 uint8_t* pPredI8x8 = pPred + pBlockOffset[i << 2];
102 uint8_t uiMode = pIntra8x8PredMode[g_kuiScan4[i << 2]];102 uint8_t uiMode = pIntra8x8PredMode[g_kuiScan4[i << 2]];
103 103
104 pGetI8x8LumaPredFunc[uiMode] (pPredI8x8, iLumaStride, bTLAvail[i], bTRAvail[i]);104 pGetI8x8LumaPredFunc[uiMode] (pPredI8x8, iLumaStride, bTLAvail[i], bTRAvail[i]);
105 105
106 int32_t iIndex = g_kuiMbCountScan4Idx[i << 2];106 int32_t iIndex = g_kuiMbCountScan4Idx[i << 2];
107 if (pDqLayer->pNzc[iMbXy][iIndex] || pDqLayer->pNzc[iMbXy][iIndex + 1] || pDqLayer->pNzc[iMbXy][iIndex + 4]107 if (pDqLayer->pNzc[iMbXy][iIndex] || pDqLayer->pNzc[iMbXy][iIndex + 1] || pDqLayer->pNzc[iMbXy][iIndex + 4]
108 || pDqLayer->pNzc[iMbXy][iIndex + 5]) {108 || pDqLayer->pNzc[iMbXy][iIndex + 5]) {
109 int16_t* pRSI8x8 = &pRS[i << 6];109 int16_t* pRSI8x8 = &pRS[i << 6];
110 pIdctResAddPredFunc (pPredI8x8, iLumaStride, pRSI8x8);110 pIdctResAddPredFunc (pPredI8x8, iLumaStride, pRSI8x8);
111 }111 }
112 }112 }
113 113
114 return ERR_NONE;114 return ERR_NONE;
115}115}
116 116
117int32_t RecI4x4Mb (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {117int32_t RecI4x4Mb (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
118 RecI4x4Luma (iMBXY, pCtx, pScoeffLevel, pDqLayer);118 RecI4x4Luma (iMBXY, pCtx, pScoeffLevel, pDqLayer);
119 RecI4x4Chroma (iMBXY, pCtx, pScoeffLevel, pDqLayer);119 RecI4x4Chroma (iMBXY, pCtx, pScoeffLevel, pDqLayer);
120 return ERR_NONE;120 return ERR_NONE;
121}121}
122 122
123 123
124int32_t RecI4x4Luma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {124int32_t RecI4x4Luma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
125 /*****get local variable from outer variable********/125 /*****get local variable from outer variable********/
126 /*prediction info*/126 /*prediction info*/
127 uint8_t* pPred = pDqLayer->pPred[0];127 uint8_t* pPred = pDqLayer->pPred[0];
128 128
129 int32_t iLumaStride = pDqLayer->iLumaStride;129 int32_t iLumaStride = pDqLayer->iLumaStride;
130 int32_t* pBlockOffset = pCtx->iDecBlockOffsetArray;130 int32_t* pBlockOffset = pCtx->iDecBlockOffsetArray;
131 PGetIntraPredFunc* pGetI4x4LumaPredFunc = pCtx->pGetI4x4LumaPredFunc;131 PGetIntraPredFunc* pGetI4x4LumaPredFunc = pCtx->pGetI4x4LumaPredFunc;
132 132
133 int8_t* pIntra4x4PredMode = pDqLayer->pIntra4x4FinalMode[iMBXY];133 int8_t* pIntra4x4PredMode = pDqLayer->pIntra4x4FinalMode[iMBXY];
134 int16_t* pRS = pScoeffLevel;134 int16_t* pRS = pScoeffLevel;
135 /*itransform info*/135 /*itransform info*/
136 PIdctResAddPredFunc pIdctResAddPredFunc = pCtx->pIdctResAddPredFunc;136 PIdctResAddPredFunc pIdctResAddPredFunc = pCtx->pIdctResAddPredFunc;
137 137
138 138
139 /*************local variable********************/139 /*************local variable********************/
140 uint8_t i = 0;140 uint8_t i = 0;
141 141
142 /*************real process*********************/142 /*************real process*********************/
143 for (i = 0; i < 16; i++) {143 for (i = 0; i < 16; i++) {
144 144
145 uint8_t* pPredI4x4 = pPred + pBlockOffset[i];145 uint8_t* pPredI4x4 = pPred + pBlockOffset[i];
146 uint8_t uiMode = pIntra4x4PredMode[g_kuiScan4[i]];146 uint8_t uiMode = pIntra4x4PredMode[g_kuiScan4[i]];
147 147
148 pGetI4x4LumaPredFunc[uiMode] (pPredI4x4, iLumaStride);148 pGetI4x4LumaPredFunc[uiMode] (pPredI4x4, iLumaStride);
149 149
150 if (pDqLayer->pNzc[iMBXY][g_kuiMbCountScan4Idx[i]]) {150 if (pDqLayer->pNzc[iMBXY][g_kuiMbCountScan4Idx[i]]) {
151 int16_t* pRSI4x4 = &pRS[i << 4];151 int16_t* pRSI4x4 = &pRS[i << 4];
152 pIdctResAddPredFunc (pPredI4x4, iLumaStride, pRSI4x4);152 pIdctResAddPredFunc (pPredI4x4, iLumaStride, pRSI4x4);
153 }153 }
154 }154 }
155 155
156 return ERR_NONE;156 return ERR_NONE;
157}157}
158 158
159 159
160int32_t RecI4x4Chroma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {160int32_t RecI4x4Chroma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
161 int32_t iChromaStride = pCtx->pCurDqLayer->pDec->iLinesize[1];161 int32_t iChromaStride = pCtx->pCurDqLayer->pDec->iLinesize[1];
162 162
163 int8_t iChromaPredMode = pDqLayer->pChromaPredMode[iMBXY];163 int8_t iChromaPredMode = pDqLayer->pChromaPredMode[iMBXY];
164 164
165 PGetIntraPredFunc* pGetIChromaPredFunc = pCtx->pGetIChromaPredFunc;165 PGetIntraPredFunc* pGetIChromaPredFunc = pCtx->pGetIChromaPredFunc;
166 166
167 uint8_t* pPred = pDqLayer->pPred[1];167 uint8_t* pPred = pDqLayer->pPred[1];
168 168
169 pGetIChromaPredFunc[iChromaPredMode] (pPred, iChromaStride);169 pGetIChromaPredFunc[iChromaPredMode] (pPred, iChromaStride);
170 pPred = pDqLayer->pPred[2];170 pPred = pDqLayer->pPred[2];
171 pGetIChromaPredFunc[iChromaPredMode] (pPred, iChromaStride);171 pGetIChromaPredFunc[iChromaPredMode] (pPred, iChromaStride);
172 172
173 RecChroma (iMBXY, pCtx, pScoeffLevel, pDqLayer);173 RecChroma (iMBXY, pCtx, pScoeffLevel, pDqLayer);
174 174
175 return ERR_NONE;175 return ERR_NONE;
176}176}
177 177
178 178
179int32_t RecI16x16Mb (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {179int32_t RecI16x16Mb (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {
180 /*decoder use, encoder no use*/180 /*decoder use, encoder no use*/
181 int8_t iI16x16PredMode = pDqLayer->pIntraPredMode[iMBXY][7];181 int8_t iI16x16PredMode = pDqLayer->pIntraPredMode[iMBXY][7];
182 int8_t iChromaPredMode = pDqLayer->pChromaPredMode[iMBXY];182 int8_t iChromaPredMode = pDqLayer->pChromaPredMode[iMBXY];
183 PGetIntraPredFunc* pGetIChromaPredFunc = pCtx->pGetIChromaPredFunc;183 PGetIntraPredFunc* pGetIChromaPredFunc = pCtx->pGetIChromaPredFunc;
184 PGetIntraPredFunc* pGetI16x16LumaPredFunc = pCtx->pGetI16x16LumaPredFunc;184 PGetIntraPredFunc* pGetI16x16LumaPredFunc = pCtx->pGetI16x16LumaPredFunc;
185 int32_t iUVStride = pCtx->pCurDqLayer->pDec->iLinesize[1];185 int32_t iUVStride = pCtx->pCurDqLayer->pDec->iLinesize[1];
186 186
187 /*common use by decoder&encoder*/187 /*common use by decoder&encoder*/
188 int32_t iYStride = pDqLayer->iLumaStride;188 int32_t iYStride = pDqLayer->iLumaStride;
189 int16_t* pRS = pScoeffLevel;189 int16_t* pRS = pScoeffLevel;
190 190
191 uint8_t* pPred = pDqLayer->pPred[0];191 uint8_t* pPred = pDqLayer->pPred[0];
192 192
193 PIdctFourResAddPredFunc pIdctFourResAddPredFunc = pCtx->pIdctFourResAddPredFunc;193 PIdctFourResAddPredFunc pIdctFourResAddPredFunc = pCtx->pIdctFourResAddPredFunc;
194 194
195 /*decode i16x16 y*/195 /*decode i16x16 y*/
196 pGetI16x16LumaPredFunc[iI16x16PredMode] (pPred, iYStride);196 pGetI16x16LumaPredFunc[iI16x16PredMode] (pPred, iYStride);
197 197
198 /*1 mb is divided 16 4x4_block to idct*/198 /*1 mb is divided 16 4x4_block to idct*/
199 const int8_t* pNzc = pDqLayer->pNzc[iMBXY];199 const int8_t* pNzc = pDqLayer->pNzc[iMBXY];
200 pIdctFourResAddPredFunc (pPred + 0 * iYStride + 0, iYStride, pRS + 0 * 64, pNzc + 0);200 pIdctFourResAddPredFunc (pPred + 0 * iYStride + 0, iYStride, pRS + 0 * 64, pNzc + 0);
201 pIdctFourResAddPredFunc (pPred + 0 * iYStride + 8, iYStride, pRS + 1 * 64, pNzc + 2);201 pIdctFourResAddPredFunc (pPred + 0 * iYStride + 8, iYStride, pRS + 1 * 64, pNzc + 2);
202 pIdctFourResAddPredFunc (pPred + 8 * iYStride + 0, iYStride, pRS + 2 * 64, pNzc + 8);202 pIdctFourResAddPredFunc (pPred + 8 * iYStride + 0, iYStride, pRS + 2 * 64, pNzc + 8);
203 pIdctFourResAddPredFunc (pPred + 8 * iYStride + 8, iYStride, pRS + 3 * 64, pNzc + 10);203 pIdctFourResAddPredFunc (pPred + 8 * iYStride + 8, iYStride, pRS + 3 * 64, pNzc + 10);
204 204
205 /*decode intra mb cb&cr*/205 /*decode intra mb cb&cr*/
206 pPred = pDqLayer->pPred[1];206 pPred = pDqLayer->pPred[1];
207 pGetIChromaPredFunc[iChromaPredMode] (pPred, iUVStride);207 pGetIChromaPredFunc[iChromaPredMode] (pPred, iUVStride);
208 pPred = pDqLayer->pPred[2];208 pPred = pDqLayer->pPred[2];
209 pGetIChromaPredFunc[iChromaPredMode] (pPred, iUVStride);209 pGetIChromaPredFunc[iChromaPredMode] (pPred, iUVStride);
210 RecChroma (iMBXY, pCtx, pScoeffLevel, pDqLayer);210 RecChroma (iMBXY, pCtx, pScoeffLevel, pDqLayer);
211 211
212 return ERR_NONE;212 return ERR_NONE;
213}213}
214 214
215 215
216//according to current 8*8 block ref_index to gain reference picture216//according to current 8*8 block ref_index to gain reference picture
217static inline void GetRefPic (sMCRefMember* pMCRefMem, PWelsDecoderContext pCtx, int8_t* pRefIdxList,217static inline void GetRefPic (sMCRefMember* pMCRefMem, PWelsDecoderContext pCtx, int8_t* pRefIdxList,
218 int32_t iIndex) {218 int32_t iIndex, int32_t listIdx) {
219 PPicture pRefPic;219 PPicture pRefPic;
220 220
221 int8_t iRefIdx = pRefIdxList[iIndex];221 int8_t iRefIdx = pRefIdxList[iIndex];
222 pRefPic = pCtx->sRefPic.pRefList[LIST_0][iRefIdx];222 pRefPic = pCtx->sRefPic.pRefList[listIdx][iRefIdx];
223 223
224 pMCRefMem->iSrcLineLuma = pRefPic->iLinesize[0];224 pMCRefMem->iSrcLineLuma = pRefPic->iLinesize[0];
225 pMCRefMem->iSrcLineChroma = pRefPic->iLinesize[1];225 pMCRefMem->iSrcLineChroma = pRefPic->iLinesize[1];
226 226
227 pMCRefMem->pSrcY = pRefPic->pData[0];227 pMCRefMem->pSrcY = pRefPic->pData[0];
228 pMCRefMem->pSrcU = pRefPic->pData[1];228 pMCRefMem->pSrcU = pRefPic->pData[1];
229 pMCRefMem->pSrcV = pRefPic->pData[2];229 pMCRefMem->pSrcV = pRefPic->pData[2];
230}230}
231 231
232 232
233#ifndef MC_FLOW_SIMPLE_JUDGE233#ifndef MC_FLOW_SIMPLE_JUDGE
234#define MC_FLOW_SIMPLE_JUDGE 1234#define MC_FLOW_SIMPLE_JUDGE 1
235#endif //MC_FLOW_SIMPLE_JUDGE235#endif //MC_FLOW_SIMPLE_JUDGE
236void BaseMC (sMCRefMember* pMCRefMem, int32_t iXOffset, int32_t iYOffset, SMcFunc* pMCFunc,236void BaseMC (sMCRefMember* pMCRefMem, int32_t iXOffset, int32_t iYOffset, SMcFunc* pMCFunc,
237 int32_t iBlkWidth, int32_t iBlkHeight, int16_t iMVs[2]) {237 int32_t iBlkWidth, int32_t iBlkHeight, int16_t iMVs[2]) {
238 int32_t iFullMVx = (iXOffset << 2) + iMVs[0]; //quarter pixel238 int32_t iFullMVx = (iXOffset << 2) + iMVs[0]; //quarter pixel
239 int32_t iFullMVy = (iYOffset << 2) + iMVs[1];239 int32_t iFullMVy = (iYOffset << 2) + iMVs[1];
240 iFullMVx = WELS_CLIP3 (iFullMVx, ((-PADDING_LENGTH + 2) * (1 << 2)),240 iFullMVx = WELS_CLIP3 (iFullMVx, ((-PADDING_LENGTH + 2) * (1 << 2)),
241 ((pMCRefMem->iPicWidth + PADDING_LENGTH - 19) * (1 << 2)));241 ((pMCRefMem->iPicWidth + PADDING_LENGTH - 19) * (1 << 2)));
242 iFullMVy = WELS_CLIP3 (iFullMVy, ((-PADDING_LENGTH + 2) * (1 << 2)),242 iFullMVy = WELS_CLIP3 (iFullMVy, ((-PADDING_LENGTH + 2) * (1 << 2)),
243 ((pMCRefMem->iPicHeight + PADDING_LENGTH - 19) * (1 << 2)));243 ((pMCRefMem->iPicHeight + PADDING_LENGTH - 19) * (1 << 2)));
244 244
245 int32_t iSrcPixOffsetLuma = (iFullMVx >> 2) + (iFullMVy >> 2) * pMCRefMem->iSrcLineLuma;245 int32_t iSrcPixOffsetLuma = (iFullMVx >> 2) + (iFullMVy >> 2) * pMCRefMem->iSrcLineLuma;
246 int32_t iSrcPixOffsetChroma = (iFullMVx >> 3) + (iFullMVy >> 3) * pMCRefMem->iSrcLineChroma;246 int32_t iSrcPixOffsetChroma = (iFullMVx >> 3) + (iFullMVy >> 3) * pMCRefMem->iSrcLineChroma;
247 247
248 int32_t iBlkWidthChroma = iBlkWidth >> 1;248 int32_t iBlkWidthChroma = iBlkWidth >> 1;
249 int32_t iBlkHeightChroma = iBlkHeight >> 1;249 int32_t iBlkHeightChroma = iBlkHeight >> 1;
250 250
251 uint8_t* pSrcY = pMCRefMem->pSrcY + iSrcPixOffsetLuma;251 uint8_t* pSrcY = pMCRefMem->pSrcY + iSrcPixOffsetLuma;
252 uint8_t* pSrcU = pMCRefMem->pSrcU + iSrcPixOffsetChroma;252 uint8_t* pSrcU = pMCRefMem->pSrcU + iSrcPixOffsetChroma;
253 uint8_t* pSrcV = pMCRefMem->pSrcV + iSrcPixOffsetChroma;253 uint8_t* pSrcV = pMCRefMem->pSrcV + iSrcPixOffsetChroma;
254 uint8_t* pDstY = pMCRefMem->pDstY;254 uint8_t* pDstY = pMCRefMem->pDstY;
255 uint8_t* pDstU = pMCRefMem->pDstU;255 uint8_t* pDstU = pMCRefMem->pDstU;
256 uint8_t* pDstV = pMCRefMem->pDstV;256 uint8_t* pDstV = pMCRefMem->pDstV;
257 257
258 pMCFunc->pMcLumaFunc (pSrcY, pMCRefMem->iSrcLineLuma, pDstY, pMCRefMem->iDstLineLuma, iFullMVx, iFullMVy, iBlkWidth,258 pMCFunc->pMcLumaFunc (pSrcY, pMCRefMem->iSrcLineLuma, pDstY, pMCRefMem->iDstLineLuma, iFullMVx, iFullMVy, iBlkWidth,
259 iBlkHeight);259 iBlkHeight);
260 pMCFunc->pMcChromaFunc (pSrcU, pMCRefMem->iSrcLineChroma, pDstU, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,260 pMCFunc->pMcChromaFunc (pSrcU, pMCRefMem->iSrcLineChroma, pDstU, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
261 iBlkWidthChroma, iBlkHeightChroma);261 iBlkWidthChroma, iBlkHeightChroma);
262 pMCFunc->pMcChromaFunc (pSrcV, pMCRefMem->iSrcLineChroma, pDstV, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,262 pMCFunc->pMcChromaFunc (pSrcV, pMCRefMem->iSrcLineChroma, pDstV, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
263 iBlkWidthChroma, iBlkHeightChroma);263 iBlkWidthChroma, iBlkHeightChroma);
264 264
265}265}
266 266
267void WeightPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, int32_t iRefIdx, int32_t iBlkWidth,267static void WeightPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, int32_t listIdx, int32_t iRefIdx,
268 int32_t iBlkHeight) {268 int32_t iBlkWidth,
269 269 int32_t iBlkHeight) {
270 270
271 int32_t iLog2denom, iWoc, iOoc;271
272 int32_t iPredTemp, iLineStride;272 int32_t iLog2denom, iWoc, iOoc;
273 int32_t iPixel = 0;273 int32_t iPredTemp, iLineStride;
274 uint8_t* pDst;274 int32_t iPixel = 0;
275 //luma275 uint8_t* pDst;
276 iLog2denom = pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom;276 //luma
277 iWoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaWeight[iRefIdx];277 iLog2denom = pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom;
278 iOoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaOffset[iRefIdx];278 iWoc = pCurDqLayer->pPredWeightTable->sPredList[listIdx].iLumaWeight[iRefIdx];
279 iLineStride = pMCRefMem->iDstLineLuma;279 iOoc = pCurDqLayer->pPredWeightTable->sPredList[listIdx].iLumaOffset[iRefIdx];
280 280 iLineStride = pMCRefMem->iDstLineLuma;
281 for (int i = 0; i < iBlkHeight; i++) {281
282 for (int j = 0; j < iBlkWidth; j++) {282 for (int i = 0; i < iBlkHeight; i++) {
283 iPixel = j + i * (iLineStride);283 for (int j = 0; j < iBlkWidth; j++) {
284 if (iLog2denom >= 1) {284 iPixel = j + i * (iLineStride);
285 iPredTemp = ((pMCRefMem->pDstY[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;285 if (iLog2denom >= 1) {
286 286 iPredTemp = ((pMCRefMem->pDstY[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
287 pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);287
288 } else {288 pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
289 iPredTemp = pMCRefMem->pDstY[iPixel] * iWoc + iOoc;289 } else {
290 290 iPredTemp = pMCRefMem->pDstY[iPixel] * iWoc + iOoc;
291 pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);291
292 292 pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
293 }293
294 }294 }
295 }295 }
296 296 }
297 297
298 //UV298
299 iBlkWidth = iBlkWidth >> 1;299 //UV
300 iBlkHeight = iBlkHeight >> 1;300 iBlkWidth = iBlkWidth >> 1;
301 iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;301 iBlkHeight = iBlkHeight >> 1;
302 iLineStride = pMCRefMem->iDstLineChroma;302 iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
303 303 iLineStride = pMCRefMem->iDstLineChroma;
304 for (int i = 0; i < 2; i++) {304
305 305 for (int i = 0; i < 2; i++) {
306 306
307 //iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;307
308 iWoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaWeight[iRefIdx][i];308 //iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
309 iOoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaOffset[iRefIdx][i];309 iWoc = pCurDqLayer->pPredWeightTable->sPredList[listIdx].iChromaWeight[iRefIdx][i];
310 pDst = i ? pMCRefMem->pDstV : pMCRefMem->pDstU;310 iOoc = pCurDqLayer->pPredWeightTable->sPredList[listIdx].iChromaOffset[iRefIdx][i];
311 //iLineStride = pMCRefMem->iDstLineChroma;311 pDst = i ? pMCRefMem->pDstV : pMCRefMem->pDstU;
312 312 //iLineStride = pMCRefMem->iDstLineChroma;
313 for (int i = 0; i < iBlkHeight ; i++) {313
314 for (int j = 0; j < iBlkWidth; j++) {314 for (int i = 0; i < iBlkHeight ; i++) {
315 iPixel = j + i * (iLineStride);315 for (int j = 0; j < iBlkWidth; j++) {
316 if (iLog2denom >= 1) {316 iPixel = j + i * (iLineStride);
317 iPredTemp = ((pDst[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;317 if (iLog2denom >= 1) {
318 318 iPredTemp = ((pDst[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
319 pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);319
320 } else {320 pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
321 iPredTemp = pDst[iPixel] * iWoc + iOoc;321 } else {
322 322 iPredTemp = pDst[iPixel] * iWoc + iOoc;
323 pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);323
324 324 pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
325 }325
326 }326 }
327 327 }
328 }328
329 329 }
330 330
331 }331
332}332 }
333 333}
334 334
335void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx) {335static void BiWeightPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, sMCRefMember* pTempMCRefMem,
336 sMCRefMember pMCRefMem;336 int32_t iRefIdx1, int32_t iRefIdx2, bool bWeightedBipredIdcIs1, int32_t iBlkWidth,
337 PDqLayer pCurDqLayer = pCtx->pCurDqLayer;337 int32_t iBlkHeight) {
338 SMcFunc* pMCFunc = &pCtx->sMcFunc;338 int32_t iWoc1 = 0, iOoc1 = 0, iWoc2 = 0, iOoc2 = 0;
339 339 int32_t iPredTemp, iLineStride;
340 int32_t iMBXY = pCurDqLayer->iMbXyIndex;340 int32_t iPixel = 0;
341 341 //luma
342 int16_t iMVs[2] = {0};342 int32_t iLog2denom = pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom;
343 343 if (bWeightedBipredIdcIs1) {
344 int32_t iMBType = pCurDqLayer->pMbType[iMBXY];344 iWoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaWeight[iRefIdx1];
345 345 iOoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaOffset[iRefIdx1];
346 int32_t iMBOffsetX = pCurDqLayer->iMbX << 4;346 iWoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iLumaWeight[iRefIdx2];
347 int32_t iMBOffsetY = pCurDqLayer->iMbY << 4;347 iOoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iLumaOffset[iRefIdx2];
348 348 } else {
349 int32_t iDstLineLuma = pCtx->pDec->iLinesize[0];349 iWoc1 = pCurDqLayer->pPredWeightTable->iImplicitWeight[iRefIdx1][iRefIdx2];
350 int32_t iDstLineChroma = pCtx->pDec->iLinesize[1];350 iWoc2 = 64 - iWoc1;
351 351 }
352 int32_t iBlk8X, iBlk8Y, iBlk4X, iBlk4Y, i, j, iIIdx, iJIdx;352 iLineStride = pMCRefMem->iDstLineLuma;
353 353
354 pMCRefMem.iPicWidth = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbWidth << 4);354 for (int i = 0; i < iBlkHeight; i++) {
355 pMCRefMem.iPicHeight = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbHeight << 4);355 for (int j = 0; j < iBlkWidth; j++) {
356 356 iPixel = j + i * (iLineStride);
357 pMCRefMem.pDstY = pPredY;357 iPredTemp = ((pMCRefMem->pDstY[iPixel] * iWoc1 + pTempMCRefMem->pDstY[iPixel] * iWoc2 + (1 << iLog2denom)) >>
358 pMCRefMem.pDstU = pPredCb;358 (iLog2denom + 1)) + ((iOoc1 + iOoc2 + 1) >> 1);
359 pMCRefMem.pDstV = pPredCr;359 pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
360 360 }
361 pMCRefMem.iDstLineLuma = iDstLineLuma;361 }
362 pMCRefMem.iDstLineChroma = iDstLineChroma;362
363 363 //UV
364 int32_t iRefIndex = 0;364 iBlkWidth = iBlkWidth >> 1;
365 365 iBlkHeight = iBlkHeight >> 1;
366 switch (iMBType) {366 iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
367 case MB_TYPE_SKIP:367 iLineStride = pMCRefMem->iDstLineChroma;
368 case MB_TYPE_16x16:368
369 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];369 uint8_t* pDst;
370 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];370 uint8_t* pTempDst;
371 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);371 for (int k = 0; k < 2; k++) {
372 BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);372 //iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
373 373 if (bWeightedBipredIdcIs1) {
374 if (pCurDqLayer->bUseWeightPredictionFlag) {374 iWoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaWeight[iRefIdx1][k];
375 iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];375 iOoc1 = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaOffset[iRefIdx1][k];
376 WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 16);376 iWoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iChromaWeight[iRefIdx2][k];
377 }377 iOoc2 = pCurDqLayer->pPredWeightTable->sPredList[LIST_1].iChromaOffset[iRefIdx2][k];
378 break;378 }
379 case MB_TYPE_16x8:379 pDst = k ? pMCRefMem->pDstV : pMCRefMem->pDstU;
380 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];380 pTempDst = k ? pTempMCRefMem->pDstV : pTempMCRefMem->pDstU;
381 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];381 //iLineStride = pMCRefMem->iDstLineChroma;
382 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);382
383 BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 8, iMVs);383 for (int i = 0; i < iBlkHeight; i++) {
384 384 for (int j = 0; j < iBlkWidth; j++) {
385 if (pCurDqLayer->bUseWeightPredictionFlag) {385 iPixel = j + i * (iLineStride);
386 iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];386 iPredTemp = ((pDst[iPixel] * iWoc1 + pTempDst[iPixel] * iWoc2 + (1 << iLog2denom)) >> (iLog2denom + 1)) + ((
387 WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 8);387 iOoc1 + iOoc2 + 1) >> 1);
388 }388 pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
389 389 }
390 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][8][0];390 }
391 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][8][1];391 }
392 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 8);392}
393 pMCRefMem.pDstY = pPredY + (iDstLineLuma << 3);393
394 pMCRefMem.pDstU = pPredCb + (iDstLineChroma << 2);394static void BiPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, sMCRefMember* pTempMCRefMem, int32_t iBlkWidth,
395 pMCRefMem.pDstV = pPredCr + (iDstLineChroma << 2);395 int32_t iBlkHeight) {
396 BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY + 8, pMCFunc, 16, 8, iMVs);396 int32_t iPredTemp, iLineStride;
397 397 int32_t iPixel = 0;
398 if (pCurDqLayer->bUseWeightPredictionFlag) {398 //luma
399 iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][8];399 iLineStride = pMCRefMem->iDstLineLuma;
400 WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 8);400
401 }401 for (int i = 0; i < iBlkHeight; i++) {
402 break;402 for (int j = 0; j < iBlkWidth; j++) {
403 case MB_TYPE_8x16:403 iPixel = j + i * (iLineStride);
404 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];404 iPredTemp = (pMCRefMem->pDstY[iPixel] + pTempMCRefMem->pDstY[iPixel] + 1) >> 1;
405 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];405 pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
406 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);406 }
407 BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 8, 16, iMVs);407 }
408 if (pCurDqLayer->bUseWeightPredictionFlag) {408
409 iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];409 //UV
410 WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 16);410 iBlkWidth = iBlkWidth >> 1;
411 }411 iBlkHeight = iBlkHeight >> 1;
412 412 iLineStride = pMCRefMem->iDstLineChroma;
413 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][2][0];413
414 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][2][1];414 uint8_t* pDst;
415 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 2);415 uint8_t* pTempDst;
416 pMCRefMem.pDstY = pPredY + 8;416 for (int k = 0; k < 2; k++) {
417 pMCRefMem.pDstU = pPredCb + 4;417 pDst = k ? pMCRefMem->pDstV : pMCRefMem->pDstU;
418 pMCRefMem.pDstV = pPredCr + 4;418 pTempDst = k ? pTempMCRefMem->pDstV : pTempMCRefMem->pDstU;
419 BaseMC (&pMCRefMem, iMBOffsetX + 8, iMBOffsetY, pMCFunc, 8, 16, iMVs);419 //iLineStride = pMCRefMem->iDstLineChroma;
420 420
421 if (pCurDqLayer->bUseWeightPredictionFlag) {421 for (int i = 0; i < iBlkHeight; i++) {
422 iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][2];422 for (int j = 0; j < iBlkWidth; j++) {
423 WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 16);423 iPixel = j + i * (iLineStride);
424 }424 iPredTemp = (pDst[iPixel] + pTempDst[iPixel] + 1) >> 1;
425 break;425 pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
426 case MB_TYPE_8x8:426 }
427 case MB_TYPE_8x8_REF0: {427 }
428 uint32_t iSubMBType;428 }
429 int32_t iXOffset, iYOffset;429}
430 uint8_t* pDstY, *pDstU, *pDstV;430
431 for (i = 0; i < 4; i++) {431void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx) {
432 iSubMBType = pCurDqLayer->pSubMbType[iMBXY][i];432 sMCRefMember pMCRefMem;
433 iBlk8X = (i & 1) << 3;433 PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
434 iBlk8Y = (i >> 1) << 3;434 SMcFunc* pMCFunc = &pCtx->sMcFunc;
435 iXOffset = iMBOffsetX + iBlk8X;435
436 iYOffset = iMBOffsetY + iBlk8Y;436 int32_t iMBXY = pCurDqLayer->iMbXyIndex;
437 437
438 iIIdx = ((i >> 1) << 3) + ((i & 1) << 1);438 int16_t iMVs[2] = {0};
439 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], iIIdx);439
440 iRefIndex = pCurDqLayer->bUseWeightPredictionFlag ? pCurDqLayer->pRefIndex[0][iMBXY][iIIdx] : 0;440 uint32_t iMBType = pCurDqLayer->pMbType[iMBXY];
441 441
442 pDstY = pPredY + iBlk8X + iBlk8Y * iDstLineLuma;442 int32_t iMBOffsetX = pCurDqLayer->iMbX << 4;
443 pDstU = pPredCb + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;443 int32_t iMBOffsetY = pCurDqLayer->iMbY << 4;
444 pDstV = pPredCr + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;444
445 pMCRefMem.pDstY = pDstY;445 int32_t iDstLineLuma = pCtx->pDec->iLinesize[0];
446 pMCRefMem.pDstU = pDstU;446 int32_t iDstLineChroma = pCtx->pDec->iLinesize[1];
447 pMCRefMem.pDstV = pDstV;447
448 switch (iSubMBType) {448 int32_t iBlk8X, iBlk8Y, iBlk4X, iBlk4Y, i, j, iIIdx, iJIdx;
449 case SUB_MB_TYPE_8x8:449
450 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];450 pMCRefMem.iPicWidth = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbWidth << 4);
451 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];451 pMCRefMem.iPicHeight = (pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iMbHeight << 4);
452 BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);452
453 if (pCurDqLayer->bUseWeightPredictionFlag) {453 pMCRefMem.pDstY = pPredY;
454 454 pMCRefMem.pDstU = pPredCb;
455 WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 8);455 pMCRefMem.pDstV = pPredCr;
456 }456
457 457 pMCRefMem.iDstLineLuma = iDstLineLuma;
458 break;458 pMCRefMem.iDstLineChroma = iDstLineChroma;
459 case SUB_MB_TYPE_8x4:459
460 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];460 int32_t iRefIndex = 0;
461 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];461
462 BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);462 switch (iMBType) {
463 if (pCurDqLayer->bUseWeightPredictionFlag) {463 case MB_TYPE_SKIP:
464 464 case MB_TYPE_16x16:
465 WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 4);465 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
466 }466 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
467 467 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0);
468 468 BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
469 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 4][0];469
470 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 4][1];470 if (pCurDqLayer->bUseWeightPredictionFlag) {
471 pMCRefMem.pDstY += (iDstLineLuma << 2);471 iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
472 pMCRefMem.pDstU += (iDstLineChroma << 1);472 WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 16, 16);
473 pMCRefMem.pDstV += (iDstLineChroma << 1);473 }
474 BaseMC (&pMCRefMem, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);474 break;
475 if (pCurDqLayer->bUseWeightPredictionFlag) {475 case MB_TYPE_16x8:
476 476 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
477 WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 4);477 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
478 }478 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0);
479 479 BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 8, iMVs);
480 break;480
481 case SUB_MB_TYPE_4x8:481 if (pCurDqLayer->bUseWeightPredictionFlag) {
482 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];482 iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
483 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];483 WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 16, 8);
484 BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);484 }
485 if (pCurDqLayer->bUseWeightPredictionFlag) {485
486 486 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][8][0];
487 WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 8);487 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][8][1];
488 }488 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 8, LIST_0);
489 489 pMCRefMem.pDstY = pPredY + (iDstLineLuma << 3);
490 490 pMCRefMem.pDstU = pPredCb + (iDstLineChroma << 2);
491 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 1][0];491 pMCRefMem.pDstV = pPredCr + (iDstLineChroma << 2);
492 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 1][1];492 BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY + 8, pMCFunc, 16, 8, iMVs);
493 pMCRefMem.pDstY += 4;493
494 pMCRefMem.pDstU += 2;494 if (pCurDqLayer->bUseWeightPredictionFlag) {
495 pMCRefMem.pDstV += 2;495 iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][8];
496 BaseMC (&pMCRefMem, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);496 WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 16, 8);
497 if (pCurDqLayer->bUseWeightPredictionFlag) {497 }
498 498 break;
499 WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 8);499 case MB_TYPE_8x16:
500 }500 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
501 501 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
502 break;502 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0);
503 case SUB_MB_TYPE_4x4: {503 BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 8, 16, iMVs);
504 for (j = 0; j < 4; j++) {504 if (pCurDqLayer->bUseWeightPredictionFlag) {
505 int32_t iUVLineStride;505 iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
506 iJIdx = ((j >> 1) << 2) + (j & 1);506 WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 16);
507 507 }
508 iBlk4X = (j & 1) << 2;508
509 iBlk4Y = (j >> 1) << 2;509 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][2][0];
510 510 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][2][1];
511 iUVLineStride = (iBlk4X >> 1) + (iBlk4Y >> 1) * iDstLineChroma;511 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 2, LIST_0);
512 pMCRefMem.pDstY = pDstY + iBlk4X + iBlk4Y * iDstLineLuma;512 pMCRefMem.pDstY = pPredY + 8;
513 pMCRefMem.pDstU = pDstU + iUVLineStride;513 pMCRefMem.pDstU = pPredCb + 4;
514 pMCRefMem.pDstV = pDstV + iUVLineStride;514 pMCRefMem.pDstV = pPredCr + 4;
515 515 BaseMC (&pMCRefMem, iMBOffsetX + 8, iMBOffsetY, pMCFunc, 8, 16, iMVs);
516 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + iJIdx][0];516
517 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + iJIdx][1];517 if (pCurDqLayer->bUseWeightPredictionFlag) {
518 BaseMC (&pMCRefMem, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);518 iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][2];
519 if (pCurDqLayer->bUseWeightPredictionFlag) {519 WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 16);
520 520 }
521 WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 4);521 break;
522 }522 case MB_TYPE_8x8:
523 523 case MB_TYPE_8x8_REF0: {
524 }524 uint32_t iSubMBType;
525 }525 int32_t iXOffset, iYOffset;
526 break;526 uint8_t* pDstY, *pDstU, *pDstV;
527 default:527 for (i = 0; i < 4; i++) {
528 break;528 iSubMBType = pCurDqLayer->pSubMbType[iMBXY][i];
529 }529 iBlk8X = (i & 1) << 3;
530 }530 iBlk8Y = (i >> 1) << 3;
531 }531 iXOffset = iMBOffsetX + iBlk8X;
532 break;532 iYOffset = iMBOffsetY + iBlk8Y;
533 default:533
534 break;534 iIIdx = ((i >> 1) << 3) + ((i & 1) << 1);
535 }535 GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], iIIdx, LIST_0);
536}536 iRefIndex = pCurDqLayer->bUseWeightPredictionFlag ? pCurDqLayer->pRefIndex[0][iMBXY][iIIdx] : 0;
537 537
538int32_t RecChroma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer) {538 pDstY = pPredY + iBlk8X + iBlk8Y * iDstLineLuma;
539 int32_t iChromaStride = pCtx->pCurDqLayer->pDec->iLinesize[1];539 pDstU = pPredCb + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
540 PIdctFourResAddPredFunc pIdctFourResAddPredFunc = pCtx->pIdctFourResAddPredFunc;540 pDstV = pPredCr + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
541 541 pMCRefMem.pDstY = pDstY;
542 uint8_t i = 0;542 pMCRefMem.pDstU = pDstU;
543 uint8_t uiCbpC = pDqLayer->pCbp[iMBXY] >> 4;543 pMCRefMem.pDstV = pDstV;
544 544 switch (iSubMBType) {
545 if (1 == uiCbpC || 2 == uiCbpC) {545 case SUB_MB_TYPE_8x8:
546 for (i = 0; i < 2; i++) {546 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
547 int16_t* pRS = pScoeffLevel + 256 + (i << 6);547 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
548 uint8_t* pPred = pDqLayer->pPred[i + 1];548 BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
549 const int8_t* pNzc = pDqLayer->pNzc[iMBXY] + 16 + 2 * i;549 if (pCurDqLayer->bUseWeightPredictionFlag) {
550 550
551 /*1 chroma is divided 4 4x4_block to idct*/551 WeightPrediction (pCurDqLayer, &pMCRefMem, LIST_0, iRefIndex, 8, 8);
552 pIdctFourResAddPredFunc (pPred, iChromaStride, pRS, pNzc);552 }
553 }553
554 }554 break;
555 555 case SUB_MB_TYPE_8x4:
556 return ERR_NONE;556 iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
557}557 iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
558 558 BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
559} // namespace WelsDec559 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
634void 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
1019int32_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