Showing the changes to codec/encoder/core/src/slice_multi_threading.cpp (1 of 5 files). Show all
Unified · Split
| @@ -70,12 +70,6 @@ · 69 unmodified lines | |||
| 70 | #define MT_TRACE_LOG(x, ...) | 70 | #define MT_TRACE_LOG(x, ...) |
| 71 | #endif | 71 | #endif |
| 72 | 72 | ||
| 73 | #define WELS_THREAD_SIGNAL_AND_BREAK(CodedEventList, CodedMasterEvent, iEventIdx) { \ | ||
| 74 | WelsEventSignal(&CodedEventList[iEventIdx]); \ | ||
| 75 | WelsEventSignal (&CodedMasterEvent); \ | ||
| 76 | break; \ | ||
| 77 | } | ||
| 78 | |||
| 79 | namespace WelsEnc { | 73 | namespace WelsEnc { |
| 80 | void UpdateMbListNeighborParallel (SDqLayer* pCurDq, | 74 | void UpdateMbListNeighborParallel (SDqLayer* pCurDq, |
| 81 | SMB* pMbList, | 75 | SMB* pMbList, |
| @@ -314,12 +308,6 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara · 232 unmodified lines | |||
| 314 | pSmt->pThreadPEncCtx[iIdx].iThreadIndex = iIdx; | 308 | pSmt->pThreadPEncCtx[iIdx].iThreadIndex = iIdx; |
| 315 | pSmt->pThreadHandles[iIdx] = 0; | 309 | pSmt->pThreadHandles[iIdx] = 0; |
| 316 | 310 | ||
| 317 | WelsSnprintf (name, SEM_NAME_MAX, "ee%d%s", iIdx, pSmt->eventNamespace); | ||
| 318 | err = WelsEventOpen (&pSmt->pExitEncodeEvent[iIdx], name); | ||
| 319 | MT_TRACE_LOG (pLogCtx, WELS_LOG_INFO, "[MT] Open pExitEncodeEvent%d named(%s) ret%d err%d", iIdx, name, err, errno); | ||
| 320 | WelsSnprintf (name, SEM_NAME_MAX, "tm%d%s", iIdx, pSmt->eventNamespace); | ||
| 321 | err = WelsEventOpen (&pSmt->pThreadMasterEvent[iIdx], name); | ||
| 322 | MT_TRACE_LOG (pLogCtx, WELS_LOG_INFO, "[MT] Open pThreadMasterEvent%d named(%s) ret%d err%d", iIdx, name, err, errno); | ||
| 323 | // length of semaphore name should be system constrained at least on mac 10.7 | 311 | // length of semaphore name should be system constrained at least on mac 10.7 |
| 324 | WelsSnprintf (name, SEM_NAME_MAX, "ud%d%s", iIdx, pSmt->eventNamespace); | 312 | WelsSnprintf (name, SEM_NAME_MAX, "ud%d%s", iIdx, pSmt->eventNamespace); |
| 325 | err = WelsEventOpen (&pSmt->pUpdateMbListEvent[iIdx], name); | 313 | err = WelsEventOpen (&pSmt->pUpdateMbListEvent[iIdx], name); |
| @@ -391,10 +379,6 @@ void ReleaseMtResource (sWelsEncCtx** ppCtx) { · 65 unmodified lines | |||
| 391 | char ename[SEM_NAME_MAX] = {0}; | 379 | char ename[SEM_NAME_MAX] = {0}; |
| 392 | while (iIdx < iThreadNum) { | 380 | while (iIdx < iThreadNum) { |
| 393 | // length of semaphore name should be system constrained at least on mac 10.7 | 381 | // length of semaphore name should be system constrained at least on mac 10.7 |
| 394 | WelsSnprintf (ename, SEM_NAME_MAX, "ee%d%s", iIdx, pSmt->eventNamespace); | ||
| 395 | WelsEventClose (&pSmt->pExitEncodeEvent[iIdx], ename); | ||
| 396 | WelsSnprintf (ename, SEM_NAME_MAX, "tm%d%s", iIdx, pSmt->eventNamespace); | ||
| 397 | WelsEventClose (&pSmt->pThreadMasterEvent[iIdx], ename); | ||
| 398 | WelsSnprintf (ename, SEM_NAME_MAX, "sc%d%s", iIdx, pSmt->eventNamespace); | 382 | WelsSnprintf (ename, SEM_NAME_MAX, "sc%d%s", iIdx, pSmt->eventNamespace); |
| 399 | WelsEventClose (&pSmt->pSliceCodedEvent[iIdx], ename); | 383 | WelsEventClose (&pSmt->pSliceCodedEvent[iIdx], ename); |
| 400 | WelsSnprintf (ename, SEM_NAME_MAX, "rc%d%s", iIdx, pSmt->eventNamespace); | 384 | WelsSnprintf (ename, SEM_NAME_MAX, "rc%d%s", iIdx, pSmt->eventNamespace); |
| @@ -509,343 +493,6 @@ int32_t WriteSliceBs (sWelsEncCtx* pCtx, SWelsSliceBs* pSliceBs, const int32_t i · 108 unmodified lines | |||
| 509 | } | 493 | } |
| 510 | 494 | ||
| 511 | // thread process for coding one pSlice | 495 | // thread process for coding one pSlice |
| 512 | WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) { | ||
| 513 | SSliceThreadPrivateData* pPrivateData = (SSliceThreadPrivateData*)arg; | ||
| 514 | sWelsEncCtx* pEncPEncCtx = NULL; | ||
| 515 | SDqLayer* pCurDq = NULL; | ||
| 516 | SSlice* pSlice = NULL; | ||
| 517 | SWelsSliceBs* pSliceBs = NULL; | ||
| 518 | WELS_EVENT pEventsList[3]; | ||
| 519 | int32_t iEventCount = 0; | ||
| 520 | WELS_THREAD_ERROR_CODE iWaitRet = WELS_THREAD_ERROR_GENERAL; | ||
| 521 | uint32_t uiThrdRet = 0; | ||
| 522 | int32_t iSliceSize = 0; | ||
| 523 | int32_t iSliceIdx = -1; | ||
| 524 | int32_t iThreadIdx = -1; | ||
| 525 | int32_t iEventIdx = -1; | ||
| 526 | bool bNeedPrefix = false; | ||
| 527 | EWelsNalUnitType eNalType = NAL_UNIT_UNSPEC_0; | ||
| 528 | EWelsNalRefIdc eNalRefIdc = NRI_PRI_LOWEST; | ||
| 529 | int32_t iReturn = ENC_RETURN_SUCCESS; | ||
| 530 | |||
| 531 | if (NULL == pPrivateData) | ||
| 532 | WELS_THREAD_ROUTINE_RETURN (1); | ||
| 533 | |||
| 534 | pEncPEncCtx = (sWelsEncCtx*)pPrivateData->pWelsPEncCtx; | ||
| 535 | |||
| 536 | iThreadIdx = pPrivateData->iThreadIndex; | ||
| 537 | iEventIdx = iThreadIdx; | ||
| 538 | |||
| 539 | pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pReadySliceCodingEvent[iEventIdx]; | ||
| 540 | pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pExitEncodeEvent[iEventIdx]; | ||
| 541 | pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pUpdateMbListEvent[iEventIdx]; | ||
| 542 | |||
| 543 | WelsThreadSetName ("OpenH264Enc_CodingSliceThreadProc"); | ||
| 544 | |||
| 545 | do { | ||
| 546 | MT_TRACE_LOG (& (pEncPEncCtx->sLogCtx), WELS_LOG_INFO, | ||
| 547 | "[MT] CodingSliceThreadProc(), try to call WelsMultipleEventsWaitSingleBlocking(pEventsList= %p %p %p), pEncPEncCtx= %p!", | ||
| 548 | pEventsList[0], pEventsList[1], pEventsList[1], (void*)pEncPEncCtx); | ||
| 549 | iWaitRet = WelsMultipleEventsWaitSingleBlocking (iEventCount, | ||
| 550 | &pEventsList[0], | ||
| 551 | &pEncPEncCtx->pSliceThreading->pThreadMasterEvent[iEventIdx], | ||
| 552 | &pEncPEncCtx->pSliceThreading->mutexEvent); // blocking until at least one event is signalled | ||
| 553 | if (WELS_THREAD_ERROR_WAIT_OBJECT_0 == iWaitRet) { // start pSlice coding signal waited | ||
| 554 | //int iLayerIndex = pEncPEncCtx->pOut->iLayerBsIndex; | ||
| 555 | //SFrameBSInfo* pFrameBsInfo = pPrivateData->pFrameBsInfo; | ||
| 556 | //SLayerBSInfo* pLbi = &pFrameBsInfo->sLayerInfo [iLayerIndex]; | ||
| 557 | |||
| 558 | const int32_t kiCurDid = pEncPEncCtx->uiDependencyId; | ||
| 559 | SWelsSvcCodingParam* pCodingParam = pEncPEncCtx->pSvcParam; | ||
| 560 | SSpatialLayerConfig* pParamD = &pCodingParam->sSpatialLayers[kiCurDid]; | ||
| 561 | SSlice* pCurSlice = NULL; | ||
| 562 | |||
| 563 | pCurDq = pEncPEncCtx->pCurDqLayer; | ||
| 564 | eNalType = pEncPEncCtx->eNalType; | ||
| 565 | eNalRefIdc = pEncPEncCtx->eNalPriority; | ||
| 566 | bNeedPrefix = pEncPEncCtx->bNeedPrefixNalFlag; | ||
| 567 | |||
| 568 | if (pParamD->sSliceArgument.uiSliceMode != SM_SIZELIMITED_SLICE) { | ||
| 569 | int64_t iSliceStart = 0; | ||
| 570 | bool bDsaFlag = false; | ||
| 571 | iSliceIdx = pPrivateData->iSliceIndex; | ||
| 572 | pSlice = &pCurDq->sSliceThreadInfo[iThreadIdx].pSliceInThread[iSliceIdx]; | ||
| 573 | pSliceBs = &pSlice->sSliceBs; | ||
| 574 | |||
| 575 | bDsaFlag = ((pParamD->sSliceArgument.uiSliceMode == SM_FIXEDSLCNUM_SLICE) && | ||
| 576 | pCodingParam->iMultipleThreadIdc > 1 && | ||
| 577 | pCodingParam->iMultipleThreadIdc >= pParamD->sSliceArgument.uiSliceNum); | ||
| 578 | if (bDsaFlag) | ||
| 579 | iSliceStart = WelsTime(); | ||
| 580 | |||
| 581 | pSliceBs->uiBsPos = 0; | ||
| 582 | pSliceBs->iNalIndex = 0; | ||
| 583 | assert ((void*) (&pSliceBs->sBsWrite) == (void*)pSlice->pSliceBsa); | ||
| 584 | InitBits (&pSliceBs->sBsWrite, pSliceBs->pBsBuffer, pSliceBs->uiSize); | ||
| 585 | |||
| 586 | #if MT_DEBUG_BS_WR | ||
| 587 | pSliceBs->bSliceCodedFlag = false; | ||
| 588 | #endif//MT_DEBUG_BS_WR | ||
| 589 | |||
| 590 | if (bNeedPrefix) { | ||
| 591 | if (eNalRefIdc != NRI_PRI_LOWEST) { | ||
| 592 | WelsLoadNalForSlice (pSliceBs, NAL_UNIT_PREFIX, eNalRefIdc); | ||
| 593 | WelsWriteSVCPrefixNal (&pSliceBs->sBsWrite, eNalRefIdc, (NAL_UNIT_CODED_SLICE_IDR == eNalType)); | ||
| 594 | WelsUnloadNalForSlice (pSliceBs); | ||
| 595 | } else { // No Prefix NAL Unit RBSP syntax here, but need add NAL Unit Header extension | ||
| 596 | WelsLoadNalForSlice (pSliceBs, NAL_UNIT_PREFIX, eNalRefIdc); | ||
| 597 | // No need write any syntax of prefix NAL Unit RBSP here | ||
| 598 | WelsUnloadNalForSlice (pSliceBs); | ||
| 599 | } | ||
| 600 | } | ||
| 601 | |||
| 602 | WelsLoadNalForSlice (pSliceBs, eNalType, eNalRefIdc); | ||
| 603 | pCurSlice = pEncPEncCtx->pCurDqLayer->ppSliceInLayer[iSliceIdx]; | ||
| 604 | assert (iSliceIdx == (int) pCurSlice->iSliceIdx); | ||
| 605 | iReturn = SetSliceBoundaryInfo(pEncPEncCtx->pCurDqLayer, pCurSlice, iSliceIdx); | ||
| 606 | if (ENC_RETURN_SUCCESS != iReturn) { | ||
| 607 | uiThrdRet = iReturn; | ||
| 608 | WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, | ||
| 609 | pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, | ||
| 610 | iEventIdx); | ||
| 611 | } | ||
| 612 | |||
| 613 | iReturn = SetSliceBoundaryInfo(pEncPEncCtx->pCurDqLayer, pSlice, iSliceIdx); | ||
| 614 | if (ENC_RETURN_SUCCESS != iReturn) { | ||
| 615 | uiThrdRet = iReturn; | ||
| 616 | WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, | ||
| 617 | pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, | ||
| 618 | iEventIdx); | ||
| 619 | } | ||
| 620 | |||
| 621 | assert (iSliceIdx == pSlice->iSliceIdx); | ||
| 622 | iReturn = WelsCodeOneSlice (pEncPEncCtx, pSlice, eNalType); | ||
| 623 | if (ENC_RETURN_SUCCESS != iReturn) { | ||
| 624 | uiThrdRet = iReturn; | ||
| 625 | WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, | ||
| 626 | pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, | ||
| 627 | iEventIdx); | ||
| 628 | } | ||
| 629 | |||
| 630 | WelsUnloadNalForSlice (pSliceBs); | ||
| 631 | |||
| 632 | iReturn = WriteSliceBs (pEncPEncCtx, pSliceBs, iSliceIdx, iSliceSize); | ||
| 633 | if (ENC_RETURN_SUCCESS != iReturn) { | ||
| 634 | uiThrdRet = iReturn; | ||
| 635 | WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, | ||
| 636 | pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, | ||
| 637 | iEventIdx); | ||
| 638 | } | ||
| 639 | |||
| 640 | pEncPEncCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (pCurDq, pEncPEncCtx->pFuncList, pSlice); | ||
| 641 | |||
| 642 | if (bDsaFlag) { | ||
| 643 | pSlice->uiSliceConsumeTime = (uint32_t) (WelsTime() - iSliceStart); | ||
| 644 | MT_TRACE_LOG (& (pEncPEncCtx->sLogCtx), WELS_LOG_INFO, | ||
| 645 | "[MT] CodingSliceThreadProc(), coding_idx %d, iSliceIdx %d, uiSliceConsumeTime %d, iSliceSize %d, iFirstMbInSlice %d, count_num_mb_in_slice %d", | ||
| 646 | pEncPEncCtx->iCodingIndex, iSliceIdx, | ||
| 647 | pSlice->uiSliceConsumeTime, iSliceSize, | ||
| 648 | pSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice, | ||
| 649 | pSlice->iCountMbNumInSlice); | ||
| 650 | } | ||
| 651 | |||
| 652 | #if defined(SLICE_INFO_OUTPUT) | ||
| 653 | fprintf (stderr, | ||
| 654 | "@pSlice=%-6d sliceType:%c idc:%d size:%-6d\n", | ||
| 655 | iSliceIdx, | ||
| 656 | (pEncPEncCtx->eSliceType == P_SLICE ? 'P' : 'I'), | ||
| 657 | eNalRefIdc, | ||
| 658 | iSliceSize | ||
| 659 | ); | ||
| 660 | #endif//SLICE_INFO_OUTPUT | ||
| 661 | |||
| 662 | #if MT_DEBUG_BS_WR | ||
| 663 | pSliceBs->bSliceCodedFlag = true; | ||
| 664 | #endif//MT_DEBUG_BS_WR | ||
| 665 | |||
| 666 | WelsEventSignal ( | ||
| 667 | &pEncPEncCtx->pSliceThreading->pSliceCodedEvent[iEventIdx]); // mean finished coding current pSlice | ||
| 668 | WelsEventSignal ( | ||
| 669 | &pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent); | ||
| 670 | } else { // for SM_SIZELIMITED_SLICE parallelization | ||
| 671 | const int32_t kiPartitionId = iThreadIdx; | ||
| 672 | const int32_t kiSliceIdxStep = pEncPEncCtx->iActiveThreadsNum; | ||
| 673 | const int32_t kiFirstMbInPartition = pCurDq->FirstMbIdxOfPartition[kiPartitionId]; | ||
| 674 | const int32_t kiEndMbIdxInPartition = pCurDq->EndMbIdxOfPartition[kiPartitionId]; | ||
| 675 | int32_t iAnyMbLeftInPartition = kiEndMbIdxInPartition - kiFirstMbInPartition + 1; | ||
| 676 | SSpatialLayerInternal *pParamInternal = &pCodingParam->sDependencyLayers[kiCurDid]; | ||
| 677 | iSliceIdx = pPrivateData->iSliceIndex; | ||
| 678 | SSlice* pStartSlice = &pCurDq->sSliceThreadInfo[iThreadIdx].pSliceInThread[iSliceIdx]; | ||
| 679 | pStartSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice = kiFirstMbInPartition; | ||
| 680 | while (iAnyMbLeftInPartition > 0) { | ||
| 681 | if (iSliceIdx >= pCurDq->iMaxSliceNum) { | ||
| 682 | // TODO: need exception handler for not large enough of MAX_SLICES_NUM related memory usage | ||
| 683 | // No idea about its solution due MAX_SLICES_NUM is fixed lenght in relevent pData structure | ||
| 684 | uiThrdRet = 1; | ||
| 685 | WelsLog (&pEncPEncCtx->sLogCtx, WELS_LOG_WARNING, | ||
| 686 | "[MT] CodingSliceThreadProc Too many slices: coding_idx %d, iSliceIdx %d, pCurDq->iMaxSliceNum %d", | ||
| 687 | pParamInternal->iCodingIndex, | ||
| 688 | iSliceIdx, pCurDq->iMaxSliceNum); | ||
| 689 | WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, | ||
| 690 | pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, | ||
| 691 | iEventIdx); | ||
| 692 | } | ||
| 693 | pSlice = &pCurDq->sSliceThreadInfo[iThreadIdx].pSliceInThread[iSliceIdx]; | ||
| 694 | pSliceBs = &pSlice->sSliceBs; | ||
| 695 | pSliceBs->uiBsPos = 0; | ||
| 696 | pSliceBs->iNalIndex = 0; | ||
| 697 | |||
| 698 | SetOneSliceBsBufferUnderMultithread (pEncPEncCtx, kiPartitionId, pSlice); | ||
| 699 | InitBits (&pSliceBs->sBsWrite, pSliceBs->pBsBuffer, pSliceBs->uiSize); | ||
| 700 | |||
| 701 | if (bNeedPrefix) { | ||
| 702 | if (eNalRefIdc != NRI_PRI_LOWEST) { | ||
| 703 | WelsLoadNalForSlice (pSliceBs, NAL_UNIT_PREFIX, eNalRefIdc); | ||
| 704 | WelsWriteSVCPrefixNal (&pSliceBs->sBsWrite, eNalRefIdc, (NAL_UNIT_CODED_SLICE_IDR == eNalType)); | ||
| 705 | WelsUnloadNalForSlice (pSliceBs); | ||
| 706 | } else { // No Prefix NAL Unit RBSP syntax here, but need add NAL Unit Header extension | ||
| 707 | WelsLoadNalForSlice (pSliceBs, NAL_UNIT_PREFIX, eNalRefIdc); | ||
| 708 | // No need write any syntax of prefix NAL Unit RBSP here | ||
| 709 | WelsUnloadNalForSlice (pSliceBs); | ||
| 710 | } | ||
| 711 | } | ||
| 712 | |||
| 713 | WelsLoadNalForSlice (pSliceBs, eNalType, eNalRefIdc); | ||
| 714 | assert (iSliceIdx == pSlice->iSliceIdx); | ||
| 715 | iReturn = WelsCodeOneSlice (pEncPEncCtx, pSlice, eNalType); | ||
| 716 | if (ENC_RETURN_SUCCESS != iReturn) { | ||
| 717 | uiThrdRet = iReturn; | ||
| 718 | WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, | ||
| 719 | pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, | ||
| 720 | iEventIdx); | ||
| 721 | } | ||
| 722 | |||
| 723 | WelsUnloadNalForSlice (pSliceBs); | ||
| 724 | |||
| 725 | iReturn = WriteSliceBs (pEncPEncCtx, pSliceBs, iSliceIdx, iSliceSize); | ||
| 726 | if (ENC_RETURN_SUCCESS != iReturn) { | ||
| 727 | uiThrdRet = iReturn; | ||
| 728 | WelsLog (&pEncPEncCtx->sLogCtx, WELS_LOG_WARNING, | ||
| 729 | "[MT] CodingSliceThreadProc, WriteSliceBs not successful: coding_idx %d, iSliceIdx %d, BufferSize %d, m_iSliceSize %d, iPayloadSize %d", | ||
| 730 | pParamInternal->iCodingIndex, | ||
| 731 | iSliceIdx, pSliceBs->uiSize, iSliceSize, pSliceBs->sNalList[0].iPayloadSize); | ||
| 732 | |||
| 733 | WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, | ||
| 734 | pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, | ||
| 735 | iEventIdx); | ||
| 736 | } | ||
| 737 | |||
| 738 | pEncPEncCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (pCurDq, pEncPEncCtx->pFuncList, pSlice); | ||
| 739 | |||
| 740 | #if defined(SLICE_INFO_OUTPUT) | ||
| 741 | fprintf (stderr, | ||
| 742 | "@pSlice=%-6d sliceType:%c idc:%d size:%-6d\n", | ||
| 743 | iSliceIdx, | ||
| 744 | (pEncPEncCtx->eSliceType == P_SLICE ? 'P' : 'I'), | ||
| 745 | eNalRefIdc, | ||
| 746 | iSliceSize | ||
| 747 | ); | ||
| 748 | #endif//SLICE_INFO_OUTPUT | ||
| 749 | |||
| 750 | MT_TRACE_LOG (&(pEncPEncCtx->sLogCtx), WELS_LOG_INFO, | ||
| 751 | "[MT] CodingSliceThreadProc(), coding_idx %d, iPartitionId %d, iSliceIdx %d, iSliceSize %d, count_mb_slice %d, iEndMbInPartition %d, pCurDq->LastCodedMbIdxOfPartition[%d] %d\n", | ||
| 752 | pEncPEncCtx->iCodingIndex, kiPartitionId, iSliceIdx, iSliceSize, | ||
| 753 | pSlice->iCountMbNumInSlice, | ||
| 754 | kiEndMbIdxInPartition, kiPartitionId, pCurDq->LastCodedMbIdxOfPartition[kiPartitionId]); | ||
| 755 | |||
| 756 | iAnyMbLeftInPartition = kiEndMbIdxInPartition - pCurDq->LastCodedMbIdxOfPartition[kiPartitionId]; | ||
| 757 | iSliceIdx += kiSliceIdxStep; | ||
| 758 | } | ||
| 759 | |||
| 760 | if (uiThrdRet) { // any exception?? | ||
| 761 | WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, | ||
| 762 | pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, | ||
| 763 | iEventIdx); | ||
| 764 | } | ||
| 765 | |||
| 766 | WelsEventSignal (&pEncPEncCtx->pSliceThreading->pSliceCodedEvent[iEventIdx]); // mean finished coding current pSlice | ||
| 767 | WelsEventSignal (&pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent); | ||
| 768 | } | ||
| 769 | } else if (WELS_THREAD_ERROR_WAIT_OBJECT_0 + 1 == iWaitRet) { // exit thread signal | ||
| 770 | uiThrdRet = 0; | ||
| 771 | break; | ||
| 772 | } else if (WELS_THREAD_ERROR_WAIT_OBJECT_0 + 2 == iWaitRet) { // update pMb list singal | ||
| 773 | iSliceIdx = | ||
| 774 | iEventIdx; // pPrivateData->iSliceIndex; old threads can not be terminated, pPrivateData is not correct for applicable | ||
| 775 | pCurDq = pEncPEncCtx->pCurDqLayer; | ||
| 776 | UpdateMbListNeighborParallel (pCurDq, pCurDq->sMbDataP, iSliceIdx); | ||
| 777 | WelsEventSignal ( | ||
| 778 | &pEncPEncCtx->pSliceThreading->pFinUpdateMbListEvent[iEventIdx]); // mean finished update pMb list for this pSlice | ||
| 779 | } else { // WELS_THREAD_ERROR_WAIT_TIMEOUT, or WELS_THREAD_ERROR_WAIT_FAILED | ||
| 780 | WelsLog (& (pEncPEncCtx->sLogCtx), WELS_LOG_WARNING, | ||
| 781 | "[MT] CodingSliceThreadProc(), waiting pReadySliceCodingEvent[%d] failed(%d) and thread%d terminated!", iEventIdx, | ||
| 782 | iWaitRet, iThreadIdx); | ||
| 783 | uiThrdRet = 1; | ||
| 784 | break; | ||
| 785 | } | ||
| 786 | } while (1); | ||
| 787 | |||
| 788 | //sync multi-threading error | ||
| 789 | WelsMutexLock (&pEncPEncCtx->mutexEncoderError); | ||
| 790 | if (uiThrdRet) pEncPEncCtx->iEncoderError |= uiThrdRet; | ||
| 791 | WelsMutexUnlock (&pEncPEncCtx->mutexEncoderError); | ||
| 792 | |||
| 793 | WELS_THREAD_ROUTINE_RETURN (uiThrdRet); | ||
| 794 | } | ||
| 795 | |||
| 796 | int32_t CreateSliceThreads (sWelsEncCtx* pCtx) { | ||
| 797 | const int32_t kiThreadCount = pCtx->pSvcParam->iMultipleThreadIdc; | ||
| 798 | int32_t iIdx = 0; | ||
| 799 | |||
| 800 | while (iIdx < kiThreadCount) { | ||
| 801 | if (WelsThreadCreate (&pCtx->pSliceThreading->pThreadHandles[iIdx], CodingSliceThreadProc, | ||
| 802 | &pCtx->pSliceThreading->pThreadPEncCtx[iIdx], 0)) { | ||
| 803 | return 1; | ||
| 804 | } | ||
| 805 | |||
| 806 | |||
| 807 | ++ iIdx; | ||
| 808 | } | ||
| 809 | MT_TRACE_LOG (& (pCtx->sLogCtx), WELS_LOG_INFO, "CreateSliceThreads() exit.."); | ||
| 810 | return 0; | ||
| 811 | } | ||
| 812 | |||
| 813 | int32_t FiredSliceThreads (sWelsEncCtx* pCtx, SSliceThreadPrivateData* pPriData, WELS_EVENT* pEventsList, | ||
| 814 | WELS_EVENT* pMasterEventsList, SFrameBSInfo* pFrameBsInfo, | ||
| 815 | const uint32_t uiNumThreads) { | ||
| 816 | int32_t iIdx = 0; | ||
| 817 | const int32_t kiEventCnt = uiNumThreads; | ||
| 818 | int32_t iLayerBsIdx = pCtx->pOut->iLayerBsIndex; | ||
| 819 | SLayerBSInfo* pLbi = &pFrameBsInfo->sLayerInfo[iLayerBsIdx]; | ||
| 820 | |||
| 821 | if (pPriData == NULL || pFrameBsInfo == NULL || pLbi == NULL || kiEventCnt <= 0 || pEventsList == NULL) { | ||
| 822 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, | ||
| 823 | "FiredSliceThreads(), fail due pPriData == %p ||pFrameBsInfo == %p || pLbi == %p || iEventCnt(%d) <= 0 || pEventsList == %p!!", | ||
| 824 | (void*)pPriData, (void*)pFrameBsInfo, (void*)pLbi, uiNumThreads, (void*)pEventsList); | ||
| 825 | return 1; | ||
| 826 | } | ||
| 827 | |||
| 828 | pLbi->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer; | ||
| 829 | pLbi->uiLayerType = VIDEO_CODING_LAYER; | ||
| 830 | pLbi->uiSpatialId = pCtx->uiDependencyId; | ||
| 831 | pLbi->uiTemporalId = pCtx->uiTemporalId; | ||
| 832 | pLbi->uiQualityId = 0; | ||
| 833 | pLbi->iNalCount = 0; | ||
| 834 | |||
| 835 | iIdx = 0; | ||
| 836 | while (iIdx < kiEventCnt) { | ||
| 837 | pPriData[iIdx].pFrameBsInfo = pFrameBsInfo; | ||
| 838 | pPriData[iIdx].iSliceIndex = iIdx; | ||
| 839 | |||
| 840 | WelsEventSignal (&pEventsList[iIdx]); | ||
| 841 | WelsEventSignal (&pMasterEventsList[iIdx]); | ||
| 842 | |||
| 843 | ++ iIdx; | ||
| 844 | } | ||
| 845 | |||
| 846 | return 0; | ||
| 847 | } | ||
| 848 | |||
| 849 | int32_t DynamicDetectCpuCores() { | 496 | int32_t DynamicDetectCpuCores() { |
| 850 | WelsLogicalProcessInfo info; | 497 | WelsLogicalProcessInfo info; |
| 851 | WelsQueryLogicalProcessInfo (&info); | 498 | WelsQueryLogicalProcessInfo (&info); |