📄 umc_h264_deblocking_tools.cpp
字号:
/*//// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright (c) 2003-2005 Intel Corporation. All Rights Reserved.////*/#include "umc_h264_deblocking_tools.h"#include "umc_h264_dec.h"namespace UMC{H264ThreadedDeblockingTools::H264ThreadedDeblockingTools(void){ vm_thread_set_invalid(&m_hDeblockingSliceSecondThread); vm_thread_set_invalid(&m_hDeblockingSliceAsyncSecondThread); vm_event_set_invalid(&m_hBeginFrame); vm_event_set_invalid(&m_hBeginSlice); vm_event_set_invalid(&m_hBeginRow); vm_event_set_invalid(&m_hDoneBorder); vm_event_set_invalid(&m_hDoneRow); vm_event_set_invalid(&m_hDoneSlice); m_bQuit = false;} // H264ThreadedDeblockingTools::H264ThreadedDeblockingTools(void)H264ThreadedDeblockingTools::~H264ThreadedDeblockingTools(void){ Release();} // H264ThreadedDeblockingTools::~H264ThreadedDeblockingTools(void)void H264ThreadedDeblockingTools::Release(void){ // terminate second thread(s) if (vm_thread_is_valid(&m_hDeblockingSliceSecondThread)) { m_bQuit = true; vm_event_signal(&m_hBeginRow); vm_thread_wait(&m_hDeblockingSliceSecondThread); vm_thread_close(&m_hDeblockingSliceSecondThread); } if (vm_thread_is_valid(&m_hDeblockingSliceAsyncSecondThread)) { m_bQuit = true; vm_event_signal(&m_hBeginSlice); vm_thread_wait(&m_hDeblockingSliceAsyncSecondThread); vm_thread_close(&m_hDeblockingSliceAsyncSecondThread); } // destroy objects if (vm_event_is_valid(&m_hBeginFrame)) vm_event_destroy(&m_hBeginFrame); if (vm_event_is_valid(&m_hBeginSlice)) vm_event_destroy(&m_hBeginSlice); if (vm_event_is_valid(&m_hBeginRow)) vm_event_destroy(&m_hBeginRow); if (vm_event_is_valid(&m_hDoneBorder)) vm_event_destroy(&m_hDoneBorder); if (vm_event_is_valid(&m_hDoneRow)) vm_event_destroy(&m_hDoneRow); if (vm_event_is_valid(&m_hDoneSlice)) vm_event_destroy(&m_hDoneSlice); vm_thread_set_invalid(&m_hDeblockingSliceSecondThread); vm_thread_set_invalid(&m_hDeblockingSliceAsyncSecondThread); vm_event_set_invalid(&m_hBeginFrame); vm_event_set_invalid(&m_hBeginSlice); vm_event_set_invalid(&m_hBeginRow); vm_event_set_invalid(&m_hDoneBorder); vm_event_set_invalid(&m_hDoneRow); vm_event_set_invalid(&m_hDoneSlice); m_bQuit = false;} // void H264ThreadedDeblockingTools::Release(void)Status H264ThreadedDeblockingTools::Initialize(H264VideoDecoder *pDecoder){ vm_status res; // release object before initialization Release(); // save pointer m_pDecoder = pDecoder; // create objects res = vm_event_init(&m_hBeginFrame, 0, 0); if (VM_OK != res) return UMC_FAILED_TO_INITIALIZE; res = vm_event_init(&m_hBeginSlice, 0, 0); if (VM_OK != res) return UMC_FAILED_TO_INITIALIZE; res = vm_event_init(&m_hBeginRow, 0, 0); if (VM_OK != res) return UMC_FAILED_TO_INITIALIZE; res = vm_event_init(&m_hDoneBorder, 0, 0); if (VM_OK != res) return UMC_FAILED_TO_INITIALIZE; res = vm_event_init(&m_hDoneRow, 0, 0); if (VM_OK != res) return UMC_FAILED_TO_INITIALIZE; res = vm_event_init(&m_hDoneSlice, 0, 1); if (VM_OK != res) return UMC_FAILED_TO_INITIALIZE; // run second thread(s) { int res; res = vm_thread_create(&m_hDeblockingSliceSecondThread, DeblockSliceSecondThread, this); if (0 == res) return UMC_FAILED_TO_INITIALIZE; res = vm_thread_create(&m_hDeblockingSliceAsyncSecondThread, DeblockSliceAsyncSecondThread, this); if (0 == res) return UMC_FAILED_TO_INITIALIZE; } return UMC_OK;} // Status H264ThreadedDeblockingTools::Initialize(H264VideoDecoder *pDecoder)void H264ThreadedDeblockingTools::DeblockSliceTwoThreaded(Ipp32u uFirstMB, Ipp32u unumMBs, H264VideoDecoder::DeblockingFunction pDeblocking){ Ipp32u mb_width = m_pDecoder->mb_width << m_nMBAFF; Ipp32u nBorder = (mb_width / 2) & (~m_nMBAFF); Ipp32u i, nCurrMB, nMaxMB; // reset border signal to avoid complex logic vm_event_reset(&m_hDoneBorder); // set maximum MB number nMaxMB = uFirstMB + unumMBs; // deblock blocks in first row before border nCurrMB = uFirstMB; for (i = uFirstMB % mb_width;(i < nBorder) && (nCurrMB < nMaxMB);i += 1, nCurrMB += 1) (m_pDecoder->*(pDeblocking))(nCurrMB); if (nCurrMB < nMaxMB) { // fill thread interaction parameters m_nFirstMB = nCurrMB; m_nNumMB = nMaxMB - nCurrMB; m_pDeblocking = pDeblocking; // send signal to second thread vm_event_signal(&m_hBeginRow); // align macroblock number to new line nCurrMB += mb_width - nCurrMB % mb_width; while (nCurrMB < nMaxMB) { // deblock row up to border macroblock(s) for (i = 0;(i < (nBorder - 1 - m_nMBAFF)) && (nCurrMB < nMaxMB);i += 1, nCurrMB += 1) (m_pDecoder->*(pDeblocking))(nCurrMB); // wait response from second thread vm_event_wait(&m_hDoneBorder); if (nCurrMB < nMaxMB) { // deblock border macroblock(s) for (;(i < (nBorder)) && (nCurrMB < nMaxMB);i += 1, nCurrMB += 1) (m_pDecoder->*(pDeblocking))(nCurrMB); // send signal to second thread if (nCurrMB < nMaxMB) vm_event_signal(&m_hBeginRow); nCurrMB += mb_width - nBorder; } } // wait for second thread vm_event_wait(&m_hDoneRow); } // set event of slice is done vm_event_signal(&m_hDoneSlice);} // void H264ThreadedDeblockingTools::DeblockSliceTwoThreaded(Ipp32u uFirstMB, Ipp32u unumMBs, H264VideoDecoder::DeblockingFunction pDeblocking)void H264ThreadedDeblockingTools::DeblockSliceAsync(Ipp32u uFirstMB, Ipp32u unumMBs, H264VideoDecoder::DeblockingFunction pDeblocking){ // fill thread interaction parameters m_nFirstMB = uFirstMB; m_nNumMB = unumMBs; m_pDeblocking = pDeblocking; vm_event_signal(&m_hBeginSlice);} // void H264ThreadedDeblockingTools::DeblockSliceAsync(Ipp32u uFirstMB, Ipp32u unumMBs, H264VideoDecoder::DeblockingFunction pDeblocking)void H264ThreadedDeblockingTools::WaitEndOfSlice(void){ vm_event_wait(&m_hDoneSlice);} // void H264ThreadedDeblockingTools::WaitEndOfSlice(void)unsigned int H264ThreadedDeblockingTools::DeblockSliceSecondThread(void *p){ H264ThreadedDeblockingTools *pTools = (H264ThreadedDeblockingTools *) p; H264VideoDecoder *pDec; // check error(s) VM_ASSERT(pTools); if (NULL == pTools) return (unsigned int) 0x0bad; pDec = pTools->m_pDecoder; { vm_event *phBeginRow = &(pTools->m_hBeginRow); vm_event *phDoneRow = &(pTools->m_hDoneRow); vm_event *phDoneBorder = &(pTools->m_hDoneBorder); // wait response from main thread vm_event_wait(phBeginRow); // is it exit ? while (false == pTools->m_bQuit) { Ipp32u i, nCurrMB; Ipp32u nMaxMB = pTools->m_nFirstMB + pTools->m_nNumMB; H264VideoDecoder::DeblockingFunction pDeblocking = pTools->m_pDeblocking; Ipp32u mb_width = pDec->mb_width << pTools->m_nMBAFF; Ipp32u nBorder = (mb_width / 2) & (~(pTools->m_nMBAFF)); nCurrMB = pTools->m_nFirstMB; while (nCurrMB < nMaxMB) { // wait response from main thread if (nCurrMB != pTools->m_nFirstMB) vm_event_wait(phBeginRow); // deblock border macroblock(s) if (nCurrMB % mb_width == nBorder) { for (i = 0;i < (1 + pTools->m_nMBAFF);i += 1, nCurrMB += 1) (pDec->*(pDeblocking))(nCurrMB); i = nBorder + 1 + pTools->m_nMBAFF; } else i = nCurrMB % mb_width; // send signal to main thread, even border macroblock wasn't processed vm_event_signal(phDoneBorder); // deblock all macroblock up to end of row for (;(i < mb_width) && (nCurrMB < nMaxMB);i += 1, nCurrMB += 1) (pDec->*(pDeblocking))(nCurrMB); nCurrMB += nBorder; } // send signal to main thread vm_event_signal(phDoneRow); // wait response from main thread vm_event_wait(phBeginRow); } } return 1;} // unsigned int H264ThreadedDeblockingTools::DeblockSliceSecondThread(void *p)unsigned int H264ThreadedDeblockingTools::DeblockSliceAsyncSecondThread(void *p){ H264ThreadedDeblockingTools *pTools = (H264ThreadedDeblockingTools *) p; H264VideoDecoder *pDec; // check error(s) VM_ASSERT(pTools); if (NULL == pTools) return (unsigned int) 0x0bad; pDec = pTools->m_pDecoder; { vm_event *phBeginSlice = &(pTools->m_hBeginSlice); vm_event *phDoneSlice = &(pTools->m_hDoneSlice); // wait response from main thread vm_event_wait(phBeginSlice); // is it exit ? while (false == pTools->m_bQuit) { Ipp32u i; H264VideoDecoder::DeblockingFunction pDeblocking = pTools->m_pDeblocking; Ipp32u nFirstMB = pTools->m_nFirstMB; Ipp32u nNumMB = pTools->m_nNumMB; // deblock macroblocks for (i = nFirstMB; i < nFirstMB + nNumMB; i++) (pDec->*(pDeblocking))(i); // send signal to main thread vm_event_signal(phDoneSlice); // wait response from main thread vm_event_wait(phBeginSlice); } } return 1;} // unsigned int H264ThreadedDeblockingTools::DeblockSliceAsyncSecondThread(void *p)} // namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -