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 | 70 | #define MT_TRACE_LOG(x, ...) |
| 71 | 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 | 73 | namespace WelsEnc { |
| 80 | 74 | void UpdateMbListNeighborParallel (SDqLayer* pCurDq, |
| 81 | 75 | SMB* pMbList, |
| @@ -314,12 +308,6 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara · 232 unmodified lines | ||
| 314 | 308 | pSmt->pThreadPEncCtx[iIdx].iThreadIndex = iIdx; |
| 315 | 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 | 311 | // length of semaphore name should be system constrained at least on mac 10.7 |
| 324 | 312 | WelsSnprintf (name, SEM_NAME_MAX, "ud%d%s", iIdx, pSmt->eventNamespace); |
| 325 | 313 | err = WelsEventOpen (&pSmt->pUpdateMbListEvent[iIdx], name); |
| @@ -391,10 +379,6 @@ void ReleaseMtResource (sWelsEncCtx** ppCtx) { · 65 unmodified lines | ||
| 391 | 379 | char ename[SEM_NAME_MAX] = {0}; |
| 392 | 380 | while (iIdx < iThreadNum) { |
| 393 | 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 | 382 | WelsSnprintf (ename, SEM_NAME_MAX, "sc%d%s", iIdx, pSmt->eventNamespace); |
| 399 | 383 | WelsEventClose (&pSmt->pSliceCodedEvent[iIdx], ename); |
| 400 | 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 | 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 | 496 | int32_t DynamicDetectCpuCores() { |
| 850 | 497 | WelsLogicalProcessInfo info; |
| 851 | 498 | WelsQueryLogicalProcessInfo (&info); |