This avoids using a separate thread for handling pUpdateMbListEvent events, and later allowing using the encode exit event on unix instead of pthread cancellation.
Showing the changes to codec/encoder/core/src/slice_multi_threading.cpp (1 of 4 files). Show all
Unified · Split
| @@ -275,6 +275,7 @@ void DynamicAdjustSlicing (sWelsEncCtx* pCtx, · 274 unmodified lines | |||
| 275 | int32_t iThreadIdx = 0; | 275 | int32_t iThreadIdx = 0; |
| 276 | do { | 276 | do { |
| 277 | WelsEventSignal (&pCtx->pSliceThreading->pUpdateMbListEvent[iThreadIdx]); | 277 | WelsEventSignal (&pCtx->pSliceThreading->pUpdateMbListEvent[iThreadIdx]); |
| 278 | WelsEventSignal (&pCtx->pSliceThreading->pThreadMasterEvent[iThreadIdx]); | ||
| 278 | ++ iThreadIdx; | 279 | ++ iThreadIdx; |
| 279 | } while (iThreadIdx < kiThreadNum); | 280 | } while (iThreadIdx < kiThreadNum); |
| 280 | 281 | ||
| @@ -365,10 +366,13 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara · 84 unmodified lines | |||
| 365 | WelsSnprintf (name, SEM_NAME_MAX, "fs%d%s", iIdx, pSmt->eventNamespace); | 366 | WelsSnprintf (name, SEM_NAME_MAX, "fs%d%s", iIdx, pSmt->eventNamespace); |
| 366 | err = WelsEventOpen (&pSmt->pFinSliceCodingEvent[iIdx], name); | 367 | err = WelsEventOpen (&pSmt->pFinSliceCodingEvent[iIdx], name); |
| 367 | MT_TRACE_LOG ((*ppCtx), WELS_LOG_INFO, "[MT] Open pFinSliceCodingEvent%d named(%s) ret%d err%d\n", iIdx, name, err, errno); | 368 | MT_TRACE_LOG ((*ppCtx), WELS_LOG_INFO, "[MT] Open pFinSliceCodingEvent%d named(%s) ret%d err%d\n", iIdx, name, err, errno); |
| 369 | #endif//_WIN32 | ||
| 368 | WelsSnprintf (name, SEM_NAME_MAX, "ee%d%s", iIdx, pSmt->eventNamespace); | 370 | WelsSnprintf (name, SEM_NAME_MAX, "ee%d%s", iIdx, pSmt->eventNamespace); |
| 369 | err = WelsEventOpen (&pSmt->pExitEncodeEvent[iIdx], name); | 371 | err = WelsEventOpen (&pSmt->pExitEncodeEvent[iIdx], name); |
| 370 | MT_TRACE_LOG ((*ppCtx), WELS_LOG_INFO, "[MT] Open pExitEncodeEvent%d named(%s) ret%d err%d\n", iIdx, name, err, errno); | 372 | MT_TRACE_LOG ((*ppCtx), WELS_LOG_INFO, "[MT] Open pExitEncodeEvent%d named(%s) ret%d err%d\n", iIdx, name, err, errno); |
| 371 | #endif//_WIN32 | 373 | WelsSnprintf (name, SEM_NAME_MAX, "tm%d%s", iIdx, pSmt->eventNamespace); |
| 374 | err = WelsEventOpen (&pSmt->pThreadMasterEvent[iIdx], name); | ||
| 375 | MT_TRACE_LOG ((*ppCtx), WELS_LOG_INFO, "[MT] Open pThreadMasterEvent%d named(%s) ret%d err%d\n", iIdx, name, err, errno); | ||
| 372 | // length of semaphore name should be system constrained at least on mac 10.7 | 376 | // length of semaphore name should be system constrained at least on mac 10.7 |
| 373 | WelsSnprintf (name, SEM_NAME_MAX, "ud%d%s", iIdx, pSmt->eventNamespace); | 377 | WelsSnprintf (name, SEM_NAME_MAX, "ud%d%s", iIdx, pSmt->eventNamespace); |
| 374 | err = WelsEventOpen (&pSmt->pUpdateMbListEvent[iIdx], name); | 378 | err = WelsEventOpen (&pSmt->pUpdateMbListEvent[iIdx], name); |
| @@ -458,9 +462,11 @@ void ReleaseMtResource (sWelsEncCtx** ppCtx) { · 83 unmodified lines | |||
| 458 | 462 | ||
| 459 | WelsSnprintf (ename, SEM_NAME_MAX, "fs%d%s", iIdx, pSmt->eventNamespace); | 463 | WelsSnprintf (ename, SEM_NAME_MAX, "fs%d%s", iIdx, pSmt->eventNamespace); |
| 460 | WelsEventClose (&pSmt->pFinSliceCodingEvent[iIdx], ename); | 464 | WelsEventClose (&pSmt->pFinSliceCodingEvent[iIdx], ename); |
| 465 | #endif//_WIN32 | ||
| 461 | WelsSnprintf (ename, SEM_NAME_MAX, "ee%d%s", iIdx, pSmt->eventNamespace); | 466 | WelsSnprintf (ename, SEM_NAME_MAX, "ee%d%s", iIdx, pSmt->eventNamespace); |
| 462 | WelsEventClose (&pSmt->pExitEncodeEvent[iIdx], ename); | 467 | WelsEventClose (&pSmt->pExitEncodeEvent[iIdx], ename); |
| 463 | #endif//_WIN32 | 468 | WelsSnprintf (ename, SEM_NAME_MAX, "tm%d%s", iIdx, pSmt->eventNamespace); |
| 469 | WelsEventClose (&pSmt->pThreadMasterEvent[iIdx], ename); | ||
| 464 | WelsSnprintf (ename, SEM_NAME_MAX, "sc%d%s", iIdx, pSmt->eventNamespace); | 470 | WelsSnprintf (ename, SEM_NAME_MAX, "sc%d%s", iIdx, pSmt->eventNamespace); |
| 465 | WelsEventClose (&pSmt->pSliceCodedEvent[iIdx], ename); | 471 | WelsEventClose (&pSmt->pSliceCodedEvent[iIdx], ename); |
| 466 | WelsSnprintf (ename, SEM_NAME_MAX, "rc%d%s", iIdx, pSmt->eventNamespace); | 472 | WelsSnprintf (ename, SEM_NAME_MAX, "rc%d%s", iIdx, pSmt->eventNamespace); |
| @@ -676,45 +682,6 @@ int32_t WriteSliceBs (sWelsEncCtx* pCtx, uint8_t* pSliceBsBuf, const int32_t iSl · 209 unmodified lines | |||
| 676 | return iReturn; | 682 | return iReturn; |
| 677 | } | 683 | } |
| 678 | 684 | ||
| 679 | #if !defined(_WIN32) | ||
| 680 | WELS_THREAD_ROUTINE_TYPE UpdateMbListThreadProc (void* arg) { | ||
| 681 | SSliceThreadPrivateData* pPrivateData = (SSliceThreadPrivateData*)arg; | ||
| 682 | sWelsEncCtx* pEncPEncCtx = NULL; | ||
| 683 | SDqLayer* pCurDq = NULL; | ||
| 684 | int32_t iSliceIdx = -1; | ||
| 685 | int32_t iEventIdx = -1; | ||
| 686 | WELS_THREAD_ERROR_CODE iWaitRet = WELS_THREAD_ERROR_GENERAL; | ||
| 687 | uint32_t uiThrdRet = 0; | ||
| 688 | |||
| 689 | if (NULL == pPrivateData) | ||
| 690 | WELS_THREAD_ROUTINE_RETURN (1); | ||
| 691 | |||
| 692 | pEncPEncCtx = (sWelsEncCtx*)pPrivateData->pWelsPEncCtx; | ||
| 693 | iSliceIdx = pPrivateData->iSliceIndex; | ||
| 694 | iEventIdx = pPrivateData->iThreadIndex; | ||
| 695 | |||
| 696 | do { | ||
| 697 | MT_TRACE_LOG (pEncPEncCtx, WELS_LOG_INFO, "[MT] UpdateMbListThreadProc(), try to wait (pUpdateMbListEvent[%d])!\n", | ||
| 698 | iEventIdx); | ||
| 699 | iWaitRet = WelsEventWait (&pEncPEncCtx->pSliceThreading->pUpdateMbListEvent[iEventIdx]); | ||
| 700 | if (WELS_THREAD_ERROR_WAIT_OBJECT_0 == iWaitRet) { | ||
| 701 | pCurDq = pEncPEncCtx->pCurDqLayer; | ||
| 702 | UpdateMbListNeighborParallel (pCurDq->pSliceEncCtx, pCurDq->sMbDataP, iSliceIdx); | ||
| 703 | WelsEventSignal ( | ||
| 704 | &pEncPEncCtx->pSliceThreading->pFinUpdateMbListEvent[iEventIdx]); // mean finished update pMb list for this pSlice | ||
| 705 | } else { | ||
| 706 | WelsLog (pEncPEncCtx, WELS_LOG_WARNING, | ||
| 707 | "[MT] UpdateMbListThreadProc(), waiting pUpdateMbListEvent[%d] failed(%d) and thread%d terminated!\n", iEventIdx, | ||
| 708 | iWaitRet, iEventIdx); | ||
| 709 | uiThrdRet = 1; | ||
| 710 | break; | ||
| 711 | } | ||
| 712 | } while (1); | ||
| 713 | |||
| 714 | WELS_THREAD_ROUTINE_RETURN (uiThrdRet); | ||
| 715 | } | ||
| 716 | #endif//!_WIN32 | ||
| 717 | |||
| 718 | // thread process for coding one pSlice | 685 | // thread process for coding one pSlice |
| 719 | WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) { | 686 | WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) { |
| 720 | SSliceThreadPrivateData* pPrivateData = (SSliceThreadPrivateData*)arg; | 687 | SSliceThreadPrivateData* pPrivateData = (SSliceThreadPrivateData*)arg; |
| @@ -722,10 +689,8 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) { · 1 unmodified line | |||
| 722 | SDqLayer* pCurDq = NULL; | 689 | SDqLayer* pCurDq = NULL; |
| 723 | SSlice* pSlice = NULL; | 690 | SSlice* pSlice = NULL; |
| 724 | SWelsSliceBs* pSliceBs = NULL; | 691 | SWelsSliceBs* pSliceBs = NULL; |
| 725 | #ifdef _WIN32 | ||
| 726 | WELS_EVENT pEventsList[3]; | 692 | WELS_EVENT pEventsList[3]; |
| 727 | int32_t iEventCount = 0; | 693 | int32_t iEventCount = 0; |
| 728 | #endif | ||
| 729 | WELS_THREAD_ERROR_CODE iWaitRet = WELS_THREAD_ERROR_GENERAL; | 694 | WELS_THREAD_ERROR_CODE iWaitRet = WELS_THREAD_ERROR_GENERAL; |
| 730 | uint32_t uiThrdRet = 0; | 695 | uint32_t uiThrdRet = 0; |
| 731 | int32_t iSliceSize = 0; | 696 | int32_t iSliceSize = 0; |
| @@ -747,22 +712,16 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) { · 15 unmodified lines | |||
| 747 | iThreadIdx = pPrivateData->iThreadIndex; | 712 | iThreadIdx = pPrivateData->iThreadIndex; |
| 748 | iEventIdx = iThreadIdx; | 713 | iEventIdx = iThreadIdx; |
| 749 | 714 | ||
| 750 | #ifdef _WIN32 | ||
| 751 | pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pReadySliceCodingEvent[iEventIdx]; | 715 | pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pReadySliceCodingEvent[iEventIdx]; |
| 752 | pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pExitEncodeEvent[iEventIdx]; | 716 | pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pExitEncodeEvent[iEventIdx]; |
| 753 | pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pUpdateMbListEvent[iEventIdx]; | 717 | pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pUpdateMbListEvent[iEventIdx]; |
| 754 | #endif//_WIN32 | ||
| 755 | 718 | ||
| 756 | do { | 719 | do { |
| 757 | #ifdef _WIN32 | ||
| 758 | iWaitRet = WelsMultipleEventsWaitSingleBlocking (iEventCount, | ||
| 759 | &pEventsList[0]); // blocking until at least one event is | ||
| 760 | #else | ||
| 761 | MT_TRACE_LOG (pEncPEncCtx, WELS_LOG_INFO, | 720 | MT_TRACE_LOG (pEncPEncCtx, WELS_LOG_INFO, |
| 762 | "[MT] CodingSliceThreadProc(), try to call WelsEventWait(pReadySliceCodingEvent[%d]= 0x%p), pEncPEncCtx= 0x%p!\n", | 721 | "[MT] CodingSliceThreadProc(), try to call WelsMultipleEventsWaitSingleBlocking(pEventsList= %p %p %p), pEncPEncCtx= %p!\n", |
| 763 | iEventIdx, (void*) (pEncPEncCtx->pSliceThreading->pReadySliceCodingEvent[iEventIdx]), (void*)pEncPEncCtx); | 722 | pEventsList[0], pEventsList[1], pEventsList[1], (void*)pEncPEncCtx); |
| 764 | iWaitRet = WelsEventWait (&pEncPEncCtx->pSliceThreading->pReadySliceCodingEvent[iEventIdx]); | 723 | iWaitRet = WelsMultipleEventsWaitSingleBlocking (iEventCount, |
| 765 | #endif//WIN32 | 724 | &pEventsList[0], &pEncPEncCtx->pSliceThreading->pThreadMasterEvent[iEventIdx]); // blocking until at least one event is signalled |
| 766 | if (WELS_THREAD_ERROR_WAIT_OBJECT_0 == iWaitRet) { // start pSlice coding signal waited | 725 | if (WELS_THREAD_ERROR_WAIT_OBJECT_0 == iWaitRet) { // start pSlice coding signal waited |
| 767 | SLayerBSInfo* pLbi = pPrivateData->pLayerBs; | 726 | SLayerBSInfo* pLbi = pPrivateData->pLayerBs; |
| 768 | const int32_t kiCurDid = pEncPEncCtx->uiDependencyId; | 727 | const int32_t kiCurDid = pEncPEncCtx->uiDependencyId; |
| @@ -979,7 +938,6 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) { · 210 unmodified lines | |||
| 979 | WelsEventSignal (&pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent); | 938 | WelsEventSignal (&pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent); |
| 980 | } | 939 | } |
| 981 | } | 940 | } |
| 982 | #ifdef _WIN32 | ||
| 983 | else if (WELS_THREAD_ERROR_WAIT_OBJECT_0 + 1 == iWaitRet) { // exit thread signal | 941 | else if (WELS_THREAD_ERROR_WAIT_OBJECT_0 + 1 == iWaitRet) { // exit thread signal |
| 984 | uiThrdRet = 0; | 942 | uiThrdRet = 0; |
| 985 | break; | 943 | break; |
| @@ -992,7 +950,6 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) { · 6 unmodified lines | |||
| 992 | WelsEventSignal ( | 950 | WelsEventSignal ( |
| 993 | &pEncPEncCtx->pSliceThreading->pFinUpdateMbListEvent[iEventIdx]); // mean finished update pMb list for this pSlice | 951 | &pEncPEncCtx->pSliceThreading->pFinUpdateMbListEvent[iEventIdx]); // mean finished update pMb list for this pSlice |
| 994 | } | 952 | } |
| 995 | #endif//WIN32 | ||
| 996 | else { // WELS_THREAD_ERROR_WAIT_TIMEOUT, or WELS_THREAD_ERROR_WAIT_FAILED | 953 | else { // WELS_THREAD_ERROR_WAIT_TIMEOUT, or WELS_THREAD_ERROR_WAIT_FAILED |
| 997 | WelsLog (pEncPEncCtx, WELS_LOG_WARNING, | 954 | WelsLog (pEncPEncCtx, WELS_LOG_WARNING, |
| 998 | "[MT] CodingSliceThreadProc(), waiting pReadySliceCodingEvent[%d] failed(%d) and thread%d terminated!\n", iEventIdx, | 955 | "[MT] CodingSliceThreadProc(), waiting pReadySliceCodingEvent[%d] failed(%d) and thread%d terminated!\n", iEventIdx, |
| @@ -1040,13 +997,6 @@ int32_t CreateSliceThreads (sWelsEncCtx* pCtx) { · 41 unmodified lines | |||
| 1040 | } | 997 | } |
| 1041 | } | 998 | } |
| 1042 | #endif//WIN32 && BIND_CPU_CORES_TO_THREADS | 999 | #endif//WIN32 && BIND_CPU_CORES_TO_THREADS |
| 1043 | // We need extra threads for update_mb_list_proc on __GNUC__ like OS (mac/linux) | ||
| 1044 | // due to WelsMultipleEventsWaitSingleBlocking implememtation can not work well | ||
| 1045 | // in case waiting pUpdateMbListEvent and pReadySliceCodingEvent events at the same time | ||
| 1046 | #if !defined(_WIN32) | ||
| 1047 | WelsThreadCreate (&pCtx->pSliceThreading->pUpdateMbListThrdHandles[iIdx], UpdateMbListThreadProc, | ||
| 1048 | &pCtx->pSliceThreading->pThreadPEncCtx[iIdx], 0); | ||
| 1049 | #endif//!_WIN32 | ||
| 1050 | 1000 | ||
| 1051 | ++ iIdx; | 1001 | ++ iIdx; |
| 1052 | } | 1002 | } |
| @@ -1054,7 +1004,7 @@ int32_t CreateSliceThreads (sWelsEncCtx* pCtx) { · 1 unmodified line | |||
| 1054 | return 0; | 1004 | return 0; |
| 1055 | } | 1005 | } |
| 1056 | 1006 | ||
| 1057 | int32_t FiredSliceThreads (SSliceThreadPrivateData* pPriData, WELS_EVENT* pEventsList, SLayerBSInfo* pLbi, | 1007 | int32_t FiredSliceThreads (SSliceThreadPrivateData* pPriData, WELS_EVENT* pEventsList, WELS_EVENT* pMasterEventsList, SLayerBSInfo* pLbi, |
| 1058 | const uint32_t uiNumThreads, SSliceCtx* pSliceCtx, const bool bIsDynamicSlicingMode) | 1008 | const uint32_t uiNumThreads, SSliceCtx* pSliceCtx, const bool bIsDynamicSlicingMode) |
| 1059 | { | 1009 | { |
| 1060 | int32_t iEndMbIdx = 0; | 1010 | int32_t iEndMbIdx = 0; |
| @@ -1085,6 +1035,8 @@ int32_t FiredSliceThreads (SSliceThreadPrivateData* pPriData, WELS_EVENT* pEvent · 24 unmodified lines | |||
| 1085 | pPriData[iIdx].iSliceIndex = iIdx; | 1035 | pPriData[iIdx].iSliceIndex = iIdx; |
| 1086 | if (pEventsList[iIdx]) | 1036 | if (pEventsList[iIdx]) |
| 1087 | WelsEventSignal (&pEventsList[iIdx]); | 1037 | WelsEventSignal (&pEventsList[iIdx]); |
| 1038 | if (pMasterEventsList[iIdx]) | ||
| 1039 | WelsEventSignal (&pMasterEventsList[iIdx]); | ||
| 1088 | ++ iIdx; | 1040 | ++ iIdx; |
| 1089 | } | 1041 | } |
| 1090 | 1042 | ||