⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_h264_deblocking_tools.cpp

📁 audio-video-codecs.rar语音编解码器
💻 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-2007 Intel Corporation. All Rights Reserved.
//
//
*/

#include "umc_h264_deblocking_tools.h"
#include "umc_h264_video_encoder.h"
#include "umc_h264_core_enc.h"

using namespace UMC;
namespace UMC_H264_ENCODER
{
    template <class PixType, class CoeffsType>
    void H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::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 H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::Release(void)

template <class PixType, class CoeffsType>
Status H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::Initialize(H264CoreEncoder<PixType, CoeffsType> *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_ERR_INIT;

    res = vm_event_init(&m_hBeginSlice, 0, 0);
    if (VM_OK != res)
        return UMC_ERR_INIT;

    res = vm_event_init(&m_hBeginRow, 0, 0);
    if (VM_OK != res)
        return UMC_ERR_INIT;

    res = vm_event_init(&m_hDoneBorder, 0, 0);
    if (VM_OK != res)
        return UMC_ERR_INIT;

    res = vm_event_init(&m_hDoneRow, 0, 0);
    if (VM_OK != res)
        return UMC_ERR_INIT;

    res = vm_event_init(&m_hDoneSlice, 0, 1);
    if (VM_OK != res)
        return UMC_ERR_INIT;

    // run second thread(s)
    {
        Ipp32s res;

        res = vm_thread_create(&m_hDeblockingSliceSecondThread, DeblockSliceSecondThread, this);
        if (0 == res)
            return UMC_ERR_INIT;

        res = vm_thread_create(&m_hDeblockingSliceAsyncSecondThread, DeblockSliceAsyncSecondThread, this);
        if (0 == res)
            return UMC_ERR_INIT;
    }

    return UMC_OK;

} // Status H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::Initialize(H264CoreEncoder *pDecoder)

template <class PixType, class CoeffsType>
H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::H264EncoderThreadedDeblockingTools (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;

} // H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::H264EncoderThreadedDeblockingTools<PixType, CoeffsType> (void)

template <class PixType, class CoeffsType>
H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::~H264EncoderThreadedDeblockingTools(void)
{
    Release();

} // H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::~H264EncoderThreadedDeblockingTools<PixType, CoeffsType> (void)

template <class PixType, class CoeffsType>
void H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::DeblockSliceTwoThreaded(Ipp32u uFirstMB, Ipp32u unumMBs, typename H264CoreEncoder<PixType,CoeffsType>::DeblockingFunction pDeblocking)
{
    Ipp32u mb_width = m_pDecoder->m_WidthInMBs << 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 H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::DeblockSliceTwoThreaded(Ipp32u uFirstMB, Ipp32u unumMBs, H264CoreEncoder::DeblockingFunction pDeblocking)

template <class PixType, class CoeffsType>
void H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::DeblockSliceAsync(Ipp32u uFirstMB, Ipp32u unumMBs, typename H264CoreEncoder<PixType, CoeffsType>::DeblockingFunction pDeblocking)
{
    // fill thread interaction parameters
    m_nFirstMB = uFirstMB;
    m_nNumMB = unumMBs;
    m_pDeblocking = pDeblocking;
    vm_event_signal(&m_hBeginSlice);

} // void H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::DeblockSliceAsync(Ipp32u uFirstMB, Ipp32u unumMBs, H264CoreEncoder::DeblockingFunction pDeblocking)

template <class PixType, class CoeffsType>
void H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::WaitEndOfSlice(void)
{
    vm_event_wait(&m_hDoneSlice);

} // void H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::WaitEndOfSlice(void)

template <class PixType, class CoeffsType>
Ipp32u VM_THREAD_CALLCONVENTION H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::DeblockSliceSecondThread(void *p)
{
    H264EncoderThreadedDeblockingTools<PixType, CoeffsType>  *pTools = (H264EncoderThreadedDeblockingTools<PixType, CoeffsType>  *) p;
    H264CoreEncoder<PixType, CoeffsType> *pDec;

    // check error(s)
    VM_ASSERT(pTools);
    if (NULL == pTools)
        return 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;
            typename H264CoreEncoder<PixType, CoeffsType>::DeblockingFunction pDeblocking = pTools->m_pDeblocking;
            Ipp32u mb_width = pDec->m_WidthInMBs << 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;

} // Ipp32u VM_THREAD_CALLCONVENTION H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::DeblockSliceSecondThread(void *p)

template <class PixType, class CoeffsType>
Ipp32u H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::DeblockSliceAsyncSecondThread(void *p)
{
    H264EncoderThreadedDeblockingTools<PixType, CoeffsType>  *pTools = (H264EncoderThreadedDeblockingTools<PixType, CoeffsType>  *) p;
    H264CoreEncoder<PixType, CoeffsType> *pDec;

    // check error(s)
    VM_ASSERT(pTools);
    if (NULL == pTools)
        return 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;
            typename H264CoreEncoder<PixType, CoeffsType>::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;

} // Ipp32u H264EncoderThreadedDeblockingTools<PixType, CoeffsType> ::DeblockSliceAsyncSecondThread(void *p)

template class H264EncoderThreadedDeblockingTools<Ipp8u, Ipp16s>;
#if defined BITDEPTH_9_12
template class H264EncoderThreadedDeblockingTools<Ipp16u, Ipp32s>;
#endif // BITDEPTH_9_12

} // namespace UMC_H264_ENCODER

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -