History

Initial Commit

Ethan Hugg committed 12 years ago

Commit 70e5e621 parent bd509b2308 files · +97095 −-5Browse files

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

Unified · Split

codec/encoder/core/src/svc_encode_slice.cpp+1194−0
@@ -0,0 +1,1194 @@
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
59namespace WelsSVCEnc {
60//#define ENC_TRACE
61
62typedef void (*PWelsCodingSliceFunc)( sWelsEncCtx *pCtx, SSlice *pSlice );
63typedef void (*PWelsSliceHeaderWriteFunc)( SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice *pSlice, int32_t* pPpsIdDelta );
64
65void 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
78void 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
100void 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)
159void 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*/
198void 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*/
227void 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
267void 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
336void 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
451void 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
462void 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)
487void 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
503void 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)
526void 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
578void 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)
665void 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
681void 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
697void 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
718void 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;
741PWelsCodingSliceFunc g_pWelsSliceCoding[2][2] =
742{
743 { WelsCodePSlice, WelsCodePOverDynamicSlice }, // P SSlice
744 { WelsISliceMdEnc, WelsISliceMdEncDynamic } // I SSlice
745};
746PWelsSliceHeaderWriteFunc g_pWelsWriteSliceHeader[2] = // 0: for base; 1: for ext;
747{
748 WelsSliceHeaderWrite,
749 WelsSliceHeaderExtWrite
750};
751
752
753void 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()
800void 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
856void 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
896BOOL_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
978void 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
1066void 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

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