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).
Showing the changes to codec/decoder/plus/src/welsDecoderExt.cpp (1 of 4 files). Show all
Unified · Split
| @@ -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 | #else | 72 | #else |
| 71 | #include <sys/time.h> | 73 | #include <sys/time.h> |
| 72 | #endif | 74 | #endif |
| 73 | 75 | ||
| 74 | #define _PICTURE_REORDERING_ 1 | ||
| 75 | |||
| 76 | namespace WelsDec { | 76 | namespace WelsDec { |
| 77 | 77 | ||
| 78 | ////////////////////////////////////////////////////////////////////// | 78 | ////////////////////////////////////////////////////////////////////// |
| @@ -88,9 +88,58 @@ namespace WelsDec { · 9 unmodified lines | |||
| 88 | * | 88 | * |
| 89 | * return: none | 89 | * return: none |
| 90 | ***************************************************************************/ | 90 | ***************************************************************************/ |
| 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 | |||
| 91 | CWelsDecoder::CWelsDecoder (void) | 131 | CWelsDecoder::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_STREAM | 143 | #ifdef OUTPUT_BIT_STREAM |
| 95 | char chFileName[1024] = { 0 }; //for .264 | 144 | 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_STREAM | 175 | #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_STREAM | 233 | #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 | ||
| 192 | long CWelsDecoder::Initialize (const SDecodingParam* pParam) { | 254 | long CWelsDecoder::Initialize (const SDecodingParam* pParam) { |
| @@ -215,26 +277,87 @@ long CWelsDecoder::Uninitialize() { · 22 unmodified lines | |||
| 215 | } | 277 | } |
| 216 | 278 | ||
| 217 | void CWelsDecoder::UninitDecoder (void) { | 279 | void 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.", | 290 | void 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 | } | ||
| 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 | } | ||
| 223 | 339 | ||
| 224 | WelsEndDecoder (m_pDecContext); | 340 | void 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 context | 374 | //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) //free | 380 | 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. | ||
| 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) | ||
| 257 | return cmMallocMemeError; | 402 | return cmMallocMemeError; |
| 258 | int32_t iCacheLineSize = 16; // on chip cache line size in byte | 403 | 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 context | 407 | //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 context | 416 | //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 decoder | 423 | //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 | ||
| 285 | int32_t CWelsDecoder::ResetDecoder() { | 430 | int32_t CWelsDecoder::ResetDecoder (PWelsDecoderContext& pCtx) { |
| 286 | // TBC: need to be modified when context and trace point are null | 431 | // 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()); | 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); | ||
| 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 | */ |
| 306 | long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) { | 470 | long 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 status | 508 | } 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 idc | 520 | 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 | */ |
| 380 | long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) { | 568 | long 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_REF | 586 | #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 | #endif | 604 | #endif |
| 413 | else if (DECODER_OPTION_VCL_NAL == eOptID) { //feedback whether or not have VCL NAL in current AU | 605 | 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 ID | 609 | } 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 debugging | 623 | } 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 status | 628 | 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 VUI | 642 | } 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 | ||
| 509 | DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, | 711 | DECODING_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_STREAM | 743 | #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; //initialize | 757 | } |
| 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_REF | 765 | #ifdef LONG_TERM_REF |
| 560 | m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR | 766 | 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; //initialize | 769 | pDecContext->iFrameNum = -1; //initialize |
| 564 | #endif | 770 | #endif |
| 565 | 771 | ||
| 566 | m_pDecContext->iFeedbackTidInAu = -1; //initialize | 772 | pDecContext->iFeedbackTidInAu = -1; //initialize |
| 567 | m_pDecContext->iFeedbackNalRefIdc = -1; //initialize | 773 | 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 function | 781 | pDstInfo, NULL); //iErrorCode has been modified in this function |
| 576 | m_pDecContext->bInstantDecFlag = false; //reset no-delay flag | 782 | 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 currently | 785 | 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_REF | 811 | #ifdef LONG_TERM_REF |
| 606 | m_pDecContext->bParamSetsLostFlag = true; | 812 | pDecContext->bParamSetsLostFlag = true; |
| 607 | #else | 813 | #else |
| 608 | m_pDecContext->bReferenceLostAtT0Flag = true; | 814 | pDecContext->bReferenceLostAtT0Flag = true; |
| 609 | #endif | 815 | #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 updated | 831 | //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_t | 835 | 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 | #endif | 861 | 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 well | 870 | // 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_t | 875 | 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 | #endif | 887 | 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 | ||
| 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 | |||
| 680 | DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst, | 904 | DECODING_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 | ||
| 761 | DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay (unsigned char** ppDst, SBufferInfo* pDstInfo) { | 994 | void 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 = 0 | 1011 | //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) { | 1051 | void 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.iMinPOC | 1055 | 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 | #endif | 1071 | #endif |
| 842 | #endif | 1072 | #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 > IMinInt32 | 1139 | 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 | #endif | 1143 | #endif |
| 881 | #endif | 1144 | #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 | ||
| 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 | } | ||
| 897 | return iRet; | 1169 | return iRet; |
| 898 | } | 1170 | } |
| 899 | 1171 | ||
| 900 | DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc, | 1172 | DECODING_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_STREAM | 1200 | #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; //initialize | 1211 | pDecContext->iFeedbackNalRefIdc = -1; //initialize |
| 940 | if (!m_pDecContext->bFramePending) { //frame complete | 1212 | 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 count | 1234 | 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_t | 1236 | 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 flag | 1243 | 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 | ||
| 983 | DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc, | 1254 | DECODING_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 | ||
| 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 | |||
| 1022 | } // namespace WelsDec | 1379 | } // namespace WelsDec |
| 1023 | 1380 | ||
| 1024 | 1381 | ||