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