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
51//#include "macros.h"51//#include "macros.h"
52#include "decoder.h"52#include "decoder.h"
53#include "decoder_core.h"53#include "decoder_core.h"
54#include "manage_dec_ref.h"
54#include "error_concealment.h"55#include "error_concealment.h"
55 56
56#include "measure_time.h"57#include "measure_time.h"
@@ -67,12 +68,11 @@ extern "C" { · 10 unmodified lines
67#include <stdio.h>68#include <stdio.h>
68#include <stdarg.h>69#include <stdarg.h>
69#include <sys/types.h>70#include <sys/types.h>
71#include <malloc.h>
70#else72#else
71#include <sys/time.h>73#include <sys/time.h>
72#endif74#endif
73 75
74#define _PICTURE_REORDERING_ 1
75
76namespace WelsDec {76namespace WelsDec {
77 77
78//////////////////////////////////////////////////////////////////////78//////////////////////////////////////////////////////////////////////
@@ -88,9 +88,58 @@ namespace WelsDec { · 9 unmodified lines
88*88*
89* return: none89* return: none
90***************************************************************************/90***************************************************************************/
91DECLARE_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
99static 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
115DECLARE_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
91CWelsDecoder::CWelsDecoder (void)131CWelsDecoder::CWelsDecoder (void)
92 : m_pDecContext (NULL),132 : m_pWelsTrace (NULL),
93 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) {
94#ifdef OUTPUT_BIT_STREAM143#ifdef OUTPUT_BIT_STREAM
95 char chFileName[1024] = { 0 }; //for .264144 char chFileName[1024] = { 0 }; //for .264
96 int iBufUsed = 0;145 int iBufUsed = 0;
@@ -114,6 +163,15 @@ CWelsDecoder::CWelsDecoder (void) · 17 unmodified lines
114 163
115 ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, true);164 ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, true);
116 165
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 }
117#ifdef OUTPUT_BIT_STREAM175#ifdef OUTPUT_BIT_STREAM
118 SWelsTime sCurTime;176 SWelsTime sCurTime;
119 177
@@ -169,7 +227,7 @@ CWelsDecoder::~CWelsDecoder() { · 49 unmodified lines
169 if (m_pWelsTrace != NULL) {227 if (m_pWelsTrace != NULL) {
170 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::~CWelsDecoder()");228 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::~CWelsDecoder()");
171 }229 }
172 230 CloseDecoderThreads();
173 UninitDecoder();231 UninitDecoder();
174 232
175#ifdef OUTPUT_BIT_STREAM233#ifdef OUTPUT_BIT_STREAM
@@ -187,6 +245,10 @@ CWelsDecoder::~CWelsDecoder() { · 11 unmodified lines
187 delete m_pWelsTrace;245 delete m_pWelsTrace;
188 m_pWelsTrace = NULL;246 m_pWelsTrace = NULL;
189 }247 }
248 if (m_pDecThrCtx != NULL) {
249 delete[] m_pDecThrCtx;
250 m_pDecThrCtx = NULL;
251 }
190}252}
191 253
192long CWelsDecoder::Initialize (const SDecodingParam* pParam) {254long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
@@ -215,26 +277,87 @@ long CWelsDecoder::Uninitialize() { · 22 unmodified lines
215}277}
216 278
217void CWelsDecoder::UninitDecoder (void) {279void CWelsDecoder::UninitDecoder (void) {
218 if (NULL == m_pDecContext)280 for (int32_t i = 0; i < m_iThreadCount; ++i) {
219 return;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}
220 289
221 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::UninitDecoder(), openh264 codec version = %s.",290void CWelsDecoder::OpenDecoderThreads() {
222 VERSION_NUMBER);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}
320void 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}
223 339
224 WelsEndDecoder (m_pDecContext);340void CWelsDecoder::UninitDecoderCtx (PWelsDecoderContext& pCtx) {
341 if (pCtx != NULL) {
225 342
226 if (m_pDecContext->pMemAlign != NULL) {343 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::UninitDecoderCtx(), openh264 codec version = %s.",
227 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,344 VERSION_NUMBER);
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 }
233 345
234 if (NULL != m_pDecContext) {346 WelsEndDecoder (pCtx);
235 WelsFree (m_pDecContext, "m_pDecContext");
236 347
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 }
238 }361 }
239}362}
240 363
@@ -244,59 +367,100 @@ int32_t CWelsDecoder::InitDecoder (const SDecodingParam* pParam) { · 3 unmodified lines
244 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,367 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
245 "CWelsDecoder::init_decoder(), openh264 codec version = %s, ParseOnly = %d",368 "CWelsDecoder::init_decoder(), openh264 codec version = %s, ParseOnly = %d",
246 VERSION_NUMBER, (int32_t)pParam->bParseOnly);369 VERSION_NUMBER, (int32_t)pParam->bParseOnly);
247 370 if (m_iThreadCount > 1 && pParam->bParseOnly) {
371 m_iThreadCount = 1;
372 }
373 OpenDecoderThreads();
248 //reset decoder context374 //reset decoder context
249 memset (&m_sDecoderStatistics, 0, sizeof (SDecoderStatistics));375 memset (&m_sDecoderStatistics, 0, sizeof (SDecoderStatistics));
250 memset (&m_sLastDecPicInfo, 0, sizeof (SWelsLastDecPicInfo));376 memset (&m_sLastDecPicInfo, 0, sizeof (SWelsLastDecPicInfo));
251 memset (&m_sVlcTable, 0, sizeof (SVlcTable));377 memset (&m_sVlcTable, 0, sizeof (SVlcTable));
378 UninitDecoder();
252 WelsDecoderLastDecPicInfoDefaults (m_sLastDecPicInfo);379 WelsDecoderLastDecPicInfoDefaults (m_sLastDecPicInfo);
253 if (m_pDecContext) //free380 for (int32_t i = 0; i < m_iThreadCount; ++i) {
254 UninitDecoder();381 InitDecoderCtx (m_pDecThrCtx[i].pCtx, pParam);
255 m_pDecContext = (PWelsDecoderContext)WelsMallocz (sizeof (SWelsDecoderContext), "m_pDecContext");382 if (m_iThreadCount > 1) {
256 if (NULL == m_pDecContext)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.
392int32_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)
257 return cmMallocMemeError;402 return cmMallocMemeError;
258 int32_t iCacheLineSize = 16; // on chip cache line size in byte403 int32_t iCacheLineSize = 16; // on chip cache line size in byte
259 m_pDecContext->pMemAlign = new CMemoryAlign (iCacheLineSize);404 pCtx->pMemAlign = new CMemoryAlign (iCacheLineSize);
260 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pMemAlign), UninitDecoder())405 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == pCtx->pMemAlign), UninitDecoderCtx (pCtx))
261 406
262 //fill in default value into context407 //fill in default value into context
263 m_pDecContext->pLastDecPicInfo = &m_sLastDecPicInfo;408 pCtx->pLastDecPicInfo = &m_sLastDecPicInfo;
264 m_pDecContext->pDecoderStatistics = &m_sDecoderStatistics;409 pCtx->pDecoderStatistics = &m_sDecoderStatistics;
265 m_pDecContext->pVlcTable = &m_sVlcTable;410 pCtx->pVlcTable = &m_sVlcTable;
266 m_pDecContext->pPictInfoList = m_sPictInfoList;411 pCtx->pPictInfoList = m_sPictInfoList;
267 m_pDecContext->pPictReoderingStatus = &m_sReoderingStatus;412 pCtx->pPictReoderingStatus = &m_sReoderingStatus;
268 WelsDecoderDefaults (m_pDecContext, &m_pWelsTrace->m_sLogCtx);413 pCtx->pCsDecoder = &m_csDecoder;
269 WelsDecoderSpsPpsDefaults (m_pDecContext->sSpsPpsCtx);414 WelsDecoderDefaults (pCtx, &m_pWelsTrace->m_sLogCtx);
270 415 WelsDecoderSpsPpsDefaults (pCtx->sSpsPpsCtx);
271 //check param and update decoder context416 //check param and update decoder context
272 m_pDecContext->pParam = (SDecodingParam*)m_pDecContext->pMemAlign->WelsMallocz (sizeof (SDecodingParam),417 pCtx->pParam = (SDecodingParam*)pCtx->pMemAlign->WelsMallocz (sizeof (SDecodingParam),
273 "SDecodingParam");418 "SDecodingParam");
274 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pParam), UninitDecoder());419 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == pCtx->pParam), UninitDecoderCtx (pCtx));
275 int32_t iRet = DecoderConfigParam (m_pDecContext, pParam);420 int32_t iRet = DecoderConfigParam (pCtx, pParam);
276 WELS_VERIFY_RETURN_IFNEQ (iRet, cmResultSuccess);421 WELS_VERIFY_RETURN_IFNEQ (iRet, cmResultSuccess);
277 422
278 //init decoder423 //init decoder
279 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx),424 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, WelsInitDecoder (pCtx, &m_pWelsTrace->m_sLogCtx),
280 UninitDecoder())425 UninitDecoderCtx (pCtx))
281 426 pCtx->pPicBuff = NULL;
282 return cmResultSuccess;427 return cmResultSuccess;
283}428}
284 429
285int32_t CWelsDecoder::ResetDecoder() {430int32_t CWelsDecoder::ResetDecoder (PWelsDecoderContext& pCtx) {
286 // TBC: need to be modified when context and trace point are null431 // TBC: need to be modified when context and trace point are null
287 if (m_pDecContext != NULL && m_pWelsTrace != NULL) {432 if (m_iThreadCount > 1) {
288 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ResetDecoder(), context error code is %d",433 ThreadResetDecoder (pCtx);
289 m_pDecContext->iErrorCode);434 } else {
290 SDecodingParam sPrevParam;435 if (pCtx != NULL && m_pWelsTrace != NULL) {
291 memcpy (&sPrevParam, m_pDecContext->pParam, sizeof (SDecodingParam));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}
292 450
293 WELS_VERIFY_RETURN_PROC_IF (cmInitParaError, InitDecoder (&sPrevParam), UninitDecoder());451int32_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);
294 } else if (m_pWelsTrace != NULL) {461 } else if (m_pWelsTrace != NULL) {
295 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "ResetDecoder() failed as decoder context null");462 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "ResetDecoder() failed as decoder context null");
296 }463 }
297#ifdef _PICTURE_REORDERING_
298 ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, false);
299#endif
300 return ERR_INFO_UNINIT;464 return ERR_INFO_UNINIT;
301}465}
302 466
@@ -305,71 +469,95 @@ int32_t CWelsDecoder::ResetDecoder() { · 2 unmodified lines
305 */469 */
306long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {470long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
307 int iVal = 0;471 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;
308 502
309 if (m_pDecContext == NULL && eOptID != DECODER_OPTION_TRACE_LEVEL &&503 iVal = * ((int*)pOption); // boolean value for whether enabled End Of Stream flag
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
317 504
318 m_pDecContext->bEndOfStreamFlag = iVal ? true : false;505 pDecContext->bEndOfStreamFlag = iVal ? true : false;
319 506
320 return cmResultSuccess;507 return cmResultSuccess;
321 } else if (eOptID == DECODER_OPTION_ERROR_CON_IDC) { // Indicate error concealment status508 } else if (eOptID == DECODER_OPTION_ERROR_CON_IDC) { // Indicate error concealment status
322 if (pOption == NULL)509 if (pOption == NULL)
323 return cmInitParaError;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 }
324 519
325 iVal = * ((int*)pOption); // int value for error concealment idc520 pDecContext->pParam->eEcActiveIdc = (ERROR_CON_IDC)iVal;
326 iVal = WELS_CLIP3 (iVal, (int32_t)ERROR_CON_DISABLE, (int32_t)ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE);521 InitErrorCon (pDecContext);
327 if ((m_pDecContext->pParam->bParseOnly) && (iVal != (int32_t)ERROR_CON_DISABLE)) {
328 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,522 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
329 "CWelsDecoder::SetOption for ERROR_CON_IDC = %d not allowd for parse only!.", iVal);523 "CWelsDecoder::SetOption for ERROR_CON_IDC = %d.", 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);
337 524
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));
367 return cmResultSuccess;525 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;
368 }560 }
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;
373 }561 }
374 return cmInitParaError;562 return cmInitParaError;
375}563}
@@ -379,105 +567,109 @@ long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) { · 3 unmodified lines
379 */567 */
380long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) {568long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) {
381 int iVal = 0;569 int iVal = 0;
382 570 if (DECODER_OPTION_NUM_OF_THREADS == eOptID) {
383 if (m_pDecContext == NULL)571 * ((int*)pOption) = m_iThreadCount;
572 return cmResultSuccess;
573 }
574 PWelsDecoderContext pDecContext = m_pDecThrCtx[0].pCtx;
575 if (pDecContext == NULL)
384 return cmInitExpected;576 return cmInitExpected;
385 577
386 if (pOption == NULL)578 if (pOption == NULL)
387 return cmInitParaError;579 return cmInitParaError;
388 580
389 if (DECODER_OPTION_END_OF_STREAM == eOptID) {581 if (DECODER_OPTION_END_OF_STREAM == eOptID) {
390 iVal = m_pDecContext->bEndOfStreamFlag;582 iVal = pDecContext->bEndOfStreamFlag;
391 * ((int*)pOption) = iVal;583 * ((int*)pOption) = iVal;
392 return cmResultSuccess;584 return cmResultSuccess;
393 }585 }
394#ifdef LONG_TERM_REF586#ifdef LONG_TERM_REF
395 else if (DECODER_OPTION_IDR_PIC_ID == eOptID) {587 else if (DECODER_OPTION_IDR_PIC_ID == eOptID) {
396 iVal = m_pDecContext->uiCurIdrPicId;588 iVal = pDecContext->uiCurIdrPicId;
397 * ((int*)pOption) = iVal;589 * ((int*)pOption) = iVal;
398 return cmResultSuccess;590 return cmResultSuccess;
399 } else if (DECODER_OPTION_FRAME_NUM == eOptID) {591 } else if (DECODER_OPTION_FRAME_NUM == eOptID) {
400 iVal = m_pDecContext->iFrameNum;592 iVal = pDecContext->iFrameNum;
401 * ((int*)pOption) = iVal;593 * ((int*)pOption) = iVal;
402 return cmResultSuccess;594 return cmResultSuccess;
403 } else if (DECODER_OPTION_LTR_MARKING_FLAG == eOptID) {595 } else if (DECODER_OPTION_LTR_MARKING_FLAG == eOptID) {
404 iVal = m_pDecContext->bCurAuContainLtrMarkSeFlag;596 iVal = pDecContext->bCurAuContainLtrMarkSeFlag;
405 * ((int*)pOption) = iVal;597 * ((int*)pOption) = iVal;
406 return cmResultSuccess;598 return cmResultSuccess;
407 } else if (DECODER_OPTION_LTR_MARKED_FRAME_NUM == eOptID) {599 } else if (DECODER_OPTION_LTR_MARKED_FRAME_NUM == eOptID) {
408 iVal = m_pDecContext->iFrameNumOfAuMarkedLtr;600 iVal = pDecContext->iFrameNumOfAuMarkedLtr;
409 * ((int*)pOption) = iVal;601 * ((int*)pOption) = iVal;
410 return cmResultSuccess;602 return cmResultSuccess;
411 }603 }
412#endif604#endif
413 else if (DECODER_OPTION_VCL_NAL == eOptID) { //feedback whether or not have VCL NAL in current AU605 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;
415 * ((int*)pOption) = iVal;607 * ((int*)pOption) = iVal;
416 return cmResultSuccess;608 return cmResultSuccess;
417 } else if (DECODER_OPTION_TEMPORAL_ID == eOptID) { //if have VCL NAL in current AU, then feedback the temporal ID609 } 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;
419 * ((int*)pOption) = iVal;611 * ((int*)pOption) = iVal;
420 return cmResultSuccess;612 return cmResultSuccess;
421 } else if (DECODER_OPTION_IS_REF_PIC == eOptID) {613 } else if (DECODER_OPTION_IS_REF_PIC == eOptID) {
422 iVal = m_pDecContext->iFeedbackNalRefIdc;614 iVal = pDecContext->iFeedbackNalRefIdc;
423 if (iVal > 0)615 if (iVal > 0)
424 iVal = 1;616 iVal = 1;
425 * ((int*)pOption) = iVal;617 * ((int*)pOption) = iVal;
426 return cmResultSuccess;618 return cmResultSuccess;
427 } else if (DECODER_OPTION_ERROR_CON_IDC == eOptID) {619 } else if (DECODER_OPTION_ERROR_CON_IDC == eOptID) {
428 iVal = (int)m_pDecContext->pParam->eEcActiveIdc;620 iVal = (int)pDecContext->pParam->eEcActiveIdc;
429 * ((int*)pOption) = iVal;621 * ((int*)pOption) = iVal;
430 return cmResultSuccess;622 return cmResultSuccess;
431 } else if (DECODER_OPTION_GET_STATISTICS == eOptID) { // get decoder statistics info for real time debugging623 } else if (DECODER_OPTION_GET_STATISTICS == eOptID) { // get decoder statistics info for real time debugging
432 SDecoderStatistics* pDecoderStatistics = (static_cast<SDecoderStatistics*> (pOption));624 SDecoderStatistics* pDecoderStatistics = (static_cast<SDecoderStatistics*> (pOption));
433 625
434 memcpy (pDecoderStatistics, m_pDecContext->pDecoderStatistics, sizeof (SDecoderStatistics));626 memcpy (pDecoderStatistics, pDecContext->pDecoderStatistics, sizeof (SDecoderStatistics));
435 627
436 if (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount != 0) { //not original status628 if (pDecContext->pDecoderStatistics->uiDecodedFrameCount != 0) { //not original status
437 pDecoderStatistics->fAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /629 pDecoderStatistics->fAverageFrameSpeedInMs = (float) (pDecContext->dDecTime) /
438 (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount);630 (pDecContext->pDecoderStatistics->uiDecodedFrameCount);
439 pDecoderStatistics->fActualAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /631 pDecoderStatistics->fActualAverageFrameSpeedInMs = (float) (pDecContext->dDecTime) /
440 (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount + m_pDecContext->pDecoderStatistics->uiFreezingIDRNum +632 (pDecContext->pDecoderStatistics->uiDecodedFrameCount + pDecContext->pDecoderStatistics->uiFreezingIDRNum +
441 m_pDecContext->pDecoderStatistics->uiFreezingNonIDRNum);633 pDecContext->pDecoderStatistics->uiFreezingNonIDRNum);
442 }634 }
443 return cmResultSuccess;635 return cmResultSuccess;
444 } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {636 } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
445 if (pOption) {637 if (pOption) {
446 iVal = m_pDecContext->pDecoderStatistics->iStatisticsLogInterval;638 iVal = pDecContext->pDecoderStatistics->iStatisticsLogInterval;
447 * ((unsigned int*)pOption) = iVal;639 * ((unsigned int*)pOption) = iVal;
448 return cmResultSuccess;640 return cmResultSuccess;
449 }641 }
450 } else if (DECODER_OPTION_GET_SAR_INFO == eOptID) { //get decoder SAR info in VUI642 } else if (DECODER_OPTION_GET_SAR_INFO == eOptID) { //get decoder SAR info in VUI
451 PVuiSarInfo pVuiSarInfo = (static_cast<PVuiSarInfo> (pOption));643 PVuiSarInfo pVuiSarInfo = (static_cast<PVuiSarInfo> (pOption));
452 memset (pVuiSarInfo, 0, sizeof (SVuiSarInfo));644 memset (pVuiSarInfo, 0, sizeof (SVuiSarInfo));
453 if (!m_pDecContext->pSps) {645 if (!pDecContext->pSps) {
454 return cmInitExpected;646 return cmInitExpected;
455 } else {647 } else {
456 pVuiSarInfo->uiSarWidth = m_pDecContext->pSps->sVui.uiSarWidth;648 pVuiSarInfo->uiSarWidth = pDecContext->pSps->sVui.uiSarWidth;
457 pVuiSarInfo->uiSarHeight = m_pDecContext->pSps->sVui.uiSarHeight;649 pVuiSarInfo->uiSarHeight = pDecContext->pSps->sVui.uiSarHeight;
458 pVuiSarInfo->bOverscanAppropriateFlag = m_pDecContext->pSps->sVui.bOverscanAppropriateFlag;650 pVuiSarInfo->bOverscanAppropriateFlag = pDecContext->pSps->sVui.bOverscanAppropriateFlag;
459 return cmResultSuccess;651 return cmResultSuccess;
460 }652 }
461 } else if (DECODER_OPTION_PROFILE == eOptID) {653 } else if (DECODER_OPTION_PROFILE == eOptID) {
462 if (!m_pDecContext->pSps) {654 if (!pDecContext->pSps) {
463 return cmInitExpected;655 return cmInitExpected;
464 }656 }
465 iVal = (int)m_pDecContext->pSps->uiProfileIdc;657 iVal = (int)pDecContext->pSps->uiProfileIdc;
466 * ((int*)pOption) = iVal;658 * ((int*)pOption) = iVal;
467 return cmResultSuccess;659 return cmResultSuccess;
468 } else if (DECODER_OPTION_LEVEL == eOptID) {660 } else if (DECODER_OPTION_LEVEL == eOptID) {
469 if (!m_pDecContext->pSps) {661 if (!pDecContext->pSps) {
470 return cmInitExpected;662 return cmInitExpected;
471 }663 }
472 iVal = (int)m_pDecContext->pSps->uiLevelIdc;664 iVal = (int)pDecContext->pSps->uiLevelIdc;
473 * ((int*)pOption) = iVal;665 * ((int*)pOption) = iVal;
474 return cmResultSuccess;666 return cmResultSuccess;
475 } else if (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER == eOptID) {667 } else if (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER == eOptID) {
476 if (m_pDecContext->pSps && m_pDecContext->pSps->uiProfileIdc != 66) {668 for (int32_t activeThread = 0; activeThread < m_DecCtxActiveCount; ++activeThread) {
477 * ((int*)pOption) = m_sReoderingStatus.iNumOfPicts > 0 ? m_sReoderingStatus.iNumOfPicts : 0;669 WAIT_SEMAPHORE (&m_pDecThrCtxActive[activeThread]->sThreadInfo.sIsIdle, WELS_DEC_THREAD_WAIT_INFINITE);
478 } else {670 RELEASE_SEMAPHORE (&m_pDecThrCtxActive[activeThread]->sThreadInfo.sIsIdle);
479 * ((int*)pOption) = 0;
480 }671 }
672 * ((int*)pOption) = m_sReoderingStatus.iNumOfPicts;
481 return cmResultSuccess;673 return cmResultSuccess;
482 }674 }
483 675
@@ -488,7 +680,17 @@ DECODING_STATE CWelsDecoder::DecodeFrameNoDelay (const unsigned char* kpSrc, · 4 unmodified lines
488 const int kiSrcLen,680 const int kiSrcLen,
489 unsigned char** ppDst,681 unsigned char** ppDst,
490 SBufferInfo* pDstInfo) {682 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 }
492 //SBufferInfo sTmpBufferInfo;694 //SBufferInfo sTmpBufferInfo;
493 //unsigned char* ppTmpDst[3] = {NULL, NULL, NULL};695 //unsigned char* ppTmpDst[3] = {NULL, NULL, NULL};
494 iRet = (int)DecodeFrame2 (kpSrc, kiSrcLen, ppDst, pDstInfo);696 iRet = (int)DecodeFrame2 (kpSrc, kiSrcLen, ppDst, pDstInfo);
@@ -506,24 +708,24 @@ DECODING_STATE CWelsDecoder::DecodeFrameNoDelay (const unsigned char* kpSrc, · 11 unmodified lines
506 return (DECODING_STATE)iRet;708 return (DECODING_STATE)iRet;
507}709}
508 710
509DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,711DECODING_STATE CWelsDecoder::DecodeFrame2WithCtx (PWelsDecoderContext pDecContext, const unsigned char* kpSrc,
510 const int kiSrcLen,712 const int kiSrcLen,
511 unsigned char** ppDst,713 unsigned char** ppDst,
512 SBufferInfo* pDstInfo) {714 SBufferInfo* pDstInfo) {
513 if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {715 if (pDecContext == NULL || pDecContext->pParam == NULL) {
514 if (m_pWelsTrace != NULL) {716 if (m_pWelsTrace != NULL) {
515 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeFrame2 without Initialize.\n");717 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeFrame2 without Initialize.\n");
516 }718 }
517 return dsInitialOptExpected;719 return dsInitialOptExpected;
518 }720 }
519 721
520 if (m_pDecContext->pParam->bParseOnly) {722 if (pDecContext->pParam->bParseOnly) {
521 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be false for this API calling! \n");723 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;
523 return dsInvalidArgument;725 return dsInvalidArgument;
524 }726 }
525 if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {727 if (CheckBsBuffer (pDecContext, kiSrcLen)) {
526 if (ResetDecoder())728 if (ResetDecoder (pDecContext))
527 return dsOutOfMemory;729 return dsOutOfMemory;
528 730
529 return dsErrorFree;731 return dsErrorFree;
@@ -539,147 +741,175 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, · 9 unmodified lines
539 WelsFflush (m_pFBSSize);741 WelsFflush (m_pFBSSize);
540 }742 }
541#endif//OUTPUT_BIT_STREAM743#endif//OUTPUT_BIT_STREAM
542 m_pDecContext->bEndOfStreamFlag = false;744 pDecContext->bEndOfStreamFlag = false;
543 } else {745 } else {
544 //For application MODE, the error detection should be added for safe.746 //For application MODE, the error detection should be added for safe.
545 //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.747 //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
546 m_pDecContext->bEndOfStreamFlag = true;748 pDecContext->bEndOfStreamFlag = true;
547 m_pDecContext->bInstantDecFlag = true;749 pDecContext->bInstantDecFlag = true;
548 }750 }
549 751
550 int64_t iStart, iEnd;752 int64_t iStart, iEnd;
551 iStart = WelsTime();753 iStart = WelsTime();
552 754
553 ppDst[0] = ppDst[1] = ppDst[2] = NULL;755 if (pDecContext->pThreadCtx == NULL) {
554 m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.756 ppDst[0] = ppDst[1] = ppDst[2] = NULL;
555 m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize757 }
758 pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
759 pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
556 unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;760 unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;
557 memset (pDstInfo, 0, sizeof (SBufferInfo));761 if (pDecContext->pThreadCtx == NULL) {
762 memset (pDstInfo, 0, sizeof (SBufferInfo));
763 }
558 pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;764 pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;
559#ifdef LONG_TERM_REF765#ifdef LONG_TERM_REF
560 m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR766 pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
561 m_pDecContext->bCurAuContainLtrMarkSeFlag = false;767 pDecContext->bCurAuContainLtrMarkSeFlag = false;
562 m_pDecContext->iFrameNumOfAuMarkedLtr = 0;768 pDecContext->iFrameNumOfAuMarkedLtr = 0;
563 m_pDecContext->iFrameNum = -1; //initialize769 pDecContext->iFrameNum = -1; //initialize
564#endif770#endif
565 771
566 m_pDecContext->iFeedbackTidInAu = -1; //initialize772 pDecContext->iFeedbackTidInAu = -1; //initialize
567 m_pDecContext->iFeedbackNalRefIdc = -1; //initialize773 pDecContext->iFeedbackNalRefIdc = -1; //initialize
568 if (pDstInfo) {774 if (pDstInfo) {
569 pDstInfo->uiOutYuvTimeStamp = 0;775 pDstInfo->uiOutYuvTimeStamp = 0;
570 m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;776 pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
571 } else {777 } else {
572 m_pDecContext->uiTimeStamp = 0;778 pDecContext->uiTimeStamp = 0;
573 }779 }
574 WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, ppDst,780 WelsDecodeBs (pDecContext, kpSrc, kiSrcLen, ppDst,
575 pDstInfo, NULL); //iErrorCode has been modified in this function781 pDstInfo, NULL); //iErrorCode has been modified in this function
576 m_pDecContext->bInstantDecFlag = false; //reset no-delay flag782 pDecContext->bInstantDecFlag = false; //reset no-delay flag
577 if (m_pDecContext->iErrorCode) {783 if (pDecContext->iErrorCode) {
578 EWelsNalUnitType eNalType =784 EWelsNalUnitType eNalType =
579 NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently785 NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently
580 786
581 eNalType = m_pDecContext->sCurNalHead.eNalUnitType;787 eNalType = pDecContext->sCurNalHead.eNalUnitType;
582 if (m_pDecContext->iErrorCode & dsOutOfMemory) {788 if (pDecContext->iErrorCode & dsOutOfMemory) {
583 if (ResetDecoder()) {789 if (ResetDecoder (pDecContext)) {
584 return dsOutOfMemory;790 return dsOutOfMemory;
585 }791 }
586 return dsErrorFree;792 return dsErrorFree;
587 }793 }
588 if (m_pDecContext->iErrorCode & dsRefListNullPtrs) {794 if (pDecContext->iErrorCode & dsRefListNullPtrs) {
589 if (ResetDecoder()) {795 if (ResetDecoder (pDecContext)) {
590 return dsRefListNullPtrs;796 return dsRefListNullPtrs;
591 }797 }
592 return dsErrorFree;798 return dsErrorFree;
593 }799 }
594 if ((m_pDecContext->iErrorCode & (dsBitstreamError | dsDataErrorConcealed)) && m_pDecContext->eSliceType == B_SLICE) {800 if ((pDecContext->iErrorCode & (dsBitstreamError | dsDataErrorConcealed)) && pDecContext->eSliceType == B_SLICE) {
595 if (ResetDecoder()) {801 if (ResetDecoder (pDecContext)) {
596 pDstInfo->iBufferStatus = 0;802 pDstInfo->iBufferStatus = 0;
597 return (DECODING_STATE)m_pDecContext->iErrorCode;803 return (DECODING_STATE)pDecContext->iErrorCode;
598 }804 }
599 return dsErrorFree;805 return dsErrorFree;
600 }806 }
601 //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.807 //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.
602 if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||808 if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||
603 (VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType)) {809 (VIDEO_BITSTREAM_AVC == pDecContext->eVideoType)) {
604 if (m_pDecContext->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {810 if (pDecContext->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
605#ifdef LONG_TERM_REF811#ifdef LONG_TERM_REF
606 m_pDecContext->bParamSetsLostFlag = true;812 pDecContext->bParamSetsLostFlag = true;
607#else813#else
608 m_pDecContext->bReferenceLostAtT0Flag = true;814 pDecContext->bReferenceLostAtT0Flag = true;
609#endif815#endif
610 }816 }
611 }817 }
612 818
613 if (m_pDecContext->bPrintFrameErrorTraceFlag) {819 if (pDecContext->bPrintFrameErrorTraceFlag) {
614 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n",820 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n",
615 m_pDecContext->iErrorCode);821 pDecContext->iErrorCode);
616 m_pDecContext->bPrintFrameErrorTraceFlag = false;822 pDecContext->bPrintFrameErrorTraceFlag = false;
617 } else {823 } else {
618 m_pDecContext->iIgnoredErrorInfoPacketCount++;824 pDecContext->iIgnoredErrorInfoPacketCount++;
619 if (m_pDecContext->iIgnoredErrorInfoPacketCount == INT_MAX) {825 if (pDecContext->iIgnoredErrorInfoPacketCount == INT_MAX) {
620 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING, "continuous error reached INT_MAX! Restart as 0.");826 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;
622 }828 }
623 }829 }
624 if ((m_pDecContext->pParam->eEcActiveIdc != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {830 if ((pDecContext->pParam->eEcActiveIdc != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {
625 //TODO after dec status updated831 //TODO after dec status updated
626 m_pDecContext->iErrorCode |= dsDataErrorConcealed;832 pDecContext->iErrorCode |= dsDataErrorConcealed;
627 833
628 m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;834 pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
629 if (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t835 if (pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
630 ResetDecStatNums (m_pDecContext->pDecoderStatistics);836 ResetDecStatNums (pDecContext->pDecoderStatistics);
631 m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;837 pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
632 }838 }
633 int32_t iMbConcealedNum = m_pDecContext->iMbEcedNum + m_pDecContext->iMbEcedPropNum;839 int32_t iMbConcealedNum = pDecContext->iMbEcedNum + pDecContext->iMbEcedPropNum;
634 m_pDecContext->pDecoderStatistics->uiAvgEcRatio = m_pDecContext->iMbNum == 0 ?840 pDecContext->pDecoderStatistics->uiAvgEcRatio = pDecContext->iMbNum == 0 ?
635 (m_pDecContext->pDecoderStatistics->uiAvgEcRatio * m_pDecContext->pDecoderStatistics->uiEcFrameNum) : ((841 (pDecContext->pDecoderStatistics->uiAvgEcRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) : ((
636 m_pDecContext->pDecoderStatistics->uiAvgEcRatio * m_pDecContext->pDecoderStatistics->uiEcFrameNum) + ((842 pDecContext->pDecoderStatistics->uiAvgEcRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) + ((
637 iMbConcealedNum * 100) / m_pDecContext->iMbNum));843 iMbConcealedNum * 100) / pDecContext->iMbNum));
638 m_pDecContext->pDecoderStatistics->uiAvgEcPropRatio = m_pDecContext->iMbNum == 0 ?844 pDecContext->pDecoderStatistics->uiAvgEcPropRatio = pDecContext->iMbNum == 0 ?
639 (m_pDecContext->pDecoderStatistics->uiAvgEcPropRatio * m_pDecContext->pDecoderStatistics->uiEcFrameNum) : ((845 (pDecContext->pDecoderStatistics->uiAvgEcPropRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) : ((
640 m_pDecContext->pDecoderStatistics->uiAvgEcPropRatio * m_pDecContext->pDecoderStatistics->uiEcFrameNum) + ((846 pDecContext->pDecoderStatistics->uiAvgEcPropRatio * pDecContext->pDecoderStatistics->uiEcFrameNum) + ((
641 m_pDecContext->iMbEcedPropNum * 100) / m_pDecContext->iMbNum));847 pDecContext->iMbEcedPropNum * 100) / pDecContext->iMbNum));
642 m_pDecContext->pDecoderStatistics->uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1);848 pDecContext->pDecoderStatistics->uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1);
643 m_pDecContext->pDecoderStatistics->uiAvgEcRatio = m_pDecContext->pDecoderStatistics->uiEcFrameNum == 0 ? 0 :849 pDecContext->pDecoderStatistics->uiAvgEcRatio = pDecContext->pDecoderStatistics->uiEcFrameNum == 0 ? 0 :
644 m_pDecContext->pDecoderStatistics->uiAvgEcRatio / m_pDecContext->pDecoderStatistics->uiEcFrameNum;850 pDecContext->pDecoderStatistics->uiAvgEcRatio / pDecContext->pDecoderStatistics->uiEcFrameNum;
645 m_pDecContext->pDecoderStatistics->uiAvgEcPropRatio = m_pDecContext->pDecoderStatistics->uiEcFrameNum == 0 ? 0 :851 pDecContext->pDecoderStatistics->uiAvgEcPropRatio = pDecContext->pDecoderStatistics->uiEcFrameNum == 0 ? 0 :
646 m_pDecContext->pDecoderStatistics->uiAvgEcPropRatio / m_pDecContext->pDecoderStatistics->uiEcFrameNum;852 pDecContext->pDecoderStatistics->uiAvgEcPropRatio / pDecContext->pDecoderStatistics->uiEcFrameNum;
647 }853 }
648 iEnd = WelsTime();854 iEnd = WelsTime();
649 m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;855 pDecContext->dDecTime += (iEnd - iStart) / 1e3;
650 856
651 OutputStatisticsLog (*m_pDecContext->pDecoderStatistics);857 OutputStatisticsLog (*pDecContext->pDecoderStatistics);
652 858
653#ifdef _PICTURE_REORDERING_859 if (pDecContext->pThreadCtx != NULL) {
654 ReorderPicturesInDisplay (ppDst, pDstInfo);860 WAIT_EVENT (&m_sReleaseBufferEvent, WELS_DEC_THREAD_WAIT_INFINITE);
655#endif861 RESET_EVENT (&m_sBufferingEvent);
862 BufferingReadyPicture (pDecContext, ppDst, pDstInfo);
863 SET_EVENT (&m_sBufferingEvent);
864 } else {
865 ReorderPicturesInDisplay (pDecContext, ppDst, pDstInfo);
866 }
656 867
657 return (DECODING_STATE)m_pDecContext->iErrorCode;868 return (DECODING_STATE)pDecContext->iErrorCode;
658 }869 }
659 // else Error free, the current codec works well870 // else Error free, the current codec works well
660 871
661 if (pDstInfo->iBufferStatus == 1) {872 if (pDstInfo->iBufferStatus == 1) {
662 873
663 m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;874 pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
664 if (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t875 if (pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
665 ResetDecStatNums (m_pDecContext->pDecoderStatistics);876 ResetDecStatNums (pDecContext->pDecoderStatistics);
666 m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;877 pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
667 }878 }
668 879
669 OutputStatisticsLog (*m_pDecContext->pDecoderStatistics);880 OutputStatisticsLog (*pDecContext->pDecoderStatistics);
670 }881 }
671 iEnd = WelsTime();882 iEnd = WelsTime();
672 m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;883 pDecContext->dDecTime += (iEnd - iStart) / 1e3;
673 884
674#ifdef _PICTURE_REORDERING_885 if (pDecContext->pThreadCtx != NULL) {
675 ReorderPicturesInDisplay (ppDst, pDstInfo);886 WAIT_EVENT (&m_sReleaseBufferEvent, WELS_DEC_THREAD_WAIT_INFINITE);
676#endif887 RESET_EVENT (&m_sBufferingEvent);
888 BufferingReadyPicture (pDecContext, ppDst, pDstInfo);
889 SET_EVENT (&m_sBufferingEvent);
890 } else {
891 ReorderPicturesInDisplay (pDecContext, ppDst, pDstInfo);
892 }
677 return dsErrorFree;893 return dsErrorFree;
678}894}
679 895
896DECODING_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
680DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst,904DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst,
681 SBufferInfo* pDstInfo) {905 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) {
683 m_sReoderingStatus.iMinPOC = IMinInt32;913 m_sReoderingStatus.iMinPOC = IMinInt32;
684 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {914 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
685 if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32) {915 if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32) {
@@ -704,12 +934,15 @@ DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst, · 18 unmodified lines
704 ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];934 ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
705 ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];935 ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
706 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;936 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
707 if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)937 PPicBuff pPicBuff = m_iThreadCount == 1 ? m_pDecThrCtx[0].pCtx->pPicBuff : m_pPicBuff;
708 m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;938 if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < pPicBuff->iCapacity) {
939 pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
940 }
709 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;941 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
710 m_sReoderingStatus.iMinPOC = IMinInt32;942 m_sReoderingStatus.iMinPOC = IMinInt32;
711 --m_sReoderingStatus.iNumOfPicts;943 --m_sReoderingStatus.iNumOfPicts;
712 }944 }
945
713 return dsErrorFree;946 return dsErrorFree;
714}947}
715 948
@@ -758,24 +991,15 @@ void CWelsDecoder::OutputStatisticsLog (SDecoderStatistics& sDecoderStatistics) · 42 unmodified lines
758 }991 }
759}992}
760 993
761DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay (unsigned char** ppDst, SBufferInfo* pDstInfo) {994void CWelsDecoder::BufferingReadyPicture (PWelsDecoderContext pCtx, unsigned char** ppDst,
762 DECODING_STATE iRet = dsErrorFree;995 SBufferInfo* pDstInfo) {
763 if (pDstInfo->iBufferStatus == 0) {996 if (pDstInfo->iBufferStatus == 0) {
764 return iRet;997 return;
765 }998 }
766 ++m_pDecContext->uiDecodingTimeStamp;999 m_bIsBaseline = pCtx->pSps->uiProfileIdc == 66 || pCtx->pSps->uiProfileIdc == 83;
767 if (m_pDecContext->pSps->uiProfileIdc != 66 && m_pDecContext->pSps->uiProfileIdc != 83) {1000 if (!m_bIsBaseline) {
768 /*if (m_pDecContext->pSliceHeader->iPicOrderCntLsb == 0) {1001 if (m_sReoderingStatus.iNumOfPicts && pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb
769 m_sReoderingStatus.iLastWrittenPOC = 0;1002 && pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb->bNewSeqBegin) {
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) {
779 m_sReoderingStatus.iLastGOPRemainPicts = m_sReoderingStatus.iNumOfPicts;1003 m_sReoderingStatus.iLastGOPRemainPicts = m_sReoderingStatus.iNumOfPicts;
780 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {1004 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
781 if (m_sPictInfoList[i].iPOC > IMinInt32) {1005 if (m_sPictInfoList[i].iPOC > IMinInt32) {
@@ -787,7 +1011,7 @@ DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay (unsigned char** ppDst, SB · 5 unmodified lines
787 //This can happen when decoder moves to next GOP without being able to decoder first picture PicOrderCntLsb = 01011 //This can happen when decoder moves to next GOP without being able to decoder first picture PicOrderCntLsb = 0
788 bool hasGOPChanged = false;1012 bool hasGOPChanged = false;
789 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {1013 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) {
791 hasGOPChanged = true;1015 hasGOPChanged = true;
792 break;1016 break;
793 }1017 }
@@ -802,119 +1026,167 @@ DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay (unsigned char** ppDst, SB · 8 unmodified lines
802 }1026 }
803 }1027 }
804 }1028 }
805 for (int32_t i = 0; i < 16; ++i) {1029 }
806 if (m_sPictInfoList[i].iPOC == IMinInt32) {1030 for (int32_t i = 0; i < 16; ++i) {
807 memcpy (&m_sPictInfoList[i].sBufferInfo, pDstInfo, sizeof (SBufferInfo));1031 if (m_sPictInfoList[i].iPOC == IMinInt32) {
808 m_sPictInfoList[i].pData[0] = ppDst[0];1032 memcpy (&m_sPictInfoList[i].sBufferInfo, pDstInfo, sizeof (SBufferInfo));
809 m_sPictInfoList[i].pData[1] = ppDst[1];1033 m_sPictInfoList[i].pData[0] = ppDst[0];
810 m_sPictInfoList[i].pData[2] = ppDst[2];1034 m_sPictInfoList[i].pData[1] = ppDst[1];
811 m_sPictInfoList[i].iPOC = m_pDecContext->pSliceHeader->iPicOrderCntLsb;1035 m_sPictInfoList[i].pData[2] = ppDst[2];
812 m_sPictInfoList[i].uiDecodingTimeStamp = m_pDecContext->uiDecodingTimeStamp;1036 m_sPictInfoList[i].iPOC = pCtx->pSliceHeader->iPicOrderCntLsb;
813 m_sPictInfoList[i].iPicBuffIdx = m_pDecContext->pLastDecPicInfo->pPreviousDecodedPictureInDpb->iPicBuffIdx;1037 m_sPictInfoList[i].uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp;
814 m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[i].iPicBuffIdx]->bAvailableFlag = false;1038 m_sPictInfoList[i].iPicBuffIdx = pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb->iPicBuffIdx;
815 m_sPictInfoList[i].bLastGOP = false;1039 pCtx->pPicBuff->ppPic[m_sPictInfoList[i].iPicBuffIdx]->bAvailableFlag = false;
816 pDstInfo->iBufferStatus = 0;1040 m_sPictInfoList[i].bLastGOP = false;
817 ++m_sReoderingStatus.iNumOfPicts;1041 pDstInfo->iBufferStatus = 0;
818 if (i > m_sReoderingStatus.iLargestBufferedPicIndex) {1042 ++m_sReoderingStatus.iNumOfPicts;
819 m_sReoderingStatus.iLargestBufferedPicIndex = i;1043 if (i > m_sReoderingStatus.iLargestBufferedPicIndex) {
820 }1044 m_sReoderingStatus.iLargestBufferedPicIndex = i;
821 break;
822 }1045 }
1046 break;
823 }1047 }
824 if (m_sReoderingStatus.iLastGOPRemainPicts > 0) {1048 }
825 m_sReoderingStatus.iMinPOC = IMinInt32;1049}
826 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {1050
827 if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].bLastGOP) {1051void CWelsDecoder::ReleaseBufferedReadyPicture (PWelsDecoderContext pCtx, unsigned char** ppDst,
828 m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;1052 SBufferInfo* pDstInfo) {
829 m_sReoderingStatus.iPictInfoIndex = i;1053 PPicBuff pPicBuff = pCtx ? pCtx->pPicBuff : m_pPicBuff;
830 }1054 if (!m_bIsBaseline && m_sReoderingStatus.iLastGOPRemainPicts > 0) {
831 if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC1055 m_sReoderingStatus.iMinPOC = IMinInt32;
832 && m_sPictInfoList[i].bLastGOP) {1056 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
833 m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;1057 if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].bLastGOP) {
834 m_sReoderingStatus.iPictInfoIndex = i;1058 m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
835 }1059 m_sReoderingStatus.iPictInfoIndex = i;
836 }1060 }
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;
838#if defined (_DEBUG)1068#if defined (_DEBUG)
839#ifdef _MOTION_VECTOR_DUMP_1069#ifdef _MOTION_VECTOR_DUMP_
840 fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);1070 fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
841#endif1071#endif
842#endif1072#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) {
843 memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));1105 memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
844 ppDst[0] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[0];1106 ppDst[0] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[0];
845 ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];1107 ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
846 ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];1108 ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
847 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;1109 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
848 if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)1110 pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
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;
852 --m_sReoderingStatus.iNumOfPicts;1111 --m_sReoderingStatus.iNumOfPicts;
853 --m_sReoderingStatus.iLastGOPRemainPicts;
854 if (m_sReoderingStatus.iLastGOPRemainPicts == 0) {
855 m_sReoderingStatus.iLastWrittenPOC = IMinInt32;
856 }
857 return iRet;
858 }1112 }
859 if (m_sReoderingStatus.iNumOfPicts > 0) {1113 return;
860 m_sReoderingStatus.iMinPOC = IMinInt32;1114 }
861 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {1115 if (m_sReoderingStatus.iNumOfPicts > 0) {
862 if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32) {1116 m_sReoderingStatus.iMinPOC = IMinInt32;
863 m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;1117 for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
864 m_sReoderingStatus.iPictInfoIndex = i;1118 if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32) {
865 }1119 m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
866 if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC) {1120 m_sReoderingStatus.iPictInfoIndex = i;
867 m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
868 m_sReoderingStatus.iPictInfoIndex = i;
869 }
870 }1121 }
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) ;
871 }1137 }
872 if (m_sReoderingStatus.iMinPOC > IMinInt32) {1138 if (isReady) {
873 if ((m_sReoderingStatus.iLastWrittenPOC > IMinInt321139 m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
874 && m_sReoderingStatus.iMinPOC - m_sReoderingStatus.iLastWrittenPOC <= 1)
875 || m_sReoderingStatus.iMinPOC < m_pDecContext->pSliceHeader->iPicOrderCntLsb) {
876 m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
877#if defined (_DEBUG)1140#if defined (_DEBUG)
878#ifdef _MOTION_VECTOR_DUMP_1141#ifdef _MOTION_VECTOR_DUMP_
879 fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);1142 fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
880#endif1143#endif
881#endif1144#endif
882 memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));1145 memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
883 ppDst[0] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[0];1146 ppDst[0] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[0];
884 ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];1147 ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
885 ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];1148 ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
886 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;1149 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
887 if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)1150 pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
888 m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;1151 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
889 m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;1152 m_sReoderingStatus.iMinPOC = IMinInt32;
890 m_sReoderingStatus.iMinPOC = IMinInt32;1153 --m_sReoderingStatus.iNumOfPicts;
891 --m_sReoderingStatus.iNumOfPicts;
892 return iRet;
893 }
894 }1154 }
895 }1155 }
1156}
896 1157
1158DECODING_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 }
897 return iRet;1169 return iRet;
898}1170}
899 1171
900DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,1172DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc, const int kiSrcLen, SParserBsInfo* pDstInfo) {
901 const int kiSrcLen,1173 PWelsDecoderContext pDecContext = m_pDecThrCtx[0].pCtx;
902 SParserBsInfo* pDstInfo) {1174
903 if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {1175 if (pDecContext == NULL || pDecContext->pParam == NULL) {
904 if (m_pWelsTrace != NULL) {1176 if (m_pWelsTrace != NULL) {
905 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeParser without Initialize.\n");1177 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeParser without Initialize.\n");
906 }1178 }
907 return dsInitialOptExpected;1179 return dsInitialOptExpected;
908 }1180 }
909 1181
910 if (!m_pDecContext->pParam->bParseOnly) {1182 if (!pDecContext->pParam->bParseOnly) {
911 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be true for this API calling! \n");1183 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;
913 return dsInvalidArgument;1185 return dsInvalidArgument;
914 }1186 }
915 int64_t iEnd, iStart = WelsTime();1187 int64_t iEnd, iStart = WelsTime();
916 if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {1188 if (CheckBsBuffer (pDecContext, kiSrcLen)) {
917 if (ResetDecoder())1189 if (ResetDecoder (pDecContext))
918 return dsOutOfMemory;1190 return dsOutOfMemory;
919 1191
920 return dsErrorFree;1192 return dsErrorFree;
@@ -926,58 +1198,57 @@ DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc, · 5 unmodified lines
926 WelsFflush (m_pFBS);1198 WelsFflush (m_pFBS);
927 }1199 }
928#endif//OUTPUT_BIT_STREAM1200#endif//OUTPUT_BIT_STREAM
929 m_pDecContext->bEndOfStreamFlag = false;1201 pDecContext->bEndOfStreamFlag = false;
930 } else {1202 } else {
931 //For application MODE, the error detection should be added for safe.1203 //For application MODE, the error detection should be added for safe.
932 //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.1204 //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
933 m_pDecContext->bEndOfStreamFlag = true;1205 pDecContext->bEndOfStreamFlag = true;
934 m_pDecContext->bInstantDecFlag = true;1206 pDecContext->bInstantDecFlag = true;
935 }1207 }
936 1208
937 m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.1209 pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
938 m_pDecContext->pParam->eEcActiveIdc = ERROR_CON_DISABLE; //add protection to disable EC here.1210 pDecContext->pParam->eEcActiveIdc = ERROR_CON_DISABLE; //add protection to disable EC here.
939 m_pDecContext->iFeedbackNalRefIdc = -1; //initialize1211 pDecContext->iFeedbackNalRefIdc = -1; //initialize
940 if (!m_pDecContext->bFramePending) { //frame complete1212 if (!pDecContext->bFramePending) { //frame complete
941 m_pDecContext->pParserBsInfo->iNalNum = 0;1213 pDecContext->pParserBsInfo->iNalNum = 0;
942 memset (m_pDecContext->pParserBsInfo->pNalLenInByte, 0, MAX_NAL_UNITS_IN_LAYER);1214 memset (pDecContext->pParserBsInfo->pNalLenInByte, 0, MAX_NAL_UNITS_IN_LAYER);
943 }1215 }
944 pDstInfo->iNalNum = 0;1216 pDstInfo->iNalNum = 0;
945 pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;1217 pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;
946 if (pDstInfo) {1218 if (pDstInfo) {
947 m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;1219 pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
948 pDstInfo->uiOutBsTimeStamp = 0;1220 pDstInfo->uiOutBsTimeStamp = 0;
949 } else {1221 } else {
950 m_pDecContext->uiTimeStamp = 0;1222 pDecContext->uiTimeStamp = 0;
951 }1223 }
952 WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);1224 WelsDecodeBs (pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);
953 if (m_pDecContext->iErrorCode & dsOutOfMemory) {1225 if (pDecContext->iErrorCode & dsOutOfMemory) {
954 if (ResetDecoder())1226 if (ResetDecoder (pDecContext))
955 return dsOutOfMemory;1227 return dsOutOfMemory;
956 return dsErrorFree;1228 return dsErrorFree;
957 }1229 }
958 1230
959 if (!m_pDecContext->bFramePending && m_pDecContext->pParserBsInfo->iNalNum) {1231 if (!pDecContext->bFramePending && pDecContext->pParserBsInfo->iNalNum) {
960 memcpy (pDstInfo, m_pDecContext->pParserBsInfo, sizeof (SParserBsInfo));1232 memcpy (pDstInfo, pDecContext->pParserBsInfo, sizeof (SParserBsInfo));
961 1233
962 if (m_pDecContext->iErrorCode == ERR_NONE) { //update statistics: decoding frame count1234 if (pDecContext->iErrorCode == ERR_NONE) { //update statistics: decoding frame count
963 m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;1235 pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
964 if (m_pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t1236 if (pDecContext->pDecoderStatistics->uiDecodedFrameCount == 0) { //exceed max value of uint32_t
965 ResetDecStatNums (m_pDecContext->pDecoderStatistics);1237 ResetDecStatNums (pDecContext->pDecoderStatistics);
966 m_pDecContext->pDecoderStatistics->uiDecodedFrameCount++;1238 pDecContext->pDecoderStatistics->uiDecodedFrameCount++;
967 }1239 }
968 }1240 }
969 }1241 }
970 1242
971 m_pDecContext->bInstantDecFlag = false; //reset no-delay flag1243 pDecContext->bInstantDecFlag = false; //reset no-delay flag
972 1244
973 if (m_pDecContext->iErrorCode && m_pDecContext->bPrintFrameErrorTraceFlag) {1245 if (pDecContext->iErrorCode && pDecContext->bPrintFrameErrorTraceFlag) {
974 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n", m_pDecContext->iErrorCode);1246 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n", pDecContext->iErrorCode);
975 m_pDecContext->bPrintFrameErrorTraceFlag = false;1247 pDecContext->bPrintFrameErrorTraceFlag = false;
976 }1248 }
977 iEnd = WelsTime();1249 iEnd = WelsTime();
978 m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;1250 pDecContext->dDecTime += (iEnd - iStart) / 1e3;
979 1251 return (DECODING_STATE)pDecContext->iErrorCode;
980 return (DECODING_STATE) m_pDecContext->iErrorCode;
981}1252}
982 1253
983DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,1254DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,
@@ -1019,6 +1290,92 @@ DECODING_STATE CWelsDecoder::DecodeFrameEx (const unsigned char* kpSrc, · 35 unmodified lines
1019 return state;1290 return state;
1020}1291}
1021 1292
1293DECODING_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
1330int 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
1022} // namespace WelsDec1379} // namespace WelsDec
1023 1380
1024 1381

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