ref: 5b12578960b1a9cbb009a4ed2ffb41459345ec71
parent: 5a1aedb622fa15f0d6fb9fbf8306e7cf9312972a
parent: 9ef0c74fdd58b076377bf20aef0a79ee5f8a271e
author: dongzha <dongzha@cisco.com>
date: Wed Mar 4 09:58:40 EST 2015
Merge pull request #1829 from syureyi/wp_p Decoder WP support
--- a/codec/decoder/core/inc/dec_frame.h
+++ b/codec/decoder/core/inc/dec_frame.h
@@ -102,7 +102,9 @@
int32_t iInterLayerSliceBetaOffset;
//SPosOffset sScaledRefLayer;
int32_t iSliceGroupChangeCycle;
+
PRefPicListReorderSyn pRefPicListReordering;
+ PPredWeightTabSyn pPredWeightTable;
PRefPicMarking pRefPicMarking; // Decoded reference picture marking syntaxs
PRefBasePicMarking pRefPicBaseMarking;
@@ -109,6 +111,7 @@
PPicture pRef; // reference picture pointer
PPicture pDec; // reconstruction picture pointer for layer
+ bool bUseWeightPredictionFlag;
bool bStoreRefBasePicFlag; // iCurTid == 0 && iCurQid = 0 && bEncodeKeyPic = 1
bool bTCoeffLevelPredFlag;
bool bConstrainedIntraResamplingFlag;
--- a/codec/decoder/core/inc/error_code.h
+++ b/codec/decoder/core/inc/error_code.h
@@ -147,6 +147,13 @@
ERR_INFO_INVALID_I16x16_PRED_MODE,
ERR_INFO_INVALID_I_CHROMA_PRED_MODE,
+ERR_INFO_INVALID_LUMA_LOG2_WEIGHT_DENOM,
+ERR_INFO_INVALID_CHROMA_LOG2_WEIGHT_DENOM,
+ERR_INFO_INVALID_LUMA_WEIGHT,
+ERR_INFO_INVALID_CHROMA_WEIGHT,
+ERR_INFO_INVALID_LUMA_OFFSET,
+ERR_INFO_INVALID_CHROMA_OFFSET,
+
ERR_INFO_UNSUPPORTED_NON_BASELINE,
ERR_INFO_UNSUPPORTED_FMOTYPE,
ERR_INFO_UNSUPPORTED_MBAFF,
--- a/codec/decoder/core/inc/slice.h
+++ b/codec/decoder/core/inc/slice.h
@@ -68,7 +68,7 @@
bool bLumaWeightFlag;
bool bChromaWeightFlag;
} sPredList[LIST_A];
-} SPredWeightTabSyn;
+} SPredWeightTabSyn,*PPredWeightTabSyn;
/* Decoded reference picture marking syntax, refer to Page 66 in JVT X201wcm */
typedef struct TagRefPicMarking {
--- a/codec/decoder/core/src/au_parser.cpp
+++ b/codec/decoder/core/src/au_parser.cpp
@@ -1353,10 +1353,10 @@
pPps->bWeightedPredFlag = !!uiCode;
WELS_READ_VERIFY (BsGetBits (pBsAux, 2, &uiCode)); //weighted_bipred_idc
pPps->uiWeightedBipredIdc = uiCode;
- if (pPps->bWeightedPredFlag || pPps->uiWeightedBipredIdc != 0) {
+ if (pPps->uiWeightedBipredIdc != 0) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
- "ParsePps(): weighted_pred_flag (%d) weighted_bipred_idc (%d) neither supported.\n",
- pPps->bWeightedPredFlag, pPps->uiWeightedBipredIdc);
+ "ParsePps(): weighted_bipred_idc (%d) not supported.\n",
+ pPps->uiWeightedBipredIdc);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_WP);
}
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -179,6 +179,78 @@
return iRet;
}
+int32_t ParsePredWeightedTable (PBitStringAux pBs, PSliceHeader pSh) {
+ uint32_t uiCode;
+ int32_t iList = 0;
+ int32_t iCode;
+
+ WELS_READ_VERIFY (BsGetUe (pBs, &uiCode));
+ WELS_CHECK_SE_BOTH_ERROR_NOLOG (uiCode, 0, 7, "luma_log2_weight_denom",
+ GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_LOG2_WEIGHT_DENOM));
+ pSh->sPredWeightTable.uiLumaLog2WeightDenom = uiCode;
+ if (pSh->pSps->uiChromaArrayType != 0) {
+ WELS_READ_VERIFY (BsGetUe (pBs, &uiCode));
+ WELS_CHECK_SE_BOTH_ERROR_NOLOG (uiCode, 0, 7, "chroma_log2_weight_denom",
+ GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_LOG2_WEIGHT_DENOM));
+ pSh->sPredWeightTable.uiChromaLog2WeightDenom = uiCode;
+ }
+
+
+ do {
+
+ for (int i = 0; i < pSh->uiRefCount[iList]; i++) {
+ //luma
+ WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));
+ if (!!uiCode) {
+
+ WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
+ WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "luma_weight",
+ GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_WEIGHT));
+ pSh->sPredWeightTable.sPredList[iList].iLumaWeight[i] = iCode;
+
+ WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
+ WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "luma_offset",
+ GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_OFFSET));
+ pSh->sPredWeightTable.sPredList[iList].iLumaOffset[i] = iCode;
+ } else {
+ pSh->sPredWeightTable.sPredList[iList].iLumaWeight[i] = 1 << (pSh->sPredWeightTable.uiLumaLog2WeightDenom);
+ pSh->sPredWeightTable.sPredList[iList].iLumaOffset[i] = 0;
+
+ }
+ //chroma
+ if (pSh->pSps->uiChromaArrayType == 0)
+ continue;
+
+ WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));
+ if (!!uiCode) {
+ for (int j = 0; j < 2; j++) {
+
+
+ WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
+ WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "chroma_weight",
+ GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_WEIGHT));
+ pSh->sPredWeightTable.sPredList[iList].iChromaWeight[i][j] = iCode;
+
+ WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
+ WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "chroma_offset",
+ GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_OFFSET));
+ pSh->sPredWeightTable.sPredList[iList].iChromaOffset[i][j] = iCode;
+ }
+ } else {
+ for (int j = 0; j < 2; j++) {
+
+
+ pSh->sPredWeightTable.sPredList[iList].iChromaWeight[i][j] = 1 << (pSh->sPredWeightTable.uiChromaLog2WeightDenom);
+ pSh->sPredWeightTable.sPredList[iList].iChromaOffset[i][j] = 0;
+ }
+ }
+
+ }
+ ++iList;
+ } while (iList < LIST_1);//TODO: SUPPORT LIST_A
+ return ERR_NONE;
+}
+
/*
* Predeclared function routines ..
*/
@@ -728,6 +800,14 @@
return iRet;
}
+ if (pPps->bWeightedPredFlag && (uiSliceType == P_SLICE)) {
+ iRet = ParsePredWeightedTable (pBs, pSliceHead);
+ if (iRet != ERR_NONE) {
+ WelsLog (pLogCtx, WELS_LOG_WARNING, "invalid weighted prediction syntaxs!");
+ return iRet;
+ }
+ }
+
if (kbExtensionFlag) {
if (pNalHeaderExt->iNoInterLayerPredFlag || pNalHeaderExt->uiQualityId > 0)
pSliceHeadExt->bBasePredWeightTableFlag = false;
@@ -1876,6 +1956,14 @@
if (kuiQualityId == BASE_QUALITY_ID) {
pDqLayer->pRefPicListReordering = &pSh->pRefPicListReordering;
pDqLayer->pRefPicMarking = &pSh->sRefMarking;
+
+ if (pSh->pPps->bWeightedPredFlag) {
+ pDqLayer->bUseWeightPredictionFlag = true;
+ pDqLayer->pPredWeightTable = &pSh->sPredWeightTable;
+
+ } else
+ pDqLayer->bUseWeightPredictionFlag = false;
+
pDqLayer->pRefPicBaseMarking = &pShExt->sRefBasePicMarking;
}
--- a/codec/decoder/core/src/rec_mb.cpp
+++ b/codec/decoder/core/src/rec_mb.cpp
@@ -186,7 +186,7 @@
#define MC_FLOW_SIMPLE_JUDGE 1
#endif //MC_FLOW_SIMPLE_JUDGE
void BaseMC (sMCRefMember* pMCRefMem, int32_t iXOffset, int32_t iYOffset, SMcFunc* pMCFunc,
- int32_t iBlkWidth, int32_t iBlkHeight, int16_t iMVs[2]) {
+ int32_t iBlkWidth, int32_t iBlkHeight, int16_t iMVs[2]) {
int32_t iFullMVx = (iXOffset << 2) + iMVs[0]; //quarter pixel
int32_t iFullMVy = (iYOffset << 2) + iMVs[1];
iFullMVx = WELS_CLIP3 (iFullMVx, ((-PADDING_LENGTH + 2) << 2), ((pMCRefMem->iPicWidth + PADDING_LENGTH - 19) << 2));
@@ -214,6 +214,74 @@
}
+void WeightPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, int32_t iRefIdx, int32_t iBlkWidth,
+ int32_t iBlkHeight) {
+
+
+ int32_t iLog2denom, iWoc, iOoc;
+ int32_t iPredTemp, iLineStride;
+ int32_t iPixel = 0;
+ uint8_t* pDst;
+ //luma
+ iLog2denom = pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom;
+ iWoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaWeight[iRefIdx];
+ iOoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaOffset[iRefIdx];
+ iLineStride = pMCRefMem->iDstLineLuma;
+
+ for (int i = 0; i < iBlkHeight; i++) {
+ for (int j = 0; j < iBlkWidth; j++) {
+ iPixel = j + i * (iLineStride);
+ if (iLog2denom >= 1) {
+ iPredTemp = ((pMCRefMem->pDstY[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
+
+ pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
+ } else {
+ iPredTemp = pMCRefMem->pDstY[iPixel] * iWoc + iOoc;
+
+ pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
+
+ }
+ }
+ }
+
+
+ //UV
+ iBlkWidth = iBlkWidth >> 2;
+ iBlkHeight = iBlkHeight >> 2;
+ iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
+ iLineStride = pMCRefMem->iDstLineChroma;
+
+ for (int i = 0; i < 2; i++) {
+
+
+ //iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
+ iWoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaWeight[iRefIdx][i];
+ iOoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaOffset[iRefIdx][i];
+ pDst = i ? pMCRefMem->pDstV : pMCRefMem->pDstU;
+ //iLineStride = pMCRefMem->iDstLineChroma;
+
+ for (int i = 0; i < iBlkHeight ; i++) {
+ for (int j = 0; j < iBlkWidth; j++) {
+ iPixel = j + i * (iLineStride);
+ if (iLog2denom >= 1) {
+ iPredTemp = ((pDst[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
+
+ pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
+ } else {
+ iPredTemp = pDst[iPixel] * iWoc + iOoc;
+
+ pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
+
+ }
+ }
+
+ }
+
+
+ }
+}
+
+
void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx) {
sMCRefMember pMCRefMem;
PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
@@ -242,6 +310,9 @@
pMCRefMem.iDstLineLuma = iDstLineLuma;
pMCRefMem.iDstLineChroma = iDstLineChroma;
+
+ int32_t iRefIndex = 0;
+
switch (iMBType) {
case MB_TYPE_SKIP:
case MB_TYPE_16x16:
@@ -249,6 +320,11 @@
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);
BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
+
+ if (pCurDqLayer->bUseWeightPredictionFlag) {
+ iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
+ WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 16);
+ }
break;
case MB_TYPE_16x8:
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
@@ -256,6 +332,11 @@
GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);
BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 8, iMVs);
+ if (pCurDqLayer->bUseWeightPredictionFlag) {
+ iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
+ WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 8);
+ }
+
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][8][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][8][1];
GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 8);
@@ -263,6 +344,11 @@
pMCRefMem.pDstU = pPredCb + (iDstLineChroma << 2);
pMCRefMem.pDstV = pPredCr + (iDstLineChroma << 2);
BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY + 8, pMCFunc, 16, 8, iMVs);
+
+ if (pCurDqLayer->bUseWeightPredictionFlag) {
+ iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][8];
+ WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 8);
+ }
break;
case MB_TYPE_8x16:
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
@@ -269,6 +355,10 @@
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);
BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 8, 16, iMVs);
+ if (pCurDqLayer->bUseWeightPredictionFlag) {
+ iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
+ WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 16);
+ }
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][2][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][2][1];
@@ -277,6 +367,11 @@
pMCRefMem.pDstU = pPredCb + 4;
pMCRefMem.pDstV = pPredCr + 4;
BaseMC (&pMCRefMem, iMBOffsetX + 8, iMBOffsetY, pMCFunc, 8, 16, iMVs);
+
+ if (pCurDqLayer->bUseWeightPredictionFlag) {
+ iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][2];
+ WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 16);
+ }
break;
case MB_TYPE_8x8:
case MB_TYPE_8x8_REF0: {
@@ -292,6 +387,7 @@
iIIdx = ((i >> 1) << 3) + ((i & 1) << 1);
GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], iIIdx);
+ iRefIndex = pCurDqLayer->bUseWeightPredictionFlag ? pCurDqLayer->pRefIndex[0][iMBXY][iIIdx] : 0;
pDstY = pPredY + iBlk8X + iBlk8Y * iDstLineLuma;
pDstU = pPredCb + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
@@ -304,12 +400,22 @@
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
+ if (pCurDqLayer->bUseWeightPredictionFlag) {
+
+ WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 8);
+ }
+
break;
case SUB_MB_TYPE_8x4:
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
+ if (pCurDqLayer->bUseWeightPredictionFlag) {
+ WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 4);
+ }
+
+
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 4][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 4][1];
pMCRefMem.pDstY += (iDstLineLuma << 2);
@@ -316,12 +422,22 @@
pMCRefMem.pDstU += (iDstLineChroma << 1);
pMCRefMem.pDstV += (iDstLineChroma << 1);
BaseMC (&pMCRefMem, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);
+ if (pCurDqLayer->bUseWeightPredictionFlag) {
+
+ WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 4);
+ }
+
break;
case SUB_MB_TYPE_4x8:
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);
+ if (pCurDqLayer->bUseWeightPredictionFlag) {
+ WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 8);
+ }
+
+
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 1][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 1][1];
pMCRefMem.pDstY += 4;
@@ -328,6 +444,11 @@
pMCRefMem.pDstU += 2;
pMCRefMem.pDstV += 2;
BaseMC (&pMCRefMem, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);
+ if (pCurDqLayer->bUseWeightPredictionFlag) {
+
+ WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 8);
+ }
+
break;
case SUB_MB_TYPE_4x4: {
for (j = 0; j < 4; j++) {
@@ -345,6 +466,11 @@
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + iJIdx][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + iJIdx][1];
BaseMC (&pMCRefMem, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);
+ if (pCurDqLayer->bUseWeightPredictionFlag) {
+
+ WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 4);
+ }
+
}
}
break;