History

Initial Commit

Ethan Hugg committed 12 years ago

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

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

Unified · Split

codec/decoder/core/src/decoder.cpp+850−0
@@ -0,0 +1,850 @@
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 decoder.c
33 *
34 * \brief Interfaces implementation introduced in decoder system architecture
35 *
36 * \date 03/10/2009 Created
37 *
38 *************************************************************************************
39 */
40#include <string.h>
41#include "macros.h"
42#include "codec_def.h"
43#include "decoder.h"
44#include "error_code.h"
45#include "cpu.h"
46#include "cpu_core.h"
47#include "au_parser.h"
48#include "utils.h"
49#include "nal_prefix.h"
50#include "dec_frame.h"
51#include "pic_queue.h"
52#include "vlc_decoder.h"
53#include "get_intra_predictor.h"
54#include "rec_mb.h"
55#include "mc.h"
56#include "decode_mb_aux.h"
57#include "manage_dec_ref.h"
58#include "codec_app_def.h"
59#include "decoder_core.h"
60#include "deblocking.h"
61#include "expand_pic.h"
62#include "decode_slice.h"
63#include "crt_util_safe_x.h" // Safe CRT routines like utils for cross platforms
64#include "mem_align.h"
65
66namespace WelsDec {
67
68extern PPicture AllocPicture( PWelsDecoderContext pCtx,const int32_t kiPicWidth, const int32_t kiPicHeight );
69
70extern void_t FreePicture( PPicture pPic );
71
72#ifdef WORDS_BIGENDIAN
73inline void_t GetValueOf4Bytes( uint8_t* pDstNal, int32_t iDdstIdx )
74{
75 pDstNal[0] = (iDdstIdx & 0xff000000) >> 24;
76 pDstNal[1] = (iDdstIdx & 0xff0000) >> 16;
77 pDstNal[2] = (iDdstIdx & 0xff00) >> 8;
78 pDstNal[3] = (iDdstIdx & 0xff);
79}
80#else //WORDS_BIGENDIAN
81inline void_t GetValueOf4Bytes( uint8_t* pDstNal, int32_t iDdstIdx )
82{
83 pDstNal[0] = (iDdstIdx & 0xff);
84 pDstNal[1] = (iDdstIdx & 0xff00) >> 8;
85 pDstNal[2] = (iDdstIdx & 0xff0000) >> 16;
86 pDstNal[3] = (iDdstIdx & 0xff000000) >> 24;
87}
88#endif //WORDS_BIGENDIAN
89
90static int32_t CreatePicBuff(PWelsDecoderContext pCtx, PPicBuff *ppPicBuf, const int32_t kiSize, const int32_t kiPicWidth, const int32_t kiPicHeight)
91{
92 PPicBuff pPicBuf = NULL;
93 int32_t iPicIdx = 0;
94 if (kiSize <= 0 || kiPicWidth <= 0 || kiPicHeight <= 0)
95 {
96 return 1;
97 }
98
99 pPicBuf = (PPicBuff)WelsMalloc( sizeof(SPicBuff), "PPicBuff" );
100
101 if ( NULL == pPicBuf )
102 {
103 return 1;
104 }
105
106 pPicBuf->ppPic = (PPicture *)WelsMalloc(kiSize * sizeof(PPicture), "PPicture*");
107
108 if ( NULL == pPicBuf->ppPic )
109 {
110 return 1;
111 }
112 for (iPicIdx = 0; iPicIdx < kiSize; ++ iPicIdx)
113 {
114 PPicture pPic = AllocPicture( pCtx, kiPicWidth, kiPicHeight );
115 if ( NULL == pPic )
116 {
117 return 1;
118 }
119 pPicBuf->ppPic[iPicIdx] = pPic;
120 }
121
122 // initialize context in queue
123 pPicBuf->iCapacity = kiSize;
124 pPicBuf->iCurrentIdx = 0;
125 *ppPicBuf = pPicBuf;
126
127 return 0;
128}
129
130static void_t DestroyPicBuff( PPicBuff *ppPicBuf )
131{
132 PPicBuff pPicBuf = NULL;
133
134 if ( NULL == ppPicBuf || NULL == *ppPicBuf )
135 return;
136
137 pPicBuf = *ppPicBuf;
138 while(pPicBuf->ppPic != NULL)
139 {
140 int32_t iPicIdx = 0;
141 while (iPicIdx < pPicBuf->iCapacity)
142 {
143 PPicture pPic = pPicBuf->ppPic[iPicIdx];
144 if(pPic != NULL)
145 {
146 FreePicture( pPic );
147 }
148 pPic = NULL;
149 ++ iPicIdx;
150 }
151
152 WelsFree(pPicBuf->ppPic, "pPicBuf->queue");
153
154 pPicBuf->ppPic = NULL;
155 }
156 pPicBuf->iCapacity = 0;
157 pPicBuf->iCurrentIdx= 0;
158
159 WelsFree( pPicBuf, "pPicBuf" );
160
161 pPicBuf = NULL;
162 *ppPicBuf = NULL;
163}
164/*
165 * fill data fields in default for decoder context
166 */
167void_t WelsDecoderDefaults( PWelsDecoderContext pCtx )
168{
169 int32_t iCpuCores = 1;
170 memset( pCtx, 0, sizeof(SWelsDecoderContext) ); // fill zero first
171
172 pCtx->pArgDec = NULL;
173
174 pCtx->iOutputColorFormat = videoFormatI420; // yuv in default
175 pCtx->bHaveGotMemory = false; // not ever request memory blocks for decoder context related
176 pCtx->uiCpuFlag = 0;
177
178 pCtx->bAuReadyFlag = 0; // au data is not ready
179
180
181 g_uiCacheLineSize = 16;
182#if defined(X86_ASM)
183 pCtx->uiCpuFlag = WelsCPUFeatureDetect(&iCpuCores);
184#ifdef HAVE_CACHE_LINE_ALIGN
185 if ( pCtx->uiCpuFlag & WELS_CPU_CACHELINE_64 )
186 {
187 g_uiCacheLineSize = 64;
188 }
189 else if ( pCtx->uiCpuFlag & WELS_CPU_CACHELINE_32 )
190 {
191 g_uiCacheLineSize = 32;
192 }
193#endif//HAVE_CACHE_LINE_ALIGN
194#endif//X86_ASM
195
196 pCtx->iImgWidthInPixel = 0;
197 pCtx->iImgHeightInPixel = 0; // alloc picture data when picture size is available
198
199 pCtx->iFrameNum = -1;
200 pCtx->iPrevFrameNum = -1;
201 pCtx->iErrorCode = ERR_NONE;
202
203 pCtx->pDec = NULL;
204
205 WelsResetRefPic(pCtx);
206
207 pCtx->iActiveFmoNum = 0;
208
209 pCtx->pPicBuff[LIST_0] = NULL;
210 pCtx->pPicBuff[LIST_1] = NULL;
211
212 pCtx->bAvcBasedFlag = true;
213
214}
215
216/*
217 * destory_mb_blocks
218 */
219
220
221/*
222 * get size of reference picture list in target layer incoming, = (iNumRefFrames x 2)
223 */
224static inline int32_t GetTargetRefListSize( PWelsDecoderContext pCtx )
225{
226 bool_t *pSubsetSpsAvail= &pCtx->bSubspsAvailFlags[0];
227 bool_t *pSpsAvail = &pCtx->bSpsAvailFlags[0];
228 int32_t iSubsetIdx = -1;
229 int32_t iSpsIdx = -1;
230 bool_t bExistSubsetSps = false;
231 int32_t bExistSps = false;
232 int32_t iPos = MAX_SPS_COUNT - 1;
233 int32_t iNumRefFrames = 0;
234
235 while (iPos >= 0)
236 {
237 if ( pSubsetSpsAvail[iPos] )
238 {
239 bExistSubsetSps = true;
240 iSubsetIdx = iPos;
241 break;
242 }
243 -- iPos;
244 }
245
246 if ( !bExistSubsetSps )
247 {
248 iPos = MAX_SPS_COUNT - 1;
249 while (iPos >= 0)
250 {
251 if ( pSpsAvail[iPos] )
252 {
253 bExistSps = true;
254 iSpsIdx = iPos;
255 break;
256 }
257 -- iPos;
258 }
259 }
260
261 if ( !(bExistSubsetSps || bExistSps) )
262 {
263 iNumRefFrames = MAX_REF_PIC_COUNT;
264 }
265 else
266 {
267 PSps pSps = bExistSubsetSps ? (&pCtx->sSubsetSpsBuffer[iSubsetIdx].sSps) : (&pCtx->sSpsBuffer[iSpsIdx]);
268
269 iNumRefFrames = (pSps->iNumRefFrames ) + 1;
270 }
271
272 if ( 0 == iNumRefFrames )
273 iNumRefFrames = (MIN_REF_PIC_COUNT);
274
275#ifdef LONG_TERM_REF
276 //pic_queue size minimum set 2
277 if (iNumRefFrames <2)
278 {
279 iNumRefFrames = 2;
280 }
281#endif
282
283 return iNumRefFrames;
284}
285
286/*
287 * request memory blocks for decoder avc part
288 */
289int32_t WelsRequestMem( PWelsDecoderContext pCtx, const int32_t kiMbWidth, const int32_t kiMbHeight )
290{
291 const int32_t kiPicWidth = kiMbWidth << 4;
292 const int32_t kiPicHeight = kiMbHeight << 4;
293 int32_t iErr = ERR_NONE;
294
295 int32_t iListIdx = 0; //, mb_blocks = 0;
296 int32_t iPicQueueSize = 0; // adaptive size of picture queue, = (pSps->iNumRefFrames x 2)
297 bool_t bNeedChangePicQueue = true;
298
299 WELS_VERIFY_RETURN_IF( ERR_INFO_INVALID_PARAM, ( NULL == pCtx || kiPicWidth <= 0 || kiPicHeight <= 0 ) )
300
301 // Fixed the issue about different gop size over last, 5/17/2010
302 // get picture queue size currently
303 iPicQueueSize = GetTargetRefListSize( pCtx ); // adaptive size of picture queue, = (pSps->iNumRefFrames x 2)
304 pCtx->iPicQueueNumber = iPicQueueSize;
305 if ( pCtx->pPicBuff[LIST_0] != NULL && pCtx->pPicBuff[LIST_0]->iCapacity == iPicQueueSize ) // comparing current picture queue size requested and previous allocation picture queue
306 bNeedChangePicQueue = false;
307 // HD based pic buffer need consider memory size consumed when switch from 720p to other lower size
308 WELS_VERIFY_RETURN_IF( ERR_NONE, pCtx->bHaveGotMemory && ( kiPicWidth == pCtx->iImgWidthInPixel && kiPicHeight == pCtx->iImgHeightInPixel ) && (!bNeedChangePicQueue) ) // have same scaled buffer
309
310 // sync update pRefList
311 WelsResetRefPic( pCtx ); // added to sync update ref list due to pictures are free
312
313 // for Recycled_Pic_Queue
314 for ( iListIdx = LIST_0; iListIdx < LIST_A; ++ iListIdx )
315 {
316 PPicBuff *ppPic = &pCtx->pPicBuff[iListIdx];
317 if ( NULL != ppPic && NULL != *ppPic )
318 {
319 DestroyPicBuff( ppPic );
320 }
321 }
322
323 // currently only active for LIST_0 due to have no B frames
324 iErr = CreatePicBuff( pCtx, &pCtx->pPicBuff[LIST_0], iPicQueueSize, kiPicWidth, kiPicHeight );
325 if ( iErr != ERR_NONE )
326 return iErr;
327
328
329 pCtx->iImgWidthInPixel = kiPicWidth; // target width of image to be reconstruted while decoding
330 pCtx->iImgHeightInPixel = kiPicHeight; // target height of image to be reconstruted while decoding
331
332 pCtx->bHaveGotMemory = true; // global memory for decoder context related is requested
333 pCtx->pDec = NULL; // need prefetch a new pic due to spatial size changed
334 return ERR_NONE;
335}
336
337/*
338 * free memory blocks in avc
339 */
340void_t WelsFreeMem( PWelsDecoderContext pCtx )
341{
342 int32_t iListIdx = 0;
343
344 /* TODO: free memory blocks introduced in avc */
345 ResetFmoList( pCtx );
346
347 WelsResetRefPic( pCtx );
348
349 // for sPicBuff
350 for ( iListIdx = LIST_0; iListIdx < LIST_A; ++ iListIdx )
351 {
352 PPicBuff *pPicBuff = &pCtx->pPicBuff[iListIdx];
353 if ( NULL != pPicBuff && NULL != *pPicBuff )
354 {
355 DestroyPicBuff( pPicBuff );
356 }
357 }
358
359 // added for safe memory
360 pCtx->iImgWidthInPixel = 0;
361 pCtx->iImgHeightInPixel = 0;
362 pCtx->bHaveGotMemory = false;
363
364}
365
366/*!
367 * \brief Open decoder
368 */
369void_t WelsOpenDecoder( PWelsDecoderContext pCtx )
370{
371 // function pointers
372 //initial MC function pointer--
373 InitMcFunc(&(pCtx->sMcFunc), pCtx->uiCpuFlag);
374
375 InitExpandPictureFunc(&(pCtx->sExpandPicFunc), pCtx->uiCpuFlag);
376 AssignFuncPointerForRec(pCtx);
377
378 // vlc tables
379 InitVlcTable(&pCtx->sVlcTable);
380
381 // startup memory
382 if ( ERR_NONE != WelsInitMemory( pCtx ) )
383 return;
384
385 pCtx->iMaxWidthInSps = 0;
386 pCtx->iMaxHeightInSps = 0;
387#ifdef LONG_TERM_REF
388 pCtx->bParamSetsLostFlag = true;
389#else
390 pCtx->bReferenceLostAtT0Flag = true; // should be true to waiting IDR at incoming AU bits following, 6/4/2010
391#endif //LONG_TERM_REF
392}
393
394/*!
395 * \brief Close decoder
396 */
397void_t WelsCloseDecoder( PWelsDecoderContext pCtx )
398{
399 WelsFreeMem( pCtx );
400
401 WelsFreeMemory( pCtx );
402
403 UninitialDqLayersContext( pCtx );
404
405#ifdef LONG_TERM_REF
406 pCtx->bParamSetsLostFlag = false;
407#else
408 pCtx->bReferenceLostAtT0Flag = false;
409#endif
410}
411
412/*!
413 * \brief configure decoder parameters
414 */
415int32_t DecoderConfigParam ( PWelsDecoderContext pCtx, const void_t* kpParam )
416{
417 if ( NULL == pCtx || NULL == kpParam )
418 return 1;
419
420 pCtx->pParam = (SDecodingParam *)WelsMalloc( sizeof(SDecodingParam), "SDecodingParam" );
421
422 if ( NULL == pCtx->pParam )
423 return 1;
424
425 memcpy( pCtx->pParam, kpParam, sizeof(SDecodingParam) );
426 pCtx->iOutputColorFormat = pCtx->pParam->iOutputColorFormat;
427 pCtx->bErrorResilienceFlag = pCtx->pParam->uiEcActiveFlag ? true : false;
428
429 if ( VIDEO_BITSTREAM_SVC == pCtx->pParam->sVideoProperty.eVideoBsType ||
430 VIDEO_BITSTREAM_AVC == pCtx->pParam->sVideoProperty.eVideoBsType )
431 {
432 pCtx->eVideoType = pCtx->pParam->sVideoProperty.eVideoBsType;
433 }
434 else
435 {
436 pCtx->eVideoType = VIDEO_BITSTREAM_DEFAULT;
437 }
438
439 WelsLog(pCtx, WELS_LOG_INFO, "eVideoType: %d\n", pCtx->eVideoType);
440
441 return 0;
442}
443
444/*!
445 *************************************************************************************
446 * \brief Initialize Wels decoder parameters and memory
447 *
448 * \param pCtx input context to be initialized at first stage
449 *
450 * \return 0 - successed
451 * \return 1 - failed
452 *
453 * \note N/A
454 *************************************************************************************
455 */
456int32_t WelsInitDecoder( PWelsDecoderContext pCtx, void_t * pTraceHandle, PWelsLogCallbackFunc pLog )
457{
458 if ( pCtx == NULL ){
459 return ERR_INFO_INVALID_PTR;
460 }
461
462 // default
463 WelsDecoderDefaults( pCtx );
464
465 pCtx->pTraceHandle = pTraceHandle;
466
467 g_pLog = pLog;
468
469 // open decoder
470 WelsOpenDecoder( pCtx );
471
472 // decode mode setting
473 pCtx->iDecoderMode = SW_MODE;
474 pCtx->iSetMode = AUTO_MODE;
475 pCtx->iDecoderOutputProperty = BUFFER_HOST;
476 pCtx->iModeSwitchType = 0; // 0: do not do mode switch
477
478
479 return ERR_NONE;
480}
481
482/*!
483 *************************************************************************************
484 * \brief Uninitialize Wels decoder parameters and memory
485 *
486 * \param pCtx input context to be uninitialized at release stage
487 *
488 * \return NONE
489 *
490 * \note N/A
491 *************************************************************************************
492 */
493void_t WelsEndDecoder( PWelsDecoderContext pCtx )
494{
495 // close decoder
496 WelsCloseDecoder( pCtx );
497}
498
499void_t GetVclNalTemporalId( PWelsDecoderContext pCtx )
500{
501 PAccessUnit pAccessUnit = pCtx->pAccessUnitList;
502 int32_t idx = pAccessUnit->uiStartPos;
503
504 pCtx->iFeedbackVclNalInAu = FEEDBACK_VCL_NAL;
505 pCtx->iFeedbackTidInAu = pAccessUnit->pNalUnitsList[idx]->sNalHeaderExt.uiTemporalId;
506}
507
508/*!
509 *************************************************************************************
510 * \brief First entrance to decoding core interface.
511 *
512 * \param pCtx decoder context
513 * \param pBufBs bit streaming buffer
514 * \param kBsLen size in bytes length of bit streaming buffer input
515 * \param ppDst picture payload data to be output
516 * \param pDstBufInfo buf information of ouput data
517 *
518 * \return 0 - successed
519 * \return 1 - failed
520 *
521 * \note N/A
522 *************************************************************************************
523 */
524int32_t WelsDecodeBs( PWelsDecoderContext pCtx, const uint8_t *kpBsBuf, const int32_t kiBsLen,
525 uint8_t **ppDst, SBufferInfo* pDstBufInfo)
526{
527 if ( !pCtx->bEndOfStreamFlag)
528 {
529 SDataBuffer* pRawData = &pCtx->sRawData;
530
531 int32_t iSrcIdx = 0; //the index of source bit-stream till now after parsing one or more NALs
532 int32_t iSrcConsumed = 0; // consumed bit count of source bs
533 int32_t iDstIdx = 0; //the size of current NAL after 0x03 removal and 00 00 01 removal
534 int32_t iSrcLength = 0; //the total size of current AU or NAL
535
536 int32_t iConsumedBytes = 0;
537 int32_t iOffset = 0;
538
539 uint8_t* pSrcNal = NULL;
540 uint8_t* pDstNal = NULL;
541 uint8_t *pNalPayload = NULL;
542
543
544 if ( NULL == DetectStartCodePrefix( kpBsBuf, &iOffset, kiBsLen ) ) //CAN'T find the 00 00 01 start prefix from the source buffer
545 {
546 return dsBitstreamError;
547 }
548
549 pSrcNal = const_cast<uint8_t*> (kpBsBuf) + iOffset;
550 iSrcLength = kiBsLen - iOffset;
551
552 if ( (kiBsLen + 4) > ( pRawData->pEnd - pRawData->pCurPos ) )
553 {
554 pRawData->pCurPos = pRawData->pHead;
555 }
556
557
558 //copy raw data from source buffer (application) to raw data buffer (codec inside)
559 //0x03 removal and extract all of NAL Unit from current raw data
560 pDstNal = pRawData->pCurPos + 4; //4-bytes used to write the length of current NAL rbsp
561
562 while ( iSrcConsumed < iSrcLength )
563 {
564 if ( ( 2 + iSrcConsumed < iSrcLength ) &&
565 ( 0 == LD16(pSrcNal+iSrcIdx) ) &&
566 ( (pSrcNal[2+iSrcIdx]==0x03) || (pSrcNal[2+iSrcIdx]==0x01) ) )
567 {
568 if ( pSrcNal[2+iSrcIdx] == 0x03 )
569 {
570 ST16(pDstNal+iDstIdx, 0);
571 iDstIdx += 2;
572 iSrcIdx += 3;
573 iSrcConsumed += 3;
574 }
575 else
576 {
577 GetValueOf4Bytes( pDstNal-4, iDstIdx ); //pDstNal-4 (non-aligned by 4) in Solaris10(SPARC). Given value by byte.
578
579 iConsumedBytes = 0;
580 pNalPayload = ParseNalHeader( pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal-3, iSrcIdx+3, &iConsumedBytes );
581
582 if (pCtx->bAuReadyFlag)
583 {
584 ConstructAccessUnit( pCtx, ppDst, pDstBufInfo );
585
586 if ( (dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode)
587 {
588#ifdef LONG_TERM_REF
589 pCtx->bParamSetsLostFlag = true;
590#else
591 pCtx->bReferenceLostAtT0Flag = true;
592#endif
593 ResetParameterSetsState( pCtx );
594
595 if( dsOutOfMemory & pCtx->iErrorCode){
596 return pCtx->iErrorCode;
597 }
598 }
599 }
600
601 if( (IS_PARAM_SETS_NALS(pCtx->sCurNalHead.eNalUnitType) || IS_SEI_NAL(pCtx->sCurNalHead.eNalUnitType)) &&
602 pNalPayload )
603 {
604 if ( ParseNonVclNal( pCtx, pNalPayload, iDstIdx-iConsumedBytes ) )
605 {
606 if ( dsNoParamSets & pCtx->iErrorCode )
607 {
608#ifdef LONG_TERM_REF
609 pCtx->bParamSetsLostFlag = true;
610#else
611 pCtx->bReferenceLostAtT0Flag = true;
612#endif
613 ResetParameterSetsState( pCtx );
614 }
615 return pCtx->iErrorCode;
616 }
617 }
618
619 pDstNal += iDstIdx; //update current position
620 if ( (iSrcLength - iSrcConsumed + 4) > (pRawData->pEnd - pDstNal) )
621 {
622 pRawData->pCurPos = pRawData->pHead;
623 }
624 else
625 {
626 pRawData->pCurPos = pDstNal;
627 }
628 pDstNal = pRawData->pCurPos + 4; //init, 4 bytes used to store the next NAL
629
630 pSrcNal += iSrcIdx+3;
631 iSrcConsumed += 3;
632 iSrcIdx = 0;
633 iDstIdx = 0; //reset 0, used to statistic the length of next NAL
634 }
635 continue;
636 }
637 pDstNal[iDstIdx++] = pSrcNal[iSrcIdx++];
638 iSrcConsumed++;
639 }
640
641 //last NAL decoding
642 GetValueOf4Bytes( pDstNal-4, iDstIdx ); //pDstNal-4 (non-aligned by 4) in Solaris10(SPARC). Given value by byte.
643
644 iConsumedBytes = 0;
645 pNalPayload = ParseNalHeader( pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal-3, iSrcIdx+3, &iConsumedBytes );
646
647 if (pCtx->bAuReadyFlag)
648 {
649 ConstructAccessUnit( pCtx, ppDst, pDstBufInfo );
650
651 if ( (dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode)
652 {
653#ifdef LONG_TERM_REF
654 pCtx->bParamSetsLostFlag = true;
655#else
656 pCtx->bReferenceLostAtT0Flag = true;
657#endif
658 ResetParameterSetsState( pCtx );
659 return pCtx->iErrorCode;
660 }
661 }
662
663 if( (IS_PARAM_SETS_NALS(pCtx->sCurNalHead.eNalUnitType) || IS_SEI_NAL(pCtx->sCurNalHead.eNalUnitType)) && pNalPayload )
664 {
665 if ( ParseNonVclNal( pCtx, pNalPayload, iDstIdx-iConsumedBytes ) )
666 {
667 if ( dsNoParamSets & pCtx->iErrorCode )
668 {
669#ifdef LONG_TERM_REF
670 pCtx->bParamSetsLostFlag = true;
671#else
672 pCtx->bReferenceLostAtT0Flag = true;
673#endif
674 ResetParameterSetsState( pCtx );
675 }
676 return pCtx->iErrorCode;
677 }
678 }
679
680 pDstNal += iDstIdx;
681 pRawData->pCurPos = pDstNal; //init the pCurPos for next NAL(s) storage
682 }
683 else /* no supplementary picture payload input, but stored a picture */
684 {
685 PAccessUnit pCurAu = pCtx->pAccessUnitList; // current access unit, it will never point to NULL after decode's successful initialization
686
687 if ( pCurAu->uiAvailUnitsNum == 0 )
688 {
689 return pCtx->iErrorCode;
690 }
691 else
692 {
693 pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
694
695 ConstructAccessUnit( pCtx, ppDst, pDstBufInfo );
696
697 if ( (dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode)
698 {
699#ifdef LONG_TERM_REF
700 pCtx->bParamSetsLostFlag = true;
701#else
702 pCtx->bReferenceLostAtT0Flag = true;
703#endif
704 ResetParameterSetsState( pCtx );
705 return pCtx->iErrorCode;
706 }
707
708 }
709 }
710
711 return pCtx->iErrorCode;
712}
713
714/*
715 * set colorspace format in decoder
716 */
717int32_t DecoderSetCsp(PWelsDecoderContext pCtx, const int32_t kiColorFormat)
718{
719 WELS_VERIFY_RETURN_IF( 1, (NULL == pCtx) );
720
721 pCtx->iOutputColorFormat = kiColorFormat;
722 if ( pCtx->pParam != NULL )
723 {
724 pCtx->pParam->iOutputColorFormat = kiColorFormat;
725 }
726
727 return 0;
728}
729
730/*!
731 * \brief make sure synchonozization picture resolution (get from slice header) among different parts (i.e, memory related and so on)
732 * over decoder internal
733 * ( MB coordinate and parts of data within decoder context structure )
734 * \param pCtx Wels decoder context
735 * \param iMbWidth MB width
736 * \pram iMbHeight MB height
737 * \return 0 - successful; none 0 - something wrong
738 */
739int32_t SyncPictureResolutionExt( PWelsDecoderContext pCtx, const int32_t kiMbWidth, const int32_t kiMbHeight )
740{
741 int32_t iErr = ERR_NONE;
742 const int32_t kiPicWidth = kiMbWidth << 4;
743 const int32_t kiPicHeight = kiMbHeight<< 4;
744
745 iErr = WelsRequestMem( pCtx, kiMbWidth, kiMbHeight ); // common memory used
746 if ( ERR_NONE != iErr )
747 {
748 WelsLog( pCtx, WELS_LOG_WARNING, "SyncPictureResolutionExt()::WelsRequestMem--buffer allocated failure.\n" );
749 pCtx->iErrorCode = dsOutOfMemory;
750 return iErr;
751 }
752
753 iErr = InitialDqLayersContext( pCtx, kiPicWidth, kiPicHeight );
754 if ( ERR_NONE != iErr )
755 {
756 WelsLog( pCtx, WELS_LOG_WARNING, "SyncPictureResolutionExt()::InitialDqLayersContext--buffer allocated failure.\n" );
757 pCtx->iErrorCode = dsOutOfMemory;
758 }
759
760 return iErr;
761}
762
763/*!
764 * \brief update maximal picture width and height if applicable when receiving a SPS NAL
765 */
766void_t UpdateMaxPictureResolution( PWelsDecoderContext pCtx, const int32_t kiCurWidth, const int32_t kiCurHeight )
767{
768 //any dimension larger than that of current dimension, should modify the max-dimension
769 if ( kiCurWidth > pCtx->iMaxWidthInSps || kiCurHeight > pCtx->iMaxHeightInSps)
770 {
771 pCtx->iMaxWidthInSps = kiCurWidth;
772 pCtx->iMaxHeightInSps = kiCurHeight;
773 }
774
775 return;
776}
777
778void_t AssignFuncPointerForRec(PWelsDecoderContext pCtx)
779{
780 pCtx->pGetI16x16LumaPredFunc[I16_PRED_V ] = WelsI16x16LumaPredV_c;
781 pCtx->pGetI16x16LumaPredFunc[I16_PRED_H ] = WelsI16x16LumaPredH_c;
782 pCtx->pGetI16x16LumaPredFunc[I16_PRED_DC ] = WelsI16x16LumaPredDc_c;
783 pCtx->pGetI16x16LumaPredFunc[I16_PRED_P ] = WelsI16x16LumaPredPlane_c;
784 pCtx->pGetI16x16LumaPredFunc[I16_PRED_DC_L ] = WelsI16x16LumaPredDcLeft_c;
785 pCtx->pGetI16x16LumaPredFunc[I16_PRED_DC_T ] = WelsI16x16LumaPredDcTop_c;
786 pCtx->pGetI16x16LumaPredFunc[I16_PRED_DC_128] = WelsI16x16LumaPredDcNA_c;
787
788 pCtx->pGetI4x4LumaPredFunc[I4_PRED_V ] = WelsI4x4LumaPredV_c;
789 pCtx->pGetI4x4LumaPredFunc[I4_PRED_H ] = WelsI4x4LumaPredH_c;
790 pCtx->pGetI4x4LumaPredFunc[I4_PRED_DC ] = WelsI4x4LumaPredDc_c;
791 pCtx->pGetI4x4LumaPredFunc[I4_PRED_DC_L ] = WelsI4x4LumaPredDcLeft_c;
792 pCtx->pGetI4x4LumaPredFunc[I4_PRED_DC_T ] = WelsI4x4LumaPredDcTop_c;
793 pCtx->pGetI4x4LumaPredFunc[I4_PRED_DC_128] = WelsI4x4LumaPredDcNA_c;
794 pCtx->pGetI4x4LumaPredFunc[I4_PRED_DDL ] = WelsI4x4LumaPredDDL_c;
795 pCtx->pGetI4x4LumaPredFunc[I4_PRED_DDL_TOP] = WelsI4x4LumaPredDDLTop_c;
796 pCtx->pGetI4x4LumaPredFunc[I4_PRED_DDR ] = WelsI4x4LumaPredDDR_c;
797 pCtx->pGetI4x4LumaPredFunc[I4_PRED_VL ] = WelsI4x4LumaPredVL_c;
798 pCtx->pGetI4x4LumaPredFunc[I4_PRED_VL_TOP] = WelsI4x4LumaPredVLTop_c;
799 pCtx->pGetI4x4LumaPredFunc[I4_PRED_VR ] = WelsI4x4LumaPredVR_c;
800 pCtx->pGetI4x4LumaPredFunc[I4_PRED_HU ] = WelsI4x4LumaPredHU_c;
801 pCtx->pGetI4x4LumaPredFunc[I4_PRED_HD ] = WelsI4x4LumaPredHD_c;
802
803 pCtx->pGetIChromaPredFunc[C_PRED_DC ] = WelsIChromaPredDc_c;
804 pCtx->pGetIChromaPredFunc[C_PRED_H ] = WelsIChromaPredH_c;
805 pCtx->pGetIChromaPredFunc[C_PRED_V ] = WelsIChromaPredV_c;
806 pCtx->pGetIChromaPredFunc[C_PRED_P ] = WelsIChromaPredPlane_c;
807 pCtx->pGetIChromaPredFunc[C_PRED_DC_L ] = WelsIChromaPredDcLeft_c;
808 pCtx->pGetIChromaPredFunc[C_PRED_DC_T ] = WelsIChromaPredDcTop_c;
809 pCtx->pGetIChromaPredFunc[C_PRED_DC_128] = WelsIChromaPredDcNA_c;
810
811 InitDctClipTable();
812 pCtx->pIdctResAddPredFunc = IdctResAddPred_c;
813
814#if defined(X86_ASM)
815 if ( pCtx->uiCpuFlag & WELS_CPU_MMXEXT )
816 {
817 pCtx->pIdctResAddPredFunc = IdctResAddPred_mmx;
818
819 /////////mmx code opt---
820 pCtx->pGetIChromaPredFunc[C_PRED_H] = WelsIChromaPredH_mmx;
821 pCtx->pGetIChromaPredFunc[C_PRED_V] = WelsIChromaPredV_mmx;
822 pCtx->pGetIChromaPredFunc[C_PRED_DC_L ] = WelsIChromaPredDcLeft_mmx;
823 pCtx->pGetIChromaPredFunc[C_PRED_DC_128] = WelsIChromaPredDcNA_mmx;
824 pCtx->pGetI4x4LumaPredFunc[I4_PRED_DDR] = WelsI4x4LumaPredDDR_mmx;
825 pCtx->pGetI4x4LumaPredFunc[I4_PRED_HD ] = WelsI4x4LumaPredHD_mmx;
826 pCtx->pGetI4x4LumaPredFunc[I4_PRED_HU ] = WelsI4x4LumaPredHU_mmx;
827 pCtx->pGetI4x4LumaPredFunc[I4_PRED_VR ] = WelsI4x4LumaPredVR_mmx;
828 pCtx->pGetI4x4LumaPredFunc[I4_PRED_DDL] = WelsI4x4LumaPredDDL_mmx;
829 pCtx->pGetI4x4LumaPredFunc[I4_PRED_VL ] = WelsI4x4LumaPredVL_mmx;
830 }
831 if ( pCtx->uiCpuFlag & WELS_CPU_SSE2 )
832 {
833 /////////sse2 code opt---
834 pCtx->pGetI16x16LumaPredFunc[I16_PRED_DC] = WelsI16x16LumaPredDc_sse2;
835 pCtx->pGetI16x16LumaPredFunc[I16_PRED_P] = WelsI16x16LumaPredPlane_sse2;
836 pCtx->pGetI16x16LumaPredFunc[I16_PRED_H] = WelsI16x16LumaPredH_sse2;
837 pCtx->pGetI16x16LumaPredFunc[I16_PRED_V] = WelsI16x16LumaPredV_sse2;
838 pCtx->pGetI16x16LumaPredFunc[I16_PRED_DC_T ] = WelsI16x16LumaPredDcTop_sse2;
839 pCtx->pGetI16x16LumaPredFunc[I16_PRED_DC_128] = WelsI16x16LumaPredDcNA_sse2;
840 pCtx->pGetIChromaPredFunc[C_PRED_P ] = WelsIChromaPredPlane_sse2;
841 pCtx->pGetIChromaPredFunc[C_PRED_DC] = WelsIChromaPredDc_sse2;
842 pCtx->pGetIChromaPredFunc[C_PRED_DC_T] = WelsIChromaPredDcTop_sse2;
843 }
844#endif
845 DeblockingInit(&pCtx->sDeblockingFunc, pCtx->uiCpuFlag);
846
847 WelsBlockFuncInit(&pCtx->sBlockFunc, pCtx->uiCpuFlag);
848}
849
850} // namespace WelsDec

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t