History

commit-4 of multi-thread decoding support.

Add various internal thread functions. Create function ParseAccessUnit and thread function ConstructAccessUnit in the condition that each input bitstream segment must contain exact one access unit (i.e. one slice or one frame).

xiaotian.shi committed 7 years ago

Commit 4863c661 parent 4bc0b8a4 files · +869 −392Browse files

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

Unified · Split

codec/decoder/plus/src/welsDecoderExt.cpp+700−343
@@ -51,6 +51,7 @@ · 50 unmodified lines
5151 //#include "macros.h"
5252 #include "decoder.h"
5353 #include "decoder_core.h"
54+#include "manage_dec_ref.h"
5455 #include "error_concealment.h"
5556
5657 #include "measure_time.h"
@@ -67,12 +68,11 @@ extern "C" { · 10 unmodified lines
6768 #include <stdio.h>
6869 #include <stdarg.h>
6970 #include <sys/types.h>
71+#include <malloc.h>
7072 #else
7173 #include <sys/time.h>
7274 #endif
7375
74−#define _PICTURE_REORDERING_ 1
75−
7676 namespace WelsDec {
7777
7878 //////////////////////////////////////////////////////////////////////
@@ -88,9 +88,58 @@ namespace WelsDec { · 9 unmodified lines
8888 *
8989 * return: none
9090 ***************************************************************************/
91+DECLARE_PROCTHREAD (pThrProcInit, p) {
92+ SWelsDecThreadInfo* sThreadInfo = (SWelsDecThreadInfo*)p;
93+#if defined(WIN32)
94+ _alloca (WELS_DEC_MAX_THREAD_STACK_SIZE * (sThreadInfo->uiThrNum + 1));
95+#endif
96+ return sThreadInfo->pThrProcMain (p);
97+}
98+
99+static DECODING_STATE ConstructAccessUnit (CWelsDecoder* pWelsDecoder, PWelsDecoderThreadCTX pThrCtx) {
100+ int iRet = dsErrorFree;
101+ //WelsMutexLock (&pWelsDecoder->m_csDecoder);
102+ if (pThrCtx->pCtx->pLastThreadCtx != NULL) {
103+ PWelsDecoderThreadCTX pLastThreadCtx = (PWelsDecoderThreadCTX) (pThrCtx->pCtx->pLastThreadCtx);
104+ WAIT_EVENT (&pLastThreadCtx->sSliceDecodeStart, WELS_DEC_THREAD_WAIT_INFINITE);
105+ RESET_EVENT (&pLastThreadCtx->sSliceDecodeStart);
106+ }
107+ pThrCtx->pDec = NULL;
108+ RESET_EVENT (&pThrCtx->sSliceDecodeFinsh);
109+ iRet |= pWelsDecoder->DecodeFrame2WithCtx (pThrCtx->pCtx, NULL, 0, pThrCtx->ppDst, &pThrCtx->sDstInfo);
110+
111+ //WelsMutexUnlock (&pWelsDecoder->m_csDecoder);
112+ return (DECODING_STATE)iRet;
113+}
114+
115+DECLARE_PROCTHREAD (pThrProcFrame, p) {
116+ SWelsDecoderThreadCTX* pThrCtx = (SWelsDecoderThreadCTX*)p;
117+ while (1) {
118+ RELEASE_SEMAPHORE (pThrCtx->sThreadInfo.sIsBusy);
119+ RELEASE_SEMAPHORE (&pThrCtx->sThreadInfo.sIsIdle);
120+ WAIT_SEMAPHORE (&pThrCtx->sThreadInfo.sIsActivated, WELS_DEC_THREAD_WAIT_INFINITE);
121+ if (pThrCtx->sThreadInfo.uiCommand == WELS_DEC_THREAD_COMMAND_RUN) {
122+ CWelsDecoder* pWelsDecoder = (CWelsDecoder*)pThrCtx->threadCtxOwner;
123+ ConstructAccessUnit (pWelsDecoder, pThrCtx);
124+ } else if (pThrCtx->sThreadInfo.uiCommand == WELS_DEC_THREAD_COMMAND_ABORT) {
125+ break;
126+ }
127+ }
128+ return 0;
129+}
130+
91131 CWelsDecoder::CWelsDecoder (void)
92− : m_pDecContext (NULL),
93− m_pWelsTrace (NULL) {
132+ : m_pWelsTrace (NULL),
133+ m_uiDecodeTimeStamp (0),
134+ m_bIsBaseline (false),
135+ m_iCpuCount (1),
136+ m_iThreadCount (1),
137+ m_pPicBuff (NULL),
138+ m_bParamSetsLostFlag (false),
139+ m_bFreezeOutput (false),
140+ m_DecCtxActiveCount (0),
141+ m_pDecThrCtx (NULL),
142+ m_pLastDecThrCtx (NULL) {
94143 #ifdef OUTPUT_BIT_STREAM
95144 char chFileName[1024] = { 0 }; //for .264
96145 int iBufUsed = 0;
@@ -114,6 +163,15 @@ CWelsDecoder::CWelsDecoder (void) · 17 unmodified lines
114163
115164 ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, true);
116165
166+ m_iCpuCount = GetCPUCount();
167+ if (m_iCpuCount > WELS_DEC_MAX_NUM_CPU) {
168+ m_iCpuCount = WELS_DEC_MAX_NUM_CPU;
169+ }
170+ m_pDecThrCtx = new SWelsDecoderThreadCTX[m_iThreadCount];
171+ memset (m_pDecThrCtx, 0, sizeof (SWelsDecoderThreadCTX)*m_iThreadCount);
172+ for (int32_t i = 0; i < WELS_DEC_MAX_NUM_CPU; ++i) {
173+ m_pDecThrCtxActive[i] = NULL;
174+ }
117175 #ifdef OUTPUT_BIT_STREAM
118176 SWelsTime sCurTime;
119177
@@ -169,7 +227,7 @@ CWelsDecoder::~CWelsDecoder() { · 49 unmodified lines
169227 if (m_pWelsTrace != NULL) {
170228 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::~CWelsDecoder()");
171229 }
172−
230+ CloseDecoderThreads();
173231 UninitDecoder();
174232
175233 #ifdef OUTPUT_BIT_STREAM
@@ -187,6 +245,10 @@ CWelsDecoder::~CWelsDecoder() { · 11 unmodified lines
187245 delete m_pWelsTrace;
188246 m_pWelsTrace = NULL;
189247 }
248+ if (m_pDecThrCtx != NULL) {
249+ delete[] m_pDecThrCtx;
250+ m_pDecThrCtx = NULL;
251+ }
190252 }
191253
192254 long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
@@ -215,26 +277,87 @@ long CWelsDecoder::Uninitialize() { · 22 unmodified lines
215277 }
216278
217279 void CWelsDecoder::UninitDecoder (void) {
218− if (NULL == m_pDecContext)
219− return;
280+ for (int32_t i = 0; i < m_iThreadCount; ++i) {
281+ if (m_pDecThrCtx[i].pCtx != NULL) {
282+ if (i > 0) {
283+ WelsResetRefPicWithoutUnRef (m_pDecThrCtx[i].pCtx);
284+ }
285+ UninitDecoderCtx (m_pDecThrCtx[i].pCtx);
286+ }
287+ }
288+}
220289
221− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::UninitDecoder(), openh264 codec version = %s.",
222− VERSION_NUMBER);
290+void CWelsDecoder::OpenDecoderThreads() {
291+ if (m_iThreadCount > 1) {
292+ m_uiDecodeTimeStamp = 0;
293+ CREATE_SEMAPHORE (&m_sIsBusy, m_iThreadCount, m_iThreadCount, NULL);
294+ WelsMutexInit (&m_csDecoder);
295+ CREATE_EVENT (&m_sBufferingEvent, 1, 0, NULL);
296+ SET_EVENT (&m_sBufferingEvent);
297+ CREATE_EVENT (&m_sReleaseBufferEvent, 1, 0, NULL);
298+ SET_EVENT (&m_sReleaseBufferEvent);
299+ for (int32_t i = 0; i < m_iThreadCount; ++i) {
300+ m_pDecThrCtx[i].sThreadInfo.uiThrMaxNum = m_iThreadCount;
301+ m_pDecThrCtx[i].sThreadInfo.uiThrNum = i;
302+ m_pDecThrCtx[i].sThreadInfo.uiThrStackSize = WELS_DEC_MAX_THREAD_STACK_SIZE;
303+ m_pDecThrCtx[i].sThreadInfo.pThrProcMain = pThrProcFrame;
304+ m_pDecThrCtx[i].sThreadInfo.sIsBusy = &m_sIsBusy;
305+ m_pDecThrCtx[i].sThreadInfo.uiCommand = WELS_DEC_THREAD_COMMAND_RUN;
306+ m_pDecThrCtx[i].threadCtxOwner = this;
307+ m_pDecThrCtx[i].kpSrc = NULL;
308+ m_pDecThrCtx[i].kiSrcLen = 0;
309+ m_pDecThrCtx[i].ppDst = NULL;
310+ m_pDecThrCtx[i].pDec = NULL;
311+ CREATE_EVENT (&m_pDecThrCtx[i].sImageReady, 1, 0, NULL);
312+ CREATE_EVENT (&m_pDecThrCtx[i].sSliceDecodeStart, 1, 0, NULL);
313+ CREATE_EVENT (&m_pDecThrCtx[i].sSliceDecodeFinsh, 1, 0, NULL);
314+ CREATE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsIdle, 0, 1, NULL);
315+ CREATE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsActivated, 0, 1, NULL);
316+ CREATE_THREAD (&m_pDecThrCtx[i].sThreadInfo.sThrHandle, pThrProcInit, (void*) (& (m_pDecThrCtx[i])));
317+ }
318+ }
319+}
320+void CWelsDecoder::CloseDecoderThreads() {
321+ if (m_iThreadCount > 1) {
322+ for (int32_t i = 0; i < m_iThreadCount; i++) { //waiting the completion begun slices
323+ WAIT_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsIdle, WELS_DEC_THREAD_WAIT_INFINITE);
324+ m_pDecThrCtx[i].sThreadInfo.uiCommand = WELS_DEC_THREAD_COMMAND_ABORT;
325+ RELEASE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsActivated);
326+ WAIT_THREAD (&m_pDecThrCtx[i].sThreadInfo.sThrHandle);
327+ CLOSE_EVENT (&m_pDecThrCtx[i].sImageReady);
328+ CLOSE_EVENT (&m_pDecThrCtx[i].sSliceDecodeStart);
329+ CLOSE_EVENT (&m_pDecThrCtx[i].sSliceDecodeFinsh);
330+ CLOSE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsIdle);
331+ CLOSE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsActivated);
332+ }
333+ WelsMutexDestroy (&m_csDecoder);
334+ CLOSE_EVENT (&m_sBufferingEvent);
335+ CLOSE_EVENT (&m_sReleaseBufferEvent);
336+ CLOSE_SEMAPHORE (&m_sIsBusy);
337+ }
338+}
223339
224− WelsEndDecoder (m_pDecContext);
340+void CWelsDecoder::UninitDecoderCtx (PWelsDecoderContext& pCtx) {
341+ if (pCtx != NULL) {
225342
226− if (m_pDecContext->pMemAlign != NULL) {
227− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
228− "CWelsDecoder::UninitDecoder(), verify memory usage (%d bytes) after free..",
229− m_pDecContext->pMemAlign->WelsGetMemoryUsage());
230− delete m_pDecContext->pMemAlign;
231− m_pDecContext->pMemAlign = NULL;
232− }
343+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::UninitDecoderCtx(), openh264 codec version = %s.",
344+ VERSION_NUMBER);
233345
234− if (NULL != m_pDecContext) {
235− WelsFree (m_pDecContext, "m_pDecContext");
346+ WelsEndDecoder (pCtx);
236347
237− m_pDecContext = NULL;
348+ if (pCtx->pMemAlign != NULL) {
349+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
350+ "CWelsDecoder::UninitDecoder(), verify memory usage (%d bytes) after free..",
351+ pCtx->pMemAlign->WelsGetMemoryUsage());
352+ delete pCtx->pMemAlign;
353+ pCtx->pMemAlign = NULL;
354+ }
355+
356+ if (NULL != pCtx) {
357+ WelsFree (pCtx, "m_pDecContext");
358+
359+ pCtx = NULL;
360+ }
238361 }
239362 }
240363
@@ -244,59 +367,100 @@ int32_t CWelsDecoder::InitDecoder (const SDecodingParam* pParam) { · 3 unmodified lines
244367 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
245368 "CWelsDecoder::init_decoder(), openh264 codec version = %s, ParseOnly = %d",
246369 VERSION_NUMBER, (int32_t)pParam->bParseOnly);
247−
370+ if (m_iThreadCount > 1 && pParam->bParseOnly) {
371+ m_iThreadCount = 1;
372+ }
373+ OpenDecoderThreads();
248374 //reset decoder context
249375 memset (&m_sDecoderStatistics, 0, sizeof (SDecoderStatistics));
250376 memset (&m_sLastDecPicInfo, 0, sizeof (SWelsLastDecPicInfo));
251377 memset (&m_sVlcTable, 0, sizeof (SVlcTable));
378+ UninitDecoder();
252379 WelsDecoderLastDecPicInfoDefaults (m_sLastDecPicInfo);
253− if (m_pDecContext) //free
254− UninitDecoder();
255− m_pDecContext = (PWelsDecoderContext)WelsMallocz (sizeof (SWelsDecoderContext), "m_pDecContext");
256− if (NULL == m_pDecContext)
380+ for (int32_t i = 0; i < m_iThreadCount; ++i) {
381+ InitDecoderCtx (m_pDecThrCtx[i].pCtx, pParam);
382+ if (m_iThreadCount > 1) {
383+ m_pDecThrCtx[i].pCtx->pThreadCtx = &m_pDecThrCtx[i];
384+ }
385+ }
386+ m_bParamSetsLostFlag = false;
387+ m_bFreezeOutput = false;
388+ return cmResultSuccess;
389+}
390+
391+// the return value of this function is not suitable, it need report failure info to upper layer.
392+int32_t CWelsDecoder::InitDecoderCtx (PWelsDecoderContext& pCtx, const SDecodingParam* pParam) {
393+
394+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
395+ "CWelsDecoder::init_decoder(), openh264 codec version = %s, ParseOnly = %d",
396+ VERSION_NUMBER, (int32_t)pParam->bParseOnly);
397+
398+ //reset decoder context
399+ UninitDecoderCtx (pCtx);
400+ pCtx = (PWelsDecoderContext)WelsMallocz (sizeof (SWelsDecoderContext), "m_pDecContext");
401+ if (NULL == pCtx)
257402 return cmMallocMemeError;
258403 int32_t iCacheLineSize = 16; // on chip cache line size in byte
259− m_pDecContext->pMemAlign = new CMemoryAlign (iCacheLineSize);
260− WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pMemAlign), UninitDecoder())
404+ pCtx->pMemAlign = new CMemoryAlign (iCacheLineSize);
405+ WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == pCtx->pMemAlign), UninitDecoderCtx (pCtx))
261406
262407 //fill in default value into context
263− m_pDecContext->pLastDecPicInfo = &m_sLastDecPicInfo;
264− m_pDecContext->pDecoderStatistics = &m_sDecoderStatistics;
265− m_pDecContext->pVlcTable = &m_sVlcTable;
266− m_pDecContext->pPictInfoList = m_sPictInfoList;
267− m_pDecContext->pPictReoderingStatus = &m_sReoderingStatus;
268− WelsDecoderDefaults (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
269− WelsDecoderSpsPpsDefaults (m_pDecContext->sSpsPpsCtx);
270−
408+ pCtx->pLastDecPicInfo = &m_sLastDecPicInfo;
409+ pCtx->pDecoderStatistics = &m_sDecoderStatistics;
410+ pCtx->pVlcTable = &m_sVlcTable;
411+ pCtx->pPictInfoList = m_sPictInfoList;
412+ pCtx->pPictReoderingStatus = &m_sReoderingStatus;
413+ pCtx->pCsDecoder = &m_csDecoder;
414+ WelsDecoderDefaults (pCtx, &m_pWelsTrace->m_sLogCtx);
415+ WelsDecoderSpsPpsDefaults (pCtx->sSpsPpsCtx);
271416 //check param and update decoder context
272− m_pDecContext->pParam = (SDecodingParam*)m_pDecContext->pMemAlign->WelsMallocz (sizeof (SDecodingParam),
273− "SDecodingParam");
274− WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pParam), UninitDecoder());
275− int32_t iRet = DecoderConfigParam (m_pDecContext, pParam);
417+ pCtx->pParam = (SDecodingParam*)pCtx->pMemAlign->WelsMallocz (sizeof (SDecodingParam),
418+ "SDecodingParam");
419+ WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == pCtx->pParam), UninitDecoderCtx (pCtx));
420+ int32_t iRet = DecoderConfigParam (pCtx, pParam);
276421 WELS_VERIFY_RETURN_IFNEQ (iRet, cmResultSuccess);
277422
278423 //init decoder
279− WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx),
280− UninitDecoder())
281−
424+ WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, WelsInitDecoder (pCtx, &m_pWelsTrace->m_sLogCtx),
425+ UninitDecoderCtx (pCtx))
426+ pCtx->pPicBuff = NULL;
282427 return cmResultSuccess;
283428 }
284429
285−int32_t CWelsDecoder::ResetDecoder() {
430+int32_t CWelsDecoder::ResetDecoder (PWelsDecoderContext& pCtx) {
286431 // TBC: need to be modified when context and trace point are null
287− if (m_pDecContext != NULL && m_pWelsTrace != NULL) {
288− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ResetDecoder(), context error code is %d",
289− m_pDecContext->iErrorCode);
290− SDecodingParam sPrevParam;
291− memcpy (&sPrevParam, m_pDecContext->pParam, sizeof (SDecodingParam));
432+ if (m_iThreadCount > 1) {
433+ ThreadResetDecoder (pCtx);
434+ } else {
435+ if (pCtx != NULL && m_pWelsTrace != NULL) {
436+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ResetDecoder(), context error code is %d",
437+ pCtx->iErrorCode);
438+ SDecodingParam sPrevParam;
439+ memcpy (&sPrevParam, pCtx->pParam, sizeof (SDecodingParam));
440+
441+ WELS_VERIFY_RETURN_PROC_IF (cmInitParaError, InitDecoderCtx (pCtx, &sPrevParam),
442+ UninitDecoderCtx (pCtx));
443+ } else if (m_pWelsTrace != NULL) {
444+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "ResetDecoder() failed as decoder context null");
445+ }
446+ ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, false);
447+ }
448+ return ERR_INFO_UNINIT;
449+}
292450
293− WELS_VERIFY_RETURN_PROC_IF (cmInitParaError, InitDecoder (&sPrevParam), UninitDecoder());
451+int32_t CWelsDecoder::ThreadResetDecoder (PWelsDecoderContext& pCtx) {
452+ // TBC: need to be modified when context and trace point are null
453+ SDecodingParam sPrevParam;
454+ if (pCtx != NULL && m_pWelsTrace != NULL) {
455+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ResetDecoder(), context error code is %d", pCtx->iErrorCode);
456+ memcpy (&sPrevParam, pCtx->pParam, sizeof (SDecodingParam));
457+ ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, true);
458+ CloseDecoderThreads();
459+ UninitDecoder();
460+ InitDecoder (&sPrevParam);
294461 } else if (m_pWelsTrace != NULL) {
295462 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "ResetDecoder() failed as decoder context null");
296463 }
297−#ifdef _PICTURE_REORDERING_
298− ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, false);
299−#endif
300464 return ERR_INFO_UNINIT;
301465 }
302466
@@ -305,71 +469,95 @@ int32_t CWelsDecoder::ResetDecoder() { · 2 unmodified lines
305469 */
306470 long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
307471 int iVal = 0;
472+ if (eOptID == DECODER_OPTION_NUM_OF_THREADS) {
473+ if (pOption != NULL) {
474+ int32_t threadCount = * ((int32_t*)pOption);
475+ if (threadCount <= 0) {
476+ threadCount = 1;
477+ } else if (threadCount > m_iCpuCount) {
478+ threadCount = m_iCpuCount;
479+ }
480+ if (threadCount > 3) {
481+ threadCount = 3;
482+ }
483+ if (threadCount != m_iThreadCount) {
484+ m_iThreadCount = threadCount;
485+ if (m_pDecThrCtx != NULL) {
486+ delete [] m_pDecThrCtx;
487+ m_pDecThrCtx = new SWelsDecoderThreadCTX[m_iThreadCount];
488+ memset (m_pDecThrCtx, 0, sizeof (SWelsDecoderThreadCTX)*m_iThreadCount);
489+ }
490+ }
491+ }
492+ return cmResultSuccess;
493+ }
494+ for (int32_t i = 0; i < m_iThreadCount; ++i) {
495+ PWelsDecoderContext pDecContext = m_pDecThrCtx[i].pCtx;
496+ if (pDecContext == NULL && eOptID != DECODER_OPTION_TRACE_LEVEL &&
497+ eOptID != DECODER_OPTION_TRACE_CALLBACK && eOptID != DECODER_OPTION_TRACE_CALLBACK_CONTEXT)
498+ return dsInitialOptExpected;
499+ if (eOptID == DECODER_OPTION_END_OF_STREAM) { // Indicate bit-stream of the final frame to be decoded
500+ if (pOption == NULL)
501+ return cmInitParaError;
308502
309− if (m_pDecContext == NULL && eOptID != DECODER_OPTION_TRACE_LEVEL &&
310− eOptID != DECODER_OPTION_TRACE_CALLBACK && eOptID != DECODER_OPTION_TRACE_CALLBACK_CONTEXT)
311− return dsInitialOptExpected;
312− if (eOptID == DECODER_OPTION_END_OF_STREAM) { // Indicate bit-stream of the final frame to be decoded
313− if (pOption == NULL)
314− return cmInitParaError;
315−
316− iVal = * ((int*)pOption); // boolean value for whether enabled End Of Stream flag
503+ iVal = * ((int*)pOption); // boolean value for whether enabled End Of Stream flag
317504
318− m_pDecContext->bEndOfStreamFlag = iVal ? true : false;
505+ pDecContext->bEndOfStreamFlag = iVal ? true : false;
319506
320− return cmResultSuccess;
321− } else if (eOptID == DECODER_OPTION_ERROR_CON_IDC) { // Indicate error concealment status
322− if (pOption == NULL)
323− return cmInitParaError;
507+ return cmResultSuccess;
508+ } else if (eOptID == DECODER_OPTION_ERROR_CON_IDC) { // Indicate error concealment status
509+ if (pOption == NULL)
510+ return cmInitParaError;
511+
512+ iVal = * ((int*)pOption); // int value for error concealment idc
513+ iVal = WELS_CLIP3 (iVal, (int32_t)ERROR_CON_DISABLE, (int32_t)ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE);
514+ if ((pDecContext->pParam->bParseOnly) && (iVal != (int32_t)ERROR_CON_DISABLE)) {
515+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
516+ "CWelsDecoder::SetOption for ERROR_CON_IDC = %d not allowd for parse only!.", iVal);
517+ return cmInitParaError;
518+ }
324519
325− iVal = * ((int*)pOption); // int value for error concealment idc
326− iVal = WELS_CLIP3 (iVal, (int32_t)ERROR_CON_DISABLE, (int32_t)ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE);
327− if ((m_pDecContext->pParam->bParseOnly) && (iVal != (int32_t)ERROR_CON_DISABLE)) {
520+ pDecContext->pParam->eEcActiveIdc = (ERROR_CON_IDC)iVal;
521+ InitErrorCon (pDecContext);
328522 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
329− "CWelsDecoder::SetOption for ERROR_CON_IDC = %d not allowd for parse only!.", iVal);
330− return cmInitParaError;
331− }
332−
333− m_pDecContext->pParam->eEcActiveIdc = (ERROR_CON_IDC)iVal;
334− InitErrorCon (m_pDecContext);
335− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
336− "CWelsDecoder::SetOption for ERROR_CON_IDC = %d.", iVal);
523+ "CWelsDecoder::SetOption for ERROR_CON_IDC = %d.", iVal);
337524
338− return cmResultSuccess;
339− } else if (eOptID == DECODER_OPTION_TRACE_LEVEL) {
340− if (m_pWelsTrace) {
341− uint32_t level = * ((uint32_t*)pOption);
342− m_pWelsTrace->SetTraceLevel (level);
343− }
344− return cmResultSuccess;
345− } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK) {
346− if (m_pWelsTrace) {
347− WelsTraceCallback callback = * ((WelsTraceCallback*)pOption);
348− m_pWelsTrace->SetTraceCallback (callback);
349− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
350− "CWelsDecoder::SetOption():DECODER_OPTION_TRACE_CALLBACK callback = %p.",
351− callback);
352− }
353− return cmResultSuccess;
354− } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK_CONTEXT) {
355− if (m_pWelsTrace) {
356− void* ctx = * ((void**)pOption);
357− m_pWelsTrace->SetTraceCallbackContext (ctx);
358− }
359− return cmResultSuccess;
360− } else if (eOptID == DECODER_OPTION_GET_STATISTICS) {
361− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
362− "CWelsDecoder::SetOption():DECODER_OPTION_GET_STATISTICS: this option is get-only!");
363− return cmInitParaError;
364− } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
365− if (pOption) {
366− m_pDecContext->pDecoderStatistics->iStatisticsLogInterval = (* ((unsigned int*)pOption));
367525 return cmResultSuccess;
526+ } else if (eOptID == DECODER_OPTION_TRACE_LEVEL) {
527+ if (m_pWelsTrace) {
528+ uint32_t level = * ((uint32_t*)pOption);
529+ m_pWelsTrace->SetTraceLevel (level);
530+ }
531+ return cmResultSuccess;
532+ } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK) {
533+ if (m_pWelsTrace) {
534+ WelsTraceCallback callback = * ((WelsTraceCallback*)pOption);
535+ m_pWelsTrace->SetTraceCallback (callback);
536+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
537+ "CWelsDecoder::SetOption():DECODER_OPTION_TRACE_CALLBACK callback = %p.",
538+ callback);
539+ }
540+ return cmResultSuccess;
541+ } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK_CONTEXT) {
542+ if (m_pWelsTrace) {
543+ void* ctx = * ((void**)pOption);
544+ m_pWelsTrace->SetTraceCallbackContext (ctx);
545+ }
546+ return cmResultSuccess;
547+ } else if (eOptID == DECODER_OPTION_GET_STATISTICS) {
548+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
549+ "CWelsDecoder::SetOption():DECODER_OPTION_GET_STATISTICS: this option is get-only!");
550+ return cmInitParaError;
551+ } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
552+ if (pOption) {
553+ pDecContext->pDecoderStatistics->iStatisticsLogInterval = (* ((unsigned int*)pOption));
554+ return cmResultSuccess;
555+ }
556+ } else if (eOptID == DECODER_OPTION_GET_SAR_INFO) {
557+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
558+ "CWelsDecoder::SetOption():DECODER_OPTION_GET_SAR_INFO: this option is get-only!");
559+ return cmInitParaError;
368560 }
369− } else if (eOptID == DECODER_OPTION_GET_SAR_INFO) {
370− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
371− "CWelsDecoder::SetOption():DECODER_OPTION_GET_SAR_INFO: this option is get-only!");
372− return cmInitParaError;
373561 }
374562 return cmInitParaError;
375563 }
@@ -379,105 +567,109 @@ long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) { · 3 unmodified lines
379567 */
380568 long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) {
381569 int iVal = 0;
382−
383− if (m_pDecContext == NULL)
570+ if (DECODER_OPTION_NUM_OF_THREADS == eOptID) {
571+ * ((int*)pOption) = m_iThreadCount;
572+ return cmResultSuccess;
573+ }
574+ PWelsDecoderContext pDecContext = m_pDecThrCtx[0].pCtx;
575+ if (pDecContext == NULL)
384576 return cmInitExpected;
385577
386578 if (pOption == NULL)
387579 return cmInitParaError;
388580
389581 if (DECODER_OPTION_END_OF_STREAM == eOptID) {
390− iVal = m_pDecContext->bEndOfStreamFlag;
582+ iVal = pDecContext->bEndOfStreamFlag;
391583 * ((int*)pOption) = iVal;
392584 return cmResultSuccess;
393585 }
394586 #ifdef LONG_TERM_REF
395587 else if (DECODER_OPTION_IDR_PIC_ID == eOptID) {
396− iVal = m_pDecContext->uiCurIdrPicId;
588+ iVal = pDecContext->uiCurIdrPicId;
397589 * ((int*)pOption) = iVal;
398590 return cmResultSuccess;
399591 } else if (DECODER_OPTION_FRAME_NUM == eOptID) {
400− iVal = m_pDecContext->iFrameNum;
592+ iVal = pDecContext->iFrameNum;
401593 * ((int*)pOption) = iVal;
402594 return cmResultSuccess;
403595 } else if (DECODER_OPTION_LTR_MARKING_FLAG == eOptID) {
404− iVal = m_pDecContext->bCurAuContainLtrMarkSeFlag;
596+ iVal = pDecContext->bCurAuContainLtrMarkSeFlag;
405597 * ((int*)pOption) = iVal;
406598 return cmResultSuccess;
407599 } else if (DECODER_OPTION_LTR_MARKED_FRAME_NUM == eOptID) {
408− iVal = m_pDecContext->iFrameNumOfAuMarkedLtr;
600+ iVal = pDecContext->iFrameNumOfAuMarkedLtr;
409601 * ((int*)pOption) = iVal;
410602 return cmResultSuccess;
411603 }
412604 #endif
413605 else if (DECODER_OPTION_VCL_NAL == eOptID) { //feedback whether or not have VCL NAL in current AU
414− iVal = m_pDecContext->iFeedbackVclNalInAu;
606+ iVal = pDecContext->iFeedbackVclNalInAu;
415607 * ((int*)pOption) = iVal;
416608 return cmResultSuccess;
417609 } else if (DECODER_OPTION_TEMPORAL_ID == eOptID) { //if have VCL NAL in current AU, then feedback the temporal ID
418− iVal = m_pDecContext->iFeedbackTidInAu;
610+ iVal = pDecContext->iFeedbackTidInAu;
419611 * ((int*)pOption) = iVal;
420612 return cmResultSuccess;
421613 } else if (DECODER_OPTION_IS_REF_PIC == eOptID) {
422− iVal = m_pDecContext->iFeedbackNalRefIdc;
614+ iVal = pDecContext->iFeedbackNalRefIdc;
423615 if (iVal > 0)
424616 iVal = 1;
425617 * ((int*)pOption) = iVal;
426618 return cmResultSuccess;
427619 } else if (DECODER_OPTION_ERROR_CON_IDC == eOptID) {
428− iVal = (int)m_pDecContext->pParam->eEcActiveIdc;
620+ iVal = (int)pDecContext->pParam->eEcActiveIdc;
429621 * ((int*)pOption) = iVal;
430622 return cmResultSuccess;
431623 } else if (DECODER_OPTION_GET_STATISTICS == eOptID) { // get decoder statistics info for real time debugging
432624 SDecoderStatistics* pDecoderStatistics = (static_cast<SDecoderStatistics*> (pOption));
433625
434− memcpy (pDecoderStatistics, m_pDecContext->pDecoderStatistics, sizeof (SDecoderStatistics));
626+ memcpy (pDecoderStatistics, pDecContext->pDecoderStatistics, sizeof (SDecoderStatistics));
435627
436− if (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount != 0) { //not original status
437− pDecoderStatistics->fAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /
438− (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount);
439− pDecoderStatistics->fActualAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /
440− (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount + m_pDecContext->pDecoderStatistics->uiFreezingIDRNum +
441− m_pDecContext->pDecoderStatistics->uiFreezingNonIDRNum);
628+ if (pDecContext->pDecoderStatistics->uiDecodedFrameCount != 0) { //not original status
629+ pDecoderStatistics->fAverageFrameSpeedInMs = (float) (pDecContext->dDecTime) /
630+ (pDecContext->pDecoderStatistics->uiDecodedFrameCount);
631+ pDecoderStatistics->fActualAverageFrameSpeedInMs = (float) (pDecContext->dDecTime) /
632+ (pDecContext->pDecoderStatistics->uiDecodedFrameCount + pDecContext->pDecoderStatistics->uiFreezingIDRNum +
633+ pDecContext->pDecoderStatistics->uiFreezingNonIDRNum);
442634 }
443635 return cmResultSuccess;
444636 } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
445637 if (pOption) {
446− iVal = m_pDecContext->pDecoderStatistics->iStatisticsLogInterval;
638+ iVal = pDecContext->pDecoderStatistics->iStatisticsLogInterval;
447639 * ((unsigned int*)pOption) = iVal;
448640 return cmResultSuccess;
449641 }
450642 } else if (DECODER_OPTION_GET_SAR_INFO == eOptID) { //get decoder SAR info in VUI
451643 PVuiSarInfo pVuiSarInfo = (static_cast<PVuiSarInfo> (pOption));
452644 memset (pVuiSarInfo, 0, sizeof (SVuiSarInfo));
453− if (!m_pDecContext->pSps) {
645+ if (!pDecContext->pSps) {
454646 return cmInitExpected;
455647 } else {
456− pVuiSarInfo->uiSarWidth = m_pDecContext->pSps->sVui.uiSarWidth;
457− pVuiSarInfo->uiSarHeight = m_pDecContext->pSps->sVui.uiSarHeight;
458− pVuiSarInfo->bOverscanAppropriateFlag = m_pDecContext->pSps->sVui.bOverscanAppropriateFlag;
648+ pVuiSarInfo->uiSarWidth = pDecContext->pSps->sVui.uiSarWidth;
649+ pVuiSarInfo->uiSarHeight = pDecContext->pSps->sVui.uiSarHeight;
650+ pVuiSarInfo->bOverscanAppropriateFlag = pDecContext->pSps->sVui.bOverscanAppropriateFlag;
459651 return cmResultSuccess;
460652 }
461653 } else if (DECODER_OPTION_PROFILE == eOptID) {
462− if (!m_pDecContext->pSps) {
654+ if (!pDecContext->pSps) {
463655 return cmInitExpected;
464656 }
465− iVal = (int)m_pDecContext->pSps->uiProfileIdc;
657+ iVal = (int)pDecContext->pSps->uiProfileIdc;
466658 * ((int*)pOption) = iVal;
467659 return cmResultSuccess;
468660 } else if (DECODER_OPTION_LEVEL == eOptID) {
469− if (!m_pDecContext->pSps) {
661+ if (!pDecContext->pSps) {
470662 return cmInitExpected;
471663 }
472− iVal = (int)m_pDecContext->pSps->uiLevelIdc;
664+ iVal = (int)pDecContext->pSps->uiLevelIdc;
473665 * ((int*)pOption) = iVal;
474666 return cmResultSuccess;
475667 } else if (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER == eOptID) {
476− if (m_pDecContext->pSps && m_pDecContext->pSps->uiProfileIdc != 66) {
477− * ((int*)pOption) = m_sReoderingStatus.iNumOfPicts > 0 ? m_sReoderingStatus.iNumOfPicts : 0;
478− } else {
479− * ((int*)pOption) = 0;
668+ for (int32_t activeThread = 0; activeThread < m_DecCtxActiveCount; ++activeThread) {
669+ WAIT_SEMAPHORE (&m_pDecThrCtxActive[activeThread]->sThreadInfo.sIsIdle, WELS_DEC_THREAD_WAIT_INFINITE);
670+ RELEASE_SEMAPHORE (&m_pDecThrCtxActive[activeThread]->sThreadInfo.sIsIdle);
480671 }
672+ * ((int*)pOption) = m_sReoderingStatus.iNumOfPicts;
481673 return cmResultSuccess;
482674 }
483675
@@ -488,7 +680,17 @@ DECODING_STATE CWelsDecoder::DecodeFrameNoDelay (const unsigned char* kpSrc, · 4 unmodified lines
488680 const int kiSrcLen,
489681 unsigned char** ppDst,
490682 SBufferInfo* pDstInfo) {
491− int iRet;
683+ int iRet = dsErrorFree;
684+ if (m_iThreadCount > 1) {
685+ iRet = ThreadDecodeFrameInternal (kpSrc, kiSrcLen, ppDst, pDstInfo);
686+ if (m_sReoderingStatus.iNumOfPicts) {
687+ WAIT_EVENT (&m_sBufferingEvent, WELS_DEC_THREAD_WAIT_INFINITE);
688+ RESET_EVENT (&m_sReleaseBufferEvent);
689+ ReleaseBufferedReadyPicture (NULL, ppDst, pDstInfo);
690+ SET_EVENT (&m_sReleaseBufferEvent);
691+ }
692+ return (DECODING_STATE)iRet;
693+ }
492694 //SBufferInfo sTmpBufferInfo;
493695 //unsigned char* ppTmpDst[3] = {NULL, NULL, NULL};
494696 iRet = (int)DecodeFrame2 (kpSrc, kiSrcLen, ppDst, pDstInfo);
@@ -506,24 +708,24 @@ DECODING_STATE CWelsDecoder::DecodeFrameNoDelay (const unsigned char* kpSrc, · 11 unmodified lines
506708 return (DECODING_STATE)iRet;
507709 }
508710
509−DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
711+DECODING_STATE CWelsDecoder::DecodeFrame2WithCtx (PWelsDecoderContext pDecContext, const unsigned char* kpSrc,
510712 const int kiSrcLen,
511713 unsigned char** ppDst,
512714 SBufferInfo* pDstInfo) {
513− if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {
715+ if (pDecContext == NULL || pDecContext->pParam == NULL) {
514716 if (m_pWelsTrace != NULL) {
515717 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeFrame2 without Initialize.\n");
516718 }
517719 return dsInitialOptExpected;
518720 }
519721
520− if (m_pDecContext->pParam->bParseOnly) {
722+ if (pDecContext->pParam->bParseOnly) {
521723 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be false for this API calling! \n");
522− m_pDecContext->iErrorCode |= dsInvalidArgument;
724+ pDecContext->iErrorCode |= dsInvalidArgument;
523725 return dsInvalidArgument;
524726 }
525− if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {
526− if (ResetDecoder())
727+ if (CheckBsBuffer (pDecContext, kiSrcLen)) {
728+ if (ResetDecoder (pDecContext))
527729 return dsOutOfMemory;
528730
529731 return dsErrorFree;
@@ -539,147 +741,175 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, · 9 unmodified lines
539741 WelsFflush (m_pFBSSize);
540742 }
541743 #endif//OUTPUT_BIT_STREAM
542− m_pDecContext->bEndOfStreamFlag = false;
744+ pDecContext->bEndOfStreamFlag = false;
543745 } else {
544746 //For application MODE, the error detection should be added for safe.
545747 //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
546− m_pDecContext->bEndOfStreamFlag = true;
547− m_pDecContext->bInstantDecFlag = true;
748+ pDecContext->bEndOfStreamFlag = true;
749+ pDecContext->bInstantDecFlag = true;
548750 }
549751
550752 int64_t iStart, iEnd;
551753 iStart = WelsTime();
552754
553− ppDst[0] = ppDst[1] = ppDst[2] = NULL;
554− m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
555− m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
755+ if (pDecContext->pThreadCtx == NULL) {
756+ ppDst[0] = ppDst[1] = ppDst[2] = NULL;
757+ }
758+ pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
759+ pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
556760 unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;
557− memset (pDstInfo, 0, sizeof (SBufferInfo));
761+ if (pDecContext->pThreadCtx == NULL) {
762+ memset (pDstInfo, 0, sizeof (SBufferInfo));
763+ }
558764 pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;
559765 #ifdef LONG_TERM_REF
560− m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
561− m_pDecContext->bCurAuContainLtrMarkSeFlag = false;
562− m_pDecContext->iFrameNumOfAuMarkedLtr = 0;
563− m_pDecContext->iFrameNum = -1; //initialize
766+ pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
767+ pDecContext->bCurAuContainLtrMarkSeFlag = false;
768+ pDecContext->iFrameNumOfAuMarkedLtr = 0;
769+ pDecContext->iFrameNum = -1; //initialize
564770 #endif
565771
566− m_pDecContext->iFeedbackTidInAu = -1; //initialize
567− m_pDecContext->iFeedbackNalRefIdc = -1; //initialize
772+ pDecContext->iFeedbackTidInAu = -1; //initialize
773+ pDecContext->iFeedbackNalRefIdc = -1; //initialize
568774 if (pDstInfo) {
569775 pDstInfo->uiOutYuvTimeStamp = 0;
570− m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
776+ pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
571777 } else {
572− m_pDecContext->uiTimeStamp = 0;
778+ pDecContext->uiTimeStamp = 0;
573779 }
574− WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, ppDst,
780+ WelsDecodeBs (pDecContext, kpSrc, kiSrcLen, ppDst,
575781 pDstInfo, NULL); //iErrorCode has been modified in this function
576− m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
577− if (m_pDecContext->iErrorCode) {
782+ pDecContext->bInstantDecFlag = false; //reset no-delay flag
783+ if (pDecContext->iErrorCode) {
578784 EWelsNalUnitType eNalType =
579785 NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently
580786
581− eNalType = m_pDecContext->sCurNalHead.eNalUnitType;
582− if (m_pDecContext->iErrorCode & dsOutOfMemory) {
583− if (ResetDecoder()) {
787+ eNalType = pDecContext->sCurNalHead.eNalUnitType;
788+ if (pDecContext->iErrorCode & dsOutOfMemory) {
789+ if (ResetDecoder (pDecContext)) {
584790 return dsOutOfMemory;
585791 }
586792 return dsErrorFree;
587793 }
588− if (m_pDecContext->iErrorCode & dsRefListNullPtrs) {
589− if (ResetDecoder()) {
794+ if (pDecContext->iErrorCode & dsRefListNullPtrs) {
795+ if (ResetDecoder (pDecContext)) {
590796 return dsRefListNullPtrs;
591797 }
592798 return dsErrorFree;
593799 }
594− if ((m_pDecContext->iErrorCode & (dsBitstreamError | dsDataErrorConcealed)) && m_pDecContext->eSliceType == B_SLICE) {
595− if (ResetDecoder()) {
800+ if ((pDecContext->iErrorCode & (dsBitstreamError | dsDataErrorConcealed)) && pDecContext->eSliceType == B_SLICE) {
801+ if (ResetDecoder (pDecContext)) {
596802 pDstInfo->iBufferStatus = 0;
597− return (DECODING_STATE)m_pDecContext->iErrorCode;
803+ return (DECODING_STATE)pDecContext->iErrorCode;
598804 }
599805 return dsErrorFree;
600806 }
601807 //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.
602808 if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||
603− (VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType)) {
604− if (m_pDecContext->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
809+ (VIDEO_BITSTREAM_AVC == pDecContext->eVideoType)) {
810+ if (pDecContext->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
605811 #ifdef LONG_TERM_REF
606− m_pDecContext->bParamSetsLostFlag = true;
812+ pDecContext->bParamSetsLostFlag = true;
607813 #else
608− m_pDecContext->bReferenceLostAtT0Flag = true;
814+ pDecContext->bReferenceLostAtT0Flag = true;
609815 #endif
610816 }
611817 }
612818
613− if (m_pDecContext->bPrintFrameErrorTraceFlag) {
819+ if (pDecContext->bPrintFrameErrorTraceFlag) {
614820 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n",
615− m_pDecContext->iErrorCode);
616− m_pDecContext->bPrintFrameErrorTraceFlag = false;
821+ pDecContext->iErrorCode);
822+ pDecContext->bPrintFrameErrorTraceFlag = false;
617823 } else {
618− m_pDecContext->iIgnoredErrorInfoPacketCount++;
619− if (m_pDecContext->iIgnoredErrorInfoPacketCount == INT_MAX) {
824+ pDecContext->iIgnoredErrorInfoPacketCount++;
825+ if (pDecContext->iIgnoredErrorInfoPacketCount == INT_MAX) {
620826 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING, "continuous error reached INT_MAX! Restart as 0.");
621− m_pDecContext->iIgnoredErrorInfoPacketCount = 0;
827+ pDecContext->iIgnoredErrorInfoPacketCount = 0;
622828 }
623829 }
624− if ((m_pDecContext->pParam->eEcActiveIdc != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {
830+ if ((pDecContext->pParam->eEcActiveIdc != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {
625831 //TODO after dec status updated
626− m_pDecContext->iErrorCode |= dsDataErrorConcealed;
832+ pDecContext->iErrorCode |= dsDataErrorConcealed;
627833
628− m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
629− if (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
630− ResetDecStatNums (m_pDecContext->pDecoderStatistics);
631− m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
834+ pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
835+ if (pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
836+ ResetDecStatNums (pDecContext->pDecoderStatistics);
837+ pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
632838 }
633− int32_t iMbConcealedNum = m_pDecContext->iMbEcedNum + m_pDecContext->iMbEcedPropNum;
634− m_pDecContext->pDecoderStatistics->uiAvgEcRatio = m_pDecContext->iMbNum == 0 ?
635− (m_pDecContext->pDecoderStatistics->uiAvgEcRatio * m_pDecContext->pDecoderStatistics->uiEcFrameNum) : ((
636− m_pDecContext->pDecoderStatistics->uiAvgEcRatio * m_pDecContext->pDecoderStatistics->uiEcFrameNum) + ((
637− iMbConcealedNum * 100) / m_pDecContext->iMbNum));
638− m_pDecContext->pDecoderStatistics->uiAvgEcPropRatio = m_pDecContext->iMbNum == 0 ?
639− (m_pDecContext->pDecoderStatistics->uiAvgEcPropRatio * m_pDecContext->pDecoderStatistics->uiEcFrameNum) : ((
640− m_pDecContext->pDecoderStatistics->uiAvgEcPropRatio * m_pDecContext->pDecoderStatistics->uiEcFrameNum) + ((
641− m_pDecContext->iMbEcedPropNum * 100) / m_pDecContext->iMbNum));
642− m_pDecContext->pDecoderStatistics->uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1);
643− m_pDecContext->pDecoderStatistics->uiAvgEcRatio = m_pDecContext->pDecoderStatistics->uiEcFrameNum == 0 ? 0 :
644− m_pDecContext->pDecoderStatistics->uiAvgEcRatio / m_pDecContext->pDecoderStatistics->uiEcFrameNum;
645− m_pDecContext->pDecoderStatistics->uiAvgEcPropRatio = m_pDecContext->pDecoderStatistics->uiEcFrameNum == 0 ? 0 :
646− m_pDecContext->pDecoderStatistics->uiAvgEcPropRatio / m_pDecContext->pDecoderStatistics->uiEcFrameNum;
839+ int32_t iMbConcealedNum = pDecContext->iMbEcedNum + pDecContext->iMbEcedPropNum;
840+ pDecContext->pDecoderStatistics->uiAvgEcRatio = pDecContext->iMbNum == 0 ?
841+ (pDecContext->pDecoderStatistics->uiAvgEcRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) : ((
842+ pDecContext->pDecoderStatistics->uiAvgEcRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) + ((
843+ iMbConcealedNum * 100) / pDecContext->iMbNum));
844+ pDecContext->pDecoderStatistics->uiAvgEcPropRatio = pDecContext->iMbNum == 0 ?
845+ (pDecContext->pDecoderStatistics->uiAvgEcPropRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) : ((
846+ pDecContext->pDecoderStatistics->uiAvgEcPropRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) + ((
847+ pDecContext->iMbEcedPropNum * 100) / pDecContext->iMbNum));
848+ pDecContext->pDecoderStatistics->uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1);
849+ pDecContext->pDecoderStatistics->uiAvgEcRatio = pDecContext->pDecoderStatistics->uiEcFrameNum == 0 ? 0 :
850+ pDecContext->pDecoderStatistics->uiAvgEcRatio / pDecContext->pDecoderStatistics->uiEcFrameNum;
851+ pDecContext->pDecoderStatistics->uiAvgEcPropRatio = pDecContext->pDecoderStatistics->uiEcFrameNum == 0 ? 0 :
852+ pDecContext->pDecoderStatistics->uiAvgEcPropRatio / pDecContext->pDecoderStatistics->uiEcFrameNum;
647853 }
648854 iEnd = WelsTime();
649− m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
855+ pDecContext->dDecTime += (iEnd - iStart) / 1e3;
650856
651− OutputStatisticsLog (*m_pDecContext->pDecoderStatistics);
857+ OutputStatisticsLog (*pDecContext->pDecoderStatistics);
652858
653−#ifdef _PICTURE_REORDERING_
654− ReorderPicturesInDisplay (ppDst, pDstInfo);
655−#endif
859+ if (pDecContext->pThreadCtx != NULL) {
860+ WAIT_EVENT (&m_sReleaseBufferEvent, WELS_DEC_THREAD_WAIT_INFINITE);
861+ RESET_EVENT (&m_sBufferingEvent);
862+ BufferingReadyPicture (pDecContext, ppDst, pDstInfo);
863+ SET_EVENT (&m_sBufferingEvent);
864+ } else {
865+ ReorderPicturesInDisplay (pDecContext, ppDst, pDstInfo);
866+ }
656867
657− return (DECODING_STATE)m_pDecContext->iErrorCode;
868+ return (DECODING_STATE)pDecContext->iErrorCode;
658869 }
659870 // else Error free, the current codec works well
660871
661872 if (pDstInfo->iBufferStatus == 1) {
662873
663− m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
664− if (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
665− ResetDecStatNums (m_pDecContext->pDecoderStatistics);
666− m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
874+ pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
875+ if (pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
876+ ResetDecStatNums (pDecContext->pDecoderStatistics);
877+ pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
667878 }
668879
669− OutputStatisticsLog (*m_pDecContext->pDecoderStatistics);
880+ OutputStatisticsLog (*pDecContext->pDecoderStatistics);
670881 }
671882 iEnd = WelsTime();
672− m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
883+ pDecContext->dDecTime += (iEnd - iStart) / 1e3;
673884
674−#ifdef _PICTURE_REORDERING_
675− ReorderPicturesInDisplay (ppDst, pDstInfo);
676−#endif
885+ if (pDecContext->pThreadCtx != NULL) {
886+ WAIT_EVENT (&m_sReleaseBufferEvent, WELS_DEC_THREAD_WAIT_INFINITE);
887+ RESET_EVENT (&m_sBufferingEvent);
888+ BufferingReadyPicture (pDecContext, ppDst, pDstInfo);
889+ SET_EVENT (&m_sBufferingEvent);
890+ } else {
891+ ReorderPicturesInDisplay (pDecContext, ppDst, pDstInfo);
892+ }
677893 return dsErrorFree;
678894 }
679895
896+DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
897+ const int kiSrcLen,
898+ unsigned char** ppDst,
899+ SBufferInfo* pDstInfo) {
900+ PWelsDecoderContext pDecContext = m_pDecThrCtx[0].pCtx;
901+ return DecodeFrame2WithCtx (pDecContext, kpSrc, kiSrcLen, ppDst, pDstInfo);
902+}
903+
680904 DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst,
681905 SBufferInfo* pDstInfo) {
682− if (m_pDecContext->bEndOfStreamFlag && m_sReoderingStatus.iNumOfPicts > 0) {
906+ bool bEndOfStreamFlag = true;
907+ for (int32_t j = 0; j < m_iThreadCount; ++j) {
908+ if (!m_pDecThrCtx[j].pCtx->bEndOfStreamFlag) {
909+ bEndOfStreamFlag = false;
910+ }
911+ }
912+ if (bEndOfStreamFlag && m_sReoderingStatus.iNumOfPicts > 0) {
683913 m_sReoderingStatus.iMinPOC = IMinInt32;
684914 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
685915 if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32) {
@@ -704,12 +934,15 @@ DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst, · 18 unmodified lines
704934 ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
705935 ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
706936 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
707− if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)
708− m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
937+ PPicBuff pPicBuff = m_iThreadCount == 1 ? m_pDecThrCtx[0].pCtx->pPicBuff : m_pPicBuff;
938+ if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < pPicBuff->iCapacity) {
939+ pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
940+ }
709941 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
710942 m_sReoderingStatus.iMinPOC = IMinInt32;
711943 --m_sReoderingStatus.iNumOfPicts;
712944 }
945+
713946 return dsErrorFree;
714947 }
715948
@@ -758,24 +991,15 @@ void CWelsDecoder::OutputStatisticsLog (SDecoderStatistics& sDecoderStatistics) · 42 unmodified lines
758991 }
759992 }
760993
761−DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay (unsigned char** ppDst, SBufferInfo* pDstInfo) {
762− DECODING_STATE iRet = dsErrorFree;
994+void CWelsDecoder::BufferingReadyPicture (PWelsDecoderContext pCtx, unsigned char** ppDst,
995+ SBufferInfo* pDstInfo) {
763996 if (pDstInfo->iBufferStatus == 0) {
764− return iRet;
997+ return;
765998 }
766− ++m_pDecContext->uiDecodingTimeStamp;
767− if (m_pDecContext->pSps->uiProfileIdc != 66 && m_pDecContext->pSps->uiProfileIdc != 83) {
768− /*if (m_pDecContext->pSliceHeader->iPicOrderCntLsb == 0) {
769− m_sReoderingStatus.iLastWrittenPOC = 0;
770− return dsErrorFree;
771− }
772− if (m_sReoderingStatus.iNumOfPicts == 0 && m_pDecContext->pLastDecPicInfo->pPreviousDecodedPictureInDpb->bNewSeqBegin
773− && m_pDecContext->eSliceType != I_SLICE) {
774− m_sReoderingStatus.iLastWrittenPOC = m_pDecContext->pSliceHeader->iPicOrderCntLsb;
775− return dsErrorFree;
776− }*/
777− if (m_sReoderingStatus.iNumOfPicts && m_pDecContext->pLastDecPicInfo->pPreviousDecodedPictureInDpb
778− && m_pDecContext->pLastDecPicInfo->pPreviousDecodedPictureInDpb->bNewSeqBegin) {
999+ m_bIsBaseline = pCtx->pSps->uiProfileIdc == 66 || pCtx->pSps->uiProfileIdc == 83;
1000+ if (!m_bIsBaseline) {
1001+ if (m_sReoderingStatus.iNumOfPicts && pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb
1002+ && pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb->bNewSeqBegin) {
7791003 m_sReoderingStatus.iLastGOPRemainPicts = m_sReoderingStatus.iNumOfPicts;
7801004 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
7811005 if (m_sPictInfoList[i].iPOC > IMinInt32) {
@@ -787,7 +1011,7 @@ DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay (unsigned char** ppDst, SB · 5 unmodified lines
7871011 //This can happen when decoder moves to next GOP without being able to decoder first picture PicOrderCntLsb = 0
7881012 bool hasGOPChanged = false;
7891013 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
790− if (m_sPictInfoList[i].iPOC == m_pDecContext->pSliceHeader->iPicOrderCntLsb) {
1014+ if (m_sPictInfoList[i].iPOC == pCtx->pSliceHeader->iPicOrderCntLsb) {
7911015 hasGOPChanged = true;
7921016 break;
7931017 }
@@ -802,119 +1026,167 @@ DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay (unsigned char** ppDst, SB · 8 unmodified lines
8021026 }
8031027 }
8041028 }
805− for (int32_t i = 0; i < 16; ++i) {
806− if (m_sPictInfoList[i].iPOC == IMinInt32) {
807− memcpy (&m_sPictInfoList[i].sBufferInfo, pDstInfo, sizeof (SBufferInfo));
808− m_sPictInfoList[i].pData[0] = ppDst[0];
809− m_sPictInfoList[i].pData[1] = ppDst[1];
810− m_sPictInfoList[i].pData[2] = ppDst[2];
811− m_sPictInfoList[i].iPOC = m_pDecContext->pSliceHeader->iPicOrderCntLsb;
812− m_sPictInfoList[i].uiDecodingTimeStamp = m_pDecContext->uiDecodingTimeStamp;
813− m_sPictInfoList[i].iPicBuffIdx = m_pDecContext->pLastDecPicInfo->pPreviousDecodedPictureInDpb->iPicBuffIdx;
814− m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[i].iPicBuffIdx]->bAvailableFlag = false;
815− m_sPictInfoList[i].bLastGOP = false;
816− pDstInfo->iBufferStatus = 0;
817− ++m_sReoderingStatus.iNumOfPicts;
818− if (i > m_sReoderingStatus.iLargestBufferedPicIndex) {
819− m_sReoderingStatus.iLargestBufferedPicIndex = i;
820− }
821− break;
1029+ }
1030+ for (int32_t i = 0; i < 16; ++i) {
1031+ if (m_sPictInfoList[i].iPOC == IMinInt32) {
1032+ memcpy (&m_sPictInfoList[i].sBufferInfo, pDstInfo, sizeof (SBufferInfo));
1033+ m_sPictInfoList[i].pData[0] = ppDst[0];
1034+ m_sPictInfoList[i].pData[1] = ppDst[1];
1035+ m_sPictInfoList[i].pData[2] = ppDst[2];
1036+ m_sPictInfoList[i].iPOC = pCtx->pSliceHeader->iPicOrderCntLsb;
1037+ m_sPictInfoList[i].uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp;
1038+ m_sPictInfoList[i].iPicBuffIdx = pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb->iPicBuffIdx;
1039+ pCtx->pPicBuff->ppPic[m_sPictInfoList[i].iPicBuffIdx]->bAvailableFlag = false;
1040+ m_sPictInfoList[i].bLastGOP = false;
1041+ pDstInfo->iBufferStatus = 0;
1042+ ++m_sReoderingStatus.iNumOfPicts;
1043+ if (i > m_sReoderingStatus.iLargestBufferedPicIndex) {
1044+ m_sReoderingStatus.iLargestBufferedPicIndex = i;
8221045 }
1046+ break;
8231047 }
824− if (m_sReoderingStatus.iLastGOPRemainPicts > 0) {
825− m_sReoderingStatus.iMinPOC = IMinInt32;
826− for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
827− if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].bLastGOP) {
828− m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
829− m_sReoderingStatus.iPictInfoIndex = i;
830− }
831− if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC
832− && m_sPictInfoList[i].bLastGOP) {
833− m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
834− m_sReoderingStatus.iPictInfoIndex = i;
835− }
1048+ }
1049+}
1050+
1051+void CWelsDecoder::ReleaseBufferedReadyPicture (PWelsDecoderContext pCtx, unsigned char** ppDst,
1052+ SBufferInfo* pDstInfo) {
1053+ PPicBuff pPicBuff = pCtx ? pCtx->pPicBuff : m_pPicBuff;
1054+ if (!m_bIsBaseline && m_sReoderingStatus.iLastGOPRemainPicts > 0) {
1055+ m_sReoderingStatus.iMinPOC = IMinInt32;
1056+ for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
1057+ if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].bLastGOP) {
1058+ m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
1059+ m_sReoderingStatus.iPictInfoIndex = i;
8361060 }
837− m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
1061+ if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC
1062+ && m_sPictInfoList[i].bLastGOP) {
1063+ m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
1064+ m_sReoderingStatus.iPictInfoIndex = i;
1065+ }
1066+ }
1067+ m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
8381068 #if defined (_DEBUG)
8391069 #ifdef _MOTION_VECTOR_DUMP_
840− fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
1070+ fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
8411071 #endif
8421072 #endif
1073+ memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
1074+ ppDst[0] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[0];
1075+ ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
1076+ ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
1077+ m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
1078+ pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
1079+ m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
1080+ m_sReoderingStatus.iMinPOC = IMinInt32;
1081+ --m_sReoderingStatus.iNumOfPicts;
1082+ --m_sReoderingStatus.iLastGOPRemainPicts;
1083+ if (m_sReoderingStatus.iLastGOPRemainPicts == 0) {
1084+ m_sReoderingStatus.iLastWrittenPOC = IMinInt32;
1085+ }
1086+ return;
1087+ }
1088+ if (m_sReoderingStatus.iNumOfPicts && m_bIsBaseline) {
1089+ uint32_t uiDecodingTimeStamp = 0;
1090+ for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
1091+ if (m_sPictInfoList[i].iPOC > IMinInt32) {
1092+ uiDecodingTimeStamp = m_sPictInfoList[i].uiDecodingTimeStamp;
1093+ m_sReoderingStatus.iPictInfoIndex = i;
1094+ break;
1095+ }
1096+ }
1097+ for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
1098+ if (m_sReoderingStatus.iPictInfoIndex != i && m_sPictInfoList[i].iPOC > IMinInt32
1099+ && m_sPictInfoList[i].sBufferInfo.uiInBsTimeStamp < uiDecodingTimeStamp) {
1100+ uiDecodingTimeStamp = m_sPictInfoList[i].uiDecodingTimeStamp;
1101+ m_sReoderingStatus.iPictInfoIndex = i;
1102+ }
1103+ }
1104+ if (uiDecodingTimeStamp > 0) {
8431105 memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
8441106 ppDst[0] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[0];
8451107 ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
8461108 ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
8471109 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
848− if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)
849− m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
850− m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
851− m_sReoderingStatus.iMinPOC = IMinInt32;
1110+ pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
8521111 --m_sReoderingStatus.iNumOfPicts;
853− --m_sReoderingStatus.iLastGOPRemainPicts;
854− if (m_sReoderingStatus.iLastGOPRemainPicts == 0) {
855− m_sReoderingStatus.iLastWrittenPOC = IMinInt32;
856− }
857− return iRet;
8581112 }
859− if (m_sReoderingStatus.iNumOfPicts > 0) {
860− m_sReoderingStatus.iMinPOC = IMinInt32;
861− for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
862− if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32) {
863− m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
864− m_sReoderingStatus.iPictInfoIndex = i;
865− }
866− if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC) {
867− m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
868− m_sReoderingStatus.iPictInfoIndex = i;
869− }
1113+ return;
1114+ }
1115+ if (m_sReoderingStatus.iNumOfPicts > 0) {
1116+ m_sReoderingStatus.iMinPOC = IMinInt32;
1117+ for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
1118+ if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32) {
1119+ m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
1120+ m_sReoderingStatus.iPictInfoIndex = i;
8701121 }
1122+ if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC) {
1123+ m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
1124+ m_sReoderingStatus.iPictInfoIndex = i;
1125+ }
1126+ }
1127+ }
1128+ if (m_sReoderingStatus.iMinPOC > IMinInt32) {
1129+ bool isReady = false;
1130+ if (pCtx != NULL) {
1131+ isReady = (m_sReoderingStatus.iLastWrittenPOC > IMinInt32
1132+ && m_sReoderingStatus.iMinPOC - m_sReoderingStatus.iLastWrittenPOC <= 1)
1133+ || m_sReoderingStatus.iMinPOC < pCtx->pSliceHeader->iPicOrderCntLsb;
1134+ } else {
1135+ isReady = m_sReoderingStatus.iMinPOC == 0 || (m_sReoderingStatus.iLastWrittenPOC >= 0
1136+ && m_sReoderingStatus.iMinPOC <= m_sReoderingStatus.iLastWrittenPOC + 2) ;
8711137 }
872− if (m_sReoderingStatus.iMinPOC > IMinInt32) {
873− if ((m_sReoderingStatus.iLastWrittenPOC > IMinInt32
874− && m_sReoderingStatus.iMinPOC - m_sReoderingStatus.iLastWrittenPOC <= 1)
875− || m_sReoderingStatus.iMinPOC < m_pDecContext->pSliceHeader->iPicOrderCntLsb) {
876− m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
1138+ if (isReady) {
1139+ m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
8771140 #if defined (_DEBUG)
8781141 #ifdef _MOTION_VECTOR_DUMP_
879− fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
1142+ fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
8801143 #endif
8811144 #endif
882− memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
883− ppDst[0] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[0];
884− ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
885− ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
886− m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
887− if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)
888− m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
889− m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
890− m_sReoderingStatus.iMinPOC = IMinInt32;
891− --m_sReoderingStatus.iNumOfPicts;
892− return iRet;
893− }
1145+ memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
1146+ ppDst[0] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[0];
1147+ ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
1148+ ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
1149+ m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
1150+ pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
1151+ m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
1152+ m_sReoderingStatus.iMinPOC = IMinInt32;
1153+ --m_sReoderingStatus.iNumOfPicts;
8941154 }
8951155 }
1156+}
8961157
1158+DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay (PWelsDecoderContext pDecContext, unsigned char** ppDst,
1159+ SBufferInfo* pDstInfo) {
1160+ DECODING_STATE iRet = dsErrorFree;
1161+ if (pDstInfo->iBufferStatus == 1) {
1162+ ++pDecContext->uiDecodingTimeStamp;
1163+ m_bIsBaseline = pDecContext->pSps->uiProfileIdc == 66 || pDecContext->pSps->uiProfileIdc == 83;
1164+ if (!m_bIsBaseline) {
1165+ BufferingReadyPicture (pDecContext, ppDst, pDstInfo);
1166+ ReleaseBufferedReadyPicture (pDecContext, ppDst, pDstInfo);
1167+ }
1168+ }
8971169 return iRet;
8981170 }
8991171
900−DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,
901− const int kiSrcLen,
902− SParserBsInfo* pDstInfo) {
903− if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {
1172+DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc, const int kiSrcLen, SParserBsInfo* pDstInfo) {
1173+ PWelsDecoderContext pDecContext = m_pDecThrCtx[0].pCtx;
1174+
1175+ if (pDecContext == NULL || pDecContext->pParam == NULL) {
9041176 if (m_pWelsTrace != NULL) {
9051177 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeParser without Initialize.\n");
9061178 }
9071179 return dsInitialOptExpected;
9081180 }
9091181
910− if (!m_pDecContext->pParam->bParseOnly) {
1182+ if (!pDecContext->pParam->bParseOnly) {
9111183 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be true for this API calling! \n");
912− m_pDecContext->iErrorCode |= dsInvalidArgument;
1184+ pDecContext->iErrorCode |= dsInvalidArgument;
9131185 return dsInvalidArgument;
9141186 }
9151187 int64_t iEnd, iStart = WelsTime();
916− if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {
917− if (ResetDecoder())
1188+ if (CheckBsBuffer (pDecContext, kiSrcLen)) {
1189+ if (ResetDecoder (pDecContext))
9181190 return dsOutOfMemory;
9191191
9201192 return dsErrorFree;
@@ -926,58 +1198,57 @@ DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc, · 5 unmodified lines
9261198 WelsFflush (m_pFBS);
9271199 }
9281200 #endif//OUTPUT_BIT_STREAM
929− m_pDecContext->bEndOfStreamFlag = false;
1201+ pDecContext->bEndOfStreamFlag = false;
9301202 } else {
9311203 //For application MODE, the error detection should be added for safe.
9321204 //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
933− m_pDecContext->bEndOfStreamFlag = true;
934− m_pDecContext->bInstantDecFlag = true;
1205+ pDecContext->bEndOfStreamFlag = true;
1206+ pDecContext->bInstantDecFlag = true;
9351207 }
9361208
937− m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
938− m_pDecContext->pParam->eEcActiveIdc = ERROR_CON_DISABLE; //add protection to disable EC here.
939− m_pDecContext->iFeedbackNalRefIdc = -1; //initialize
940− if (!m_pDecContext->bFramePending) { //frame complete
941− m_pDecContext->pParserBsInfo->iNalNum = 0;
942− memset (m_pDecContext->pParserBsInfo->pNalLenInByte, 0, MAX_NAL_UNITS_IN_LAYER);
1209+ pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
1210+ pDecContext->pParam->eEcActiveIdc = ERROR_CON_DISABLE; //add protection to disable EC here.
1211+ pDecContext->iFeedbackNalRefIdc = -1; //initialize
1212+ if (!pDecContext->bFramePending) { //frame complete
1213+ pDecContext->pParserBsInfo->iNalNum = 0;
1214+ memset (pDecContext->pParserBsInfo->pNalLenInByte, 0, MAX_NAL_UNITS_IN_LAYER);
9431215 }
9441216 pDstInfo->iNalNum = 0;
9451217 pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;
9461218 if (pDstInfo) {
947− m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
1219+ pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
9481220 pDstInfo->uiOutBsTimeStamp = 0;
9491221 } else {
950− m_pDecContext->uiTimeStamp = 0;
1222+ pDecContext->uiTimeStamp = 0;
9511223 }
952− WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);
953− if (m_pDecContext->iErrorCode & dsOutOfMemory) {
954− if (ResetDecoder())
1224+ WelsDecodeBs (pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);
1225+ if (pDecContext->iErrorCode & dsOutOfMemory) {
1226+ if (ResetDecoder (pDecContext))
9551227 return dsOutOfMemory;
9561228 return dsErrorFree;
9571229 }
9581230
959− if (!m_pDecContext->bFramePending && m_pDecContext->pParserBsInfo->iNalNum) {
960− memcpy (pDstInfo, m_pDecContext->pParserBsInfo, sizeof (SParserBsInfo));
1231+ if (!pDecContext->bFramePending && pDecContext->pParserBsInfo->iNalNum) {
1232+ memcpy (pDstInfo, pDecContext->pParserBsInfo, sizeof (SParserBsInfo));
9611233
962− if (m_pDecContext->iErrorCode == ERR_NONE) { //update statistics: decoding frame count
963− m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
964− if (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
965− ResetDecStatNums (m_pDecContext->pDecoderStatistics);
966− m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
1234+ if (pDecContext->iErrorCode == ERR_NONE) { //update statistics: decoding frame count
1235+ pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
1236+ if (pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
1237+ ResetDecStatNums (pDecContext->pDecoderStatistics);
1238+ pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
9671239 }
9681240 }
9691241 }
9701242
971− m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
1243+ pDecContext->bInstantDecFlag = false; //reset no-delay flag
9721244
973− if (m_pDecContext->iErrorCode && m_pDecContext->bPrintFrameErrorTraceFlag) {
974− WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n", m_pDecContext->iErrorCode);
975− m_pDecContext->bPrintFrameErrorTraceFlag = false;
1245+ if (pDecContext->iErrorCode && pDecContext->bPrintFrameErrorTraceFlag) {
1246+ WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n", pDecContext->iErrorCode);
1247+ pDecContext->bPrintFrameErrorTraceFlag = false;
9761248 }
9771249 iEnd = WelsTime();
978− m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
979−
980− return (DECODING_STATE) m_pDecContext->iErrorCode;
1250+ pDecContext->dDecTime += (iEnd - iStart) / 1e3;
1251+ return (DECODING_STATE)pDecContext->iErrorCode;
9811252 }
9821253
9831254 DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,
@@ -1019,6 +1290,92 @@ DECODING_STATE CWelsDecoder::DecodeFrameEx (const unsigned char* kpSrc, · 35 unmodified lines
10191290 return state;
10201291 }
10211292
1293+DECODING_STATE CWelsDecoder::ParseAccessUnit (SWelsDecoderThreadCTX& sThreadCtx) {
1294+ sThreadCtx.pCtx->bHasNewSps = false;
1295+ sThreadCtx.pCtx->bParamSetsLostFlag = m_bParamSetsLostFlag;
1296+ sThreadCtx.pCtx->bFreezeOutput = m_bFreezeOutput;
1297+ sThreadCtx.pCtx->uiDecodingTimeStamp = ++m_uiDecodeTimeStamp;
1298+ bool bPicBuffChanged = false;
1299+ if (m_pLastDecThrCtx != NULL && sThreadCtx.pCtx->sSpsPpsCtx.iSeqId < m_pLastDecThrCtx->pCtx->sSpsPpsCtx.iSeqId) {
1300+ CopySpsPps (m_pLastDecThrCtx->pCtx, sThreadCtx.pCtx);
1301+ sThreadCtx.pCtx->iPicQueueNumber = m_pLastDecThrCtx->pCtx->iPicQueueNumber;
1302+ if (sThreadCtx.pCtx->pPicBuff != m_pPicBuff) {
1303+ bPicBuffChanged = true;
1304+ sThreadCtx.pCtx->pPicBuff = m_pPicBuff;
1305+ sThreadCtx.pCtx->bHaveGotMemory = m_pPicBuff != NULL;
1306+ sThreadCtx.pCtx->iImgWidthInPixel = m_pLastDecThrCtx->pCtx->iImgWidthInPixel;
1307+ sThreadCtx.pCtx->iImgHeightInPixel = m_pLastDecThrCtx->pCtx->iImgHeightInPixel;
1308+ }
1309+ }
1310+ int32_t iRet = DecodeFrame2WithCtx (sThreadCtx.pCtx, sThreadCtx.kpSrc, sThreadCtx.kiSrcLen, sThreadCtx.ppDst,
1311+ &sThreadCtx.sDstInfo);
1312+
1313+ int32_t iErr = InitConstructAccessUnit (sThreadCtx.pCtx, &sThreadCtx.sDstInfo);
1314+ if (ERR_NONE != iErr) {
1315+ return (DECODING_STATE) (iRet | iErr);
1316+ }
1317+ if (sThreadCtx.pCtx->bNewSeqBegin) {
1318+ m_pPicBuff = sThreadCtx.pCtx->pPicBuff;
1319+ } else if (bPicBuffChanged) {
1320+ InitialDqLayersContext (sThreadCtx.pCtx, sThreadCtx.pCtx->pSps->iMbWidth << 4, sThreadCtx.pCtx->pSps->iMbHeight << 4);
1321+ }
1322+ m_bParamSetsLostFlag = sThreadCtx.pCtx->bNewSeqBegin ? false : sThreadCtx.pCtx->bParamSetsLostFlag;
1323+ m_bFreezeOutput = sThreadCtx.pCtx->bNewSeqBegin ? false : sThreadCtx.pCtx->bFreezeOutput;
1324+ return (DECODING_STATE)iErr;
1325+}
1326+/*
1327+* Run decoding picture in separate thread.
1328+*/
1329+
1330+int CWelsDecoder::ThreadDecodeFrameInternal (const unsigned char* kpSrc, const int kiSrcLen, unsigned char** ppDst,
1331+ SBufferInfo* pDstInfo) {
1332+ int state = dsErrorFree;
1333+ int32_t i, j;
1334+ int32_t signal = 0;
1335+
1336+ //serial using of threads
1337+ if (m_DecCtxActiveCount < m_iThreadCount) {
1338+ signal = m_DecCtxActiveCount;
1339+ } else {
1340+ signal = m_pDecThrCtxActive[0]->sThreadInfo.uiThrNum;
1341+ }
1342+
1343+ WAIT_SEMAPHORE (&m_pDecThrCtx[signal].sThreadInfo.sIsIdle, WELS_DEC_THREAD_WAIT_INFINITE);
1344+
1345+ for (i = 0; i < m_DecCtxActiveCount; ++i) {
1346+ if (m_pDecThrCtxActive[i] == &m_pDecThrCtx[signal]) {
1347+ m_pDecThrCtxActive[i] = NULL;
1348+ for (j = i; j < m_DecCtxActiveCount - 1; j++) {
1349+ m_pDecThrCtxActive[j] = m_pDecThrCtxActive[j + 1];
1350+ m_pDecThrCtxActive[j + 1] = NULL;
1351+ }
1352+ --m_DecCtxActiveCount;
1353+ break;
1354+ }
1355+ }
1356+
1357+ m_pDecThrCtxActive[m_DecCtxActiveCount++] = &m_pDecThrCtx[signal];
1358+ if (m_pLastDecThrCtx != NULL) {
1359+ m_pDecThrCtx[signal].pCtx->pLastThreadCtx = m_pLastDecThrCtx;
1360+ }
1361+ m_pDecThrCtx[signal].kpSrc = const_cast<uint8_t*> (kpSrc);
1362+ m_pDecThrCtx[signal].kiSrcLen = kiSrcLen;
1363+ m_pDecThrCtx[signal].ppDst = ppDst;
1364+ memcpy (&m_pDecThrCtx[signal].sDstInfo, pDstInfo, sizeof (SBufferInfo));
1365+
1366+ ParseAccessUnit (m_pDecThrCtx[signal]);
1367+ m_pLastDecThrCtx = &m_pDecThrCtx[signal];
1368+ m_pDecThrCtx[signal].sThreadInfo.uiCommand = WELS_DEC_THREAD_COMMAND_RUN;
1369+ RELEASE_SEMAPHORE (&m_pDecThrCtx[signal].sThreadInfo.sIsActivated);
1370+
1371+ // wait early picture
1372+ if (m_DecCtxActiveCount >= m_iThreadCount) {
1373+ WAIT_SEMAPHORE (&m_pDecThrCtxActive[0]->sThreadInfo.sIsIdle, WELS_DEC_THREAD_WAIT_INFINITE);
1374+ RELEASE_SEMAPHORE (&m_pDecThrCtxActive[0]->sThreadInfo.sIsIdle);
1375+ }
1376+ return state;
1377+}
1378+
10221379 } // namespace WelsDec
10231380
10241381

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