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

📄 umc_h264_task_supplier.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    m_pFirstUncompletedFrame = 0;
    m_pDecodedFramesList = new H264DBPList();
    if (!m_pDecodedFramesList)
        return UMC_ERR_ALLOC;

    if (init->info.stream_subtype == AVC1_VIDEO)
    {
        m_pNALSplitter = new NALUnitSplitterMP4(&m_Heap);
    }
    else
    {
        m_pNALSplitter = new NALUnitSplitter(&m_Heap);
    }

    m_pNALSplitter->Init();



    switch(m_iThreadNum)
    {
    case 1:
        m_pTaskBroker = new TaskBrokerSingleThread(this);
        break;
    case 4:
    case 3:
    case 2:
        m_pTaskBroker = new TaskBrokerTwoThread(this);
        break;
    default:
        m_pTaskBroker = new TaskBrokerTwoThread(this);
        break;
    };

    m_pTaskBroker->Init(m_iThreadNum);


    // create slice decoder(s)
    m_pSegmentDecoder = new H264SegmentDecoderMultiThreaded *[m_iThreadNum];
    if (NULL == m_pSegmentDecoder)
        return UMC_ERR_ALLOC;
    memset(m_pSegmentDecoder, 0, sizeof(H264SegmentDecoderMultiThreaded *) * m_iThreadNum);

    Ipp32s i;
    for (i = 0; i < m_iThreadNum; i += 1)
    {
            m_pSegmentDecoder[i] = new H264SegmentDecoderMultiThreaded(m_pTaskBroker);

        if (NULL == m_pSegmentDecoder[i])
            return UMC_ERR_ALLOC;
    }

    for (i = 0; i < m_iThreadNum; i += 1)
    {
        if (UMC_OK != m_pSegmentDecoder[i]->Init(i))
            return UMC_ERR_INIT;
    }

    Ipp32s numberOfBuffers = 2*(m_iThreadNum);
    m_pMBInfo = new H264DecoderLocalMacroblockDescriptor[numberOfBuffers];
    if (NULL == m_pMBInfo)
        return UMC_ERR_ALLOC;

    m_ppMBIntraTypes = (Ipp32u **) ippsMalloc_8u((Ipp32s) (sizeof(Ipp32u *) * numberOfBuffers));
    if (NULL == m_ppMBIntraTypes)
        return UMC_ERR_ALLOC;
    memset(m_ppMBIntraTypes, 0, sizeof(Ipp32u *) * numberOfBuffers);

    // allocate intra MB types array's sizes
    m_piMBIntraProp = (H264IntraTypesProp *) ippsMalloc_8u((Ipp32s) (sizeof(H264IntraTypesProp) * numberOfBuffers));
    if (NULL == m_piMBIntraProp)
        return UMC_ERR_ALLOC;
    memset(m_piMBIntraProp, 0, sizeof(H264IntraTypesProp) * numberOfBuffers);

    m_local_delta_frame_time = 1.0/30;
    m_local_frame_time       = 0;

    if (0 < init->info.framerate)
    {
        m_local_delta_frame_time = 1 / init->info.framerate;
    }

    m_DPBSizeEx = m_iThreadNum + 1;


    return UMC_OK;
}

Status  TaskSupplier::SetParams(BaseCodecParams* params)
{
    VideoDecoderParams *pParams = DynamicCast<VideoDecoderParams>(params);

    if (NULL == pParams)
        return UMC_ERR_NULL_PTR;

    if (pParams->lTrickModesFlag == 7)
    {
        if (ABSOWN(pParams->dPlaybackRate - 1) > 0.0001)
            m_TrickModeSpeed = 2;
        else
            m_TrickModeSpeed = 1;
    }

    return UMC_OK;
}

void TaskSupplier::Close()
{
    Reset();

    if (m_pTaskBroker)
    {
        m_pTaskBroker->Release();
    }

    for (Ipp32s i = 0; i < m_iThreadNum; i += 1)
    {
        delete m_pSegmentDecoder[i];
        m_pSegmentDecoder[i] = 0;
    }

    Ipp32s numberOfBuffers = 2*(m_iThreadNum);

    if (m_ppMBIntraTypes)
    {
        ippsFree(m_ppMBIntraTypes);
        m_ppMBIntraTypes = 0;
    }

    if (m_piMBIntraProp)
    {
        for (Ipp32s i = 0; i < numberOfBuffers; i++)
        {
            if (m_piMBIntraProp[i].m_nSize == 0)
                continue;
            m_pMemoryAllocator->Unlock(m_piMBIntraProp[i].m_mid);
            m_pMemoryAllocator->Free(m_piMBIntraProp[i].m_mid);
        }

        ippsFree(m_piMBIntraProp);
        m_piMBIntraProp = 0;
    }

    delete[] m_pMBInfo;
    m_pMBInfo = 0;

    delete[] m_pSegmentDecoder;
    m_pSegmentDecoder = 0;

    delete m_pTaskBroker;
    m_pTaskBroker = 0;

    DeallocateBuffers();
    m_Headers.Reset();

    delete m_pNALSplitter;
    m_pNALSplitter = 0;

    delete m_pDecodedFramesList;
    m_pDecodedFramesList = 0;
    m_iThreadNum = 0;

    m_bSeqParamSetRead  = false;
    m_bPicParamSetRead  = false;
    m_dpbSize = 1;
    m_DPBSizeEx = 1;
    m_maxDecFrameBuffering = 1;
    m_CurrentSeqParamSet = -1;
    m_CurrentPicParamSet = -1;
}

void TaskSupplier::Reset()
{
    if (m_pTaskBroker)
        m_pTaskBroker->Reset();

    // DEBUG : need to stop threads before and Reset taskBroker
    for (Ipp32s i = 1; i < m_iThreadNum; i += 1)
    {
        m_pSegmentDecoder[i]->Reset();
    }

    if (m_pDecodedFramesList)
    {
        for (H264DecoderFrame *pFrame = m_pDecodedFramesList->head(); pFrame; pFrame = pFrame->future())
        {
            pFrame->Reset();
        }

        m_pDecodedFramesList->removeAllRef();
        m_pDecodedFramesList->removeAllDisplayable();
    }

    if (m_pNALSplitter)
        m_pNALSplitter->Reset();

    m_Headers.Reset(true);
    Skipping::Reset();
    m_SlicesHeap.Release();
    m_Heap.Reset();

    m_local_frame_time         = 0;

    m_field_index       = 0;
    m_WaitForIDR        = true;

    m_pLastDisplayed = 0;
    m_pCurrentFrame = 0;
    m_pFirstUncompletedFrame = 0;
    m_iCurrentResource = 0;

    m_PicOrderCnt = 0;
    m_PicOrderCntMsb = 0;
    m_PicOrderCntLsb = 0;
    m_FrameNum = 0;
    m_PrevFrameRefNum = 0;
    m_FrameNumOffset = 0;
    m_TopFieldPOC = 0;
    m_BottomFieldPOC = 0;

    if (m_pTaskBroker)
        m_pTaskBroker->Init(m_iThreadNum);
}

void TaskSupplier::AfterErrorRestore()
{
    if (m_pTaskBroker)
        m_pTaskBroker->Reset();

    // DEBUG : need to stop threads before and Reset taskBroker
    for (Ipp32s i = 1; i < m_iThreadNum; i += 1)
    {
        m_pSegmentDecoder[i]->Reset();
    }

    if (m_pDecodedFramesList)
    {
        for (H264DecoderFrame *pFrame = m_pDecodedFramesList->head(); pFrame; pFrame = pFrame->future())
        {
            pFrame->Reset();
        }

        m_pDecodedFramesList->removeAllRef();
        m_pDecodedFramesList->removeAllDisplayable();
    }

    if (m_pNALSplitter)
        m_pNALSplitter->Reset();

    m_Headers.Reset(true);
    Skipping::Reset();
    m_SlicesHeap.Release();
    m_Heap.Reset();

    m_field_index       = 0;

    m_pLastDisplayed = 0;
    m_pCurrentFrame = 0;
    m_pFirstUncompletedFrame = 0;
    m_iCurrentResource = 0;

    if (m_pTaskBroker)
        m_pTaskBroker->Init(m_iThreadNum);
}

Status TaskSupplier::GetInfo(VideoDecoderParams *lpInfo)
{
    Ipp32s seq_index = 0, pic_index = 0;

    lpInfo->pPostProcessing = m_PostProcessing;

    if (m_CurrentSeqParamSet == -1 && !m_bSeqParamSetRead)
    {
        return UMC_ERR_NOT_INITIALIZED;
    }
    else if (m_CurrentSeqParamSet != -1)
    {
        seq_index = m_CurrentSeqParamSet;
    }

    if (m_CurrentPicParamSet == -1 && !m_bPicParamSetRead)
    {
        return UMC_ERR_NOT_INITIALIZED;
    }
    else if(m_CurrentPicParamSet != -1)
    {
        pic_index = m_CurrentPicParamSet;
    }

    H264SeqParamSet *sps = m_Headers.GetSeqParamSet(seq_index);
    H264PicParamSet *pps = m_Headers.GetPicParamSet(pic_index);

    lpInfo->info.clip_info.height = sps->frame_height_in_mbs * 16 -
        SubHeightC[sps->chroma_format_idc]*(2 - sps->frame_mbs_only_flag) *
        (sps->frame_cropping_rect_top_offset + sps->frame_cropping_rect_bottom_offset);

    lpInfo->info.clip_info.width = sps->frame_width_in_mbs * 16 - SubWidthC[sps->chroma_format_idc] *
        (sps->frame_cropping_rect_left_offset + sps->frame_cropping_rect_right_offset);

    if (0.0 < m_local_delta_frame_time)
        lpInfo->info.framerate = 1.0 / m_local_delta_frame_time;
    else
        lpInfo->info.framerate = 0.0;

    lpInfo->info.stream_type     = H264_VIDEO;

    lpInfo->profile = sps->profile_idc;
    lpInfo->level = sps->level_idc;

    lpInfo->numThreads = m_iThreadNum;
    lpInfo->info.color_format = GetColorFormat(sps->chroma_format_idc);

    if (sps->aspect_ratio_idc == 255)
    {
        lpInfo->info.aspect_ratio_width  = sps->sar_width;
        lpInfo->info.aspect_ratio_height = sps->sar_height;
    }
    else
    {
        lpInfo->info.aspect_ratio_width  = SAspectRatio[sps->aspect_ratio_idc][0];
        lpInfo->info.aspect_ratio_height = SAspectRatio[sps->aspect_ratio_idc][1];
    }

    Ipp32u multiplier = 1 << (6 + sps->bit_rate_scale);
    lpInfo->info.bitrate = sps->bit_rate_value[0] * multiplier;

    if (sps->frame_mbs_only_flag)
        lpInfo->info.interlace_type = PROGRESSIVE;
    else
    {
        if (0 <= sps->offset_for_top_to_bottom_field)
            lpInfo->info.interlace_type = INTERLEAVED_TOP_FIELD_FIRST;
        else
            lpInfo->info.interlace_type = INTERLEAVED_BOTTOM_FIELD_FIRST;
    }

    H264VideoDecoderParams *lpH264Info = DynamicCast<H264VideoDecoderParams> (lpInfo);
    if (lpH264Info)
    {
        m_CurrentSeqParamSet = seq_index;
        SetDPBSize();
        lpH264Info->m_DPBSize = m_dpbSize + m_DPBSizeEx;

        IppiSize sz;
        sz.width    = sps->frame_width_in_mbs * 16;
        sz.height   = sps->frame_height_in_mbs * 16;
        lpH264Info->m_fullSize = sz;

        lpH264Info->m_entropy_coding_type = pps->entropy_coding_mode;
    }

    return UMC_OK;
}

Status TaskSupplier::AllocateBuffers(bool exactSizeRequested)
{
    Status      umcRes = UMC_OK;
    IppiSize desiredPaddedSize;

    H264SeqParamSet* sps = m_Headers.GetSeqParamSet(m_CurrentSeqParamSet);

    IppiSize  size;
    size.width = sps->frame_width_in_mbs * 16;
    size.height = sps->frame_height_in_mbs * 16;

    desiredPaddedSize.width  = (size.width  + 15) & ~15;
    desiredPaddedSize.height = (size.height + 15) & ~15;

    // If our buffer and internal pointers are already set up for this
    // image size, then there's nothing more to do.
    // But if exactSizeRequested, we need to see if our existing
    // buffer is oversized, and perhaps reallocate it.

    if (m_paddedParsedDataSize.width == desiredPaddedSize.width &&
        m_paddedParsedDataSize.height == desiredPaddedSize.height &&
        !exactSizeRequested)
        return umcRes;

    // Determine how much space we need
    Ipp32s     MB_Frame_Width   = desiredPaddedSize.width >> 4;
    Ipp32s     MB_Frame_Height  = desiredPaddedSize.height >> 4;

    Ipp32s     uMBMapSize   = MB_Frame_Width * MB_Frame_Height;
    Ipp32s     next_mb_size = (Ipp32s)(MB_Frame_Width*MB_Frame_Height*sizeof(H264DecoderMBAddr));

    Ipp32s     totalSize = 2*next_mb_size + uMBMapSize + YUV_ALIGNMENT;

    // Reallocate our buffer if its size is not appropriate.
    if (m_parsedDataLength < totalSize ||
        (exactSizeRequested && (m_parsedDataLength != totalSize)))
    {
        DeallocateBuffers();

        if (m_pMemoryAllocator->Alloc(&m_midParsedData,
                                      totalSize,
                                      UMC_ALLOC_PERSISTENT))
            return UMC_ERR_ALLOC;

        m_pParsedData = (Ipp8u *) m_pMemoryAllocator->Lock(m_midParsedData);
        ippsZero_8u(m_pParsedData, totalSize);

⌨️ 快捷键说明

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