History

Pretty printed the C++ code with astyle

Ethan Hugg committed 12 years ago

Commit ff6b6691 parent 063709c225 files · +48457 −51954Browse files

Showing the changes to codec/encoder/core/src/svc_encode_slice.cpp (1 of 225 files). Show all

Unified · Split

codec/encoder/core/src/svc_encode_slice.cpp+1120−1194
@@ -1,1194 +1,1120 @@
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 svc_encode_slice.c32 * \file svc_encode_slice.c
33 *33 *
34 * \brief svc encoding slice 34 * \brief svc encoding slice
35 *35 *
36 * \date 2009.07.27 Created36 * \date 2009.07.27 Created
37 *37 *
38 *************************************************************************************38 *************************************************************************************
39 */39 */
40 40
41#include <string.h>41#include <string.h>
42#include <assert.h>42#include <assert.h>
43#include "ls_defines.h"43#include "ls_defines.h"
44#include "svc_encode_slice.h"44#include "svc_encode_slice.h"
45#include "svc_enc_golomb.h"45#include "svc_enc_golomb.h"
46#include "svc_base_layer_md.h"46#include "svc_base_layer_md.h"
47#include "svc_encode_mb.h"47#include "svc_encode_mb.h"
48#include "mv_pred.h"48#include "mv_pred.h"
49#include "svc_set_mb_syn_cavlc.h"49#include "svc_set_mb_syn_cavlc.h"
50#include "encode_mb_aux.h"50#include "encode_mb_aux.h"
51#include "decode_mb_aux.h"51#include "decode_mb_aux.h"
52#include "svc_mode_decision.h"52#include "svc_mode_decision.h"
53#include "cpu_core.h"53#include "cpu_core.h"
54#include "svc_motion_estimate.h"54#include "svc_motion_estimate.h"
55#include "sample.h"55#include "sample.h"
56#include "wels_func_ptr_def.h"56#include "wels_func_ptr_def.h"
57#include "utils.h"57#include "utils.h"
58 58
59namespace WelsSVCEnc {59namespace WelsSVCEnc {
60//#define ENC_TRACE60//#define ENC_TRACE
61 61
62typedef void (*PWelsCodingSliceFunc)( sWelsEncCtx *pCtx, SSlice *pSlice );62typedef void (*PWelsCodingSliceFunc) (sWelsEncCtx* pCtx, SSlice* pSlice);
63typedef void (*PWelsSliceHeaderWriteFunc)( SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice *pSlice, int32_t* pPpsIdDelta );63typedef void (*PWelsSliceHeaderWriteFunc) (SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice,
64 64 int32_t* pPpsIdDelta);
65void UpdateNonZeroCountCache(SMB *pMb, SMbCache *pMbCache)65
66{66void UpdateNonZeroCountCache (SMB* pMb, SMbCache* pMbCache) {
67 ST32(&pMbCache->iNonZeroCoeffCount[9], LD32(&pMb->pNonZeroCount[ 0]));67 ST32 (&pMbCache->iNonZeroCoeffCount[9], LD32 (&pMb->pNonZeroCount[ 0]));
68 ST32(&pMbCache->iNonZeroCoeffCount[17], LD32(&pMb->pNonZeroCount[ 4]));68 ST32 (&pMbCache->iNonZeroCoeffCount[17], LD32 (&pMb->pNonZeroCount[ 4]));
69 ST32(&pMbCache->iNonZeroCoeffCount[25], LD32(&pMb->pNonZeroCount[ 8]));69 ST32 (&pMbCache->iNonZeroCoeffCount[25], LD32 (&pMb->pNonZeroCount[ 8]));
70 ST32(&pMbCache->iNonZeroCoeffCount[33], LD32(&pMb->pNonZeroCount[12])); 70 ST32 (&pMbCache->iNonZeroCoeffCount[33], LD32 (&pMb->pNonZeroCount[12]));
71 71
72 ST16(&pMbCache->iNonZeroCoeffCount[14], LD16(&pMb->pNonZeroCount[16]));72 ST16 (&pMbCache->iNonZeroCoeffCount[14], LD16 (&pMb->pNonZeroCount[16]));
73 ST16(&pMbCache->iNonZeroCoeffCount[38], LD16(&pMb->pNonZeroCount[18]));73 ST16 (&pMbCache->iNonZeroCoeffCount[38], LD16 (&pMb->pNonZeroCount[18]));
74 ST16(&pMbCache->iNonZeroCoeffCount[22], LD16(&pMb->pNonZeroCount[20]));74 ST16 (&pMbCache->iNonZeroCoeffCount[22], LD16 (&pMb->pNonZeroCount[20]));
75 ST16(&pMbCache->iNonZeroCoeffCount[46], LD16(&pMb->pNonZeroCount[22]));75 ST16 (&pMbCache->iNonZeroCoeffCount[46], LD16 (&pMb->pNonZeroCount[22]));
76}76}
77 77
78void WelsSliceHeaderScalExtInit( SDqLayer* pCurLayer, SSlice *pSlice )78void WelsSliceHeaderScalExtInit (SDqLayer* pCurLayer, SSlice* pSlice) {
79{79 SSliceHeaderExt* pSliceHeadExt = &pSlice->sSliceHeaderExt;
80 SSliceHeaderExt* pSliceHeadExt = &pSlice->sSliceHeaderExt;80 SNalUnitHeaderExt* pNalHeadExt = &pCurLayer->sLayerInfo.sNalHeaderExt;
81 SNalUnitHeaderExt* pNalHeadExt= &pCurLayer->sLayerInfo.sNalHeaderExt;81
82 82 uint8_t uiDependencyId = pNalHeadExt->uiDependencyId;
83 uint8_t uiDependencyId = pNalHeadExt->uiDependencyId;83
84 84 pSliceHeadExt->bSliceSkipFlag = false;
85 pSliceHeadExt->bSliceSkipFlag = false; 85
86 86 if (uiDependencyId > 0) { //spatial EL
87 if ( uiDependencyId > 0 ) //spatial EL87 //bothe adaptive and default flags should equal to 0.
88 {88 pSliceHeadExt->bAdaptiveBaseModeFlag =
89 //bothe adaptive and default flags should equal to 0.89 pSliceHeadExt->bAdaptiveMotionPredFlag =
90 pSliceHeadExt->bAdaptiveBaseModeFlag = 90 pSliceHeadExt->bAdaptiveResidualPredFlag = false;
91 pSliceHeadExt->bAdaptiveMotionPredFlag = 91
92 pSliceHeadExt->bAdaptiveResidualPredFlag = false;92 pSliceHeadExt->bDefaultBaseModeFlag =
93 93 pSliceHeadExt->bDefaultMotionPredFlag =
94 pSliceHeadExt->bDefaultBaseModeFlag = 94 pSliceHeadExt->bDefaultResidualPredFlag = false;
95 pSliceHeadExt->bDefaultMotionPredFlag =95 }
96 pSliceHeadExt->bDefaultResidualPredFlag = false;96}
97 }97
98}98void WelsSliceHeaderExtInit (sWelsEncCtx* pEncCtx, SDqLayer* pCurLayer, SSlice* pSlice) {
99 99 SSliceHeaderExt* pCurSliceExt = &pSlice->sSliceHeaderExt;
100void WelsSliceHeaderExtInit( sWelsEncCtx* pEncCtx, SDqLayer* pCurLayer, SSlice *pSlice )100 SSliceHeader* pCurSliceHeader = &pCurSliceExt->sSliceHeader;
101{101
102 SSliceHeaderExt* pCurSliceExt = &pSlice->sSliceHeaderExt;102 pCurSliceHeader->eSliceType = pEncCtx->eSliceType;
103 SSliceHeader* pCurSliceHeader = &pCurSliceExt->sSliceHeader; 103
104 104 pCurSliceExt->bStoreRefBasePicFlag = false;
105 pCurSliceHeader->eSliceType = pEncCtx->eSliceType;105
106 106 pCurSliceHeader->iFirstMbInSlice = WelsGetFirstMbOfSlice (pCurLayer->pSliceEncCtx, pSlice->uiSliceIdx);
107 pCurSliceExt->bStoreRefBasePicFlag = false; 107
108 108 pCurSliceHeader->iFrameNum = pEncCtx->iFrameNum;
109 pCurSliceHeader->iFirstMbInSlice = WelsGetFirstMbOfSlice( pCurLayer->pSliceEncCtx, pSlice->uiSliceIdx );109 pCurSliceHeader->uiIdrPicId = pEncCtx->sPSOVector.uiIdrPicId; //??
110 110
111 pCurSliceHeader->iFrameNum = pEncCtx->iFrameNum; 111 pCurSliceHeader->iPicOrderCntLsb = pEncCtx->pEncPic->iFramePoc; // 0
112 pCurSliceHeader->uiIdrPicId = pEncCtx->sPSOVector.uiIdrPicId; //??112
113 113 if (P_SLICE == pEncCtx->eSliceType) {
114 pCurSliceHeader->iPicOrderCntLsb = pEncCtx->pEncPic->iFramePoc; // 0114 pCurSliceHeader->uiNumRefIdxL0Active = 1;
115 115 if (pCurSliceHeader->uiRefCount > 0 &&
116 if ( P_SLICE == pEncCtx->eSliceType )116 pCurSliceHeader->uiRefCount < pCurLayer->sLayerInfo.pSpsP->iNumRefFrames) {
117 {117 pCurSliceHeader->bNumRefIdxActiveOverrideFlag = true;
118 pCurSliceHeader->uiNumRefIdxL0Active = 1;118 pCurSliceHeader->uiNumRefIdxL0Active = pCurSliceHeader->uiRefCount;
119 if ( pCurSliceHeader->uiRefCount > 0 && 119 }
120 pCurSliceHeader->uiRefCount < pCurLayer->sLayerInfo.pSpsP->iNumRefFrames )120 //to solve mismatch between debug&release
121 {121 else {
122 pCurSliceHeader->bNumRefIdxActiveOverrideFlag = true;122 pCurSliceHeader->bNumRefIdxActiveOverrideFlag = false;
123 pCurSliceHeader->uiNumRefIdxL0Active = pCurSliceHeader->uiRefCount;123 }
124 }124 }
125 //to solve mismatch between debug&release125
126 else126 pCurSliceHeader->iSliceQpDelta = pEncCtx->iGlobalQp - pCurLayer->sLayerInfo.pPpsP->iPicInitQp;
127 {127
128 pCurSliceHeader->bNumRefIdxActiveOverrideFlag = false;128 //for deblocking initial
129 }129 pCurSliceHeader->uiDisableDeblockingFilterIdc = pCurLayer->iLoopFilterDisableIdc;
130 }130 pCurSliceHeader->iSliceAlphaC0Offset =
131 131 pCurLayer->iLoopFilterAlphaC0Offset; // need update iSliceAlphaC0Offset & iSliceBetaOffset for pSlice-header if loop_filter_idc != 1
132 pCurSliceHeader->iSliceQpDelta = pEncCtx->iGlobalQp - pCurLayer->sLayerInfo.pPpsP->iPicInitQp;132 pCurSliceHeader->iSliceBetaOffset = pCurLayer->iLoopFilterBetaOffset;
133 133 pCurSliceExt->uiDisableInterLayerDeblockingFilterIdc = pCurLayer->uiDisableInterLayerDeblockingFilterIdc;
134 //for deblocking initial134
135 pCurSliceHeader->uiDisableDeblockingFilterIdc = pCurLayer->iLoopFilterDisableIdc;135 if (pSlice->bSliceHeaderExtFlag) {
136 pCurSliceHeader->iSliceAlphaC0Offset = pCurLayer->iLoopFilterAlphaC0Offset; // need update iSliceAlphaC0Offset & iSliceBetaOffset for pSlice-header if loop_filter_idc != 1136 WelsSliceHeaderScalExtInit (pCurLayer, pSlice);
137 pCurSliceHeader->iSliceBetaOffset = pCurLayer->iLoopFilterBetaOffset;137 } else {
138 pCurSliceExt->uiDisableInterLayerDeblockingFilterIdc = pCurLayer->uiDisableInterLayerDeblockingFilterIdc;138 //both adaptive and default flags should equal to 0.
139 139 pCurSliceExt->bAdaptiveBaseModeFlag =
140 if ( pSlice->bSliceHeaderExtFlag )140 pCurSliceExt->bAdaptiveMotionPredFlag =
141 {141 pCurSliceExt->bAdaptiveResidualPredFlag = false;
142 WelsSliceHeaderScalExtInit( pCurLayer, pSlice );142
143 }143 pCurSliceExt->bDefaultBaseModeFlag =
144 else144 pCurSliceExt->bDefaultMotionPredFlag =
145 {145 pCurSliceExt->bDefaultResidualPredFlag = false;
146 //both adaptive and default flags should equal to 0.146 }
147 pCurSliceExt->bAdaptiveBaseModeFlag = 147}
148 pCurSliceExt->bAdaptiveMotionPredFlag = 148
149 pCurSliceExt->bAdaptiveResidualPredFlag = false;149/* count MB types if enabled FRAME_INFO_OUTPUT*/
150 150#if defined(MB_TYPES_CHECK)
151 pCurSliceExt->bDefaultBaseModeFlag = 151void WelsCountMbType (int32_t (*iMbCount)[18], const EWelsSliceType keSt, const SMB* kpMb) {
152 pCurSliceExt->bDefaultMotionPredFlag =152 if (NULL == iMbCount)
153 pCurSliceExt->bDefaultResidualPredFlag = false;153 return;
154 }154
155}155 switch (kpMb->uiMbType) {
156 156 case MB_TYPE_INTRA4x4:
157/* count MB types if enabled FRAME_INFO_OUTPUT*/157 ++ iMbCount[keSt][Intra4x4];
158#if defined(MB_TYPES_CHECK)158 break;
159void WelsCountMbType(int32_t (*iMbCount)[18], const EWelsSliceType keSt, const SMB* kpMb)159 case MB_TYPE_INTRA16x16:
160{ 160 ++ iMbCount[keSt][Intra16x16];
161 if (NULL == iMbCount)161 break;
162 return;162 case MB_TYPE_SKIP:
163 163 ++ iMbCount[keSt][PSkip];
164 switch( kpMb->uiMbType ) {164 break;
165 case MB_TYPE_INTRA4x4:165 case MB_TYPE_16x16:
166 ++ iMbCount[keSt][Intra4x4];166 ++ iMbCount[keSt][Inter16x16];
167 break;167 break;
168 case MB_TYPE_INTRA16x16:168 case MB_TYPE_16x8:
169 ++ iMbCount[keSt][Intra16x16];169 ++ iMbCount[keSt][Inter16x8];
170 break;170 break;
171 case MB_TYPE_SKIP:171 case MB_TYPE_8x16:
172 ++ iMbCount[keSt][PSkip];172 ++ iMbCount[eSt][Inter8x16];
173 break;173 break;
174 case MB_TYPE_16x16:174 case MB_TYPE_8x8:
175 ++ iMbCount[keSt][Inter16x16];175 ++ iMbCount[keSt][Inter8x8];
176 break;176 break;
177 case MB_TYPE_16x8:177 case MB_TYPE_INTRA_BL:
178 ++ iMbCount[keSt][Inter16x8];178 ++ iMbCount[keSt][7];
179 break;179 break;
180 case MB_TYPE_8x16:180 default:
181 ++ iMbCount[eSt][Inter8x16];181 break;
182 break;182 }
183 case MB_TYPE_8x8:183}
184 ++ iMbCount[keSt][Inter8x8];184#endif//MB_TYPES_CHECK
185 break;185
186 case MB_TYPE_INTRA_BL:186/*!
187 ++ iMbCount[keSt][7];187* \brief write reference picture list on reordering syntax in Slice header
188 break;188*/
189 default:189void WriteReferenceReorder (SBitStringAux* pBs, SSliceHeader* sSliceHeader) {
190 break;190 SRefPicListReorderSyntax* pRefOrdering = &sSliceHeader->sRefReordering;
191 }191 uint8_t eSliceType = sSliceHeader->eSliceType % 5;
192}192 int16_t n = 0;
193#endif//MB_TYPES_CHECK193
194 194 if (I_SLICE != eSliceType && SI_SLICE != eSliceType) { // !I && !SI
195/*!195 BsWriteOneBit (pBs, true);
196* \brief write reference picture list on reordering syntax in Slice header 196// {
197*/197 uint16_t uiReorderingOfPicNumsIdc;
198void WriteReferenceReorder( SBitStringAux *pBs, SSliceHeader *sSliceHeader )198 do {
199{199 uiReorderingOfPicNumsIdc = pRefOrdering->SReorderingSyntax[n].uiReorderingOfPicNumsIdc;
200 SRefPicListReorderSyntax *pRefOrdering = &sSliceHeader->sRefReordering;200 BsWriteUE (pBs, uiReorderingOfPicNumsIdc);
201 uint8_t eSliceType = sSliceHeader->eSliceType % 5;201 if (0 == uiReorderingOfPicNumsIdc || 1 == uiReorderingOfPicNumsIdc)
202 int16_t n = 0;202 BsWriteUE (pBs, pRefOrdering->SReorderingSyntax[n].uiAbsDiffPicNumMinus1);
203 203 else if (2 == uiReorderingOfPicNumsIdc)
204 if ( I_SLICE != eSliceType && SI_SLICE != eSliceType ) // !I && !SI204 BsWriteUE (pBs, pRefOrdering->SReorderingSyntax[n].iLongTermPicNum);
205 {205
206 BsWriteOneBit( pBs, true );206 n ++;
207// {207 } while (3 != uiReorderingOfPicNumsIdc);
208 uint16_t uiReorderingOfPicNumsIdc;208// }
209 do 209 }
210 {210}
211 uiReorderingOfPicNumsIdc = pRefOrdering->SReorderingSyntax[n].uiReorderingOfPicNumsIdc; 211
212 BsWriteUE( pBs, uiReorderingOfPicNumsIdc );212/*!
213 if ( 0 == uiReorderingOfPicNumsIdc || 1 == uiReorderingOfPicNumsIdc )213* \brief write reference picture marking syntax in pSlice header
214 BsWriteUE( pBs, pRefOrdering->SReorderingSyntax[n].uiAbsDiffPicNumMinus1 );214*/
215 else if ( 2 == uiReorderingOfPicNumsIdc )215void WriteRefPicMarking (SBitStringAux* pBs, SSliceHeader* pSliceHeader, SNalUnitHeaderExt* pNalHdrExt) {
216 BsWriteUE( pBs, pRefOrdering->SReorderingSyntax[n].iLongTermPicNum );216 SRefPicMarking* sRefMarking = &pSliceHeader->sRefMarking;
217 217 int16_t n = 0;
218 n ++;218
219 } while ( 3 != uiReorderingOfPicNumsIdc );219 if (pNalHdrExt->bIdrFlag) {
220// }220 BsWriteOneBit (pBs, sRefMarking->bNoOutputOfPriorPicsFlag);
221 }221 BsWriteOneBit (pBs, sRefMarking->bLongTermRefFlag);
222}222 } else {
223 223 BsWriteOneBit (pBs, sRefMarking->bAdaptiveRefPicMarkingModeFlag);
224/*!224
225* \brief write reference picture marking syntax in pSlice header 225 if (sRefMarking->bAdaptiveRefPicMarkingModeFlag) {
226*/226 int32_t iMmcoType;
227void WriteRefPicMarking( SBitStringAux *pBs, SSliceHeader *pSliceHeader, SNalUnitHeaderExt *pNalHdrExt )227 do {
228{228 iMmcoType = sRefMarking->SMmcoRef[n].iMmcoType;
229 SRefPicMarking *sRefMarking = &pSliceHeader->sRefMarking;229 BsWriteUE (pBs, iMmcoType);
230 int16_t n = 0; 230 if (1 == iMmcoType || 3 == iMmcoType)
231 231 BsWriteUE (pBs, sRefMarking->SMmcoRef[n].iDiffOfPicNum - 1);
232 if ( pNalHdrExt->bIdrFlag )232
233 {233 if (2 == iMmcoType)
234 BsWriteOneBit( pBs, sRefMarking->bNoOutputOfPriorPicsFlag );234 BsWriteUE (pBs, sRefMarking->SMmcoRef[n].iLongTermPicNum);
235 BsWriteOneBit( pBs, sRefMarking->bLongTermRefFlag );235
236 }236 if (3 == iMmcoType || 6 == iMmcoType)
237 else 237 BsWriteUE (pBs, sRefMarking->SMmcoRef[n].iLongTermFrameIdx);
238 {238
239 BsWriteOneBit( pBs, sRefMarking->bAdaptiveRefPicMarkingModeFlag );239 if (4 == iMmcoType)
240 240 BsWriteUE (pBs, sRefMarking->SMmcoRef[n].iMaxLongTermFrameIdx + 1);
241 if ( sRefMarking->bAdaptiveRefPicMarkingModeFlag )241
242 {242 n ++;
243 int32_t iMmcoType;243 } while (0 != iMmcoType);
244 do 244 }
245 {245
246 iMmcoType = sRefMarking->SMmcoRef[n].iMmcoType;246 }
247 BsWriteUE( pBs, iMmcoType );247}
248 if ( 1 == iMmcoType || 3 == iMmcoType )248
249 BsWriteUE( pBs, sRefMarking->SMmcoRef[n].iDiffOfPicNum - 1 );249void WelsSliceHeaderWrite (SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice, int32_t* pPpsIdDelta) {
250 250 SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;
251 if ( 2 == iMmcoType )251 SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;
252 BsWriteUE( pBs, sRefMarking->SMmcoRef[n].iLongTermPicNum );252 SSliceHeader* pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
253 253 SNalUnitHeaderExt* pNalHead = &pCurLayer->sLayerInfo.sNalHeaderExt;
254 if ( 3 == iMmcoType || 6 == iMmcoType )254
255 BsWriteUE( pBs, sRefMarking->SMmcoRef[n].iLongTermFrameIdx );255 BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);
256 256 BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */
257 if ( 4 == iMmcoType )257
258 BsWriteUE( pBs, sRefMarking->SMmcoRef[n].iMaxLongTermFrameIdx + 1 );258 BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + pPpsIdDelta[pSliceHeader->pPps->iPpsId]);
259 259
260 n ++;260 BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);
261 } while ( 0 != iMmcoType );261
262 }262 if (pNalHead->bIdrFlag) { /* NAL IDR */
263 263 BsWriteUE (pBs, pSliceHeader->uiIdrPicId);
264 }264 }
265}265
266 266 BsWriteBits (pBs, pSps->iLog2MaxPocLsb, pSliceHeader->iPicOrderCntLsb);
267void WelsSliceHeaderWrite( SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice *pSlice, int32_t* pPpsIdDelta )267
268{268 if (P_SLICE == pSliceHeader->eSliceType) {
269 SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;269 BsWriteOneBit (pBs, pSliceHeader->bNumRefIdxActiveOverrideFlag);
270 SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;270 if (pSliceHeader->bNumRefIdxActiveOverrideFlag) {
271 SSliceHeader* pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; 271 BsWriteUE (pBs, pSliceHeader->uiNumRefIdxL0Active - 1);
272 SNalUnitHeaderExt* pNalHead = &pCurLayer->sLayerInfo.sNalHeaderExt; 272 }
273 273 }
274 BsWriteUE( pBs, pSliceHeader->iFirstMbInSlice );274
275 BsWriteUE( pBs, pSliceHeader->eSliceType ); /* same type things */275 if (!pNalHead->bIdrFlag)
276 276 WriteReferenceReorder (pBs, pSliceHeader);
277 BsWriteUE( pBs, pSliceHeader->pPps->iPpsId + pPpsIdDelta[pSliceHeader->pPps->iPpsId] );277
278 278 if (pNalHead->sNalHeader.uiNalRefIdc) {
279 BsWriteBits( pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum );279 WriteRefPicMarking (pBs, pSliceHeader, pNalHead);
280 280 }
281 if( pNalHead->bIdrFlag ) /* NAL IDR */281
282 {282 BsWriteSE (pBs, pSliceHeader->iSliceQpDelta); /* pSlice qp delta */
283 BsWriteUE( pBs, pSliceHeader->uiIdrPicId );283
284 }284 if (pPps->bDeblockingFilterControlPresentFlag) {
285 285 switch (pSliceHeader->uiDisableDeblockingFilterIdc) {
286 BsWriteBits( pBs, pSps->iLog2MaxPocLsb, pSliceHeader->iPicOrderCntLsb );286 case 0:
287 287 case 3:
288 if ( P_SLICE == pSliceHeader->eSliceType )288 case 4:
289 {289 case 6:
290 BsWriteOneBit( pBs, pSliceHeader->bNumRefIdxActiveOverrideFlag );290 BsWriteUE (pBs, 0);
291 if ( pSliceHeader->bNumRefIdxActiveOverrideFlag )291 break;
292 {292 case 1:
293 BsWriteUE( pBs, pSliceHeader->uiNumRefIdxL0Active - 1 );293 BsWriteUE (pBs, 1);
294 }294 break;
295 }295 case 2:
296 296 case 5:
297 if ( !pNalHead->bIdrFlag )297 BsWriteUE (pBs, 2);
298 WriteReferenceReorder( pBs, pSliceHeader );298 break;
299 299 default :
300 if ( pNalHead->sNalHeader.uiNalRefIdc )300 fprintf (stderr, "pData error for deblocking");
301 {301 break;
302 WriteRefPicMarking( pBs, pSliceHeader, pNalHead );302 }
303 } 303 if (1 != pSliceHeader->uiDisableDeblockingFilterIdc) {
304 304 BsWriteSE (pBs, pSliceHeader->iSliceAlphaC0Offset >> 1);
305 BsWriteSE( pBs, pSliceHeader->iSliceQpDelta ); /* pSlice qp delta */305 BsWriteSE (pBs, pSliceHeader->iSliceBetaOffset >> 1);
306 306 }
307 if( pPps->bDeblockingFilterControlPresentFlag )307 }
308 {308}
309 switch( pSliceHeader->uiDisableDeblockingFilterIdc )309
310 {310void WelsSliceHeaderExtWrite (SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice, int32_t* pPpsIdDelta) {
311 case 0:311 SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;
312 case 3:312 SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;
313 case 4:313 SSubsetSps* pSubSps = pCurLayer->sLayerInfo.pSubsetSpsP;
314 case 6:314 SSliceHeaderExt* pSliceHeadExt = &pSlice->sSliceHeaderExt;
315 BsWriteUE( pBs, 0 );315 SSliceHeader* pSliceHeader = &pSliceHeadExt->sSliceHeader;
316 break;316 SNalUnitHeaderExt* pNalHead = &pCurLayer->sLayerInfo.sNalHeaderExt;
317 case 1:317
318 BsWriteUE( pBs, 1 );318 BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);
319 break;319 BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */
320 case 2:320
321 case 5:321 BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + pPpsIdDelta[pSliceHeader->pPps->iPpsId]);
322 BsWriteUE( pBs, 2 );322
323 break;323 BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);
324 default :324
325 fprintf( stderr, "pData error for deblocking" );325 if (pNalHead->bIdrFlag) { /* NAL IDR */
326 break;326 BsWriteUE (pBs, pSliceHeader->uiIdrPicId);
327 }327 }
328 if ( 1 != pSliceHeader->uiDisableDeblockingFilterIdc )328
329 {329 BsWriteBits (pBs, pSps->iLog2MaxPocLsb, pSliceHeader->iPicOrderCntLsb);
330 BsWriteSE( pBs, pSliceHeader->iSliceAlphaC0Offset >> 1 );330// {
331 BsWriteSE( pBs, pSliceHeader->iSliceBetaOffset >> 1 );331 if (P_SLICE == pSliceHeader->eSliceType) {
332 }332 BsWriteOneBit (pBs, pSliceHeader->bNumRefIdxActiveOverrideFlag);
333 } 333 if (pSliceHeader->bNumRefIdxActiveOverrideFlag) {
334}334 BsWriteUE (pBs, pSliceHeader->uiNumRefIdxL0Active - 1);
335 335 }
336void WelsSliceHeaderExtWrite( SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice *pSlice, int32_t *pPpsIdDelta )336 }
337{337
338 SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP; 338 if (!pNalHead->bIdrFlag)
339 SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;339 WriteReferenceReorder (pBs, pSliceHeader);
340 SSubsetSps* pSubSps = pCurLayer->sLayerInfo.pSubsetSpsP;340
341 SSliceHeaderExt* pSliceHeadExt = &pSlice->sSliceHeaderExt;341 if (pNalHead->sNalHeader.uiNalRefIdc) {
342 SSliceHeader* pSliceHeader = &pSliceHeadExt->sSliceHeader;342 WriteRefPicMarking (pBs, pSliceHeader, pNalHead);
343 SNalUnitHeaderExt* pNalHead = &pCurLayer->sLayerInfo.sNalHeaderExt;343
344 344 if (!pSubSps->sSpsSvcExt.bSliceHeaderRestrictionFlag) {
345 BsWriteUE( pBs, pSliceHeader->iFirstMbInSlice );345 BsWriteOneBit (pBs, pSliceHeadExt->bStoreRefBasePicFlag);
346 BsWriteUE( pBs, pSliceHeader->eSliceType ); /* same type things */346 }
347 347 }
348 BsWriteUE( pBs, pSliceHeader->pPps->iPpsId + pPpsIdDelta[pSliceHeader->pPps->iPpsId] );348// }
349 349
350 BsWriteBits( pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum );350 BsWriteSE (pBs, pSliceHeader->iSliceQpDelta); /* pSlice qp delta */
351 351
352 if( pNalHead->bIdrFlag ) /* NAL IDR */352 if (pPps->bDeblockingFilterControlPresentFlag) {
353 {353 BsWriteUE (pBs, pSliceHeader->uiDisableDeblockingFilterIdc);
354 BsWriteUE( pBs, pSliceHeader->uiIdrPicId );354 if (1 != pSliceHeader->uiDisableDeblockingFilterIdc) {
355 }355 BsWriteSE (pBs, pSliceHeader->iSliceAlphaC0Offset >> 1);
356 356 BsWriteSE (pBs, pSliceHeader->iSliceBetaOffset >> 1);
357 BsWriteBits( pBs, pSps->iLog2MaxPocLsb, pSliceHeader->iPicOrderCntLsb );357 }
358// {358 }
359 if ( P_SLICE == pSliceHeader->eSliceType )359
360 {360#if !defined(DISABLE_FMO_FEATURE)
361 BsWriteOneBit( pBs, pSliceHeader->bNumRefIdxActiveOverrideFlag );361 if (pPps->uiNumSliceGroups > 1 &&
362 if ( pSliceHeader->bNumRefIdxActiveOverrideFlag )362 pPps->uiSliceGroupMapType >= 3 &&
363 {363 pPps->uiSliceGroupMapType <= 5) {
364 BsWriteUE( pBs, pSliceHeader->uiNumRefIdxL0Active - 1 );364 int32_t iNumBits;
365 }365 if (pPps->uiSliceGroupChangeRate) {
366 }366 iNumBits = WELS_CEILLOG2 (1 + pPps->uiPicSizeInMapUnits / pPps->uiSliceGroupChangeRate);
367 367 BsWriteBits (pBs, iNumBits, pSliceHeader->iSliceGroupChangeCycle);
368 if ( !pNalHead->bIdrFlag )368 }
369 WriteReferenceReorder( pBs, pSliceHeader );369 }
370 370#endif//!DISABLE_FMO_FEATURE
371 if ( pNalHead->sNalHeader.uiNalRefIdc )371
372 {372 if (false) {
373 WriteRefPicMarking( pBs, pSliceHeader, pNalHead );373 BsWriteOneBit (pBs, pSliceHeadExt->bSliceSkipFlag);
374 374 if (pSliceHeadExt->bSliceSkipFlag) {
375 if ( !pSubSps->sSpsSvcExt.bSliceHeaderRestrictionFlag )375 BsWriteUE (pBs, pSliceHeadExt->uiNumMbsInSlice - 1);
376 {376 } else {
377 BsWriteOneBit( pBs, pSliceHeadExt->bStoreRefBasePicFlag );377 BsWriteOneBit (pBs, pSliceHeadExt->bAdaptiveBaseModeFlag);
378 }378 if (!pSliceHeadExt->bAdaptiveBaseModeFlag) {
379 }379 BsWriteOneBit (pBs, pSliceHeadExt->bDefaultBaseModeFlag);
380// }380 }
381 381
382 BsWriteSE( pBs, pSliceHeader->iSliceQpDelta ); /* pSlice qp delta */382 if (!pSliceHeadExt->bDefaultBaseModeFlag) {
383 383 BsWriteOneBit (pBs, 0);
384 if( pPps->bDeblockingFilterControlPresentFlag )384 BsWriteOneBit (pBs, 0);
385 {385 }
386 BsWriteUE( pBs, pSliceHeader->uiDisableDeblockingFilterIdc );386
387 if ( 1 != pSliceHeader->uiDisableDeblockingFilterIdc )387 BsWriteOneBit (pBs, pSliceHeadExt->bAdaptiveResidualPredFlag);
388 {388 if (!pSliceHeadExt->bAdaptiveResidualPredFlag) {
389 BsWriteSE( pBs, pSliceHeader->iSliceAlphaC0Offset >> 1 );389 BsWriteOneBit (pBs, 0);
390 BsWriteSE( pBs, pSliceHeader->iSliceBetaOffset >> 1 );390 }
391 }391 }
392 } 392 if (1 == pSubSps->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag) {
393 393 BsWriteOneBit (pBs, pSliceHeadExt->bTcoeffLevelPredFlag);
394#if !defined(DISABLE_FMO_FEATURE)394 }
395 if ( pPps->uiNumSliceGroups > 1 &&395
396 pPps->uiSliceGroupMapType >= 3 && 396 }
397 pPps->uiSliceGroupMapType <= 5 )397
398 {398 if (!pSubSps->sSpsSvcExt.bSliceHeaderRestrictionFlag) {
399 int32_t iNumBits;399 BsWriteBits (pBs, 4, 0);
400 if ( pPps->uiSliceGroupChangeRate )400 BsWriteBits (pBs, 4, 15);
401 {401 }
402 iNumBits = WELS_CEILLOG2(1 + pPps->uiPicSizeInMapUnits / pPps->uiSliceGroupChangeRate);402}
403 BsWriteBits( pBs, iNumBits, pSliceHeader->iSliceGroupChangeCycle ); 403
404 }404//only BaseLayer inter MB and SpatialLayer (uiQualityId = 0) inter MB calling this pFunc.
405 }405//only for inter part
406#endif//!DISABLE_FMO_FEATURE406void WelsInterMbEncode (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb) {
407 407 SMbCache* pMbCache = &pSlice->sMbCacheInfo;
408 if ( false )408
409 {409 WelsDctMb (pMbCache->pCoeffLevel, pMbCache->SPicData.pEncMb[0], pEncCtx->pCurDqLayer->iEncStride[0],
410 BsWriteOneBit( pBs, pSliceHeadExt->bSliceSkipFlag );410 pMbCache->pMemPredLuma, pEncCtx->pFuncList->pfDctFourT4);
411 if ( pSliceHeadExt->bSliceSkipFlag )411 WelsEncInterY (pEncCtx->pFuncList, pCurMb, pMbCache);
412 {412}
413 BsWriteUE( pBs, pSliceHeadExt->uiNumMbsInSlice - 1 );413
414 }414
415 else415//only BaseLayer inter MB and SpatialLayer (uiQualityId = 0) inter MB calling this pFunc.
416 {416//only for I SSlice
417 BsWriteOneBit( pBs, pSliceHeadExt->bAdaptiveBaseModeFlag );417void WelsIMbChromaEncode (sWelsEncCtx* pEncCtx, SMB* pCurMb, SMbCache* pMbCache) {
418 if ( !pSliceHeadExt->bAdaptiveBaseModeFlag ) 418 SWelsFuncPtrList* pFunc = pEncCtx->pFuncList;
419 {419 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
420 BsWriteOneBit( pBs, pSliceHeadExt->bDefaultBaseModeFlag );420 const int32_t kiEncStride = pCurLayer->iEncStride[1];
421 }421 const int32_t kiCsStride = pCurLayer->iCsStride[1];
422 422 int16_t* pCurRS = pMbCache->pCoeffLevel;
423 if ( !pSliceHeadExt->bDefaultBaseModeFlag )423 uint8_t* pBestPred = pMbCache->pBestPredIntraChroma;
424 {424 uint8_t* pCsCb = pMbCache->SPicData.pCsMb[1];
425 BsWriteOneBit( pBs, 0 );425 uint8_t* pCsCr = pMbCache->SPicData.pCsMb[2];
426 BsWriteOneBit( pBs, 0 );426
427 }427 //cb
428 428 pFunc->pfDctFourT4 (pCurRS, pMbCache->SPicData.pEncMb[1], kiEncStride, pBestPred, 8);
429 BsWriteOneBit( pBs, pSliceHeadExt->bAdaptiveResidualPredFlag );429 WelsEncRecUV (pFunc, pCurMb, pMbCache, pCurRS, 1);
430 if ( !pSliceHeadExt->bAdaptiveResidualPredFlag )430 pFunc->pfIDctFourT4 (pCsCb, kiCsStride, pBestPred, 8, pCurRS);
431 {431
432 BsWriteOneBit( pBs, 0);432 //cr
433 }433 pFunc->pfDctFourT4 (pCurRS + 64, pMbCache->SPicData.pEncMb[2], kiEncStride, pBestPred + 64, 8);
434 }434 WelsEncRecUV (pFunc, pCurMb, pMbCache, pCurRS + 64, 2);
435 if ( 1 == pSubSps->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag )435 pFunc->pfIDctFourT4 (pCsCr, kiCsStride, pBestPred + 64, 8, pCurRS + 64);
436 {436}
437 BsWriteOneBit( pBs, pSliceHeadExt->bTcoeffLevelPredFlag );437
438 }438
439 439//only BaseLayer inter MB and SpatialLayer (uiQualityId = 0) inter MB calling this pFunc.
440 }440//for P SSlice (intra part + inter part)
441 441void WelsPMbChromaEncode (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb) {
442 if ( !pSubSps->sSpsSvcExt.bSliceHeaderRestrictionFlag )442 SWelsFuncPtrList* pFunc = pEncCtx->pFuncList;
443 {443 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
444 BsWriteBits( pBs, 4, 0 );444 const int32_t kiEncStride = pCurLayer->iEncStride[1];
445 BsWriteBits( pBs, 4, 15 );445 SMbCache* pMbCache = &pSlice->sMbCacheInfo;
446 }446 int16_t* pCurRS = pMbCache->pCoeffLevel + 256;
447}447 uint8_t* pBestPred = pMbCache->pMemPredChroma;
448 448
449//only BaseLayer inter MB and SpatialLayer (uiQualityId = 0) inter MB calling this pFunc.449 pFunc->pfDctFourT4 (pCurRS, pMbCache->SPicData.pEncMb[1], kiEncStride, pBestPred, 8);
450//only for inter part450 pFunc->pfDctFourT4 (pCurRS + 64, pMbCache->SPicData.pEncMb[2], kiEncStride, pBestPred + 64, 8);
451void WelsInterMbEncode( sWelsEncCtx* pEncCtx, SSlice *pSlice, SMB* pCurMb )451
452{452 WelsEncRecUV (pFunc, pCurMb, pMbCache, pCurRS, 1);
453 SMbCache* pMbCache = &pSlice->sMbCacheInfo;453 WelsEncRecUV (pFunc, pCurMb, pMbCache, pCurRS + 64, 2);
454 454}
455 WelsDctMb(pMbCache->pCoeffLevel, pMbCache->SPicData.pEncMb[0], pEncCtx->pCurDqLayer->iEncStride[0], pMbCache->pMemPredLuma, pEncCtx->pFuncList->pfDctFourT4 );455
456 WelsEncInterY( pEncCtx->pFuncList, pCurMb, pMbCache );456void OutputPMbWithoutConstructCsRsNoCopy (sWelsEncCtx* pCtx, SDqLayer* pDq, SSlice* pSlice, SMB* pMb) {
457}457 if (IS_INTER (pMb->uiMbType) || IS_I_BL (pMb->uiMbType)) { //intra have been reconstructed, NO COPY from CS to pDecPic--
458 458 SMbCache* pMbCache = &pSlice->sMbCacheInfo;
459 459 uint8_t* pDecY = pMbCache->SPicData.pDecMb[0];
460//only BaseLayer inter MB and SpatialLayer (uiQualityId = 0) inter MB calling this pFunc.460 uint8_t* pDecU = pMbCache->SPicData.pDecMb[1];
461//only for I SSlice461 uint8_t* pDecV = pMbCache->SPicData.pDecMb[2];
462void WelsIMbChromaEncode( sWelsEncCtx* pEncCtx, SMB* pCurMb, SMbCache *pMbCache )462 int16_t* pScaledTcoeff = pMbCache->pCoeffLevel;
463{463 const int32_t kiDecStrideLuma = pDq->pDecPic->iLineSize[0];
464 SWelsFuncPtrList *pFunc = pEncCtx->pFuncList;464 const int32_t kiDecStrideChroma = pDq->pDecPic->iLineSize[1];
465 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer; 465 PIDctFunc pfIdctFour4x4 = pCtx->pFuncList->pfIDctFourT4;
466 const int32_t kiEncStride = pCurLayer->iEncStride[1];466
467 const int32_t kiCsStride = pCurLayer->iCsStride[1];467 WelsIDctT4RecOnMb (pDecY, kiDecStrideLuma, pDecY, kiDecStrideLuma, pScaledTcoeff, pfIdctFour4x4);
468 int16_t *pCurRS = pMbCache->pCoeffLevel;468 pfIdctFour4x4 (pDecU, kiDecStrideChroma, pDecU, kiDecStrideChroma, pScaledTcoeff + 256);
469 uint8_t* pBestPred = pMbCache->pBestPredIntraChroma;469 pfIdctFour4x4 (pDecV, kiDecStrideChroma, pDecV, kiDecStrideChroma, pScaledTcoeff + 320);
470 uint8_t* pCsCb = pMbCache->SPicData.pCsMb[1];470 }
471 uint8_t* pCsCr = pMbCache->SPicData.pCsMb[2];471}
472 472
473 //cb473// for intra non-dynamic pSlice
474 pFunc->pfDctFourT4( pCurRS, pMbCache->SPicData.pEncMb[1], kiEncStride, pBestPred, 8);474//encapsulate two kinds of reconstruction:
475 WelsEncRecUV( pFunc, pCurMb, pMbCache, pCurRS, 1 );475//first. store base or highest Dependency Layer with only one quality (without CS RS reconstruction)
476 pFunc->pfIDctFourT4( pCsCb, kiCsStride, pBestPred, 8, pCurRS );476//second. lower than highest Dependency Layer, and for every Dependency Layer with one quality layer(single layer)
477 477void WelsISliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + encoding
478 //cr478 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
479 pFunc->pfDctFourT4( pCurRS+64, pMbCache->SPicData.pEncMb[2], kiEncStride, pBestPred+64, 8);479 SSliceCtx* pSliceCtx = pCurLayer->pSliceEncCtx;
480 WelsEncRecUV( pFunc, pCurMb, pMbCache, pCurRS+64, 2 );480 SMbCache* pMbCache = &pSlice->sMbCacheInfo;
481 pFunc->pfIDctFourT4( pCsCr, kiCsStride, pBestPred+64, 8, pCurRS+64 );481 SSliceHeaderExt* pSliceHdExt = &pSlice->sSliceHeaderExt;
482}482 SMB* pMbList = pCurLayer->sMbDataP;
483 483 SMB* pCurMb = NULL;
484 484 const int32_t kiSliceFirstMbXY = pSliceHdExt->sSliceHeader.iFirstMbInSlice;
485//only BaseLayer inter MB and SpatialLayer (uiQualityId = 0) inter MB calling this pFunc.485 int32_t iNextMbIdx = kiSliceFirstMbXY;
486//for P SSlice (intra part + inter part)486 const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight;
487void WelsPMbChromaEncode( sWelsEncCtx* pEncCtx, SSlice *pSlice, SMB* pCurMb )487 int32_t iCurMbIdx = 0, iNumMbCoded = 0;
488{488 const int32_t kiSliceIdx = pSlice->uiSliceIdx;
489 SWelsFuncPtrList *pFunc = pEncCtx->pFuncList; 489 const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
490 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer; 490 SWelsMD sMd;
491 const int32_t kiEncStride = pCurLayer->iEncStride[1];491
492 SMbCache* pMbCache = &pSlice->sMbCacheInfo;492 for (; ;) {
493 int16_t *pCurRS = pMbCache->pCoeffLevel+256;493 iCurMbIdx = iNextMbIdx;
494 uint8_t* pBestPred = pMbCache->pMemPredChroma; 494 pCurMb = &pMbList[ iCurMbIdx ];
495 495 pCurMb->uiLumaQp = pEncCtx->iGlobalQp;
496 pFunc->pfDctFourT4(pCurRS, pMbCache->SPicData.pEncMb[1], kiEncStride, pBestPred, 8); 496 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];
497 pFunc->pfDctFourT4(pCurRS+64, pMbCache->SPicData.pEncMb[2], kiEncStride, pBestPred+64, 8); 497
498 498 pEncCtx->pFuncList->pfRc.pfWelsRcMbInit (pEncCtx, pCurMb, pSlice);
499 WelsEncRecUV(pFunc, pCurMb, pMbCache, pCurRS, 1);499
500 WelsEncRecUV(pFunc, pCurMb, pMbCache, pCurRS+64, 2);500 sMd.iLambda = g_kiQpCostTable[pCurMb->uiLumaQp];
501}501
502 502 WelsMdIntraInit (pEncCtx, pCurMb, pMbCache, kiSliceFirstMbXY);
503void OutputPMbWithoutConstructCsRsNoCopy( sWelsEncCtx *pCtx, SDqLayer* pDq, SSlice *pSlice, SMB* pMb )503 WelsMdIntraMb (pEncCtx, &sMd, pCurMb, pMbCache);
504{ 504 UpdateNonZeroCountCache (pCurMb, pMbCache);
505 if ( IS_INTER( pMb->uiMbType ) || IS_I_BL(pMb->uiMbType) ) //intra have been reconstructed, NO COPY from CS to pDecPic--505
506 {506 WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
507 SMbCache* pMbCache = &pSlice->sMbCacheInfo;507
508 uint8_t* pDecY = pMbCache->SPicData.pDecMb[0];508 pCurMb->uiSliceIdc = kiSliceIdx;
509 uint8_t* pDecU = pMbCache->SPicData.pDecMb[1];509
510 uint8_t* pDecV = pMbCache->SPicData.pDecMb[2];510#if defined(MB_TYPES_CHECK)
511 int16_t *pScaledTcoeff = pMbCache->pCoeffLevel;511 WelsCountMbType (pEncCtx->sPerInfo.iMbCount, I_SLICE, pCurMb);
512 const int32_t kiDecStrideLuma = pDq->pDecPic->iLineSize[0];512#endif//MB_TYPES_CHECK
513 const int32_t kiDecStrideChroma = pDq->pDecPic->iLineSize[1];513
514 PIDctFunc pfIdctFour4x4 = pCtx->pFuncList->pfIDctFourT4;514 pEncCtx->pFuncList->pfRc.pfWelsRcMbInfoUpdate (pEncCtx, pCurMb, sMd.iCostLuma, pSlice);
515 515
516 WelsIDctT4RecOnMb( pDecY, kiDecStrideLuma, pDecY, kiDecStrideLuma, pScaledTcoeff, pfIdctFour4x4 );516 ++iNumMbCoded;
517 pfIdctFour4x4( pDecU, kiDecStrideChroma, pDecU, kiDecStrideChroma, pScaledTcoeff + 256 );517
518 pfIdctFour4x4( pDecV, kiDecStrideChroma, pDecV, kiDecStrideChroma, pScaledTcoeff + 320 );518 iNextMbIdx = WelsGetNextMbOfSlice (pSliceCtx, iCurMbIdx);
519 }519 if (iNextMbIdx == -1 || iNextMbIdx >= kiTotalNumMb || iNumMbCoded >= kiTotalNumMb) {
520}520 break;
521 521 }
522// for intra non-dynamic pSlice522 }
523//encapsulate two kinds of reconstruction:523}
524//first. store base or highest Dependency Layer with only one quality (without CS RS reconstruction)524
525//second. lower than highest Dependency Layer, and for every Dependency Layer with one quality layer(single layer) 525// Only for intra dynamic slicing
526void WelsISliceMdEnc( sWelsEncCtx* pEncCtx, SSlice *pSlice ) //pMd + encoding526void WelsISliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + encoding
527{527 SBitStringAux* pBs = pSlice->pSliceBsa;
528 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;528 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
529 SSliceCtx* pSliceCtx = pCurLayer->pSliceEncCtx;529 SSliceCtx* pSliceCtx = pCurLayer->pSliceEncCtx;
530 SMbCache *pMbCache = &pSlice->sMbCacheInfo;530 SMbCache* pMbCache = &pSlice->sMbCacheInfo;
531 SSliceHeaderExt *pSliceHdExt = &pSlice->sSliceHeaderExt;531 SSliceHeaderExt* pSliceHdExt = &pSlice->sSliceHeaderExt;
532 SMB* pMbList = pCurLayer->sMbDataP;532 SMB* pMbList = pCurLayer->sMbDataP;
533 SMB* pCurMb = NULL; 533 SMB* pCurMb = NULL;
534 const int32_t kiSliceFirstMbXY = pSliceHdExt->sSliceHeader.iFirstMbInSlice;534 const int32_t kiSliceFirstMbXY = pSliceHdExt->sSliceHeader.iFirstMbInSlice;
535 int32_t iNextMbIdx = kiSliceFirstMbXY; 535 int32_t iNextMbIdx = kiSliceFirstMbXY;
536 const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight;536 const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight;
537 int32_t iCurMbIdx = 0, iNumMbCoded = 0; 537 int32_t iCurMbIdx = 0, iNumMbCoded = 0;
538 const int32_t kiSliceIdx = pSlice->uiSliceIdx;538 const int32_t kiSliceIdx = pSlice->uiSliceIdx;
539 const uint8_t kuiChromaQpIndexOffset= pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;539 const int32_t kiPartitionId = (kiSliceIdx % pEncCtx->iActiveThreadsNum);
540 SWelsMD sMd; 540 const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
541 541
542 for ( ; ; )542 SWelsMD sMd;
543 {543 SDynamicSlicingStack sDss;
544 iCurMbIdx = iNextMbIdx;544 sDss.iStartPos = BsGetBitsPos (pBs);
545 pCurMb = &pMbList[ iCurMbIdx ]; 545
546 pCurMb->uiLumaQp = pEncCtx->iGlobalQp;546 for (; ;) {
547 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51(pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];547 iCurMbIdx = iNextMbIdx;
548 548 pCurMb = &pMbList[ iCurMbIdx ];
549 pEncCtx->pFuncList->pfRc.pfWelsRcMbInit(pEncCtx, pCurMb, pSlice); 549 pCurMb->uiLumaQp = pEncCtx->iGlobalQp;
550 550 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];
551 sMd.iLambda = g_kiQpCostTable[pCurMb->uiLumaQp];551
552 552 pEncCtx->pFuncList->pfRc.pfWelsRcMbInit (pEncCtx, pCurMb, pSlice);
553 WelsMdIntraInit( pEncCtx, pCurMb, pMbCache, kiSliceFirstMbXY );553 // if already reaches the largest number of slices, set QPs to the upper bound
554 WelsMdIntraMb( pEncCtx, &sMd, pCurMb, pMbCache );554 if (pSlice->bDynamicSlicingSliceSizeCtrlFlag) {
555 UpdateNonZeroCountCache( pCurMb, pMbCache );555 pCurMb->uiLumaQp = pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId].iMaxQp;
556 556 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];
557 WelsSpatialWriteMbSyn( pEncCtx, pSlice, pCurMb );557 }
558 558
559 pCurMb->uiSliceIdc = kiSliceIdx;559 sMd.iLambda = g_kiQpCostTable[pCurMb->uiLumaQp];
560 560
561 #if defined(MB_TYPES_CHECK) 561 WelsMdIntraInit (pEncCtx, pCurMb, pMbCache, kiSliceFirstMbXY);
562 WelsCountMbType( pEncCtx->sPerInfo.iMbCount, I_SLICE, pCurMb ); 562 WelsMdIntraMb (pEncCtx, &sMd, pCurMb, pMbCache);
563 #endif//MB_TYPES_CHECK563 UpdateNonZeroCountCache (pCurMb, pMbCache);
564 564 //stack pBs pointer
565 pEncCtx->pFuncList->pfRc.pfWelsRcMbInfoUpdate(pEncCtx,pCurMb,sMd.iCostLuma,pSlice);565 sDss.pBsStackBufPtr = pBs->pBufPtr;
566 566 sDss.uiBsStackCurBits = pBs->uiCurBits;
567 ++iNumMbCoded; 567 sDss.iBsStackLeftBits = pBs->iLeftBits;
568 568
569 iNextMbIdx = WelsGetNextMbOfSlice( pSliceCtx, iCurMbIdx );569 WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
570 if ( iNextMbIdx == -1 || iNextMbIdx >= kiTotalNumMb || iNumMbCoded >= kiTotalNumMb )570
571 {571 sDss.iCurrentPos = BsGetBitsPos (pBs);
572 break;572
573 }573 if (DynSlcJudgeSliceBoundaryStepBack (pEncCtx, pSlice, pSliceCtx, pCurMb, &sDss)) { //islice
574 }574 //stack pBs pointer
575}575 pBs->pBufPtr = sDss.pBsStackBufPtr;
576 576 pBs->uiCurBits = sDss.uiBsStackCurBits;
577// Only for intra dynamic slicing577 pBs->iLeftBits = sDss.iBsStackLeftBits;
578void WelsISliceMdEncDynamic( sWelsEncCtx* pEncCtx, SSlice *pSlice ) //pMd + encoding578
579{579 pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId] = iCurMbIdx -
580 SBitStringAux* pBs = pSlice->pSliceBsa;580 1; // update pLastCodedMbIdxOfPartition, need to -1 due to stepping back
581 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;581 ++ pCurLayer->pNumSliceCodedOfPartition[kiPartitionId];
582 SSliceCtx* pSliceCtx = pCurLayer->pSliceEncCtx;582
583 SMbCache *pMbCache = &pSlice->sMbCacheInfo;583 break;
584 SSliceHeaderExt *pSliceHdExt = &pSlice->sSliceHeaderExt;584 }
585 SMB* pMbList = pCurLayer->sMbDataP;585
586 SMB* pCurMb = NULL; 586 pCurMb->uiSliceIdc = kiSliceIdx;
587 const int32_t kiSliceFirstMbXY = pSliceHdExt->sSliceHeader.iFirstMbInSlice;587
588 int32_t iNextMbIdx = kiSliceFirstMbXY; 588#if defined(MB_TYPES_CHECK)
589 const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight;589 WelsCountMbType (pEncCtx->sPerInfo.iMbCount, I_SLICE, pCurMb);
590 int32_t iCurMbIdx = 0, iNumMbCoded = 0; 590#endif//MB_TYPES_CHECK
591 const int32_t kiSliceIdx = pSlice->uiSliceIdx;591
592 const int32_t kiPartitionId = (kiSliceIdx % pEncCtx->iActiveThreadsNum);592 pEncCtx->pFuncList->pfRc.pfWelsRcMbInfoUpdate (pEncCtx, pCurMb, sMd.iCostLuma, pSlice);
593 const uint8_t kuiChromaQpIndexOffset= pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;593
594 594 ++iNumMbCoded;
595 SWelsMD sMd; 595
596 SDynamicSlicingStack sDss;596 iNextMbIdx = WelsGetNextMbOfSlice (pSliceCtx, iCurMbIdx);
597 sDss.iStartPos = BsGetBitsPos(pBs);597 //whether all of MB in current pSlice encoded or not
598 598 if (iNextMbIdx == -1 || iNextMbIdx >= kiTotalNumMb || iNumMbCoded >= kiTotalNumMb) {
599 for ( ; ; )599 pSliceCtx->pCountMbNumInSlice[kiSliceIdx] = iCurMbIdx - pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId];
600 {600 pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId] =
601 iCurMbIdx = iNextMbIdx;601 iCurMbIdx; // update pLastCodedMbIdxOfPartition, finish coding, use iCurMbIdx directly
602 pCurMb = &pMbList[ iCurMbIdx ]; 602 break;
603 pCurMb->uiLumaQp = pEncCtx->iGlobalQp;603 }
604 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51(pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];604 }
605 605}
606 pEncCtx->pFuncList->pfRc.pfWelsRcMbInit(pEncCtx, pCurMb, pSlice);606
607 // if already reaches the largest number of slices, set QPs to the upper bound607//encapsulate two kinds of reconstruction:
608 if (pSlice->bDynamicSlicingSliceSizeCtrlFlag)608// first. store base or highest Dependency Layer with only one quality (without CS RS reconstruction)
609 { 609// second. lower than highest Dependency Layer, and for every Dependency Layer with one quality layer(single layer)
610 pCurMb->uiLumaQp = pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId].iMaxQp;610void WelsPSliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice, const bool_t kbIsHighestDlayerFlag) { //pMd + encoding
611 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51(pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];611 const SSliceHeaderExt* kpShExt = &pSlice->sSliceHeaderExt;
612 }612 const SSliceHeader* kpSh = &kpShExt->sSliceHeader;
613 613 const int32_t kiSliceFirstMbXY = kpSh->iFirstMbInSlice;
614 sMd.iLambda = g_kiQpCostTable[pCurMb->uiLumaQp];614 SWelsMD sMd;
615 615
616 WelsMdIntraInit( pEncCtx, pCurMb, pMbCache, kiSliceFirstMbXY );616 sMd.uiRef = kpSh->uiRefIndex;
617 WelsMdIntraMb( pEncCtx, &sMd, pCurMb, pMbCache );617 sMd.bMdUsingSad = kbIsHighestDlayerFlag;
618 UpdateNonZeroCountCache( pCurMb, pMbCache );618 if (!pEncCtx->pCurDqLayer->bBaseLayerAvailableFlag || !kbIsHighestDlayerFlag)
619 //stack pBs pointer619 memset (&sMd.sMe, 0, sizeof (sMd.sMe));
620 sDss.pBsStackBufPtr = pBs->pBufPtr;620
621 sDss.uiBsStackCurBits = pBs->uiCurBits;621 //pMb loop
622 sDss.iBsStackLeftBits = pBs->iLeftBits;622 WelsMdInterMbLoop (pEncCtx, pSlice, &sMd, kiSliceFirstMbXY);
623 623}
624 WelsSpatialWriteMbSyn( pEncCtx, pSlice, pCurMb );624
625 625void WelsPSliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice, const bool_t kbIsHighestDlayerFlag) {
626 sDss.iCurrentPos = BsGetBitsPos(pBs);626 const SSliceHeaderExt* kpShExt = &pSlice->sSliceHeaderExt;
627 627 const SSliceHeader* kpSh = &kpShExt->sSliceHeader;
628 if ( DynSlcJudgeSliceBoundaryStepBack( pEncCtx, pSlice, pSliceCtx, pCurMb, &sDss ) )//islice628 const int32_t kiSliceFirstMbXY = kpSh->iFirstMbInSlice;
629 {629 SWelsMD sMd;
630 //stack pBs pointer630
631 pBs->pBufPtr = sDss.pBsStackBufPtr;631 sMd.uiRef = kpSh->uiRefIndex;
632 pBs->uiCurBits = sDss.uiBsStackCurBits;632 sMd.bMdUsingSad = kbIsHighestDlayerFlag;
633 pBs->iLeftBits = sDss.iBsStackLeftBits;633 if (!pEncCtx->pCurDqLayer->bBaseLayerAvailableFlag || !kbIsHighestDlayerFlag)
634 634 memset (&sMd.sMe, 0, sizeof (sMd.sMe));
635 pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId] = iCurMbIdx-1; // update pLastCodedMbIdxOfPartition, need to -1 due to stepping back635
636 ++ pCurLayer->pNumSliceCodedOfPartition[kiPartitionId];636 //mb loop
637 637 WelsMdInterMbLoopOverDynamicSlice (pEncCtx, pSlice, &sMd, kiSliceFirstMbXY);
638 break;638}
639 }639
640 640void WelsCodePSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice) {
641 pCurMb->uiSliceIdc = kiSliceIdx;641 //pSlice-level init should be outside and before this function
642 642 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
643#if defined(MB_TYPES_CHECK) 643 const bool_t kbBaseAvail = pCurLayer->bBaseLayerAvailableFlag;
644 WelsCountMbType( pEncCtx->sPerInfo.iMbCount, I_SLICE, pCurMb ); 644 const bool_t kbHighestSpatial = pEncCtx->pSvcParam->iNumDependencyLayer ==
645#endif//MB_TYPES_CHECK645 (pCurLayer->sLayerInfo.sNalHeaderExt.uiDependencyId + 1);
646 646
647 pEncCtx->pFuncList->pfRc.pfWelsRcMbInfoUpdate(pEncCtx,pCurMb,sMd.iCostLuma,pSlice);647 //MD switch
648 648 if (kbBaseAvail && kbHighestSpatial) {
649 ++iNumMbCoded; 649 //initial pMd pointer
650 650 pEncCtx->pFuncList->pfInterMd = (PInterMdFunc)WelsMdInterMbEnhancelayer;
651 iNextMbIdx = WelsGetNextMbOfSlice( pSliceCtx, iCurMbIdx );651 } else {
652 //whether all of MB in current pSlice encoded or not652 //initial pMd pointer
653 if ( iNextMbIdx == -1 || iNextMbIdx >= kiTotalNumMb || iNumMbCoded >= kiTotalNumMb )653 pEncCtx->pFuncList->pfInterMd = (PInterMdFunc)WelsMdInterMb;
654 {654 }
655 pSliceCtx->pCountMbNumInSlice[kiSliceIdx] = iCurMbIdx - pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId];655 WelsPSliceMdEnc (pEncCtx, pSlice, kbHighestSpatial);
656 pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId] = iCurMbIdx; // update pLastCodedMbIdxOfPartition, finish coding, use iCurMbIdx directly656}
657 break;657
658 }658void WelsCodePOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice) {
659 }659 //pSlice-level init should be outside and before this function
660}660 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
661 661 const bool_t kbBaseAvail = pCurLayer->bBaseLayerAvailableFlag;
662//encapsulate two kinds of reconstruction:662 const bool_t kbHighestSpatial = pEncCtx->pSvcParam->iNumDependencyLayer ==
663// first. store base or highest Dependency Layer with only one quality (without CS RS reconstruction)663 (pCurLayer->sLayerInfo.sNalHeaderExt.uiDependencyId + 1);
664// second. lower than highest Dependency Layer, and for every Dependency Layer with one quality layer(single layer) 664
665void WelsPSliceMdEnc( sWelsEncCtx* pEncCtx, SSlice *pSlice, const bool_t kbIsHighestDlayerFlag ) //pMd + encoding665 //MD switch
666{666 if (kbBaseAvail && kbHighestSpatial) {
667 const SSliceHeaderExt *kpShExt = &pSlice->sSliceHeaderExt;667 //initial pMd pointer
668 const SSliceHeader *kpSh = &kpShExt->sSliceHeader;668 pEncCtx->pFuncList->pfInterMd = (PInterMdFunc)WelsMdInterMbEnhancelayer;
669 const int32_t kiSliceFirstMbXY = kpSh->iFirstMbInSlice;669 } else {
670 SWelsMD sMd;670 //initial pMd pointer
671 671 pEncCtx->pFuncList->pfInterMd = (PInterMdFunc)WelsMdInterMb;
672 sMd.uiRef = kpSh->uiRefIndex;672 }
673 sMd.bMdUsingSad = kbIsHighestDlayerFlag;673 WelsPSliceMdEncDynamic (pEncCtx, pSlice, kbHighestSpatial);
674 if (!pEncCtx->pCurDqLayer->bBaseLayerAvailableFlag || !kbIsHighestDlayerFlag)674}
675 memset( &sMd.sMe, 0, sizeof(sMd.sMe) );675
676 676// 1st index: 0: for P pSlice; 1: for I pSlice;
677 //pMb loop677// 2nd index: 0: for non-dynamic pSlice; 1: for dynamic I pSlice;
678 WelsMdInterMbLoop( pEncCtx, pSlice, &sMd, kiSliceFirstMbXY );678PWelsCodingSliceFunc g_pWelsSliceCoding[2][2] = {
679}679 { WelsCodePSlice, WelsCodePOverDynamicSlice }, // P SSlice
680 680 { WelsISliceMdEnc, WelsISliceMdEncDynamic } // I SSlice
681void WelsPSliceMdEncDynamic( sWelsEncCtx* pEncCtx, SSlice *pSlice, const bool_t kbIsHighestDlayerFlag )681};
682{682PWelsSliceHeaderWriteFunc g_pWelsWriteSliceHeader[2] = { // 0: for base; 1: for ext;
683 const SSliceHeaderExt *kpShExt = &pSlice->sSliceHeaderExt;683 WelsSliceHeaderWrite,
684 const SSliceHeader *kpSh = &kpShExt->sSliceHeader;684 WelsSliceHeaderExtWrite
685 const int32_t kiSliceFirstMbXY = kpSh->iFirstMbInSlice;685};
686 SWelsMD sMd;686
687 687
688 sMd.uiRef = kpSh->uiRefIndex;688void WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const int32_t kiNalType) {
689 sMd.bMdUsingSad = kbIsHighestDlayerFlag;689 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
690 if (!pEncCtx->pCurDqLayer->bBaseLayerAvailableFlag || !kbIsHighestDlayerFlag)690 SNalUnitHeaderExt* pNalHeadExt = &pCurLayer->sLayerInfo.sNalHeaderExt;
691 memset( &sMd.sMe, 0, sizeof(sMd.sMe) );691 SSlice* pCurSlice = &pCurLayer->sLayerInfo.pSliceInLayer[kiSliceIdx];
692 692 SBitStringAux* pBs = pCurSlice->pSliceBsa;
693 //mb loop693 const int32_t kiDynamicSliceFlag = (pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId].sMso.uiSliceMode ==
694 WelsMdInterMbLoopOverDynamicSlice( pEncCtx, pSlice, &sMd, kiSliceFirstMbXY );694 SM_DYN_SLICE);
695}695
696 696 assert (kiSliceIdx == pCurSlice->uiSliceIdx);
697void WelsCodePSlice( sWelsEncCtx* pEncCtx, SSlice *pSlice )697
698{698 if (I_SLICE == pEncCtx->eSliceType) {
699 //pSlice-level init should be outside and before this function699 pNalHeadExt->bIdrFlag = 1;
700 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;700 pCurSlice->sScaleShift = 0;
701 const bool_t kbBaseAvail = pCurLayer->bBaseLayerAvailableFlag;701 } else {
702 const bool_t kbHighestSpatial= pEncCtx->pSvcParam->iNumDependencyLayer == (pCurLayer->sLayerInfo.sNalHeaderExt.uiDependencyId + 1);702 const uint32_t kuiTemporalId = pNalHeadExt->uiTemporalId;
703 703 pCurSlice->sScaleShift = kuiTemporalId ? (kuiTemporalId - pEncCtx->pRefPic->uiTemporalId) : 0;
704 //MD switch 704 }
705 if ( kbBaseAvail && kbHighestSpatial ) 705
706 {706 WelsSliceHeaderExtInit (pEncCtx, pCurLayer, pCurSlice);
707 //initial pMd pointer707
708 pEncCtx->pFuncList->pfInterMd = (PInterMdFunc)WelsMdInterMbEnhancelayer;708
709 }709 g_pWelsWriteSliceHeader[pCurSlice->bSliceHeaderExtFlag] (pBs, pCurLayer, pCurSlice,
710 else710 & (pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[0]));
711 {711#if _DEBUG
712 //initial pMd pointer712 if (pEncCtx->sPSOVector.bEnableSpsPpsIdAddition) {
713 pEncCtx->pFuncList->pfInterMd = (PInterMdFunc)WelsMdInterMb;713 const int32_t kiEncoderPpsId = pCurSlice->sSliceHeaderExt.sSliceHeader.pPps->iPpsId;
714 }714 const int32_t kiTmpPpsIdInBs = kiEncoderPpsId +
715 WelsPSliceMdEnc( pEncCtx, pSlice, kbHighestSpatial );715 pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiEncoderPpsId ];
716}716 assert (MAX_PPS_COUNT > kiTmpPpsIdInBs);
717 717
718void WelsCodePOverDynamicSlice( sWelsEncCtx* pEncCtx, SSlice *pSlice )718 //when activated need to sure there is avialable PPS
719{719 assert (pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].bUsedParaSetIdInBs[kiTmpPpsIdInBs]);
720 //pSlice-level init should be outside and before this function720 }
721 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;721#endif
722 const bool_t kbBaseAvail = pCurLayer->bBaseLayerAvailableFlag;722
723 const bool_t kbHighestSpatial= pEncCtx->pSvcParam->iNumDependencyLayer == (pCurLayer->sLayerInfo.sNalHeaderExt.uiDependencyId + 1);723 pCurSlice->uiLastMbQp = pCurLayer->sLayerInfo.pPpsP->iPicInitQp + pCurSlice->sSliceHeaderExt.sSliceHeader.iSliceQpDelta;
724 724
725 //MD switch 725 g_pWelsSliceCoding[pNalHeadExt->bIdrFlag][kiDynamicSliceFlag] (pEncCtx, pCurSlice);
726 if ( kbBaseAvail && kbHighestSpatial ) 726
727 { 727 BsRbspTrailingBits (pBs);
728 //initial pMd pointer728
729 pEncCtx->pFuncList->pfInterMd = (PInterMdFunc)WelsMdInterMbEnhancelayer;729 BsFlush (pBs);
730 }730}
731 else731
732 {732//pFunc: UpdateMbNeighbourInfoForNextSlice()
733 //initial pMd pointer733void UpdateMbNeighbourInfoForNextSlice (SSliceCtx* pSliceCtx,
734 pEncCtx->pFuncList->pfInterMd = (PInterMdFunc)WelsMdInterMb; 734 SMB* pMbList,
735 }735 const int32_t kiFirstMbIdxOfNextSlice,
736 WelsPSliceMdEncDynamic( pEncCtx, pSlice, kbHighestSpatial );736 const int32_t kiLastMbIdxInPartition) {
737}737 const int32_t kiMbWidth = pSliceCtx->iMbWidth;
738 738 int32_t iIdx = kiFirstMbIdxOfNextSlice;
739// 1st index: 0: for P pSlice; 1: for I pSlice;739 int32_t iNextSliceFirstMbIdxRowStart = ((kiFirstMbIdxOfNextSlice % kiMbWidth) ? 1 : 0);
740// 2nd index: 0: for non-dynamic pSlice; 1: for dynamic I pSlice;740 int32_t iCountMbUpdate = kiMbWidth +
741PWelsCodingSliceFunc g_pWelsSliceCoding[2][2] =741 iNextSliceFirstMbIdxRowStart; //need to update MB(iMbXY+1) to MB(iMbXY+1+row) in common case
742{742 const int32_t kiEndMbNeedUpdate = kiFirstMbIdxOfNextSlice + iCountMbUpdate;
743 { WelsCodePSlice, WelsCodePOverDynamicSlice }, // P SSlice743 SMB* pMb = &pMbList[iIdx];
744 { WelsISliceMdEnc, WelsISliceMdEncDynamic } // I SSlice744
745};745 do {
746PWelsSliceHeaderWriteFunc g_pWelsWriteSliceHeader[2] = // 0: for base; 1: for ext;746 uint32_t uiNeighborAvailFlag = 0;
747{747 const int32_t kiMbXY = pMb->iMbXY;
748 WelsSliceHeaderWrite,748 const int32_t kiMbX = pMb->iMbX;
749 WelsSliceHeaderExtWrite749 const int32_t kiMbY = pMb->iMbY;
750};750 BOOL_T bLeft;
751 751 BOOL_T bTop;
752 752 BOOL_T bLeftTop;
753void WelsCodeOneSlice( sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const int32_t kiNalType )753 BOOL_T bRightTop;
754{ 754 int32_t iLeftXY, iTopXY, iLeftTopXY, iRightTopXY;
755 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;755 const uint8_t kuiSliceIdc = WelsMbToSliceIdc (pSliceCtx, kiMbXY);
756 SNalUnitHeaderExt* pNalHeadExt = &pCurLayer->sLayerInfo.sNalHeaderExt;756
757 SSlice *pCurSlice = &pCurLayer->sLayerInfo.pSliceInLayer[kiSliceIdx];757 pMb->uiSliceIdc = kuiSliceIdc;
758 SBitStringAux* pBs = pCurSlice->pSliceBsa;758 iLeftXY = kiMbXY - 1;
759 const int32_t kiDynamicSliceFlag = (pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId].sMso.uiSliceMode == SM_DYN_SLICE);759 iTopXY = kiMbXY - kiMbWidth;
760 760 iLeftTopXY = iTopXY - 1;
761 assert( kiSliceIdx == pCurSlice->uiSliceIdx );761 iRightTopXY = iTopXY + 1;
762 762
763 if ( I_SLICE == pEncCtx->eSliceType )763 bLeft = (kiMbX > 0) && (kuiSliceIdc == WelsMbToSliceIdc (pSliceCtx, iLeftXY));
764 {764 bTop = (kiMbY > 0) && (kuiSliceIdc == WelsMbToSliceIdc (pSliceCtx, iTopXY));
765 pNalHeadExt->bIdrFlag = 1;765 bLeftTop = (kiMbX > 0) && (kiMbY > 0) && (kuiSliceIdc == WelsMbToSliceIdc (pSliceCtx, iLeftTopXY));
766 pCurSlice->sScaleShift = 0;766 bRightTop = (kiMbX < (kiMbWidth - 1)) && (kiMbY > 0) && (kuiSliceIdc == WelsMbToSliceIdc (pSliceCtx, iRightTopXY));
767 }767
768 else768 if (bLeft) {
769 {769 uiNeighborAvailFlag |= LEFT_MB_POS;
770 const uint32_t kuiTemporalId = pNalHeadExt->uiTemporalId;770 }
771 pCurSlice->sScaleShift = kuiTemporalId ? (kuiTemporalId - pEncCtx->pRefPic->uiTemporalId) : 0;771 if (bTop) {
772 }772 uiNeighborAvailFlag |= TOP_MB_POS;
773 773 }
774 WelsSliceHeaderExtInit( pEncCtx, pCurLayer, pCurSlice ); 774 if (bLeftTop) {
775 775 uiNeighborAvailFlag |= TOPLEFT_MB_POS;
776 776 }
777 g_pWelsWriteSliceHeader[pCurSlice->bSliceHeaderExtFlag]( pBs, pCurLayer, pCurSlice, &(pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[0]) );777 if (bRightTop) {
778#if _DEBUG 778 uiNeighborAvailFlag |= TOPRIGHT_MB_POS;
779 if ( pEncCtx->sPSOVector.bEnableSpsPpsIdAddition )779 }
780 {780 pMb->uiNeighborAvail = (uint8_t)uiNeighborAvailFlag;
781 const int32_t kiEncoderPpsId = pCurSlice->sSliceHeaderExt.sSliceHeader.pPps->iPpsId;781
782 const int32_t kiTmpPpsIdInBs = kiEncoderPpsId + pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiEncoderPpsId ];782 ++ pMb;
783 assert ( MAX_PPS_COUNT > kiTmpPpsIdInBs );783 ++ iIdx;
784 784 } while ((iIdx < kiEndMbNeedUpdate) &&
785 //when activated need to sure there is avialable PPS785 (iIdx <= kiLastMbIdxInPartition));
786 assert ( pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].bUsedParaSetIdInBs[kiTmpPpsIdInBs] );786}
787 }787
788#endif788
789 789void AddSliceBoundary (sWelsEncCtx* pEncCtx, SSlice* pCurSlice, SSliceCtx* pSliceCtx, SMB* pCurMb,
790 pCurSlice->uiLastMbQp = pCurLayer->sLayerInfo.pPpsP->iPicInitQp + pCurSlice->sSliceHeaderExt.sSliceHeader.iSliceQpDelta; 790 int32_t iFirstMbIdxOfNextSlice, const int32_t kiLastMbIdxInPartition) {
791 791 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
792 g_pWelsSliceCoding[pNalHeadExt->bIdrFlag][kiDynamicSliceFlag]( pEncCtx, pCurSlice );792 int32_t iCurMbIdx = pCurMb->iMbXY;
793 793 int32_t iCurSliceIdc = pSliceCtx->pOverallMbMap[ iCurMbIdx ];
794 BsRbspTrailingBits( pBs );794 const int32_t kiSliceIdxStep = pEncCtx->iActiveThreadsNum;
795 795 int32_t iNextSliceIdc = iCurSliceIdc + kiSliceIdxStep;
796 BsFlush( pBs );796 SSlice* pNextSlice = NULL;
797}797
798 798 SMB* pMbList = pCurLayer->sMbDataP;
799//pFunc: UpdateMbNeighbourInfoForNextSlice()799
800void UpdateMbNeighbourInfoForNextSlice( SSliceCtx *pSliceCtx,800 //update cur pSlice info
801 SMB *pMbList,801 pCurSlice->sSliceHeaderExt.uiNumMbsInSlice = 1 + iCurMbIdx - pCurSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
802 const int32_t kiFirstMbIdxOfNextSlice,802
803 const int32_t kiLastMbIdxInPartition )803 //pNextSlice pointer/initialization
804{ 804 pNextSlice = & (pCurLayer->sLayerInfo.pSliceInLayer[ iNextSliceIdc ]);
805 const int32_t kiMbWidth = pSliceCtx->iMbWidth;805
806 int32_t iIdx = kiFirstMbIdxOfNextSlice;806#if _DEBUG
807 int32_t iNextSliceFirstMbIdxRowStart= (( kiFirstMbIdxOfNextSlice % kiMbWidth ) ? 1:0);807 assert (NULL != pNextSlice);
808 int32_t iCountMbUpdate = kiMbWidth + iNextSliceFirstMbIdxRowStart; //need to update MB(iMbXY+1) to MB(iMbXY+1+row) in common case808 // now ( pSliceCtx->iSliceNumInFrame < pSliceCtx->iMaxSliceNumConstraint ) always true by the call of this pFunc
809 const int32_t kiEndMbNeedUpdate = kiFirstMbIdxOfNextSlice + iCountMbUpdate;809#endif
810 SMB *pMb = &pMbList[iIdx];810
811 811 //init next pSlice info
812 do {812 pNextSlice->bSliceHeaderExtFlag =
813 uint32_t uiNeighborAvailFlag = 0;813 (NAL_UNIT_CODED_SLICE_EXT == pCurLayer->sLayerInfo.sNalHeaderExt.sNalHeader.eNalUnitType);
814 const int32_t kiMbXY = pMb->iMbXY;814 memcpy (&pNextSlice->sSliceHeaderExt, &pCurSlice->sSliceHeaderExt,
815 const int32_t kiMbX = pMb->iMbX;815 sizeof (SSliceHeaderExt)); // confirmed_safe_unsafe_usage
816 const int32_t kiMbY = pMb->iMbY;816
817 BOOL_T bLeft;817 pSliceCtx->pFirstMbInSlice[iNextSliceIdc] = iFirstMbIdxOfNextSlice;
818 BOOL_T bTop;818
819 BOOL_T bLeftTop;819#if !defined(MT_ENABLED)
820 BOOL_T bRightTop; 820 pNextSlice->uiSliceIdx = iNextSliceIdc;
821 int32_t iLeftXY, iTopXY, iLeftTopXY, iRightTopXY;821 pNextSlice->pSliceBsa = & (pEncCtx->pOut->sBsWrite);
822 const uint8_t kuiSliceIdc = WelsMbToSliceIdc(pSliceCtx, kiMbXY);822#endif//!MT_ENABLED
823 823
824 pMb->uiSliceIdc = kuiSliceIdc;824 memset (pSliceCtx->pOverallMbMap + iFirstMbIdxOfNextSlice, (uint8_t)iNextSliceIdc,
825 iLeftXY = kiMbXY - 1;825 (kiLastMbIdxInPartition - iFirstMbIdxOfNextSlice + 1)*sizeof (uint8_t));
826 iTopXY = kiMbXY - kiMbWidth;826
827 iLeftTopXY = iTopXY - 1;827 //DYNAMIC_SLICING_ONE_THREAD: update pMbList slice_neighbor_info
828 iRightTopXY = iTopXY + 1;828 UpdateMbNeighbourInfoForNextSlice (pSliceCtx, pMbList, iFirstMbIdxOfNextSlice, kiLastMbIdxInPartition);
829 829}
830 bLeft = (kiMbX > 0) && (kuiSliceIdc == WelsMbToSliceIdc(pSliceCtx, iLeftXY));830
831 bTop = (kiMbY > 0) && (kuiSliceIdc == WelsMbToSliceIdc(pSliceCtx, iTopXY));831BOOL_T DynSlcJudgeSliceBoundaryStepBack (void* pCtx, void* pSlice, SSliceCtx* pSliceCtx, SMB* pCurMb,
832 bLeftTop = (kiMbX > 0) && (kiMbY > 0) && (kuiSliceIdc == WelsMbToSliceIdc(pSliceCtx, iLeftTopXY));832 SDynamicSlicingStack* pDss) {
833 bRightTop = (kiMbX < (kiMbWidth-1)) && (kiMbY > 0) && (kuiSliceIdc == WelsMbToSliceIdc(pSliceCtx, iRightTopXY)); 833 sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
834 834 SSlice* pCurSlice = (SSlice*)pSlice;
835 if( bLeft ){835 int32_t iCurMbIdx = pCurMb->iMbXY;
836 uiNeighborAvailFlag |= LEFT_MB_POS;836 uint32_t uiLen = 0;
837 }837 int32_t iPosBitOffset = 0;
838 if( bTop ){838 const int32_t kiActiveThreadsNum = pEncCtx->iActiveThreadsNum;
839 uiNeighborAvailFlag |= TOP_MB_POS;839 const int32_t kiPartitaionId = pCurSlice->uiSliceIdx % kiActiveThreadsNum;
840 }840 const int32_t kiLastMbIdxInPartition = pEncCtx->pCurDqLayer->pLastMbIdxOfPartition[kiPartitaionId];
841 if( bLeftTop ){841
842 uiNeighborAvailFlag |= TOPLEFT_MB_POS;842 const BOOL_T kbCurMbNotFirstMbOfCurSlice = (pSliceCtx->pOverallMbMap[iCurMbIdx] ==
843 }843 pSliceCtx->pOverallMbMap[iCurMbIdx - 1]);
844 if( bRightTop ){844 const BOOL_T kbCurMbNotLastMbOfCurPartition = iCurMbIdx < kiLastMbIdxInPartition;
845 uiNeighborAvailFlag |= TOPRIGHT_MB_POS;845 const BOOL_T kbSliceNumNotExceedConstraint = pSliceCtx->iSliceNumInFrame <
846 }846 pSliceCtx->iMaxSliceNumConstraint; /*tmp choice to avoid complex memory operation, 100520, to be modify*/
847 pMb->uiNeighborAvail = (uint8_t)uiNeighborAvailFlag;847 const BOOL_T kbSliceNumReachConstraint = (pSliceCtx->iSliceNumInFrame ==
848 848 pSliceCtx->iMaxSliceNumConstraint);
849 ++ pMb;849
850 ++ iIdx;850 if (pCurSlice->bDynamicSlicingSliceSizeCtrlFlag)
851 }while ( ( iIdx < kiEndMbNeedUpdate) && 851 return false;
852 ( iIdx <= kiLastMbIdxInPartition ) );852
853} 853 iPosBitOffset = (pDss->iCurrentPos - pDss->iStartPos);
854 854#if _DEBUG
855 855 assert (iPosBitOffset >= 0);
856void AddSliceBoundary(sWelsEncCtx* pEncCtx, SSlice * pCurSlice, SSliceCtx *pSliceCtx, SMB* pCurMb, int32_t iFirstMbIdxOfNextSlice, const int32_t kiLastMbIdxInPartition )856#endif
857{857 uiLen = ((iPosBitOffset >> 3) + ((iPosBitOffset & 0x07) ? 1 : 0));
858 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;858
859 int32_t iCurMbIdx = pCurMb->iMbXY;859#ifdef MT_ENABLED
860 int32_t iCurSliceIdc = pSliceCtx->pOverallMbMap[ iCurMbIdx ];860 if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1)
861 const int32_t kiSliceIdxStep= pEncCtx->iActiveThreadsNum;861 WelsMutexLock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
862 int32_t iNextSliceIdc = iCurSliceIdc + kiSliceIdxStep;862#endif//MT_ENABLED
863 SSlice *pNextSlice = NULL;863
864 864 //DYNAMIC_SLICING_ONE_THREAD: judge jump_avoiding_pack_exceed
865 SMB *pMbList = pCurLayer->sMbDataP; 865 if (
866 866 ((kbCurMbNotFirstMbOfCurSlice
867 //update cur pSlice info 867 && JUMPPACKETSIZE_JUDGE (uiLen, iCurMbIdx, pSliceCtx->uiSliceSizeConstraint)) /*jump_avoiding_pack_exceed*/
868 pCurSlice->sSliceHeaderExt.uiNumMbsInSlice = 1 + iCurMbIdx - pCurSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;868 && kbCurMbNotLastMbOfCurPartition) //decide to add new pSlice
869 869 && (kbSliceNumNotExceedConstraint
870 //pNextSlice pointer/initialization870#ifdef MT_ENABLED
871 pNextSlice = &( pCurLayer->sLayerInfo.pSliceInLayer[ iNextSliceIdc ] );871 && ((pCurSlice->uiSliceIdx + kiActiveThreadsNum) < pSliceCtx->iMaxSliceNumConstraint)
872 872#endif//MT_ENABLED
873#if _DEBUG873 )//able to add new pSlice
874 assert( NULL != pNextSlice );874
875 // now ( pSliceCtx->iSliceNumInFrame < pSliceCtx->iMaxSliceNumConstraint ) always true by the call of this pFunc875 ) {
876#endif876
877 877 AddSliceBoundary (pEncCtx, pCurSlice, pSliceCtx, pCurMb, iCurMbIdx, kiLastMbIdxInPartition);
878 //init next pSlice info878
879 pNextSlice->bSliceHeaderExtFlag = 879 ++ pSliceCtx->iSliceNumInFrame;
880 (NAL_UNIT_CODED_SLICE_EXT == pCurLayer->sLayerInfo.sNalHeaderExt.sNalHeader.eNalUnitType);880
881 memcpy( &pNextSlice->sSliceHeaderExt, &pCurSlice->sSliceHeaderExt, sizeof(SSliceHeaderExt) ); // confirmed_safe_unsafe_usage881#ifdef MT_ENABLED
882 882 if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1)
883 pSliceCtx->pFirstMbInSlice[iNextSliceIdc] = iFirstMbIdxOfNextSlice;883 WelsMutexUnlock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
884 884#endif//MT_ENABLED
885#if !defined(MT_ENABLED)885
886 pNextSlice->uiSliceIdx = iNextSliceIdc;886 return TRUE;
887 pNextSlice->pSliceBsa = &(pEncCtx->pOut->sBsWrite);887 }
888#endif//!MT_ENABLED888
889 889 if (
890 memset(pSliceCtx->pOverallMbMap+iFirstMbIdxOfNextSlice, (uint8_t)iNextSliceIdc, (kiLastMbIdxInPartition-iFirstMbIdxOfNextSlice+1)*sizeof(uint8_t));890 (kbSliceNumReachConstraint
891 891#ifdef MT_ENABLED
892 //DYNAMIC_SLICING_ONE_THREAD: update pMbList slice_neighbor_info892 || ((pCurSlice->uiSliceIdx + kiActiveThreadsNum) >= pSliceCtx->iMaxSliceNumConstraint)
893 UpdateMbNeighbourInfoForNextSlice( pSliceCtx, pMbList, iFirstMbIdxOfNextSlice, kiLastMbIdxInPartition );893#endif//MT_ENABLED
894}894 )
895 895 && ((JUMPPACKETSIZE_JUDGE (uiLen, iCurMbIdx,
896BOOL_T DynSlcJudgeSliceBoundaryStepBack(void* pCtx, void *pSlice, SSliceCtx *pSliceCtx, SMB* pCurMb, SDynamicSlicingStack* pDss )896 pSliceCtx->uiSliceSizeConstraint - ((kiLastMbIdxInPartition - iCurMbIdx) <<
897{897 (pCurSlice->uiAssumeLog2BytePerMb) /* assume each MB consumes two byte under largest QP */)))
898 sWelsEncCtx *pEncCtx = (sWelsEncCtx*)pCtx;898 && kbCurMbNotLastMbOfCurPartition) //risk of exceeding the size constraint when pSlice num reaches constraint
899 SSlice * pCurSlice = (SSlice *)pSlice;899 ) {
900 int32_t iCurMbIdx = pCurMb->iMbXY;900 pCurSlice->bDynamicSlicingSliceSizeCtrlFlag = true;
901 uint32_t uiLen = 0;901 }
902 int32_t iPosBitOffset = 0;902
903 const int32_t kiActiveThreadsNum = pEncCtx->iActiveThreadsNum;903#ifdef MT_ENABLED
904 const int32_t kiPartitaionId = pCurSlice->uiSliceIdx % kiActiveThreadsNum;904 if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1)
905 const int32_t kiLastMbIdxInPartition = pEncCtx->pCurDqLayer->pLastMbIdxOfPartition[kiPartitaionId];905 WelsMutexUnlock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
906 906#endif//MT_ENABLED
907 const BOOL_T kbCurMbNotFirstMbOfCurSlice = (pSliceCtx->pOverallMbMap[iCurMbIdx] == pSliceCtx->pOverallMbMap[iCurMbIdx-1]);907
908 const BOOL_T kbCurMbNotLastMbOfCurPartition = iCurMbIdx < kiLastMbIdxInPartition;908 return FALSE;
909 const BOOL_T kbSliceNumNotExceedConstraint = pSliceCtx->iSliceNumInFrame < pSliceCtx->iMaxSliceNumConstraint; /*tmp choice to avoid complex memory operation, 100520, to be modify*/909}
910 const BOOL_T kbSliceNumReachConstraint = (pSliceCtx->iSliceNumInFrame == pSliceCtx->iMaxSliceNumConstraint);910
911 911///////////////
912 if ( pCurSlice->bDynamicSlicingSliceSizeCtrlFlag ) 912// pMb loop
913 return false;913///////////////
914 914// for inter non-dynamic pSlice
915 iPosBitOffset = ( pDss->iCurrentPos - pDss->iStartPos );915void WelsMdInterMbLoop (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pWelsMd, const int32_t kiSliceFirstMbXY) {
916#if _DEBUG916 SWelsMD* pMd = (SWelsMD*)pWelsMd;
917 assert(iPosBitOffset>=0);917 SBitStringAux* pBs = pSlice->pSliceBsa;
918#endif918 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
919 uiLen = ( ( iPosBitOffset>>3 ) + (( iPosBitOffset & 0x07 )? 1: 0) ); 919 SSliceCtx* pSliceCtx = pCurLayer->pSliceEncCtx;
920 920 SMbCache* pMbCache = &pSlice->sMbCacheInfo;
921#ifdef MT_ENABLED921 SMB* pMbList = pCurLayer->sMbDataP;
922 if ( pEncCtx->pSvcParam->iMultipleThreadIdc > 1 )922 SMB* pCurMb = NULL;
923 WelsMutexLock( &pEncCtx->pSliceThreading->mutexSliceNumUpdate );923 int32_t iNumMbCoded = 0;
924#endif//MT_ENABLED924 int32_t iNextMbIdx = kiSliceFirstMbXY;
925 925 int32_t iCurMbIdx = -1;
926 //DYNAMIC_SLICING_ONE_THREAD: judge jump_avoiding_pack_exceed926 int32_t iMbSkipRun = 0;
927 if (927 const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight;
928 ( ( kbCurMbNotFirstMbOfCurSlice928 const int32_t kiMvdInterTableSize = (pEncCtx->pSvcParam->iNumDependencyLayer == 1 ? 648 : 972);
929 && JUMPPACKETSIZE_JUDGE(uiLen,iCurMbIdx,pSliceCtx->uiSliceSizeConstraint) )/*jump_avoiding_pack_exceed*/ 929 const int32_t kiMvdInterTableStride = 1 + (kiMvdInterTableSize << 1);
930 && kbCurMbNotLastMbOfCurPartition )//decide to add new pSlice930 uint16_t* pMvdCostTableInter = &pEncCtx->pMvdCostTableInter[kiMvdInterTableSize];
931 && ( kbSliceNumNotExceedConstraint931 const int32_t kiSliceIdx = pSlice->uiSliceIdx;
932#ifdef MT_ENABLED932 const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
933 && ( ( pCurSlice->uiSliceIdx + kiActiveThreadsNum ) < pSliceCtx->iMaxSliceNumConstraint )933
934#endif//MT_ENABLED 934 for (;;) {
935 )//able to add new pSlice935 //point to current pMb
936 936 iCurMbIdx = iNextMbIdx;
937 )937 pCurMb = &pMbList[ iCurMbIdx ];
938 { 938
939 939 //step(1): set QP for the current MB
940 AddSliceBoundary( pEncCtx, pCurSlice, pSliceCtx, pCurMb, iCurMbIdx, kiLastMbIdxInPartition );940 pEncCtx->pFuncList->pfRc.pfWelsRcMbInit (pEncCtx, pCurMb, pSlice);
941 941
942 ++ pSliceCtx->iSliceNumInFrame;942 //step (2). save some vale for future use, initial pWelsMd
943 943 pMd->iLambda = g_kiQpCostTable[pCurMb->uiLumaQp];
944#ifdef MT_ENABLED944 pMd->pMvdCost = &pMvdCostTableInter[pCurMb->uiLumaQp * kiMvdInterTableStride];
945 if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1)945 WelsMdIntraInit (pEncCtx, pCurMb, pMbCache, kiSliceFirstMbXY);
946 WelsMutexUnlock( &pEncCtx->pSliceThreading->mutexSliceNumUpdate );946 WelsMdInterInit (pEncCtx, pSlice, pCurMb, kiSliceFirstMbXY);
947#endif//MT_ENABLED947 pEncCtx->pFuncList->pfInterMd (pEncCtx, pMd, pSlice, pCurMb, pMbCache);
948 948 //mb_qp
949 return TRUE;949
950 }950 //step (4): save from the MD process from future use
951 951 WelsMdInterSaveSadAndRefMbType ((pCurLayer->pDecPic->uiRefMbType), pMbCache, pCurMb, pMd);
952 if (952
953 ( kbSliceNumReachConstraint953 pEncCtx->pFuncList->pfInterMdBackgroundInfoUpdate (pCurLayer, pCurMb, pMbCache->bCollocatedPredFlag,
954#ifdef MT_ENABLED954 pEncCtx->pRefPic->iPictureType);
955 || ( ( pCurSlice->uiSliceIdx + kiActiveThreadsNum ) >= pSliceCtx->iMaxSliceNumConstraint )955
956#endif//MT_ENABLED956 //step (5): update cache
957 )957 UpdateNonZeroCountCache (pCurMb, pMbCache);
958 && ( ( JUMPPACKETSIZE_JUDGE(uiLen, iCurMbIdx,958
959 pSliceCtx->uiSliceSizeConstraint - ( ( kiLastMbIdxInPartition - iCurMbIdx ) << ( pCurSlice->uiAssumeLog2BytePerMb ) /* assume each MB consumes two byte under largest QP */) ) )959 //step (6): begin to write bit stream; if the pSlice size is controlled, the writing may be skipped
960 && kbCurMbNotLastMbOfCurPartition )//risk of exceeding the size constraint when pSlice num reaches constraint960 if (IS_SKIP (pCurMb->uiMbType)) {
961 )961 pCurMb->uiLumaQp = pSlice->uiLastMbQp;
962 { 962 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];
963 pCurSlice->bDynamicSlicingSliceSizeCtrlFlag = true;963
964 }964 iMbSkipRun++;
965 965 } else {
966#ifdef MT_ENABLED966 BsWriteUE (pBs, iMbSkipRun);
967 if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1)967 iMbSkipRun = 0;
968 WelsMutexUnlock( &pEncCtx->pSliceThreading->mutexSliceNumUpdate );968 WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
969#endif//MT_ENABLED969 }
970 970
971 return FALSE;971 //step (7): reconstruct current MB
972}972 pCurMb->uiSliceIdc = kiSliceIdx;
973 973 OutputPMbWithoutConstructCsRsNoCopy (pEncCtx, pCurLayer, pSlice, pCurMb);
974///////////////974
975// pMb loop975#if defined(MB_TYPES_CHECK)
976///////////////976 WelsCountMbType (pEncCtx->sPerInfo.iMbCount, P_SLICE, pCurMb);
977// for inter non-dynamic pSlice977#endif//MB_TYPES_CHECK
978void WelsMdInterMbLoop( sWelsEncCtx* pEncCtx, SSlice *pSlice, void* pWelsMd, const int32_t kiSliceFirstMbXY )978
979{979 //step (8): update status and other parameters
980 SWelsMD* pMd = (SWelsMD*)pWelsMd;980 pEncCtx->pFuncList->pfRc.pfWelsRcMbInfoUpdate (pEncCtx, pCurMb, pMd->iCostLuma, pSlice);
981 SBitStringAux* pBs = pSlice->pSliceBsa;981
982 SDqLayer *pCurLayer = pEncCtx->pCurDqLayer;982 /*judge if all pMb in cur pSlice has been encoded*/
983 SSliceCtx *pSliceCtx = pCurLayer->pSliceEncCtx;983 ++ iNumMbCoded;
984 SMbCache *pMbCache = &pSlice->sMbCacheInfo;984 iNextMbIdx = WelsGetNextMbOfSlice (pSliceCtx, iCurMbIdx);
985 SMB *pMbList = pCurLayer->sMbDataP;985 //whether all of MB in current pSlice encoded or not
986 SMB *pCurMb = NULL;986 if (iNextMbIdx == -1 || iNextMbIdx >= kiTotalNumMb || iNumMbCoded >= kiTotalNumMb) {
987 int32_t iNumMbCoded = 0;987 break;
988 int32_t iNextMbIdx = kiSliceFirstMbXY;988 }
989 int32_t iCurMbIdx = -1; 989 }
990 int32_t iMbSkipRun = 0;990
991 const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight;991 if (iMbSkipRun) {
992 const int32_t kiMvdInterTableSize = (pEncCtx->pSvcParam->iNumDependencyLayer == 1 ? 648: 972);992 BsWriteUE (pBs, iMbSkipRun);
993 const int32_t kiMvdInterTableStride= 1+(kiMvdInterTableSize<<1);993 }
994 uint16_t *pMvdCostTableInter = &pEncCtx->pMvdCostTableInter[kiMvdInterTableSize];994}
995 const int32_t kiSliceIdx = pSlice->uiSliceIdx;995
996 const uint8_t kuiChromaQpIndexOffset= pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;996// Only for inter dynamic slicing
997 997void WelsMdInterMbLoopOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pWelsMd,
998 for(;;)998 const int32_t kiSliceFirstMbXY) {
999 {999 SWelsMD* pMd = (SWelsMD*)pWelsMd;
1000 //point to current pMb1000 SBitStringAux* pBs = pSlice->pSliceBsa;
1001 iCurMbIdx = iNextMbIdx;1001 SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
1002 pCurMb = &pMbList[ iCurMbIdx ]; 1002 SSliceCtx* pSliceCtx = pCurLayer->pSliceEncCtx;
1003 1003 SMbCache* pMbCache = &pSlice->sMbCacheInfo;
1004 //step(1): set QP for the current MB1004 SMB* pMbList = pCurLayer->sMbDataP;
1005 pEncCtx->pFuncList->pfRc.pfWelsRcMbInit(pEncCtx, pCurMb, pSlice);1005 SMB* pCurMb = NULL;
1006 1006 int32_t iNumMbCoded = 0;
1007 //step (2). save some vale for future use, initial pWelsMd1007 const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight;
1008 pMd->iLambda = g_kiQpCostTable[pCurMb->uiLumaQp];1008 int32_t iNextMbIdx = kiSliceFirstMbXY;
1009 pMd->pMvdCost = &pMvdCostTableInter[pCurMb->uiLumaQp*kiMvdInterTableStride];1009 int32_t iCurMbIdx = -1;
1010 WelsMdIntraInit(pEncCtx, pCurMb, pMbCache, kiSliceFirstMbXY);1010 int32_t iMbSkipRun = 0;
1011 WelsMdInterInit(pEncCtx, pSlice, pCurMb, kiSliceFirstMbXY);1011 const int32_t kiMvdInterTableSize = (pEncCtx->pSvcParam->iNumDependencyLayer == 1 ? 648 : 972);
1012 pEncCtx->pFuncList->pfInterMd(pEncCtx, pMd, pSlice, pCurMb, pMbCache);1012 const int32_t kiMvdInterTableStride = 1 + (kiMvdInterTableSize << 1);
1013 //mb_qp1013 uint16_t* pMvdCostTableInter = &pEncCtx->pMvdCostTableInter[kiMvdInterTableSize];
1014 1014 const int32_t kiSliceIdx = pSlice->uiSliceIdx;
1015 //step (4): save from the MD process from future use1015 const int32_t kiPartitionId = (kiSliceIdx % pEncCtx->iActiveThreadsNum);
1016 WelsMdInterSaveSadAndRefMbType( (pCurLayer->pDecPic->uiRefMbType), pMbCache, pCurMb, pMd);1016 const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
1017 1017
1018 pEncCtx->pFuncList->pfInterMdBackgroundInfoUpdate( pCurLayer, pCurMb, pMbCache->bCollocatedPredFlag, pEncCtx->pRefPic->iPictureType );1018 SDynamicSlicingStack sDss;
1019 1019 sDss.iStartPos = BsGetBitsPos (pBs);
1020 //step (5): update cache1020 for (;;) {
1021 UpdateNonZeroCountCache( pCurMb, pMbCache );1021 //point to current pMb
1022 1022 iCurMbIdx = iNextMbIdx;
1023 //step (6): begin to write bit stream; if the pSlice size is controlled, the writing may be skipped1023 pCurMb = &pMbList[ iCurMbIdx ];
1024 if( IS_SKIP (pCurMb->uiMbType) )1024
1025 {1025 //step(1): set QP for the current MB
1026 pCurMb->uiLumaQp = pSlice->uiLastMbQp;1026 pEncCtx->pFuncList->pfRc.pfWelsRcMbInit (pEncCtx, pCurMb, pSlice);
1027 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51(pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];1027 // if already reaches the largest number of slices, set QPs to the upper bound
1028 1028 if (pSlice->bDynamicSlicingSliceSizeCtrlFlag) {
1029 iMbSkipRun++;1029 //a clearer logic may be:
1030 }1030 //if there is no need from size control from the pSlice size, the QP will be decided by RC; else it will be set to the max QP
1031 else1031 // however, there are some parameter updating in the rc_mb_init() function, so it cannot be skipped?
1032 {1032 pCurMb->uiLumaQp = pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId].iMaxQp;
1033 BsWriteUE( pBs, iMbSkipRun );1033 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];
1034 iMbSkipRun = 0;1034 }
1035 WelsSpatialWriteMbSyn( pEncCtx, pSlice, pCurMb );1035
1036 }1036 //step (2). save some vale for future use, initial pWelsMd
1037 1037 pMd->iLambda = g_kiQpCostTable[pCurMb->uiLumaQp];
1038 //step (7): reconstruct current MB1038 pMd->pMvdCost = &pMvdCostTableInter[pCurMb->uiLumaQp * kiMvdInterTableStride];
1039 pCurMb->uiSliceIdc = kiSliceIdx;1039
1040 OutputPMbWithoutConstructCsRsNoCopy( pEncCtx, pCurLayer, pSlice, pCurMb );1040 WelsMdIntraInit (pEncCtx, pCurMb, pMbCache, kiSliceFirstMbXY);
1041 1041 WelsMdInterInit (pEncCtx, pSlice, pCurMb, kiSliceFirstMbXY);
1042 #if defined(MB_TYPES_CHECK) 1042 pEncCtx->pFuncList->pfInterMd (pEncCtx, pMd, pSlice, pCurMb, pMbCache);
1043 WelsCountMbType( pEncCtx->sPerInfo.iMbCount, P_SLICE, pCurMb ); 1043 //mb_qp
1044 #endif//MB_TYPES_CHECK 1044
1045 1045 //step (4): save from the MD process from future use
1046 //step (8): update status and other parameters1046 WelsMdInterSaveSadAndRefMbType ((pCurLayer->pDecPic->uiRefMbType), pMbCache, pCurMb, pMd);
1047 pEncCtx->pFuncList->pfRc.pfWelsRcMbInfoUpdate(pEncCtx,pCurMb,pMd->iCostLuma,pSlice);1047
1048 1048 pEncCtx->pFuncList->pfInterMdBackgroundInfoUpdate (pCurLayer, pCurMb, pMbCache->bCollocatedPredFlag,
1049 /*judge if all pMb in cur pSlice has been encoded*/1049 pEncCtx->pRefPic->iPictureType);
1050 ++ iNumMbCoded;1050
1051 iNextMbIdx = WelsGetNextMbOfSlice( pSliceCtx, iCurMbIdx );1051 //step (5): update cache
1052 //whether all of MB in current pSlice encoded or not1052 UpdateNonZeroCountCache (pCurMb, pMbCache);
1053 if ( iNextMbIdx == -1 || iNextMbIdx >= kiTotalNumMb || iNumMbCoded >= kiTotalNumMb )1053
1054 {1054 //step (6): begin to write bit stream; if the pSlice size is controlled, the writing may be skipped
1055 break;1055
1056 }1056 //DYNAMIC_SLICING_ONE_THREAD - MultiD
1057 }1057 //stack pBs pointer
1058 1058 sDss.pBsStackBufPtr = pBs->pBufPtr;
1059 if ( iMbSkipRun )1059 sDss.uiBsStackCurBits = pBs->uiCurBits;
1060 {1060 sDss.iBsStackLeftBits = pBs->iLeftBits;
1061 BsWriteUE( pBs, iMbSkipRun );1061 //stack Pskip status
1062 }1062 sDss.iMbSkipRunStack = iMbSkipRun;
1063}1063 //DYNAMIC_SLICING_ONE_THREAD - MultiD
1064 1064
1065// Only for inter dynamic slicing1065 if (IS_SKIP (pCurMb->uiMbType)) {
1066void WelsMdInterMbLoopOverDynamicSlice( sWelsEncCtx* pEncCtx, SSlice *pSlice, void* pWelsMd, const int32_t kiSliceFirstMbXY )1066 pCurMb->uiLumaQp = pSlice->uiLastMbQp;
1067{1067 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];
1068 SWelsMD* pMd = (SWelsMD*)pWelsMd;1068
1069 SBitStringAux* pBs = pSlice->pSliceBsa;1069 iMbSkipRun++;
1070 SDqLayer *pCurLayer = pEncCtx->pCurDqLayer;1070 } else {
1071 SSliceCtx *pSliceCtx = pCurLayer->pSliceEncCtx;1071 BsWriteUE (pBs, iMbSkipRun);
1072 SMbCache *pMbCache = &pSlice->sMbCacheInfo;1072 iMbSkipRun = 0;
1073 SMB *pMbList = pCurLayer->sMbDataP;1073 WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
1074 SMB *pCurMb = NULL;1074 }
1075 int32_t iNumMbCoded = 0;1075
1076 const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight;1076 //DYNAMIC_SLICING_ONE_THREAD - MultiD
1077 int32_t iNextMbIdx = kiSliceFirstMbXY;1077 sDss.iCurrentPos = BsGetBitsPos (pBs);
1078 int32_t iCurMbIdx = -1;1078 if (DynSlcJudgeSliceBoundaryStepBack (pEncCtx, pSlice, pSliceCtx, pCurMb, &sDss)) {
1079 int32_t iMbSkipRun = 0; 1079 //stack pBs pointer
1080 const int32_t kiMvdInterTableSize = (pEncCtx->pSvcParam->iNumDependencyLayer == 1 ? 648: 972);1080 pBs->pBufPtr = sDss.pBsStackBufPtr;
1081 const int32_t kiMvdInterTableStride= 1+(kiMvdInterTableSize<<1);1081 pBs->uiCurBits = sDss.uiBsStackCurBits;
1082 uint16_t *pMvdCostTableInter = &pEncCtx->pMvdCostTableInter[kiMvdInterTableSize];1082 pBs->iLeftBits = sDss.iBsStackLeftBits;
1083 const int32_t kiSliceIdx = pSlice->uiSliceIdx;1083
1084 const int32_t kiPartitionId = (kiSliceIdx % pEncCtx->iActiveThreadsNum);1084 iMbSkipRun = sDss.iMbSkipRunStack;
1085 const uint8_t kuiChromaQpIndexOffset= pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;1085
1086 1086 pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId] = iCurMbIdx -
1087 SDynamicSlicingStack sDss;1087 1; // update pLastCodedMbIdxOfPartition, need to -1 due to stepping back
1088 sDss.iStartPos = BsGetBitsPos(pBs);1088 ++ pCurLayer->pNumSliceCodedOfPartition[kiPartitionId];
1089 for(;;)1089
1090 {1090 break;
1091 //point to current pMb1091 }
1092 iCurMbIdx = iNextMbIdx;1092
1093 pCurMb = &pMbList[ iCurMbIdx ]; 1093 //step (7): reconstruct current MB
1094 1094 pCurMb->uiSliceIdc = kiSliceIdx;
1095 //step(1): set QP for the current MB1095 OutputPMbWithoutConstructCsRsNoCopy (pEncCtx, pCurLayer, pSlice, pCurMb);
1096 pEncCtx->pFuncList->pfRc.pfWelsRcMbInit(pEncCtx, pCurMb, pSlice);1096
1097 // if already reaches the largest number of slices, set QPs to the upper bound1097#if defined(MB_TYPES_CHECK)
1098 if (pSlice->bDynamicSlicingSliceSizeCtrlFlag)1098 WelsCountMbType (pEncCtx->sPerInfo.iMbCount, P_SLICE, pCurMb);
1099 {1099#endif//MB_TYPES_CHECK
1100 //a clearer logic may be: 1100
1101 //if there is no need from size control from the pSlice size, the QP will be decided by RC; else it will be set to the max QP1101 //step (8): update status and other parameters
1102 // however, there are some parameter updating in the rc_mb_init() function, so it cannot be skipped?1102 pEncCtx->pFuncList->pfRc.pfWelsRcMbInfoUpdate (pEncCtx, pCurMb, pMd->iCostLuma, pSlice);
1103 pCurMb->uiLumaQp = pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId].iMaxQp;1103
1104 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51(pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];1104 /*judge if all pMb in cur pSlice has been encoded*/
1105 }1105 ++ iNumMbCoded;
1106 1106 iNextMbIdx = WelsGetNextMbOfSlice (pSliceCtx, iCurMbIdx);
1107 //step (2). save some vale for future use, initial pWelsMd1107 //whether all of MB in current pSlice encoded or not
1108 pMd->iLambda = g_kiQpCostTable[pCurMb->uiLumaQp];1108 if (iNextMbIdx == -1 || iNextMbIdx >= kiTotalNumMb || iNumMbCoded >= kiTotalNumMb) {
1109 pMd->pMvdCost = &pMvdCostTableInter[pCurMb->uiLumaQp*kiMvdInterTableStride];1109 pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId] =
1110 1110 iCurMbIdx; // update pLastCodedMbIdxOfPartition, finish coding, use pCurMb_idx directly
1111 WelsMdIntraInit(pEncCtx, pCurMb, pMbCache, kiSliceFirstMbXY);1111 break;
1112 WelsMdInterInit(pEncCtx, pSlice, pCurMb, kiSliceFirstMbXY);1112 }
1113 pEncCtx->pFuncList->pfInterMd(pEncCtx, pMd, pSlice, pCurMb, pMbCache);1113 }
1114 //mb_qp1114
1115 1115 if (iMbSkipRun) {
1116 //step (4): save from the MD process from future use1116 BsWriteUE (pBs, iMbSkipRun);
1117 WelsMdInterSaveSadAndRefMbType( (pCurLayer->pDecPic->uiRefMbType), pMbCache, pCurMb, pMd);1117 }
1118 1118}
1119 pEncCtx->pFuncList->pfInterMdBackgroundInfoUpdate( pCurLayer, pCurMb, pMbCache->bCollocatedPredFlag, pEncCtx->pRefPic->iPictureType );1119
1120 1120}//namespace WelsSVCEnc
1121 //step (5): update cache
1122 UpdateNonZeroCountCache( pCurMb, pMbCache );
1123
1124 //step (6): begin to write bit stream; if the pSlice size is controlled, the writing may be skipped
1125
1126 //DYNAMIC_SLICING_ONE_THREAD - MultiD
1127 //stack pBs pointer
1128 sDss.pBsStackBufPtr = pBs->pBufPtr;
1129 sDss.uiBsStackCurBits = pBs->uiCurBits;
1130 sDss.iBsStackLeftBits = pBs->iLeftBits;
1131 //stack Pskip status
1132 sDss.iMbSkipRunStack = iMbSkipRun;
1133 //DYNAMIC_SLICING_ONE_THREAD - MultiD
1134
1135 if( IS_SKIP (pCurMb->uiMbType) )
1136 {
1137 pCurMb->uiLumaQp = pSlice->uiLastMbQp;
1138 pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51(pCurMb->uiLumaQp + kuiChromaQpIndexOffset)];
1139
1140 iMbSkipRun++;
1141 }
1142 else
1143 {
1144 BsWriteUE( pBs, iMbSkipRun );
1145 iMbSkipRun = 0;
1146 WelsSpatialWriteMbSyn( pEncCtx, pSlice, pCurMb );
1147 }
1148
1149 //DYNAMIC_SLICING_ONE_THREAD - MultiD
1150 sDss.iCurrentPos = BsGetBitsPos(pBs);
1151 if ( DynSlcJudgeSliceBoundaryStepBack( pEncCtx, pSlice, pSliceCtx, pCurMb, &sDss ) )
1152 {
1153 //stack pBs pointer
1154 pBs->pBufPtr = sDss.pBsStackBufPtr;
1155 pBs->uiCurBits = sDss.uiBsStackCurBits;
1156 pBs->iLeftBits = sDss.iBsStackLeftBits;
1157
1158 iMbSkipRun = sDss.iMbSkipRunStack;
1159
1160 pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId] = iCurMbIdx-1; // update pLastCodedMbIdxOfPartition, need to -1 due to stepping back
1161 ++ pCurLayer->pNumSliceCodedOfPartition[kiPartitionId];
1162
1163 break;
1164 }
1165
1166 //step (7): reconstruct current MB
1167 pCurMb->uiSliceIdc = kiSliceIdx;
1168 OutputPMbWithoutConstructCsRsNoCopy( pEncCtx, pCurLayer, pSlice, pCurMb );
1169
1170#if defined(MB_TYPES_CHECK)
1171 WelsCountMbType( pEncCtx->sPerInfo.iMbCount, P_SLICE, pCurMb );
1172#endif//MB_TYPES_CHECK
1173
1174 //step (8): update status and other parameters
1175 pEncCtx->pFuncList->pfRc.pfWelsRcMbInfoUpdate(pEncCtx,pCurMb,pMd->iCostLuma,pSlice);
1176
1177 /*judge if all pMb in cur pSlice has been encoded*/
1178 ++ iNumMbCoded;
1179 iNextMbIdx = WelsGetNextMbOfSlice( pSliceCtx, iCurMbIdx );
1180 //whether all of MB in current pSlice encoded or not
1181 if ( iNextMbIdx == -1 || iNextMbIdx >= kiTotalNumMb || iNumMbCoded >= kiTotalNumMb )
1182 {
1183 pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId] = iCurMbIdx; // update pLastCodedMbIdxOfPartition, finish coding, use pCurMb_idx directly
1184 break;
1185 }
1186 }
1187
1188 if ( iMbSkipRun )
1189 {
1190 BsWriteUE( pBs, iMbSkipRun );
1191 }
1192}
1193
1194}//namespace WelsSVCEnc

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