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+
66+namespace WelsDec {
67+
68+extern PPicture AllocPicture( PWelsDecoderContext pCtx,const int32_t kiPicWidth, const int32_t kiPicHeight );
69+
70+extern void_t FreePicture( PPicture pPic );
71+
72+#ifdef WORDS_BIGENDIAN
73+inline 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
81+inline 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+
90+static 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+
130+static 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+ */
167+void_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+ */
224+static 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+ */
289+int32_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+ */
340+void_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+ */
369+void_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+ */
397+void_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+ */
415+int32_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+ */
456+int32_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+ */
493+void_t WelsEndDecoder( PWelsDecoderContext pCtx )
494+{
495+ // close decoder
496+ WelsCloseDecoder( pCtx );
497+}
498+
499+void_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+ */
524+int32_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+ */
717+int32_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+ */
739+int32_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+ */
766+void_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+
778+void_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