History

add EC frame/slice copy.

huili2 committed 12 years ago

Commit bc2c4b01 parent b2f71919 files · +156 −21Browse files

Showing the changes to codec/decoder/core/src (4 of 9 files). Show all

Unified · Split

4 files
  1. codec/decoder/core/src/decode_slice.cpp +1 −0
  2. codec/decoder/core/src/decoder.cpp +2 −1
  3. codec/decoder/core/src/decoder_core.cpp +40 −10
  4. codec/decoder/core/src/error_concealment.cpp +105 −8
codec/decoder/core/src/decode_slice.cpp+1−0
@@ -394,6 +394,7 @@ int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNal · 393 unmodified lines
394 }394 }
395 395
396 ++pSlice->iTotalMbInCurSlice;396 ++pSlice->iTotalMbInCurSlice;
397 pCurLayer->pMbCorrectlyDecodedFlag[iNextMbXyIndex] = true;
397 398
398 if (pSliceHeader->pPps->uiNumSliceGroups > 1) {399 if (pSliceHeader->pPps->uiNumSliceGroups > 1) {
399 iNextMbXyIndex = FmoNextMb (pFmo, iNextMbXyIndex);400 iNextMbXyIndex = FmoNextMb (pFmo, iNextMbXyIndex);
codec/decoder/core/src/decoder.cpp+2−1
@@ -164,7 +164,8 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx) { · 163 unmodified lines
164 pCtx->pPicBuff[LIST_1] = NULL;164 pCtx->pPicBuff[LIST_1] = NULL;
165 165
166 pCtx->bAvcBasedFlag = true;166 pCtx->bAvcBasedFlag = true;
167 pCtx->iErrorConMethod = ERROR_CON_DISABLE;167 pCtx->iErrorConMethod = ERROR_CON_SLICE_COPY;
168 pCtx->pPreviousDecodedPictureInDpb = NULL;
168 169
169}170}
170 171
codec/decoder/core/src/decoder_core.cpp+40−10
@@ -54,12 +54,21 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 53 unmodified lines
54 const int32_t kiHeight = pCurDq->iMbHeight << 4;54 const int32_t kiHeight = pCurDq->iMbHeight << 4;
55 55
56 const int32_t kiTotalNumMbInCurLayer = pCurDq->iMbWidth * pCurDq->iMbHeight;56 const int32_t kiTotalNumMbInCurLayer = pCurDq->iMbWidth * pCurDq->iMbHeight;
57 bool bFrameCompleteFlag = true;
57 58
58 if (pCtx->iTotalNumMbRec != kiTotalNumMbInCurLayer) {59 if (pCtx->iTotalNumMbRec != kiTotalNumMbInCurLayer) {
60 if ((pCtx->iTotalNumMbRec != 0) && (I_SLICE == pCurDq->sLayerInfo.sSliceInLayer.eSliceType)) { //TODO should be IDR instead of I_SLICE!
61 memcpy (& (pCtx->sFrameCrop), & (pCurDq->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.pSps->sFrameCrop), sizeof (SPosOffset));
62#ifdef LONG_TERM_REF
63 pCtx->bParamSetsLostFlag = false;
64#else
65 pCtx->bReferenceLostAtT0Flag = false;
66#endif //LONG_TERM_REF
67 }
59 WelsLog (pCtx, WELS_LOG_WARNING,68 WelsLog (pCtx, WELS_LOG_WARNING,
60 "DecodeFrameConstruction():::iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d \n",69 "DecodeFrameConstruction():::iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d \n",
61 pCtx->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight);70 pCtx->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight);
62 return -1;71 bFrameCompleteFlag = false; //return later after output buffer is done
63 }72 }
64#ifdef NO_WAITING_AU73#ifdef NO_WAITING_AU
65 pCtx->iTotalNumMbRec = 0;74 pCtx->iTotalNumMbRec = 0;
@@ -99,6 +108,14 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 33 unmodified lines
99 ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;108 ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
100 pDstInfo->iBufferStatus = 1;109 pDstInfo->iBufferStatus = 1;
101 110
111 if (pCtx->iErrorConMethod == ERROR_CON_DISABLE) //no buffer output if EC is disabled and frame incomplete
112 pDstInfo->iBufferStatus = (int32_t) bFrameCompleteFlag;
113
114 if (!bFrameCompleteFlag) {
115 pCtx->iErrorCode |= dsBitstreamError;
116 return -1;
117 }
118
102 return 0;119 return 0;
103}120}
104 121
@@ -955,6 +972,8 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid · 850 unmodified lines
955 pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (972 pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
956 int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]");973 int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]");
957 974
975 pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool), "pCtx->sMb.pMbCorrectlyDecodedFlag[]");
976
958 // check memory block valid due above allocated..977 // check memory block valid due above allocated..
959 WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY,978 WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY,
960 ((NULL == pCtx->sMb.pMbType[i]) ||979 ((NULL == pCtx->sMb.pMbType[i]) ||
@@ -972,7 +991,8 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid · 11 unmodified lines
972 (NULL == pCtx->sMb.pSubMbType[i]) ||991 (NULL == pCtx->sMb.pSubMbType[i]) ||
973 (NULL == pCtx->sMb.pSliceIdc[i]) ||992 (NULL == pCtx->sMb.pSliceIdc[i]) ||
974 (NULL == pCtx->sMb.pResidualPredFlag[i]) ||993 (NULL == pCtx->sMb.pResidualPredFlag[i]) ||
975 (NULL == pCtx->sMb.pInterPredictionDoneFlag[i])994 (NULL == pCtx->sMb.pInterPredictionDoneFlag[i]) ||
995 (NULL == pCtx->sMb.pMbCorrectlyDecodedFlag[i])
976 )996 )
977 )997 )
978 998
@@ -1100,6 +1120,12 @@ void UninitialDqLayersContext (PWelsDecoderContext pCtx) { · 121 unmodified lines
1100 1120
1101 pCtx->sMb.pInterPredictionDoneFlag[i] = NULL;1121 pCtx->sMb.pInterPredictionDoneFlag[i] = NULL;
1102 }1122 }
1123
1124 if (pCtx->sMb.pMbCorrectlyDecodedFlag[i]) {
1125 WelsFree (pCtx->sMb.pMbCorrectlyDecodedFlag[i], "pCtx->sMb.pMbCorrectlyDecodedFlag[]");
1126 pCtx->sMb.pMbCorrectlyDecodedFlag[i] = NULL;
1127 }
1128
1103 WelsFree (pDq, "pDq");1129 WelsFree (pDq, "pDq");
1104 1130
1105 pDq = NULL;1131 pDq = NULL;
@@ -1560,8 +1586,6 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI · 454 unmodified lines
1560 pCtx->bNewSeqBegin = false;1586 pCtx->bNewSeqBegin = false;
1561 if (ERR_NONE != iErr) {1587 if (ERR_NONE != iErr) {
1562 WelsLog (pCtx, WELS_LOG_INFO, "returned error from decoding:[0x%x]\n", iErr);1588 WelsLog (pCtx, WELS_LOG_INFO, "returned error from decoding:[0x%x]\n", iErr);
1563
1564 pDstInfo->iBufferStatus = 0;
1565 return iErr;1589 return iErr;
1566 }1590 }
1567 1591
@@ -1651,6 +1675,7 @@ void InitCurDqLayerData (PWelsDecoderContext pCtx, PDqLayer pCurDq) { · 83 unmodified lines
1651 pCurDq->pSubMbType = pCtx->sMb.pSubMbType[0];1675 pCurDq->pSubMbType = pCtx->sMb.pSubMbType[0];
1652 pCurDq->pInterPredictionDoneFlag = pCtx->sMb.pInterPredictionDoneFlag[0];1676 pCurDq->pInterPredictionDoneFlag = pCtx->sMb.pInterPredictionDoneFlag[0];
1653 pCurDq->pResidualPredFlag = pCtx->sMb.pResidualPredFlag[0];1677 pCurDq->pResidualPredFlag = pCtx->sMb.pResidualPredFlag[0];
1678 pCurDq->pMbCorrectlyDecodedFlag = pCtx->sMb.pMbCorrectlyDecodedFlag[0];
1654 }1679 }
1655}1680}
1656 1681
@@ -1725,6 +1750,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3 · 68 unmodified lines
1725 if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode1750 if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode
1726 for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i)1751 for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i)
1727 memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));1752 memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));
1753 memset (pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight);
1728 }1754 }
1729 GetI4LumaIChromaAddrTable (pCtx->iDecBlockOffsetArray, pCtx->pDec->iLinesize[0], pCtx->pDec->iLinesize[1]);1755 GetI4LumaIChromaAddrTable (pCtx->iDecBlockOffsetArray, pCtx->pDec->iLinesize[0], pCtx->pDec->iLinesize[1]);
1730 1756
@@ -1796,15 +1822,16 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3 · 65 unmodified lines
1796 "referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d\n", pCtx->iPrevFrameNum,1822 "referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d\n", pCtx->iPrevFrameNum,
1797 pSh->iFrameNum);1823 pSh->iFrameNum);
1798 1824
1825 pCtx->iErrorCode |= dsRefLost;
1826 if (pCtx->iErrorConMethod == ERROR_CON_DISABLE) {
1799#ifdef LONG_TERM_REF1827#ifdef LONG_TERM_REF
1800 pCtx->bParamSetsLostFlag = true;1828 pCtx->bParamSetsLostFlag = true;
1801#else1829#else
1802 pCtx->bReferenceLostAtT0Flag = true;1830 pCtx->bReferenceLostAtT0Flag = true;
1803#endif1831#endif
1804 ResetParameterSetsState (pCtx);1832 ResetParameterSetsState (pCtx);
1805 1833 return ERR_INFO_REFERENCE_PIC_LOST;
1806 pCtx->iErrorCode |= dsRefLost;1834 }
1807 return ERR_INFO_REFERENCE_PIC_LOST;
1808 }1835 }
1809 }1836 }
1810 1837
@@ -1875,6 +1902,9 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3 · 64 unmodified lines
1875#endif1902#endif
1876 1903
1877 }1904 }
1905
1906 pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //store latest decoded picture for EC
1907
1878 if (uiNalRefIdc > 0) {1908 if (uiNalRefIdc > 0) {
1879 iRet = WelsMarkAsRef (pCtx);1909 iRet = WelsMarkAsRef (pCtx);
1880 if (iRet != ERR_NONE) {1910 if (iRet != ERR_NONE) {
codec/decoder/core/src/error_concealment.cpp+105−8
@@ -66,33 +66,130 @@ void InitErrorCon (PWelsDecoderContext pCtx) { · 65 unmodified lines
66 66
67//Do error concealment using frame copy method67//Do error concealment using frame copy method
68void DoErrorConFrameCopy (PWelsDecoderContext pCtx) {68void DoErrorConFrameCopy (PWelsDecoderContext pCtx) {
69 //TODO69 PPicture pDstPic = pCtx->pDec;
70 PPicture pSrcPic = pCtx->pPreviousDecodedPictureInDpb;
71 uint32_t uiHeightInPixelY = (pCtx->pSps->iMbHeight) << 4;
72 int32_t iStrideY = pDstPic->iLinesize[0];
73 int32_t iStrideUV = pDstPic->iLinesize[1];
74 if (pSrcPic == NULL) { //no ref pic, assign specific data to picture
75 memset (pDstPic->pData[0], 0, uiHeightInPixelY * iStrideY);
76 memset (pDstPic->pData[1], 0, (uiHeightInPixelY >> 1) * iStrideUV);
77 memset (pDstPic->pData[2], 0, (uiHeightInPixelY >> 1) * iStrideUV);
78 } else { //has ref pic here
79 memcpy (pDstPic->pData[0], pSrcPic->pData[0], uiHeightInPixelY * iStrideY);
80 memcpy (pDstPic->pData[1], pSrcPic->pData[1], (uiHeightInPixelY >> 1) * iStrideUV);
81 memcpy (pDstPic->pData[2], pSrcPic->pData[2], (uiHeightInPixelY >> 1) * iStrideUV);
82 }
70}83}
71 84
72 85
73//Do error concealment using slice copy method86//Do error concealment using slice copy method
74void DoErrorConSliceCopy (PWelsDecoderContext pCtx) {87void DoErrorConSliceCopy (PWelsDecoderContext pCtx) {
75 //TODO88 int32_t iMbWidth = (int32_t) pCtx->pSps->iMbWidth;
89 int32_t iMbHeight = (int32_t) pCtx->pSps->iMbHeight;
90 PPicture pDstPic = pCtx->pDec;
91 PPicture pSrcPic = pCtx->pPreviousDecodedPictureInDpb;
92
93 //uint8_t *pDstData[3], *pSrcData[3];
94 bool* pMbCorrectlyDecodedFlag = pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag;
95
96 //Do slice copy late
97 int32_t iMbXyIndex;
98 uint8_t* pSrcData, *pDstData;
99 uint32_t iSrcStride; // = pSrcPic->iLinesize[0];
100 uint32_t iDstStride = pDstPic->iLinesize[0];
101 for (int32_t iMbY = 0; iMbY < iMbHeight; ++iMbY) {
102 for (int32_t iMbX = 0; iMbX < iMbWidth; ++iMbX) {
103 iMbXyIndex = iMbY * iMbWidth + iMbX;
104 if (!pMbCorrectlyDecodedFlag[iMbXyIndex]) {
105 if (pSrcPic != NULL) {
106 iSrcStride = pSrcPic->iLinesize[0];
107 //Y component
108 pDstData = pDstPic->pData[0] + iMbY * 16 * iDstStride + iMbX * 16;;
109 pSrcData = pSrcPic->pData[0] + iMbY * 16 * iSrcStride + iMbX * 16;
110 pCtx->sCopyFunc.pCopyLumaFunc (pDstData, iDstStride, pSrcData, iSrcStride);
111 //U component
112 pDstData = pDstPic->pData[1] + iMbY * 8 * iDstStride / 2 + iMbX * 8;
113 pSrcData = pSrcPic->pData[1] + iMbY * 8 * iSrcStride / 2 + iMbX * 8;
114 pCtx->sCopyFunc.pCopyChromaFunc (pDstData, iDstStride / 2, pSrcData, iSrcStride / 2);
115 //V component
116 pDstData = pDstPic->pData[2] + iMbY * 8 * iDstStride / 2 + iMbX * 8;
117 pSrcData = pSrcPic->pData[2] + iMbY * 8 * iSrcStride / 2 + iMbX * 8;
118 pCtx->sCopyFunc.pCopyChromaFunc (pDstData, iDstStride / 2, pSrcData, iSrcStride / 2);
119 } else { //pSrcPic == NULL
120 //Y component
121 pDstData = pDstPic->pData[0] + iMbY * 16 * iDstStride + iMbX * 16;
122 for (int32_t i = 0; i < 16; ++i) {
123 memset (pDstData, 0, 16);
124 pDstData += iDstStride;
125 }
126 //U component
127 pDstData = pDstPic->pData[1] + iMbY * 8 * iDstStride / 2 + iMbX * 8;
128 for (int32_t i = 0; i < 8; ++i) {
129 memset (pDstData, 0, 8);
130 pDstData += iDstStride / 2;
131 }
132 //V component
133 pDstData = pDstPic->pData[2] + iMbY * 8 * iDstStride / 2 + iMbX * 8;
134 for (int32_t i = 0; i < 8; ++i) {
135 memset (pDstData, 0, 8);
136 pDstData += iDstStride / 2;
137 }
138 } //
139 } //!pMbCorrectlyDecodedFlag[iMbXyIndex]
140 } //iMbX
141 } //iMbY
76}142}
77 143
144
78//Mark erroneous frame as Ref Pic into DPB145//Mark erroneous frame as Ref Pic into DPB
79int32_t MarkECFrameAsRef (PWelsDecoderContext pCtx) {146int32_t MarkECFrameAsRef (PWelsDecoderContext pCtx) {
80 //TODO147 int32_t iRet = WelsMarkAsRef (pCtx);
148 if (iRet != ERR_NONE) {
149 pCtx->pDec = NULL;
150 return iRet;
151 }
152 ExpandReferencingPicture (pCtx->pDec, pCtx->sExpandPicFunc.pExpandLumaPicture,
153 pCtx->sExpandPicFunc.pExpandChromaPicture);
154 pCtx->pDec = NULL;
155
81 return ERR_NONE;156 return ERR_NONE;
82}157}
83 158
84bool NeedErrorCon (PWelsDecoderContext pCtx) {159bool NeedErrorCon (PWelsDecoderContext pCtx) {
85 bool bNeedEC = false;160 bool bNeedEC = false;
86 //TODO161 int32_t iMbNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
162 for (int32_t i = 0; i < iMbNum; ++i) {
163 if (!pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag[i]) {
164 bNeedEC = true;
165 break;
166 }
167 }
87 return bNeedEC;168 return bNeedEC;
88}169}
89 170
90// ImplementErrorConceal171// ImplementErrorConceal
91// Do actual error concealment172// Do actual error concealment
92int32_t ImplementErrorCon (PWelsDecoderContext pCtx) {173void ImplementErrorCon (PWelsDecoderContext pCtx) {
93 int32_t iRet = ERR_NONE;174 if (!NeedErrorCon (pCtx))
94 //TODO175 return;
95 return iRet;176
177 if (ERROR_CON_DISABLE == pCtx->iErrorConMethod) {
178 pCtx->iErrorCode |= dsBitstreamError;
179 return;
180 } else if (ERROR_CON_FRAME_COPY == pCtx->iErrorConMethod) {
181 DoErrorConFrameCopy (pCtx);
182 } else if (ERROR_CON_SLICE_COPY == pCtx->iErrorConMethod) {
183 DoErrorConSliceCopy (pCtx);
184 } //TODO add other EC methods here in the future
185
186 //mark the erroneous frame as Ref pic in DPB
187 MarkECFrameAsRef (pCtx);
188 //need update frame_num due current frame is well decoded
189 pCtx->iPrevFrameNum = pCtx->pSliceHeader->iFrameNum;
190 if (pCtx->bLastHasMmco5)
191 pCtx->iPrevFrameNum = 0;
192
96}193}
97 194
98} // namespace WelsDec195} // 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