History

Restore unix newlines after "Merge pull request #2991 from xiaotianshi2/master"

Some newlines were fixed in "Merge pull request #2997 from GuangweiWang/fix-issue-external", but lots were still left behind.

Martin Storsjö committed 8 years ago

Commit 1fb2f7d1 parent d43bfc114 files · +9238 −9238Browse files

Showing the changes to codec/decoder/plus/src/welsDecoderExt.cpp (1 of 14 files). Show all

Unified · Split

codec/decoder/plus/src/welsDecoderExt.cpp+1016−1016
@@ -1,1016 +1,1016 @@
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− * welsDecoderExt.cpp
33− *
34− * Abstract
35− * Cisco OpenH264 decoder extension utilization
36− *
37− * History
38− * 3/12/2009 Created
39− *
40− *
41− ************************************************************************/
42−//#include <assert.h>
43−#include "welsDecoderExt.h"
44−#include "welsCodecTrace.h"
45−#include "codec_def.h"
46−#include "typedefs.h"
47−#include "memory_align.h"
48−#include "utils.h"
49−#include "version.h"
50−
51−//#include "macros.h"
52−#include "decoder.h"
53−#include "decoder_core.h"
54−#include "error_concealment.h"
55−
56−#include "measure_time.h"
57−extern "C" {
58−#include "decoder_core.h"
59−#include "manage_dec_ref.h"
60−}
61−#include "error_code.h"
62−#include "crt_util_safe_x.h" // Safe CRT routines like util for cross platforms
63−#include <time.h>
64−#if defined(_WIN32) /*&& defined(_DEBUG)*/
65−
66−#include <windows.h>
67−#include <stdio.h>
68−#include <stdarg.h>
69−#include <sys/types.h>
70−#else
71−#include <sys/time.h>
72−#endif
73−
74−#define _PICTURE_REORDERING_ 1
75−
76−static int32_t sIMinInt32 = -0x7FFFFFFF;
77−
78−namespace WelsDec {
79−
80−//////////////////////////////////////////////////////////////////////
81−// Construction/Destruction
82−//////////////////////////////////////////////////////////////////////
83−
84−/***************************************************************************
85−* Description:
86−* class CWelsDecoder constructor function, do initialization and
87−* alloc memory required
88−*
89−* Input parameters: none
90−*
91−* return: none
92−***************************************************************************/
93−CWelsDecoder::CWelsDecoder (void)
94− : m_pDecContext (NULL),
95− m_pWelsTrace (NULL),
96− m_iPictInfoIndex (0),
97− m_iMinPOC (sIMinInt32),
98− m_iNumOfPicts (0),
99− m_iLastGOPRemainPicts (0),
100− m_LastWrittenPOC (sIMinInt32),
101− m_iLargestBufferedPicIndex (0) {
102−#ifdef OUTPUT_BIT_STREAM
103− char chFileName[1024] = { 0 }; //for .264
104− int iBufUsed = 0;
105− int iBufLeft = 1023;
106− int iCurUsed;
107−
108− char chFileNameSize[1024] = { 0 }; //for .len
109− int iBufUsedSize = 0;
110− int iBufLeftSize = 1023;
111− int iCurUsedSize;
112−#endif//OUTPUT_BIT_STREAM
113−
114−
115− m_pWelsTrace = new welsCodecTrace();
116− if (m_pWelsTrace != NULL) {
117− m_pWelsTrace->SetCodecInstance (this);
118− m_pWelsTrace->SetTraceLevel (WELS_LOG_ERROR);
119−
120− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::CWelsDecoder() entry");
121− }
122−
123− for (int32_t i = 0; i < 16; ++i) {
124− m_sPictInfoList[i].bLastGOP = false;
125− m_sPictInfoList[i].iPOC = sIMinInt32;
126− }
127−
128−#ifdef OUTPUT_BIT_STREAM
129− SWelsTime sCurTime;
130−
131− WelsGetTimeOfDay (&sCurTime);
132−
133− iCurUsed = WelsSnprintf (chFileName, iBufLeft, "bs_0x%p_", (void*)this);
134− iCurUsedSize = WelsSnprintf (chFileNameSize, iBufLeftSize, "size_0x%p_", (void*)this);
135−
136− iBufUsed += iCurUsed;
137− iBufLeft -= iCurUsed;
138− if (iBufLeft > 0) {
139− iCurUsed = WelsStrftime (&chFileName[iBufUsed], iBufLeft, "%y%m%d%H%M%S", &sCurTime);
140− iBufUsed += iCurUsed;
141− iBufLeft -= iCurUsed;
142− }
143−
144− iBufUsedSize += iCurUsedSize;
145− iBufLeftSize -= iCurUsedSize;
146− if (iBufLeftSize > 0) {
147− iCurUsedSize = WelsStrftime (&chFileNameSize[iBufUsedSize], iBufLeftSize, "%y%m%d%H%M%S", &sCurTime);
148− iBufUsedSize += iCurUsedSize;
149− iBufLeftSize -= iCurUsedSize;
150− }
151−
152− if (iBufLeft > 0) {
153− iCurUsed = WelsSnprintf (&chFileName[iBufUsed], iBufLeft, ".%03.3u.264", WelsGetMillisecond (&sCurTime));
154− iBufUsed += iCurUsed;
155− iBufLeft -= iCurUsed;
156− }
157−
158− if (iBufLeftSize > 0) {
159− iCurUsedSize = WelsSnprintf (&chFileNameSize[iBufUsedSize], iBufLeftSize, ".%03.3u.len",
160− WelsGetMillisecond (&sCurTime));
161− iBufUsedSize += iCurUsedSize;
162− iBufLeftSize -= iCurUsedSize;
163− }
164−
165−
166− m_pFBS = WelsFopen (chFileName, "wb");
167− m_pFBSSize = WelsFopen (chFileNameSize, "wb");
168−#endif//OUTPUT_BIT_STREAM
169−}
170−
171−/***************************************************************************
172−* Description:
173−* class CWelsDecoder destructor function, destroy allocced memory
174−*
175−* Input parameters: none
176−*
177−* return: none
178−***************************************************************************/
179−CWelsDecoder::~CWelsDecoder() {
180− if (m_pWelsTrace != NULL) {
181− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::~CWelsDecoder()");
182− }
183−
184− UninitDecoder();
185−
186−#ifdef OUTPUT_BIT_STREAM
187− if (m_pFBS) {
188− WelsFclose (m_pFBS);
189− m_pFBS = NULL;
190− }
191− if (m_pFBSSize) {
192− WelsFclose (m_pFBSSize);
193− m_pFBSSize = NULL;
194− }
195−#endif//OUTPUT_BIT_STREAM
196−
197− if (m_pWelsTrace != NULL) {
198− delete m_pWelsTrace;
199− m_pWelsTrace = NULL;
200− }
201−}
202−
203−long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
204− int iRet = ERR_NONE;
205− if (m_pWelsTrace == NULL) {
206− return cmMallocMemeError;
207− }
208−
209− if (pParam == NULL) {
210− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsDecoder::Initialize(), invalid input argument.");
211− return cmInitParaError;
212− }
213−
214− // H.264 decoder initialization,including memory allocation,then open it ready to decode
215− iRet = InitDecoder (pParam);
216− if (iRet)
217− return iRet;
218−
219− return cmResultSuccess;
220−}
221−
222−long CWelsDecoder::Uninitialize() {
223− UninitDecoder();
224−
225− return ERR_NONE;
226−}
227−
228−void CWelsDecoder::UninitDecoder (void) {
229− if (NULL == m_pDecContext)
230− return;
231−
232− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::UninitDecoder(), openh264 codec version = %s.",
233− VERSION_NUMBER);
234−
235− WelsEndDecoder (m_pDecContext);
236−
237− if (m_pDecContext->pMemAlign != NULL) {
238− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
239− "CWelsDecoder::UninitDecoder(), verify memory usage (%d bytes) after free..",
240− m_pDecContext->pMemAlign->WelsGetMemoryUsage());
241− delete m_pDecContext->pMemAlign;
242− m_pDecContext->pMemAlign = NULL;
243− }
244−
245− if (NULL != m_pDecContext) {
246− WelsFree (m_pDecContext, "m_pDecContext");
247−
248− m_pDecContext = NULL;
249− }
250−}
251−
252−// the return value of this function is not suitable, it need report failure info to upper layer.
253−int32_t CWelsDecoder::InitDecoder (const SDecodingParam* pParam) {
254−
255− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
256− "CWelsDecoder::init_decoder(), openh264 codec version = %s, ParseOnly = %d",
257− VERSION_NUMBER, (int32_t)pParam->bParseOnly);
258−
259− //reset decoder context
260− if (m_pDecContext) //free
261− UninitDecoder();
262− m_pDecContext = (PWelsDecoderContext)WelsMallocz (sizeof (SWelsDecoderContext), "m_pDecContext");
263− if (NULL == m_pDecContext)
264− return cmMallocMemeError;
265− int32_t iCacheLineSize = 16; // on chip cache line size in byte
266− m_pDecContext->pMemAlign = new CMemoryAlign (iCacheLineSize);
267− WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pMemAlign), UninitDecoder())
268−
269− //fill in default value into context
270− WelsDecoderDefaults (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
271−
272− //check param and update decoder context
273− m_pDecContext->pParam = (SDecodingParam*)m_pDecContext->pMemAlign->WelsMallocz (sizeof (SDecodingParam),
274− "SDecodingParam");
275− WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pParam), UninitDecoder());
276− int32_t iRet = DecoderConfigParam (m_pDecContext, pParam);
277− WELS_VERIFY_RETURN_IFNEQ (iRet, cmResultSuccess);
278−
279− //init decoder
280− WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx),
281− UninitDecoder())
282−
283− return cmResultSuccess;
284−}
285−
286−int32_t CWelsDecoder::ResetDecoder() {
287− // TBC: need to be modified when context and trace point are null
288− if (m_pDecContext != NULL && m_pWelsTrace != NULL) {
289− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ResetDecoder(), context error code is %d",
290− m_pDecContext->iErrorCode);
291− SDecodingParam sPrevParam;
292− memcpy (&sPrevParam, m_pDecContext->pParam, sizeof (SDecodingParam));
293−
294− WELS_VERIFY_RETURN_PROC_IF (cmInitParaError, InitDecoder (&sPrevParam), UninitDecoder());
295− } else if (m_pWelsTrace != NULL) {
296− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "ResetDecoder() failed as decoder context null");
297− }
298− return ERR_INFO_UNINIT;
299−}
300−
301−/*
302− * Set Option
303− */
304−long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
305− int iVal = 0;
306−
307− if (m_pDecContext == NULL && eOptID != DECODER_OPTION_TRACE_LEVEL &&
308− eOptID != DECODER_OPTION_TRACE_CALLBACK && eOptID != DECODER_OPTION_TRACE_CALLBACK_CONTEXT)
309− return dsInitialOptExpected;
310− if (eOptID == DECODER_OPTION_END_OF_STREAM) { // Indicate bit-stream of the final frame to be decoded
311− if (pOption == NULL)
312− return cmInitParaError;
313−
314− iVal = * ((int*)pOption); // boolean value for whether enabled End Of Stream flag
315−
316− m_pDecContext->bEndOfStreamFlag = iVal ? true : false;
317−
318− return cmResultSuccess;
319− } else if (eOptID == DECODER_OPTION_ERROR_CON_IDC) { // Indicate error concealment status
320− if (pOption == NULL)
321− return cmInitParaError;
322−
323− iVal = * ((int*)pOption); // int value for error concealment idc
324− iVal = WELS_CLIP3 (iVal, (int32_t)ERROR_CON_DISABLE, (int32_t)ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE);
325− if ((m_pDecContext->pParam->bParseOnly) && (iVal != (int32_t)ERROR_CON_DISABLE)) {
326− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
327− "CWelsDecoder::SetOption for ERROR_CON_IDC = %d not allowd for parse only!.", iVal);
328− return cmInitParaError;
329− }
330−
331− m_pDecContext->pParam->eEcActiveIdc = (ERROR_CON_IDC)iVal;
332− InitErrorCon (m_pDecContext);
333− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
334− "CWelsDecoder::SetOption for ERROR_CON_IDC = %d.", iVal);
335−
336− return cmResultSuccess;
337− } else if (eOptID == DECODER_OPTION_TRACE_LEVEL) {
338− if (m_pWelsTrace) {
339− uint32_t level = * ((uint32_t*)pOption);
340− m_pWelsTrace->SetTraceLevel (level);
341− }
342− return cmResultSuccess;
343− } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK) {
344− if (m_pWelsTrace) {
345− WelsTraceCallback callback = * ((WelsTraceCallback*)pOption);
346− m_pWelsTrace->SetTraceCallback (callback);
347− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
348− "CWelsDecoder::SetOption():DECODER_OPTION_TRACE_CALLBACK callback = %p.",
349− callback);
350− }
351− return cmResultSuccess;
352− } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK_CONTEXT) {
353− if (m_pWelsTrace) {
354− void* ctx = * ((void**)pOption);
355− m_pWelsTrace->SetTraceCallbackContext (ctx);
356− }
357− return cmResultSuccess;
358− } else if (eOptID == DECODER_OPTION_GET_STATISTICS) {
359− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
360− "CWelsDecoder::SetOption():DECODER_OPTION_GET_STATISTICS: this option is get-only!");
361− return cmInitParaError;
362− } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
363− if (pOption) {
364− m_pDecContext->sDecoderStatistics.iStatisticsLogInterval = (* ((unsigned int*)pOption));
365− return cmResultSuccess;
366− }
367− } else if (eOptID == DECODER_OPTION_GET_SAR_INFO) {
368− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
369− "CWelsDecoder::SetOption():DECODER_OPTION_GET_SAR_INFO: this option is get-only!");
370− return cmInitParaError;
371− }
372− return cmInitParaError;
373−}
374−
375−/*
376− * Get Option
377− */
378−long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) {
379− int iVal = 0;
380−
381− if (m_pDecContext == NULL)
382− return cmInitExpected;
383−
384− if (pOption == NULL)
385− return cmInitParaError;
386−
387− if (DECODER_OPTION_END_OF_STREAM == eOptID) {
388− iVal = m_pDecContext->bEndOfStreamFlag;
389− * ((int*)pOption) = iVal;
390− return cmResultSuccess;
391− }
392−#ifdef LONG_TERM_REF
393− else if (DECODER_OPTION_IDR_PIC_ID == eOptID) {
394− iVal = m_pDecContext->uiCurIdrPicId;
395− * ((int*)pOption) = iVal;
396− return cmResultSuccess;
397− } else if (DECODER_OPTION_FRAME_NUM == eOptID) {
398− iVal = m_pDecContext->iFrameNum;
399− * ((int*)pOption) = iVal;
400− return cmResultSuccess;
401− } else if (DECODER_OPTION_LTR_MARKING_FLAG == eOptID) {
402− iVal = m_pDecContext->bCurAuContainLtrMarkSeFlag;
403− * ((int*)pOption) = iVal;
404− return cmResultSuccess;
405− } else if (DECODER_OPTION_LTR_MARKED_FRAME_NUM == eOptID) {
406− iVal = m_pDecContext->iFrameNumOfAuMarkedLtr;
407− * ((int*)pOption) = iVal;
408− return cmResultSuccess;
409− }
410−#endif
411− else if (DECODER_OPTION_VCL_NAL == eOptID) { //feedback whether or not have VCL NAL in current AU
412− iVal = m_pDecContext->iFeedbackVclNalInAu;
413− * ((int*)pOption) = iVal;
414− return cmResultSuccess;
415− } else if (DECODER_OPTION_TEMPORAL_ID == eOptID) { //if have VCL NAL in current AU, then feedback the temporal ID
416− iVal = m_pDecContext->iFeedbackTidInAu;
417− * ((int*)pOption) = iVal;
418− return cmResultSuccess;
419− } else if (DECODER_OPTION_IS_REF_PIC == eOptID) {
420− iVal = m_pDecContext->iFeedbackNalRefIdc;
421− if (iVal > 0)
422− iVal = 1;
423− * ((int*)pOption) = iVal;
424− return cmResultSuccess;
425− } else if (DECODER_OPTION_ERROR_CON_IDC == eOptID) {
426− iVal = (int)m_pDecContext->pParam->eEcActiveIdc;
427− * ((int*)pOption) = iVal;
428− return cmResultSuccess;
429− } else if (DECODER_OPTION_GET_STATISTICS == eOptID) { // get decoder statistics info for real time debugging
430− SDecoderStatistics* pDecoderStatistics = (static_cast<SDecoderStatistics*> (pOption));
431−
432− memcpy (pDecoderStatistics, &m_pDecContext->sDecoderStatistics, sizeof (SDecoderStatistics));
433−
434− if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount != 0) { //not original status
435− pDecoderStatistics->fAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /
436− (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount);
437− pDecoderStatistics->fActualAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /
438− (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount + m_pDecContext->sDecoderStatistics.uiFreezingIDRNum +
439− m_pDecContext->sDecoderStatistics.uiFreezingNonIDRNum);
440− }
441− return cmResultSuccess;
442− } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
443− if (pOption) {
444− iVal = m_pDecContext->sDecoderStatistics.iStatisticsLogInterval;
445− * ((unsigned int*)pOption) = iVal;
446− return cmResultSuccess;
447− }
448− } else if (DECODER_OPTION_GET_SAR_INFO == eOptID) { //get decoder SAR info in VUI
449− PVuiSarInfo pVuiSarInfo = (static_cast<PVuiSarInfo> (pOption));
450− memset (pVuiSarInfo, 0, sizeof (SVuiSarInfo));
451− if (!m_pDecContext->pSps) {
452− return cmInitExpected;
453− } else {
454− pVuiSarInfo->uiSarWidth = m_pDecContext->pSps->sVui.uiSarWidth;
455− pVuiSarInfo->uiSarHeight = m_pDecContext->pSps->sVui.uiSarHeight;
456− pVuiSarInfo->bOverscanAppropriateFlag = m_pDecContext->pSps->sVui.bOverscanAppropriateFlag;
457− return cmResultSuccess;
458− }
459− } else if (DECODER_OPTION_PROFILE == eOptID) {
460− if (!m_pDecContext->pSps) {
461− return cmInitExpected;
462− }
463− iVal = (int)m_pDecContext->pSps->uiProfileIdc;
464− * ((int*)pOption) = iVal;
465− return cmResultSuccess;
466− } else if (DECODER_OPTION_LEVEL == eOptID) {
467− if (!m_pDecContext->pSps) {
468− return cmInitExpected;
469− }
470− iVal = (int)m_pDecContext->pSps->uiLevelIdc;
471− * ((int*)pOption) = iVal;
472− return cmResultSuccess;
473− } else if (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER == eOptID) {
474− if (m_pDecContext->pSps && m_pDecContext->pSps->uiProfileIdc != 66 && m_pDecContext->pPps->bEntropyCodingModeFlag) {
475− * ((int*)pOption) = m_iNumOfPicts > 0 ? m_iNumOfPicts : 0;
476− }
477− return cmResultSuccess;
478− }
479−
480− return cmInitParaError;
481−}
482−
483−DECODING_STATE CWelsDecoder::DecodeFrameNoDelay (const unsigned char* kpSrc,
484− const int kiSrcLen,
485− unsigned char** ppDst,
486− SBufferInfo* pDstInfo) {
487− int iRet;
488− //SBufferInfo sTmpBufferInfo;
489− //unsigned char* ppTmpDst[3] = {NULL, NULL, NULL};
490− iRet = (int)DecodeFrame2 (kpSrc, kiSrcLen, ppDst, pDstInfo);
491− //memcpy (&sTmpBufferInfo, pDstInfo, sizeof (SBufferInfo));
492− //ppTmpDst[0] = ppDst[0];
493− //ppTmpDst[1] = ppDst[1];
494− //ppTmpDst[2] = ppDst[2];
495− iRet |= DecodeFrame2 (NULL, 0, ppDst, pDstInfo);
496− //if ((pDstInfo->iBufferStatus == 0) && (sTmpBufferInfo.iBufferStatus == 1)) {
497− //memcpy (pDstInfo, &sTmpBufferInfo, sizeof (SBufferInfo));
498− //ppDst[0] = ppTmpDst[0];
499− //ppDst[1] = ppTmpDst[1];
500− //ppDst[2] = ppTmpDst[2];
501− //}
502− return (DECODING_STATE)iRet;
503−}
504−
505−DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
506− const int kiSrcLen,
507− unsigned char** ppDst,
508− SBufferInfo* pDstInfo) {
509− if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {
510− if (m_pWelsTrace != NULL) {
511− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeFrame2 without Initialize.\n");
512− }
513− return dsInitialOptExpected;
514− }
515−
516− if (m_pDecContext->pParam->bParseOnly) {
517− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be false for this API calling! \n");
518− m_pDecContext->iErrorCode |= dsInvalidArgument;
519− return dsInvalidArgument;
520− }
521− if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {
522− if (ResetDecoder())
523− return dsOutOfMemory;
524−
525− return dsErrorFree;
526− }
527− if (kiSrcLen > 0 && kpSrc != NULL) {
528−#ifdef OUTPUT_BIT_STREAM
529− if (m_pFBS) {
530− WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS);
531− WelsFflush (m_pFBS);
532− }
533− if (m_pFBSSize) {
534− WelsFwrite (&kiSrcLen, sizeof (int), 1, m_pFBSSize);
535− WelsFflush (m_pFBSSize);
536− }
537−#endif//OUTPUT_BIT_STREAM
538− m_pDecContext->bEndOfStreamFlag = false;
539− } else {
540− //For application MODE, the error detection should be added for safe.
541− //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
542− m_pDecContext->bEndOfStreamFlag = true;
543− m_pDecContext->bInstantDecFlag = true;
544− }
545−
546− int64_t iStart, iEnd;
547− iStart = WelsTime();
548−
549− ppDst[0] = ppDst[1] = ppDst[2] = NULL;
550− m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
551− m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
552− unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;
553− memset (pDstInfo, 0, sizeof (SBufferInfo));
554− pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;
555−#ifdef LONG_TERM_REF
556− m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
557− m_pDecContext->bCurAuContainLtrMarkSeFlag = false;
558− m_pDecContext->iFrameNumOfAuMarkedLtr = 0;
559− m_pDecContext->iFrameNum = -1; //initialize
560−#endif
561−
562− m_pDecContext->iFeedbackTidInAu = -1; //initialize
563− m_pDecContext->iFeedbackNalRefIdc = -1; //initialize
564− if (pDstInfo) {
565− pDstInfo->uiOutYuvTimeStamp = 0;
566− m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
567− } else {
568− m_pDecContext->uiTimeStamp = 0;
569− }
570− WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, ppDst,
571− pDstInfo, NULL); //iErrorCode has been modified in this function
572− m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
573− if (m_pDecContext->iErrorCode) {
574− EWelsNalUnitType eNalType =
575− NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently
576−
577− eNalType = m_pDecContext->sCurNalHead.eNalUnitType;
578−
579− if (m_pDecContext->iErrorCode & dsOutOfMemory) {
580− if (ResetDecoder())
581− return dsOutOfMemory;
582−
583− return dsErrorFree;
584− }
585− //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.
586− if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||
587− (VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType)) {
588− if (m_pDecContext->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
589−#ifdef LONG_TERM_REF
590− m_pDecContext->bParamSetsLostFlag = true;
591−#else
592− m_pDecContext->bReferenceLostAtT0Flag = true;
593−#endif
594− }
595− }
596−
597− if (m_pDecContext->bPrintFrameErrorTraceFlag) {
598− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n",
599− m_pDecContext->iErrorCode);
600− m_pDecContext->bPrintFrameErrorTraceFlag = false;
601− } else {
602− m_pDecContext->iIgnoredErrorInfoPacketCount++;
603− if (m_pDecContext->iIgnoredErrorInfoPacketCount == INT_MAX) {
604− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING, "continuous error reached INT_MAX! Restart as 0.");
605− m_pDecContext->iIgnoredErrorInfoPacketCount = 0;
606− }
607− }
608− if ((m_pDecContext->pParam->eEcActiveIdc != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {
609− //TODO after dec status updated
610− m_pDecContext->iErrorCode |= dsDataErrorConcealed;
611−
612− m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
613− if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
614− ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
615− m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
616− }
617− int32_t iMbConcealedNum = m_pDecContext->iMbEcedNum + m_pDecContext->iMbEcedPropNum;
618− m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->iMbNum == 0 ?
619− (m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : ((
620− m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((
621− iMbConcealedNum * 100) / m_pDecContext->iMbNum));
622− m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->iMbNum == 0 ?
623− (m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : ((
624− m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((
625− m_pDecContext->iMbEcedPropNum * 100) / m_pDecContext->iMbNum));
626− m_pDecContext->sDecoderStatistics.uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1);
627− m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 :
628− m_pDecContext->sDecoderStatistics.uiAvgEcRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;
629− m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 :
630− m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;
631− }
632− iEnd = WelsTime();
633− m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
634−
635− OutputStatisticsLog (m_pDecContext->sDecoderStatistics);
636−
637−#ifdef _PICTURE_REORDERING_
638− ReorderPicturesInDisplay (ppDst, pDstInfo);
639−#endif
640−
641− return (DECODING_STATE)m_pDecContext->iErrorCode;
642− }
643− // else Error free, the current codec works well
644−
645− if (pDstInfo->iBufferStatus == 1) {
646−
647− m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
648− if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
649− ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
650− m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
651− }
652−
653− OutputStatisticsLog (m_pDecContext->sDecoderStatistics);
654− }
655− iEnd = WelsTime();
656− m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
657−
658−#ifdef _PICTURE_REORDERING_
659− ReorderPicturesInDisplay (ppDst, pDstInfo);
660−#endif
661− return dsErrorFree;
662−}
663−
664−DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst,
665− SBufferInfo* pDstInfo) {
666− if (m_pDecContext->bEndOfStreamFlag && m_iNumOfPicts > 0) {
667− m_iMinPOC = sIMinInt32;
668− for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
669− if (m_iMinPOC == sIMinInt32 && m_sPictInfoList[i].iPOC > sIMinInt32) {
670− m_iMinPOC = m_sPictInfoList[i].iPOC;
671− m_iPictInfoIndex = i;
672− }
673− if (m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].iPOC < m_iMinPOC) {
674− m_iMinPOC = m_sPictInfoList[i].iPOC;
675− m_iPictInfoIndex = i;
676− }
677− }
678− }
679− if (m_iMinPOC > sIMinInt32) {
680− m_LastWrittenPOC = m_iMinPOC;
681−#if defined (_DEBUG)
682−#ifdef _MOTION_VECTOR_DUMP_
683− fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
684−#endif
685−#endif
686− memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
687− ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
688− ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
689− ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
690− m_sPictInfoList[m_iPictInfoIndex].iPOC = sIMinInt32;
691− m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
692− m_iMinPOC = sIMinInt32;
693− --m_iNumOfPicts;
694− }
695− return dsErrorFree;
696−}
697−
698−void CWelsDecoder::OutputStatisticsLog (SDecoderStatistics& sDecoderStatistics) {
699− if ((sDecoderStatistics.uiDecodedFrameCount > 0) && (sDecoderStatistics.iStatisticsLogInterval > 0)
700− && ((sDecoderStatistics.uiDecodedFrameCount % sDecoderStatistics.iStatisticsLogInterval) == 0)) {
701− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
702− "DecoderStatistics: uiWidth=%d, uiHeight=%d, fAverageFrameSpeedInMs=%.1f, fActualAverageFrameSpeedInMs=%.1f, \
703− uiDecodedFrameCount=%d, uiResolutionChangeTimes=%d, uiIDRCorrectNum=%d, \
704− uiAvgEcRatio=%d, uiAvgEcPropRatio=%d, uiEcIDRNum=%d, uiEcFrameNum=%d, \
705− uiIDRLostNum=%d, uiFreezingIDRNum=%d, uiFreezingNonIDRNum=%d, iAvgLumaQp=%d, \
706− iSpsReportErrorNum=%d, iSubSpsReportErrorNum=%d, iPpsReportErrorNum=%d, iSpsNoExistNalNum=%d, iSubSpsNoExistNalNum=%d, iPpsNoExistNalNum=%d, \
707− uiProfile=%d, uiLevel=%d, \
708− iCurrentActiveSpsId=%d, iCurrentActivePpsId=%d,",
709− sDecoderStatistics.uiWidth,
710− sDecoderStatistics.uiHeight,
711− sDecoderStatistics.fAverageFrameSpeedInMs,
712− sDecoderStatistics.fActualAverageFrameSpeedInMs,
713−
714− sDecoderStatistics.uiDecodedFrameCount,
715− sDecoderStatistics.uiResolutionChangeTimes,
716− sDecoderStatistics.uiIDRCorrectNum,
717−
718− sDecoderStatistics.uiAvgEcRatio,
719− sDecoderStatistics.uiAvgEcPropRatio,
720− sDecoderStatistics.uiEcIDRNum,
721− sDecoderStatistics.uiEcFrameNum,
722−
723− sDecoderStatistics.uiIDRLostNum,
724− sDecoderStatistics.uiFreezingIDRNum,
725− sDecoderStatistics.uiFreezingNonIDRNum,
726− sDecoderStatistics.iAvgLumaQp,
727−
728− sDecoderStatistics.iSpsReportErrorNum,
729− sDecoderStatistics.iSubSpsReportErrorNum,
730− sDecoderStatistics.iPpsReportErrorNum,
731− sDecoderStatistics.iSpsNoExistNalNum,
732− sDecoderStatistics.iSubSpsNoExistNalNum,
733− sDecoderStatistics.iPpsNoExistNalNum,
734−
735− sDecoderStatistics.uiProfile,
736− sDecoderStatistics.uiLevel,
737−
738− sDecoderStatistics.iCurrentActiveSpsId,
739− sDecoderStatistics.iCurrentActivePpsId);
740− }
741−}
742−
743−DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay (unsigned char** ppDst, SBufferInfo* pDstInfo) {
744− if (pDstInfo->iBufferStatus == 1 && m_pDecContext->pSps->uiProfileIdc != 66
745− && m_pDecContext->pPps->bEntropyCodingModeFlag) {
746− if (m_pDecContext->pSliceHeader->iPicOrderCntLsb == 0) {
747− if (m_iNumOfPicts > 0) {
748− m_iLastGOPRemainPicts = m_iNumOfPicts;
749− for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
750− if (m_sPictInfoList[i].iPOC > sIMinInt32) {
751− m_sPictInfoList[i].bLastGOP = true;
752− }
753− }
754− }
755− }
756− for (int32_t i = 0; i < 16; ++i) {
757− if (m_sPictInfoList[i].iPOC == sIMinInt32) {
758− memcpy (&m_sPictInfoList[i].sBufferInfo, pDstInfo, sizeof (SBufferInfo));
759− m_sPictInfoList[i].pData[0] = ppDst[0];
760− m_sPictInfoList[i].pData[1] = ppDst[1];
761− m_sPictInfoList[i].pData[2] = ppDst[2];
762− m_sPictInfoList[i].iPOC = m_pDecContext->pSliceHeader->iPicOrderCntLsb;
763− m_sPictInfoList[i].iFrameNum = m_pDecContext->pSliceHeader->iFrameNum;
764− m_sPictInfoList[i].bLastGOP = false;
765− pDstInfo->iBufferStatus = 0;
766− ++m_iNumOfPicts;
767− if (i > m_iLargestBufferedPicIndex) {
768− m_iLargestBufferedPicIndex = i;
769− }
770− break;
771− }
772− }
773− if (m_iLastGOPRemainPicts > 0) {
774− m_iMinPOC = sIMinInt32;
775− for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
776− if (m_iMinPOC == sIMinInt32 && m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].bLastGOP) {
777− m_iMinPOC = m_sPictInfoList[i].iPOC;
778− m_iPictInfoIndex = i;
779− }
780− if (m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].iPOC < m_iMinPOC && m_sPictInfoList[i].bLastGOP) {
781− m_iMinPOC = m_sPictInfoList[i].iPOC;
782− m_iPictInfoIndex = i;
783− }
784− }
785− m_LastWrittenPOC = m_iMinPOC;
786−#if defined (_DEBUG)
787−#ifdef _MOTION_VECTOR_DUMP_
788− fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
789−#endif
790−#endif
791− memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
792− ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
793− ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
794− ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
795− m_sPictInfoList[m_iPictInfoIndex].iPOC = sIMinInt32;
796− m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
797− m_iMinPOC = sIMinInt32;
798− --m_iNumOfPicts;
799− --m_iLastGOPRemainPicts;
800− if (m_iLastGOPRemainPicts == 0) {
801− m_LastWrittenPOC = sIMinInt32;
802− }
803− return dsErrorFree;
804− }
805− if (m_iNumOfPicts > 0) {
806− m_iMinPOC = sIMinInt32;
807− for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
808− if (m_iMinPOC == sIMinInt32 && m_sPictInfoList[i].iPOC > sIMinInt32) {
809− m_iMinPOC = m_sPictInfoList[i].iPOC;
810− m_iPictInfoIndex = i;
811− }
812− if (m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].iPOC < m_iMinPOC) {
813− m_iMinPOC = m_sPictInfoList[i].iPOC;
814− m_iPictInfoIndex = i;
815− }
816− }
817− }
818− if (m_iMinPOC > sIMinInt32) {
819− if ((m_LastWrittenPOC > sIMinInt32 && m_iMinPOC - m_LastWrittenPOC <= 1)
820− || m_iMinPOC < m_pDecContext->pSliceHeader->iPicOrderCntLsb) {
821− m_LastWrittenPOC = m_iMinPOC;
822−#if defined (_DEBUG)
823−#ifdef _MOTION_VECTOR_DUMP_
824− fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
825−#endif
826−#endif
827− memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
828− ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
829− ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
830− ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
831− m_sPictInfoList[m_iPictInfoIndex].iPOC = sIMinInt32;
832− m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
833− m_iMinPOC = sIMinInt32;
834− --m_iNumOfPicts;
835− return dsErrorFree;
836− }
837− }
838− }
839−
840− return dsErrorFree;
841−}
842−
843−DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,
844− const int kiSrcLen,
845− SParserBsInfo* pDstInfo) {
846− if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {
847− if (m_pWelsTrace != NULL) {
848− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeParser without Initialize.\n");
849− }
850− return dsInitialOptExpected;
851− }
852−
853− if (!m_pDecContext->pParam->bParseOnly) {
854− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be true for this API calling! \n");
855− m_pDecContext->iErrorCode |= dsInvalidArgument;
856− return dsInvalidArgument;
857− }
858− int64_t iEnd, iStart = WelsTime();
859− if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {
860− if (ResetDecoder())
861− return dsOutOfMemory;
862−
863− return dsErrorFree;
864− }
865− if (kiSrcLen > 0 && kpSrc != NULL) {
866−#ifdef OUTPUT_BITSTREAM
867− if (m_pFBS) {
868− WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS);
869− WelsFflush (m_pFBS);
870− }
871−#endif//OUTPUT_BIT_STREAM
872− m_pDecContext->bEndOfStreamFlag = false;
873− } else {
874− //For application MODE, the error detection should be added for safe.
875− //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
876− m_pDecContext->bEndOfStreamFlag = true;
877− m_pDecContext->bInstantDecFlag = true;
878− }
879−
880− m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
881− m_pDecContext->pParam->eEcActiveIdc = ERROR_CON_DISABLE; //add protection to disable EC here.
882− m_pDecContext->iFeedbackNalRefIdc = -1; //initialize
883− if (!m_pDecContext->bFramePending) { //frame complete
884− m_pDecContext->pParserBsInfo->iNalNum = 0;
885− memset (m_pDecContext->pParserBsInfo->pNalLenInByte, 0, MAX_NAL_UNITS_IN_LAYER);
886− }
887− pDstInfo->iNalNum = 0;
888− pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;
889− if (pDstInfo) {
890− m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
891− pDstInfo->uiOutBsTimeStamp = 0;
892− } else {
893− m_pDecContext->uiTimeStamp = 0;
894− }
895− WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);
896− if (m_pDecContext->iErrorCode & dsOutOfMemory) {
897− if (ResetDecoder())
898− return dsOutOfMemory;
899− return dsErrorFree;
900− }
901−
902− if (!m_pDecContext->bFramePending && m_pDecContext->pParserBsInfo->iNalNum) {
903− memcpy (pDstInfo, m_pDecContext->pParserBsInfo, sizeof (SParserBsInfo));
904−
905− if (m_pDecContext->iErrorCode == ERR_NONE) { //update statistics: decoding frame count
906− m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
907− if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
908− ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
909− m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
910− }
911− }
912− }
913−
914− m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
915−
916− if (m_pDecContext->iErrorCode && m_pDecContext->bPrintFrameErrorTraceFlag) {
917− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n", m_pDecContext->iErrorCode);
918− m_pDecContext->bPrintFrameErrorTraceFlag = false;
919− }
920− iEnd = WelsTime();
921− m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
922−
923− return (DECODING_STATE) m_pDecContext->iErrorCode;
924−}
925−
926−DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,
927− const int kiSrcLen,
928− unsigned char** ppDst,
929− int* pStride,
930− int& iWidth,
931− int& iHeight) {
932− DECODING_STATE eDecState = dsErrorFree;
933− SBufferInfo DstInfo;
934−
935− memset (&DstInfo, 0, sizeof (SBufferInfo));
936− DstInfo.UsrData.sSystemBuffer.iStride[0] = pStride[0];
937− DstInfo.UsrData.sSystemBuffer.iStride[1] = pStride[1];
938− DstInfo.UsrData.sSystemBuffer.iWidth = iWidth;
939− DstInfo.UsrData.sSystemBuffer.iHeight = iHeight;
940−
941− eDecState = DecodeFrame2 (kpSrc, kiSrcLen, ppDst, &DstInfo);
942− if (eDecState == dsErrorFree) {
943− pStride[0] = DstInfo.UsrData.sSystemBuffer.iStride[0];
944− pStride[1] = DstInfo.UsrData.sSystemBuffer.iStride[1];
945− iWidth = DstInfo.UsrData.sSystemBuffer.iWidth;
946− iHeight = DstInfo.UsrData.sSystemBuffer.iHeight;
947− }
948−
949− return eDecState;
950−}
951−
952−DECODING_STATE CWelsDecoder::DecodeFrameEx (const unsigned char* kpSrc,
953− const int kiSrcLen,
954− unsigned char* pDst,
955− int iDstStride,
956− int& iDstLen,
957− int& iWidth,
958− int& iHeight,
959− int& iColorFormat) {
960− DECODING_STATE state = dsErrorFree;
961−
962− return state;
963−}
964−
965−
966−} // namespace WelsDec
967−
968−
969−using namespace WelsDec;
970−/*
971−* WelsGetDecoderCapability
972−* @return: DecCapability information
973−*/
974−int WelsGetDecoderCapability (SDecoderCapability* pDecCapability) {
975− memset (pDecCapability, 0, sizeof (SDecoderCapability));
976− pDecCapability->iProfileIdc = 66; //Baseline
977− pDecCapability->iProfileIop = 0xE0; //11100000b
978− pDecCapability->iLevelIdc = 32; //level_idc = 3.2
979− pDecCapability->iMaxMbps = 216000; //from level_idc = 3.2
980− pDecCapability->iMaxFs = 5120; //from level_idc = 3.2
981− pDecCapability->iMaxCpb = 20000; //from level_idc = 3.2
982− pDecCapability->iMaxDpb = 20480; //from level_idc = 3.2
983− pDecCapability->iMaxBr = 20000; //from level_idc = 3.2
984− pDecCapability->bRedPicCap = 0; //not support redundant pic
985−
986− return ERR_NONE;
987−}
988−/* WINAPI is indeed in prefix due to sync to application layer callings!! */
989−
990−/*
991−* WelsCreateDecoder
992−* @return: success in return 0, otherwise failed.
993−*/
994−long WelsCreateDecoder (ISVCDecoder** ppDecoder) {
995−
996− if (NULL == ppDecoder) {
997− return ERR_INVALID_PARAMETERS;
998− }
999−
1000− *ppDecoder = new CWelsDecoder();
1001−
1002− if (NULL == *ppDecoder) {
1003− return ERR_MALLOC_FAILED;
1004− }
1005−
1006− return ERR_NONE;
1007−}
1008−
1009−/*
1010−* WelsDestroyDecoder
1011−*/
1012−void WelsDestroyDecoder (ISVCDecoder* pDecoder) {
1013− if (NULL != pDecoder) {
1014− delete (CWelsDecoder*)pDecoder;
1015− }
1016−}
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+ * welsDecoderExt.cpp
33+ *
34+ * Abstract
35+ * Cisco OpenH264 decoder extension utilization
36+ *
37+ * History
38+ * 3/12/2009 Created
39+ *
40+ *
41+ ************************************************************************/
42+//#include <assert.h>
43+#include "welsDecoderExt.h"
44+#include "welsCodecTrace.h"
45+#include "codec_def.h"
46+#include "typedefs.h"
47+#include "memory_align.h"
48+#include "utils.h"
49+#include "version.h"
50+
51+//#include "macros.h"
52+#include "decoder.h"
53+#include "decoder_core.h"
54+#include "error_concealment.h"
55+
56+#include "measure_time.h"
57+extern "C" {
58+#include "decoder_core.h"
59+#include "manage_dec_ref.h"
60+}
61+#include "error_code.h"
62+#include "crt_util_safe_x.h" // Safe CRT routines like util for cross platforms
63+#include <time.h>
64+#if defined(_WIN32) /*&& defined(_DEBUG)*/
65+
66+#include <windows.h>
67+#include <stdio.h>
68+#include <stdarg.h>
69+#include <sys/types.h>
70+#else
71+#include <sys/time.h>
72+#endif
73+
74+#define _PICTURE_REORDERING_ 1
75+
76+static int32_t sIMinInt32 = -0x7FFFFFFF;
77+
78+namespace WelsDec {
79+
80+//////////////////////////////////////////////////////////////////////
81+// Construction/Destruction
82+//////////////////////////////////////////////////////////////////////
83+
84+/***************************************************************************
85+* Description:
86+* class CWelsDecoder constructor function, do initialization and
87+* alloc memory required
88+*
89+* Input parameters: none
90+*
91+* return: none
92+***************************************************************************/
93+CWelsDecoder::CWelsDecoder (void)
94+ : m_pDecContext (NULL),
95+ m_pWelsTrace (NULL),
96+ m_iPictInfoIndex (0),
97+ m_iMinPOC (sIMinInt32),
98+ m_iNumOfPicts (0),
99+ m_iLastGOPRemainPicts (0),
100+ m_LastWrittenPOC (sIMinInt32),
101+ m_iLargestBufferedPicIndex (0) {
102+#ifdef OUTPUT_BIT_STREAM
103+ char chFileName[1024] = { 0 }; //for .264
104+ int iBufUsed = 0;
105+ int iBufLeft = 1023;
106+ int iCurUsed;
107+
108+ char chFileNameSize[1024] = { 0 }; //for .len
109+ int iBufUsedSize = 0;
110+ int iBufLeftSize = 1023;
111+ int iCurUsedSize;
112+#endif//OUTPUT_BIT_STREAM
113+
114+
115+ m_pWelsTrace = new welsCodecTrace();
116+ if (m_pWelsTrace != NULL) {
117+ m_pWelsTrace->SetCodecInstance (this);
118+ m_pWelsTrace->SetTraceLevel (WELS_LOG_ERROR);
119+
120+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::CWelsDecoder() entry");
121+ }
122+
123+ for (int32_t i = 0; i < 16; ++i) {
124+ m_sPictInfoList[i].bLastGOP = false;
125+ m_sPictInfoList[i].iPOC = sIMinInt32;
126+ }
127+
128+#ifdef OUTPUT_BIT_STREAM
129+ SWelsTime sCurTime;
130+
131+ WelsGetTimeOfDay (&sCurTime);
132+
133+ iCurUsed = WelsSnprintf (chFileName, iBufLeft, "bs_0x%p_", (void*)this);
134+ iCurUsedSize = WelsSnprintf (chFileNameSize, iBufLeftSize, "size_0x%p_", (void*)this);
135+
136+ iBufUsed += iCurUsed;
137+ iBufLeft -= iCurUsed;
138+ if (iBufLeft > 0) {
139+ iCurUsed = WelsStrftime (&chFileName[iBufUsed], iBufLeft, "%y%m%d%H%M%S", &sCurTime);
140+ iBufUsed += iCurUsed;
141+ iBufLeft -= iCurUsed;
142+ }
143+
144+ iBufUsedSize += iCurUsedSize;
145+ iBufLeftSize -= iCurUsedSize;
146+ if (iBufLeftSize > 0) {
147+ iCurUsedSize = WelsStrftime (&chFileNameSize[iBufUsedSize], iBufLeftSize, "%y%m%d%H%M%S", &sCurTime);
148+ iBufUsedSize += iCurUsedSize;
149+ iBufLeftSize -= iCurUsedSize;
150+ }
151+
152+ if (iBufLeft > 0) {
153+ iCurUsed = WelsSnprintf (&chFileName[iBufUsed], iBufLeft, ".%03.3u.264", WelsGetMillisecond (&sCurTime));
154+ iBufUsed += iCurUsed;
155+ iBufLeft -= iCurUsed;
156+ }
157+
158+ if (iBufLeftSize > 0) {
159+ iCurUsedSize = WelsSnprintf (&chFileNameSize[iBufUsedSize], iBufLeftSize, ".%03.3u.len",
160+ WelsGetMillisecond (&sCurTime));
161+ iBufUsedSize += iCurUsedSize;
162+ iBufLeftSize -= iCurUsedSize;
163+ }
164+
165+
166+ m_pFBS = WelsFopen (chFileName, "wb");
167+ m_pFBSSize = WelsFopen (chFileNameSize, "wb");
168+#endif//OUTPUT_BIT_STREAM
169+}
170+
171+/***************************************************************************
172+* Description:
173+* class CWelsDecoder destructor function, destroy allocced memory
174+*
175+* Input parameters: none
176+*
177+* return: none
178+***************************************************************************/
179+CWelsDecoder::~CWelsDecoder() {
180+ if (m_pWelsTrace != NULL) {
181+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::~CWelsDecoder()");
182+ }
183+
184+ UninitDecoder();
185+
186+#ifdef OUTPUT_BIT_STREAM
187+ if (m_pFBS) {
188+ WelsFclose (m_pFBS);
189+ m_pFBS = NULL;
190+ }
191+ if (m_pFBSSize) {
192+ WelsFclose (m_pFBSSize);
193+ m_pFBSSize = NULL;
194+ }
195+#endif//OUTPUT_BIT_STREAM
196+
197+ if (m_pWelsTrace != NULL) {
198+ delete m_pWelsTrace;
199+ m_pWelsTrace = NULL;
200+ }
201+}
202+
203+long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
204+ int iRet = ERR_NONE;
205+ if (m_pWelsTrace == NULL) {
206+ return cmMallocMemeError;
207+ }
208+
209+ if (pParam == NULL) {
210+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsDecoder::Initialize(), invalid input argument.");
211+ return cmInitParaError;
212+ }
213+
214+ // H.264 decoder initialization,including memory allocation,then open it ready to decode
215+ iRet = InitDecoder (pParam);
216+ if (iRet)
217+ return iRet;
218+
219+ return cmResultSuccess;
220+}
221+
222+long CWelsDecoder::Uninitialize() {
223+ UninitDecoder();
224+
225+ return ERR_NONE;
226+}
227+
228+void CWelsDecoder::UninitDecoder (void) {
229+ if (NULL == m_pDecContext)
230+ return;
231+
232+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::UninitDecoder(), openh264 codec version = %s.",
233+ VERSION_NUMBER);
234+
235+ WelsEndDecoder (m_pDecContext);
236+
237+ if (m_pDecContext->pMemAlign != NULL) {
238+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
239+ "CWelsDecoder::UninitDecoder(), verify memory usage (%d bytes) after free..",
240+ m_pDecContext->pMemAlign->WelsGetMemoryUsage());
241+ delete m_pDecContext->pMemAlign;
242+ m_pDecContext->pMemAlign = NULL;
243+ }
244+
245+ if (NULL != m_pDecContext) {
246+ WelsFree (m_pDecContext, "m_pDecContext");
247+
248+ m_pDecContext = NULL;
249+ }
250+}
251+
252+// the return value of this function is not suitable, it need report failure info to upper layer.
253+int32_t CWelsDecoder::InitDecoder (const SDecodingParam* pParam) {
254+
255+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
256+ "CWelsDecoder::init_decoder(), openh264 codec version = %s, ParseOnly = %d",
257+ VERSION_NUMBER, (int32_t)pParam->bParseOnly);
258+
259+ //reset decoder context
260+ if (m_pDecContext) //free
261+ UninitDecoder();
262+ m_pDecContext = (PWelsDecoderContext)WelsMallocz (sizeof (SWelsDecoderContext), "m_pDecContext");
263+ if (NULL == m_pDecContext)
264+ return cmMallocMemeError;
265+ int32_t iCacheLineSize = 16; // on chip cache line size in byte
266+ m_pDecContext->pMemAlign = new CMemoryAlign (iCacheLineSize);
267+ WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pMemAlign), UninitDecoder())
268+
269+ //fill in default value into context
270+ WelsDecoderDefaults (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
271+
272+ //check param and update decoder context
273+ m_pDecContext->pParam = (SDecodingParam*)m_pDecContext->pMemAlign->WelsMallocz (sizeof (SDecodingParam),
274+ "SDecodingParam");
275+ WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pParam), UninitDecoder());
276+ int32_t iRet = DecoderConfigParam (m_pDecContext, pParam);
277+ WELS_VERIFY_RETURN_IFNEQ (iRet, cmResultSuccess);
278+
279+ //init decoder
280+ WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx),
281+ UninitDecoder())
282+
283+ return cmResultSuccess;
284+}
285+
286+int32_t CWelsDecoder::ResetDecoder() {
287+ // TBC: need to be modified when context and trace point are null
288+ if (m_pDecContext != NULL && m_pWelsTrace != NULL) {
289+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ResetDecoder(), context error code is %d",
290+ m_pDecContext->iErrorCode);
291+ SDecodingParam sPrevParam;
292+ memcpy (&sPrevParam, m_pDecContext->pParam, sizeof (SDecodingParam));
293+
294+ WELS_VERIFY_RETURN_PROC_IF (cmInitParaError, InitDecoder (&sPrevParam), UninitDecoder());
295+ } else if (m_pWelsTrace != NULL) {
296+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "ResetDecoder() failed as decoder context null");
297+ }
298+ return ERR_INFO_UNINIT;
299+}
300+
301+/*
302+ * Set Option
303+ */
304+long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
305+ int iVal = 0;
306+
307+ if (m_pDecContext == NULL && eOptID != DECODER_OPTION_TRACE_LEVEL &&
308+ eOptID != DECODER_OPTION_TRACE_CALLBACK && eOptID != DECODER_OPTION_TRACE_CALLBACK_CONTEXT)
309+ return dsInitialOptExpected;
310+ if (eOptID == DECODER_OPTION_END_OF_STREAM) { // Indicate bit-stream of the final frame to be decoded
311+ if (pOption == NULL)
312+ return cmInitParaError;
313+
314+ iVal = * ((int*)pOption); // boolean value for whether enabled End Of Stream flag
315+
316+ m_pDecContext->bEndOfStreamFlag = iVal ? true : false;
317+
318+ return cmResultSuccess;
319+ } else if (eOptID == DECODER_OPTION_ERROR_CON_IDC) { // Indicate error concealment status
320+ if (pOption == NULL)
321+ return cmInitParaError;
322+
323+ iVal = * ((int*)pOption); // int value for error concealment idc
324+ iVal = WELS_CLIP3 (iVal, (int32_t)ERROR_CON_DISABLE, (int32_t)ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE);
325+ if ((m_pDecContext->pParam->bParseOnly) && (iVal != (int32_t)ERROR_CON_DISABLE)) {
326+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
327+ "CWelsDecoder::SetOption for ERROR_CON_IDC = %d not allowd for parse only!.", iVal);
328+ return cmInitParaError;
329+ }
330+
331+ m_pDecContext->pParam->eEcActiveIdc = (ERROR_CON_IDC)iVal;
332+ InitErrorCon (m_pDecContext);
333+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
334+ "CWelsDecoder::SetOption for ERROR_CON_IDC = %d.", iVal);
335+
336+ return cmResultSuccess;
337+ } else if (eOptID == DECODER_OPTION_TRACE_LEVEL) {
338+ if (m_pWelsTrace) {
339+ uint32_t level = * ((uint32_t*)pOption);
340+ m_pWelsTrace->SetTraceLevel (level);
341+ }
342+ return cmResultSuccess;
343+ } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK) {
344+ if (m_pWelsTrace) {
345+ WelsTraceCallback callback = * ((WelsTraceCallback*)pOption);
346+ m_pWelsTrace->SetTraceCallback (callback);
347+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
348+ "CWelsDecoder::SetOption():DECODER_OPTION_TRACE_CALLBACK callback = %p.",
349+ callback);
350+ }
351+ return cmResultSuccess;
352+ } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK_CONTEXT) {
353+ if (m_pWelsTrace) {
354+ void* ctx = * ((void**)pOption);
355+ m_pWelsTrace->SetTraceCallbackContext (ctx);
356+ }
357+ return cmResultSuccess;
358+ } else if (eOptID == DECODER_OPTION_GET_STATISTICS) {
359+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
360+ "CWelsDecoder::SetOption():DECODER_OPTION_GET_STATISTICS: this option is get-only!");
361+ return cmInitParaError;
362+ } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
363+ if (pOption) {
364+ m_pDecContext->sDecoderStatistics.iStatisticsLogInterval = (* ((unsigned int*)pOption));
365+ return cmResultSuccess;
366+ }
367+ } else if (eOptID == DECODER_OPTION_GET_SAR_INFO) {
368+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
369+ "CWelsDecoder::SetOption():DECODER_OPTION_GET_SAR_INFO: this option is get-only!");
370+ return cmInitParaError;
371+ }
372+ return cmInitParaError;
373+}
374+
375+/*
376+ * Get Option
377+ */
378+long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) {
379+ int iVal = 0;
380+
381+ if (m_pDecContext == NULL)
382+ return cmInitExpected;
383+
384+ if (pOption == NULL)
385+ return cmInitParaError;
386+
387+ if (DECODER_OPTION_END_OF_STREAM == eOptID) {
388+ iVal = m_pDecContext->bEndOfStreamFlag;
389+ * ((int*)pOption) = iVal;
390+ return cmResultSuccess;
391+ }
392+#ifdef LONG_TERM_REF
393+ else if (DECODER_OPTION_IDR_PIC_ID == eOptID) {
394+ iVal = m_pDecContext->uiCurIdrPicId;
395+ * ((int*)pOption) = iVal;
396+ return cmResultSuccess;
397+ } else if (DECODER_OPTION_FRAME_NUM == eOptID) {
398+ iVal = m_pDecContext->iFrameNum;
399+ * ((int*)pOption) = iVal;
400+ return cmResultSuccess;
401+ } else if (DECODER_OPTION_LTR_MARKING_FLAG == eOptID) {
402+ iVal = m_pDecContext->bCurAuContainLtrMarkSeFlag;
403+ * ((int*)pOption) = iVal;
404+ return cmResultSuccess;
405+ } else if (DECODER_OPTION_LTR_MARKED_FRAME_NUM == eOptID) {
406+ iVal = m_pDecContext->iFrameNumOfAuMarkedLtr;
407+ * ((int*)pOption) = iVal;
408+ return cmResultSuccess;
409+ }
410+#endif
411+ else if (DECODER_OPTION_VCL_NAL == eOptID) { //feedback whether or not have VCL NAL in current AU
412+ iVal = m_pDecContext->iFeedbackVclNalInAu;
413+ * ((int*)pOption) = iVal;
414+ return cmResultSuccess;
415+ } else if (DECODER_OPTION_TEMPORAL_ID == eOptID) { //if have VCL NAL in current AU, then feedback the temporal ID
416+ iVal = m_pDecContext->iFeedbackTidInAu;
417+ * ((int*)pOption) = iVal;
418+ return cmResultSuccess;
419+ } else if (DECODER_OPTION_IS_REF_PIC == eOptID) {
420+ iVal = m_pDecContext->iFeedbackNalRefIdc;
421+ if (iVal > 0)
422+ iVal = 1;
423+ * ((int*)pOption) = iVal;
424+ return cmResultSuccess;
425+ } else if (DECODER_OPTION_ERROR_CON_IDC == eOptID) {
426+ iVal = (int)m_pDecContext->pParam->eEcActiveIdc;
427+ * ((int*)pOption) = iVal;
428+ return cmResultSuccess;
429+ } else if (DECODER_OPTION_GET_STATISTICS == eOptID) { // get decoder statistics info for real time debugging
430+ SDecoderStatistics* pDecoderStatistics = (static_cast<SDecoderStatistics*> (pOption));
431+
432+ memcpy (pDecoderStatistics, &m_pDecContext->sDecoderStatistics, sizeof (SDecoderStatistics));
433+
434+ if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount != 0) { //not original status
435+ pDecoderStatistics->fAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /
436+ (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount);
437+ pDecoderStatistics->fActualAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /
438+ (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount + m_pDecContext->sDecoderStatistics.uiFreezingIDRNum +
439+ m_pDecContext->sDecoderStatistics.uiFreezingNonIDRNum);
440+ }
441+ return cmResultSuccess;
442+ } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
443+ if (pOption) {
444+ iVal = m_pDecContext->sDecoderStatistics.iStatisticsLogInterval;
445+ * ((unsigned int*)pOption) = iVal;
446+ return cmResultSuccess;
447+ }
448+ } else if (DECODER_OPTION_GET_SAR_INFO == eOptID) { //get decoder SAR info in VUI
449+ PVuiSarInfo pVuiSarInfo = (static_cast<PVuiSarInfo> (pOption));
450+ memset (pVuiSarInfo, 0, sizeof (SVuiSarInfo));
451+ if (!m_pDecContext->pSps) {
452+ return cmInitExpected;
453+ } else {
454+ pVuiSarInfo->uiSarWidth = m_pDecContext->pSps->sVui.uiSarWidth;
455+ pVuiSarInfo->uiSarHeight = m_pDecContext->pSps->sVui.uiSarHeight;
456+ pVuiSarInfo->bOverscanAppropriateFlag = m_pDecContext->pSps->sVui.bOverscanAppropriateFlag;
457+ return cmResultSuccess;
458+ }
459+ } else if (DECODER_OPTION_PROFILE == eOptID) {
460+ if (!m_pDecContext->pSps) {
461+ return cmInitExpected;
462+ }
463+ iVal = (int)m_pDecContext->pSps->uiProfileIdc;
464+ * ((int*)pOption) = iVal;
465+ return cmResultSuccess;
466+ } else if (DECODER_OPTION_LEVEL == eOptID) {
467+ if (!m_pDecContext->pSps) {
468+ return cmInitExpected;
469+ }
470+ iVal = (int)m_pDecContext->pSps->uiLevelIdc;
471+ * ((int*)pOption) = iVal;
472+ return cmResultSuccess;
473+ } else if (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER == eOptID) {
474+ if (m_pDecContext->pSps && m_pDecContext->pSps->uiProfileIdc != 66 && m_pDecContext->pPps->bEntropyCodingModeFlag) {
475+ * ((int*)pOption) = m_iNumOfPicts > 0 ? m_iNumOfPicts : 0;
476+ }
477+ return cmResultSuccess;
478+ }
479+
480+ return cmInitParaError;
481+}
482+
483+DECODING_STATE CWelsDecoder::DecodeFrameNoDelay (const unsigned char* kpSrc,
484+ const int kiSrcLen,
485+ unsigned char** ppDst,
486+ SBufferInfo* pDstInfo) {
487+ int iRet;
488+ //SBufferInfo sTmpBufferInfo;
489+ //unsigned char* ppTmpDst[3] = {NULL, NULL, NULL};
490+ iRet = (int)DecodeFrame2 (kpSrc, kiSrcLen, ppDst, pDstInfo);
491+ //memcpy (&sTmpBufferInfo, pDstInfo, sizeof (SBufferInfo));
492+ //ppTmpDst[0] = ppDst[0];
493+ //ppTmpDst[1] = ppDst[1];
494+ //ppTmpDst[2] = ppDst[2];
495+ iRet |= DecodeFrame2 (NULL, 0, ppDst, pDstInfo);
496+ //if ((pDstInfo->iBufferStatus == 0) && (sTmpBufferInfo.iBufferStatus == 1)) {
497+ //memcpy (pDstInfo, &sTmpBufferInfo, sizeof (SBufferInfo));
498+ //ppDst[0] = ppTmpDst[0];
499+ //ppDst[1] = ppTmpDst[1];
500+ //ppDst[2] = ppTmpDst[2];
501+ //}
502+ return (DECODING_STATE)iRet;
503+}
504+
505+DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
506+ const int kiSrcLen,
507+ unsigned char** ppDst,
508+ SBufferInfo* pDstInfo) {
509+ if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {
510+ if (m_pWelsTrace != NULL) {
511+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeFrame2 without Initialize.\n");
512+ }
513+ return dsInitialOptExpected;
514+ }
515+
516+ if (m_pDecContext->pParam->bParseOnly) {
517+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be false for this API calling! \n");
518+ m_pDecContext->iErrorCode |= dsInvalidArgument;
519+ return dsInvalidArgument;
520+ }
521+ if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {
522+ if (ResetDecoder())
523+ return dsOutOfMemory;
524+
525+ return dsErrorFree;
526+ }
527+ if (kiSrcLen > 0 && kpSrc != NULL) {
528+#ifdef OUTPUT_BIT_STREAM
529+ if (m_pFBS) {
530+ WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS);
531+ WelsFflush (m_pFBS);
532+ }
533+ if (m_pFBSSize) {
534+ WelsFwrite (&kiSrcLen, sizeof (int), 1, m_pFBSSize);
535+ WelsFflush (m_pFBSSize);
536+ }
537+#endif//OUTPUT_BIT_STREAM
538+ m_pDecContext->bEndOfStreamFlag = false;
539+ } else {
540+ //For application MODE, the error detection should be added for safe.
541+ //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
542+ m_pDecContext->bEndOfStreamFlag = true;
543+ m_pDecContext->bInstantDecFlag = true;
544+ }
545+
546+ int64_t iStart, iEnd;
547+ iStart = WelsTime();
548+
549+ ppDst[0] = ppDst[1] = ppDst[2] = NULL;
550+ m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
551+ m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
552+ unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;
553+ memset (pDstInfo, 0, sizeof (SBufferInfo));
554+ pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;
555+#ifdef LONG_TERM_REF
556+ m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
557+ m_pDecContext->bCurAuContainLtrMarkSeFlag = false;
558+ m_pDecContext->iFrameNumOfAuMarkedLtr = 0;
559+ m_pDecContext->iFrameNum = -1; //initialize
560+#endif
561+
562+ m_pDecContext->iFeedbackTidInAu = -1; //initialize
563+ m_pDecContext->iFeedbackNalRefIdc = -1; //initialize
564+ if (pDstInfo) {
565+ pDstInfo->uiOutYuvTimeStamp = 0;
566+ m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
567+ } else {
568+ m_pDecContext->uiTimeStamp = 0;
569+ }
570+ WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, ppDst,
571+ pDstInfo, NULL); //iErrorCode has been modified in this function
572+ m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
573+ if (m_pDecContext->iErrorCode) {
574+ EWelsNalUnitType eNalType =
575+ NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently
576+
577+ eNalType = m_pDecContext->sCurNalHead.eNalUnitType;
578+
579+ if (m_pDecContext->iErrorCode & dsOutOfMemory) {
580+ if (ResetDecoder())
581+ return dsOutOfMemory;
582+
583+ return dsErrorFree;
584+ }
585+ //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.
586+ if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||
587+ (VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType)) {
588+ if (m_pDecContext->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
589+#ifdef LONG_TERM_REF
590+ m_pDecContext->bParamSetsLostFlag = true;
591+#else
592+ m_pDecContext->bReferenceLostAtT0Flag = true;
593+#endif
594+ }
595+ }
596+
597+ if (m_pDecContext->bPrintFrameErrorTraceFlag) {
598+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n",
599+ m_pDecContext->iErrorCode);
600+ m_pDecContext->bPrintFrameErrorTraceFlag = false;
601+ } else {
602+ m_pDecContext->iIgnoredErrorInfoPacketCount++;
603+ if (m_pDecContext->iIgnoredErrorInfoPacketCount == INT_MAX) {
604+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING, "continuous error reached INT_MAX! Restart as 0.");
605+ m_pDecContext->iIgnoredErrorInfoPacketCount = 0;
606+ }
607+ }
608+ if ((m_pDecContext->pParam->eEcActiveIdc != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {
609+ //TODO after dec status updated
610+ m_pDecContext->iErrorCode |= dsDataErrorConcealed;
611+
612+ m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
613+ if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
614+ ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
615+ m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
616+ }
617+ int32_t iMbConcealedNum = m_pDecContext->iMbEcedNum + m_pDecContext->iMbEcedPropNum;
618+ m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->iMbNum == 0 ?
619+ (m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : ((
620+ m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((
621+ iMbConcealedNum * 100) / m_pDecContext->iMbNum));
622+ m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->iMbNum == 0 ?
623+ (m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : ((
624+ m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((
625+ m_pDecContext->iMbEcedPropNum * 100) / m_pDecContext->iMbNum));
626+ m_pDecContext->sDecoderStatistics.uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1);
627+ m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 :
628+ m_pDecContext->sDecoderStatistics.uiAvgEcRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;
629+ m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 :
630+ m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;
631+ }
632+ iEnd = WelsTime();
633+ m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
634+
635+ OutputStatisticsLog (m_pDecContext->sDecoderStatistics);
636+
637+#ifdef _PICTURE_REORDERING_
638+ ReorderPicturesInDisplay (ppDst, pDstInfo);
639+#endif
640+
641+ return (DECODING_STATE)m_pDecContext->iErrorCode;
642+ }
643+ // else Error free, the current codec works well
644+
645+ if (pDstInfo->iBufferStatus == 1) {
646+
647+ m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
648+ if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
649+ ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
650+ m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
651+ }
652+
653+ OutputStatisticsLog (m_pDecContext->sDecoderStatistics);
654+ }
655+ iEnd = WelsTime();
656+ m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
657+
658+#ifdef _PICTURE_REORDERING_
659+ ReorderPicturesInDisplay (ppDst, pDstInfo);
660+#endif
661+ return dsErrorFree;
662+}
663+
664+DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst,
665+ SBufferInfo* pDstInfo) {
666+ if (m_pDecContext->bEndOfStreamFlag && m_iNumOfPicts > 0) {
667+ m_iMinPOC = sIMinInt32;
668+ for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
669+ if (m_iMinPOC == sIMinInt32 && m_sPictInfoList[i].iPOC > sIMinInt32) {
670+ m_iMinPOC = m_sPictInfoList[i].iPOC;
671+ m_iPictInfoIndex = i;
672+ }
673+ if (m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].iPOC < m_iMinPOC) {
674+ m_iMinPOC = m_sPictInfoList[i].iPOC;
675+ m_iPictInfoIndex = i;
676+ }
677+ }
678+ }
679+ if (m_iMinPOC > sIMinInt32) {
680+ m_LastWrittenPOC = m_iMinPOC;
681+#if defined (_DEBUG)
682+#ifdef _MOTION_VECTOR_DUMP_
683+ fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
684+#endif
685+#endif
686+ memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
687+ ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
688+ ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
689+ ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
690+ m_sPictInfoList[m_iPictInfoIndex].iPOC = sIMinInt32;
691+ m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
692+ m_iMinPOC = sIMinInt32;
693+ --m_iNumOfPicts;
694+ }
695+ return dsErrorFree;
696+}
697+
698+void CWelsDecoder::OutputStatisticsLog (SDecoderStatistics& sDecoderStatistics) {
699+ if ((sDecoderStatistics.uiDecodedFrameCount > 0) && (sDecoderStatistics.iStatisticsLogInterval > 0)
700+ && ((sDecoderStatistics.uiDecodedFrameCount % sDecoderStatistics.iStatisticsLogInterval) == 0)) {
701+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
702+ "DecoderStatistics: uiWidth=%d, uiHeight=%d, fAverageFrameSpeedInMs=%.1f, fActualAverageFrameSpeedInMs=%.1f, \
703+ uiDecodedFrameCount=%d, uiResolutionChangeTimes=%d, uiIDRCorrectNum=%d, \
704+ uiAvgEcRatio=%d, uiAvgEcPropRatio=%d, uiEcIDRNum=%d, uiEcFrameNum=%d, \
705+ uiIDRLostNum=%d, uiFreezingIDRNum=%d, uiFreezingNonIDRNum=%d, iAvgLumaQp=%d, \
706+ iSpsReportErrorNum=%d, iSubSpsReportErrorNum=%d, iPpsReportErrorNum=%d, iSpsNoExistNalNum=%d, iSubSpsNoExistNalNum=%d, iPpsNoExistNalNum=%d, \
707+ uiProfile=%d, uiLevel=%d, \
708+ iCurrentActiveSpsId=%d, iCurrentActivePpsId=%d,",
709+ sDecoderStatistics.uiWidth,
710+ sDecoderStatistics.uiHeight,
711+ sDecoderStatistics.fAverageFrameSpeedInMs,
712+ sDecoderStatistics.fActualAverageFrameSpeedInMs,
713+
714+ sDecoderStatistics.uiDecodedFrameCount,
715+ sDecoderStatistics.uiResolutionChangeTimes,
716+ sDecoderStatistics.uiIDRCorrectNum,
717+
718+ sDecoderStatistics.uiAvgEcRatio,
719+ sDecoderStatistics.uiAvgEcPropRatio,
720+ sDecoderStatistics.uiEcIDRNum,
721+ sDecoderStatistics.uiEcFrameNum,
722+
723+ sDecoderStatistics.uiIDRLostNum,
724+ sDecoderStatistics.uiFreezingIDRNum,
725+ sDecoderStatistics.uiFreezingNonIDRNum,
726+ sDecoderStatistics.iAvgLumaQp,
727+
728+ sDecoderStatistics.iSpsReportErrorNum,
729+ sDecoderStatistics.iSubSpsReportErrorNum,
730+ sDecoderStatistics.iPpsReportErrorNum,
731+ sDecoderStatistics.iSpsNoExistNalNum,
732+ sDecoderStatistics.iSubSpsNoExistNalNum,
733+ sDecoderStatistics.iPpsNoExistNalNum,
734+
735+ sDecoderStatistics.uiProfile,
736+ sDecoderStatistics.uiLevel,
737+
738+ sDecoderStatistics.iCurrentActiveSpsId,
739+ sDecoderStatistics.iCurrentActivePpsId);
740+ }
741+}
742+
743+DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay (unsigned char** ppDst, SBufferInfo* pDstInfo) {
744+ if (pDstInfo->iBufferStatus == 1 && m_pDecContext->pSps->uiProfileIdc != 66
745+ && m_pDecContext->pPps->bEntropyCodingModeFlag) {
746+ if (m_pDecContext->pSliceHeader->iPicOrderCntLsb == 0) {
747+ if (m_iNumOfPicts > 0) {
748+ m_iLastGOPRemainPicts = m_iNumOfPicts;
749+ for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
750+ if (m_sPictInfoList[i].iPOC > sIMinInt32) {
751+ m_sPictInfoList[i].bLastGOP = true;
752+ }
753+ }
754+ }
755+ }
756+ for (int32_t i = 0; i < 16; ++i) {
757+ if (m_sPictInfoList[i].iPOC == sIMinInt32) {
758+ memcpy (&m_sPictInfoList[i].sBufferInfo, pDstInfo, sizeof (SBufferInfo));
759+ m_sPictInfoList[i].pData[0] = ppDst[0];
760+ m_sPictInfoList[i].pData[1] = ppDst[1];
761+ m_sPictInfoList[i].pData[2] = ppDst[2];
762+ m_sPictInfoList[i].iPOC = m_pDecContext->pSliceHeader->iPicOrderCntLsb;
763+ m_sPictInfoList[i].iFrameNum = m_pDecContext->pSliceHeader->iFrameNum;
764+ m_sPictInfoList[i].bLastGOP = false;
765+ pDstInfo->iBufferStatus = 0;
766+ ++m_iNumOfPicts;
767+ if (i > m_iLargestBufferedPicIndex) {
768+ m_iLargestBufferedPicIndex = i;
769+ }
770+ break;
771+ }
772+ }
773+ if (m_iLastGOPRemainPicts > 0) {
774+ m_iMinPOC = sIMinInt32;
775+ for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
776+ if (m_iMinPOC == sIMinInt32 && m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].bLastGOP) {
777+ m_iMinPOC = m_sPictInfoList[i].iPOC;
778+ m_iPictInfoIndex = i;
779+ }
780+ if (m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].iPOC < m_iMinPOC && m_sPictInfoList[i].bLastGOP) {
781+ m_iMinPOC = m_sPictInfoList[i].iPOC;
782+ m_iPictInfoIndex = i;
783+ }
784+ }
785+ m_LastWrittenPOC = m_iMinPOC;
786+#if defined (_DEBUG)
787+#ifdef _MOTION_VECTOR_DUMP_
788+ fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
789+#endif
790+#endif
791+ memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
792+ ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
793+ ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
794+ ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
795+ m_sPictInfoList[m_iPictInfoIndex].iPOC = sIMinInt32;
796+ m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
797+ m_iMinPOC = sIMinInt32;
798+ --m_iNumOfPicts;
799+ --m_iLastGOPRemainPicts;
800+ if (m_iLastGOPRemainPicts == 0) {
801+ m_LastWrittenPOC = sIMinInt32;
802+ }
803+ return dsErrorFree;
804+ }
805+ if (m_iNumOfPicts > 0) {
806+ m_iMinPOC = sIMinInt32;
807+ for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
808+ if (m_iMinPOC == sIMinInt32 && m_sPictInfoList[i].iPOC > sIMinInt32) {
809+ m_iMinPOC = m_sPictInfoList[i].iPOC;
810+ m_iPictInfoIndex = i;
811+ }
812+ if (m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].iPOC < m_iMinPOC) {
813+ m_iMinPOC = m_sPictInfoList[i].iPOC;
814+ m_iPictInfoIndex = i;
815+ }
816+ }
817+ }
818+ if (m_iMinPOC > sIMinInt32) {
819+ if ((m_LastWrittenPOC > sIMinInt32 && m_iMinPOC - m_LastWrittenPOC <= 1)
820+ || m_iMinPOC < m_pDecContext->pSliceHeader->iPicOrderCntLsb) {
821+ m_LastWrittenPOC = m_iMinPOC;
822+#if defined (_DEBUG)
823+#ifdef _MOTION_VECTOR_DUMP_
824+ fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
825+#endif
826+#endif
827+ memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
828+ ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
829+ ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
830+ ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
831+ m_sPictInfoList[m_iPictInfoIndex].iPOC = sIMinInt32;
832+ m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
833+ m_iMinPOC = sIMinInt32;
834+ --m_iNumOfPicts;
835+ return dsErrorFree;
836+ }
837+ }
838+ }
839+
840+ return dsErrorFree;
841+}
842+
843+DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,
844+ const int kiSrcLen,
845+ SParserBsInfo* pDstInfo) {
846+ if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {
847+ if (m_pWelsTrace != NULL) {
848+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeParser without Initialize.\n");
849+ }
850+ return dsInitialOptExpected;
851+ }
852+
853+ if (!m_pDecContext->pParam->bParseOnly) {
854+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be true for this API calling! \n");
855+ m_pDecContext->iErrorCode |= dsInvalidArgument;
856+ return dsInvalidArgument;
857+ }
858+ int64_t iEnd, iStart = WelsTime();
859+ if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {
860+ if (ResetDecoder())
861+ return dsOutOfMemory;
862+
863+ return dsErrorFree;
864+ }
865+ if (kiSrcLen > 0 && kpSrc != NULL) {
866+#ifdef OUTPUT_BITSTREAM
867+ if (m_pFBS) {
868+ WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS);
869+ WelsFflush (m_pFBS);
870+ }
871+#endif//OUTPUT_BIT_STREAM
872+ m_pDecContext->bEndOfStreamFlag = false;
873+ } else {
874+ //For application MODE, the error detection should be added for safe.
875+ //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
876+ m_pDecContext->bEndOfStreamFlag = true;
877+ m_pDecContext->bInstantDecFlag = true;
878+ }
879+
880+ m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
881+ m_pDecContext->pParam->eEcActiveIdc = ERROR_CON_DISABLE; //add protection to disable EC here.
882+ m_pDecContext->iFeedbackNalRefIdc = -1; //initialize
883+ if (!m_pDecContext->bFramePending) { //frame complete
884+ m_pDecContext->pParserBsInfo->iNalNum = 0;
885+ memset (m_pDecContext->pParserBsInfo->pNalLenInByte, 0, MAX_NAL_UNITS_IN_LAYER);
886+ }
887+ pDstInfo->iNalNum = 0;
888+ pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;
889+ if (pDstInfo) {
890+ m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
891+ pDstInfo->uiOutBsTimeStamp = 0;
892+ } else {
893+ m_pDecContext->uiTimeStamp = 0;
894+ }
895+ WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);
896+ if (m_pDecContext->iErrorCode & dsOutOfMemory) {
897+ if (ResetDecoder())
898+ return dsOutOfMemory;
899+ return dsErrorFree;
900+ }
901+
902+ if (!m_pDecContext->bFramePending && m_pDecContext->pParserBsInfo->iNalNum) {
903+ memcpy (pDstInfo, m_pDecContext->pParserBsInfo, sizeof (SParserBsInfo));
904+
905+ if (m_pDecContext->iErrorCode == ERR_NONE) { //update statistics: decoding frame count
906+ m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
907+ if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
908+ ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
909+ m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
910+ }
911+ }
912+ }
913+
914+ m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
915+
916+ if (m_pDecContext->iErrorCode && m_pDecContext->bPrintFrameErrorTraceFlag) {
917+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n", m_pDecContext->iErrorCode);
918+ m_pDecContext->bPrintFrameErrorTraceFlag = false;
919+ }
920+ iEnd = WelsTime();
921+ m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
922+
923+ return (DECODING_STATE) m_pDecContext->iErrorCode;
924+}
925+
926+DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,
927+ const int kiSrcLen,
928+ unsigned char** ppDst,
929+ int* pStride,
930+ int& iWidth,
931+ int& iHeight) {
932+ DECODING_STATE eDecState = dsErrorFree;
933+ SBufferInfo DstInfo;
934+
935+ memset (&DstInfo, 0, sizeof (SBufferInfo));
936+ DstInfo.UsrData.sSystemBuffer.iStride[0] = pStride[0];
937+ DstInfo.UsrData.sSystemBuffer.iStride[1] = pStride[1];
938+ DstInfo.UsrData.sSystemBuffer.iWidth = iWidth;
939+ DstInfo.UsrData.sSystemBuffer.iHeight = iHeight;
940+
941+ eDecState = DecodeFrame2 (kpSrc, kiSrcLen, ppDst, &DstInfo);
942+ if (eDecState == dsErrorFree) {
943+ pStride[0] = DstInfo.UsrData.sSystemBuffer.iStride[0];
944+ pStride[1] = DstInfo.UsrData.sSystemBuffer.iStride[1];
945+ iWidth = DstInfo.UsrData.sSystemBuffer.iWidth;
946+ iHeight = DstInfo.UsrData.sSystemBuffer.iHeight;
947+ }
948+
949+ return eDecState;
950+}
951+
952+DECODING_STATE CWelsDecoder::DecodeFrameEx (const unsigned char* kpSrc,
953+ const int kiSrcLen,
954+ unsigned char* pDst,
955+ int iDstStride,
956+ int& iDstLen,
957+ int& iWidth,
958+ int& iHeight,
959+ int& iColorFormat) {
960+ DECODING_STATE state = dsErrorFree;
961+
962+ return state;
963+}
964+
965+
966+} // namespace WelsDec
967+
968+
969+using namespace WelsDec;
970+/*
971+* WelsGetDecoderCapability
972+* @return: DecCapability information
973+*/
974+int WelsGetDecoderCapability (SDecoderCapability* pDecCapability) {
975+ memset (pDecCapability, 0, sizeof (SDecoderCapability));
976+ pDecCapability->iProfileIdc = 66; //Baseline
977+ pDecCapability->iProfileIop = 0xE0; //11100000b
978+ pDecCapability->iLevelIdc = 32; //level_idc = 3.2
979+ pDecCapability->iMaxMbps = 216000; //from level_idc = 3.2
980+ pDecCapability->iMaxFs = 5120; //from level_idc = 3.2
981+ pDecCapability->iMaxCpb = 20000; //from level_idc = 3.2
982+ pDecCapability->iMaxDpb = 20480; //from level_idc = 3.2
983+ pDecCapability->iMaxBr = 20000; //from level_idc = 3.2
984+ pDecCapability->bRedPicCap = 0; //not support redundant pic
985+
986+ return ERR_NONE;
987+}
988+/* WINAPI is indeed in prefix due to sync to application layer callings!! */
989+
990+/*
991+* WelsCreateDecoder
992+* @return: success in return 0, otherwise failed.
993+*/
994+long WelsCreateDecoder (ISVCDecoder** ppDecoder) {
995+
996+ if (NULL == ppDecoder) {
997+ return ERR_INVALID_PARAMETERS;
998+ }
999+
1000+ *ppDecoder = new CWelsDecoder();
1001+
1002+ if (NULL == *ppDecoder) {
1003+ return ERR_MALLOC_FAILED;
1004+ }
1005+
1006+ return ERR_NONE;
1007+}
1008+
1009+/*
1010+* WelsDestroyDecoder
1011+*/
1012+void WelsDestroyDecoder (ISVCDecoder* pDecoder) {
1013+ if (NULL != pDecoder) {
1014+ delete (CWelsDecoder*)pDecoder;
1015+ }
1016+}

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