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

📄 umc_dv100_decoder.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    VideoData *pVideoDataOut = DynamicCast<VideoData> (pOutData);
    Status status = UMC_OK;
    Ipp32s ThreadNum;

       if (!m_bInitSuccess)
        return UMC_ERR_NOT_INITIALIZED;

    if ((NULL == pVideoDataOut))
        return UMC_ERR_NULL_PTR;

    if ((NULL == pInData))
    {
        return UMC_ERR_NOT_ENOUGH_DATA;
    }

    m_pStreamStart = reinterpret_cast<Ipp8u *> (pInData->GetDataPointer());

    //Check modes(systems) of DV100
    status = GetSystemSubtype();
    if(UMC_OK != status)
        return status;

    if (!m_PostProcessing) {
      m_PostProcessing = m_allocatedPostProcessing = createVideoProcessing();
    }

#if 0
    if (m_allocatedPostProcessing /* post processing is default */ &&
        YUY2 == lpVData->GetColorFormat() &&
        m_nWidth == pVideoDataOut->GetWidth() &&
        m_nHeight == pVideoDataOut->GetHeight())
    {
      m_pDestination = (Ipp8u*) pVideoDataOut->GetPlanePointer(0);
      m_nDestPitch = pVideoDataOut->GetPlanePitch(0);
    } else
#endif
    {
       m_pInternalFrameBuffer = (Ipp8u*) m_pMemoryAllocator->Lock(m_InternalFrameBufferMID);
       if( m_pInternalFrameBuffer == NULL )
           return UMC_ERR_NULL_PTR;

       m_pDestination = m_pInternalFrameBuffer;
       m_nDestPitch = align_value<Ipp32s> (2 * m_nWidth, WIDTH_ALIGN);
    }

    Ipp8u *pDCTBlocksBuffer = (Ipp8u*)m_pMemoryAllocator->Lock(m_DCTBlocksBufferMID);
    if(pDCTBlocksBuffer == NULL)
        return UMC_ERR_NULL_PTR;

    for (ThreadNum = 0; ThreadNum < m_nNumberOfThreads; ThreadNum += 1)
        m_ppDecodedDCTBlocks[ThreadNum] = (Ipp16s*)( ((Ipp8u*)(pDCTBlocksBuffer)) + DV100_VideoSegmentSize * ThreadNum );

    // start additional thread(s)
    for (ThreadNum = 1; ThreadNum < m_nNumberOfThreads; ThreadNum += 1)
        vm_event_signal(m_pStartEvents + ThreadNum);

    DecomressDIFSequences(0);

    // wait additional thread(s)
    for (ThreadNum = 1;ThreadNum < m_nNumberOfThreads;ThreadNum += 1)
        vm_event_wait(m_pStopEvents + ThreadNum);

    m_pMemoryAllocator->Unlock(m_DCTBlocksBufferMID);
#ifdef _DEBUG
    memset(m_ppDecodedDCTBlocks, 0, sizeof(Ipp16u*) * m_nNumberOfThreads);
#endif

    if ((m_System == System720_60p)|| (m_System == System720_50p))
    {
        if(m_nSystem720_LastDecodedChannel == 0)
            m_nSystem720_LastDecodedChannel = 2;
        else
            m_nSystem720_LastDecodedChannel = 0;
    }

    pVideoDataOut->SetFrameType(I_PICTURE);
    pVideoDataOut->SetTime(pInData->GetTime());

    if (m_LastDecodedFrame.GetColorFormat() != YUY2) {
      m_LastDecodedFrame.Init(m_nWidth,
                              m_nHeight,
                              YUY2);
    }
    m_LastDecodedFrame.SetFrameType(I_PICTURE);
    m_LastDecodedFrame.SetTime(pInData->GetTime());
    m_LastDecodedFrame.SetPlanePointer((void*)m_pDestination, 0);
    m_LastDecodedFrame.SetPlanePitch(m_nDestPitch, 0);
    if (m_pDestination == m_pInternalFrameBuffer)
    {
      status = m_PostProcessing->GetFrame(&m_LastDecodedFrame, pVideoDataOut);
      m_pMemoryAllocator->Unlock(m_InternalFrameBufferMID);
      m_pInternalFrameBuffer = NULL;
    }

    if (System1080_60i == m_System) {
        pInData->MoveDataPointer(120000*4);
        pInData->SetTime(pInData->GetTime() + 2.0/59.96);
    }
    else if(System1080_50i == m_System)
    {
        pInData->MoveDataPointer(144000*4);
        pInData->SetTime(pInData->GetTime() + 1.0/25);
    }
    else if (System720_60p == m_System)
    {
        pInData->MoveDataPointer(120000*2);
        pInData->SetTime(pInData->GetTime() + 1.0/59.96);
    }
    else if (System720_50p == m_System)
    {
        pInData->MoveDataPointer(144000*2);
        pInData->SetTime(pInData->GetTime() + 1.0/25);
    }

    return status;
}

void DV100VideoDecoder::DecomressDIFSequences(Ipp32s nThreadNum)
{
    Ipp32s nChannelNum, nDIFSeqNum, nVideoSegmentNum, nDIFSeqInChannel;
    Ipp32s nDIFSeqInFrame, nStartDIFSeqNum, nEndDIFSeqNum;
    Ipp16s TempBlock[64];

    switch(m_System)
    {
        case System1080_50i: nDIFSeqInFrame = 12*4; break;
        case System1080_60i: nDIFSeqInFrame = 10*4; break;
        case System720_60p:  nDIFSeqInFrame = 10*2; break;
        case System720_50p:  nDIFSeqInFrame = 12*2; break;
        default: nDIFSeqInFrame = 0;
    }

    nStartDIFSeqNum = nDIFSeqInFrame * nThreadNum / m_nNumberOfThreads;
    nEndDIFSeqNum   = nDIFSeqInFrame * (nThreadNum+1) / m_nNumberOfThreads;

    Ipp16s* pDecodedDCTBlocks = m_ppDecodedDCTBlocks[nThreadNum];

    union
    {
        BlockParam BlParam[40];
        Ipp32u BlParamBuffer[40];
    };

    nDIFSeqInChannel = ((m_System == System1080_50i)|| (m_System == System720_50p)) ? 12 : 10;
    for(nDIFSeqNum=nStartDIFSeqNum; nDIFSeqNum < nEndDIFSeqNum; nDIFSeqNum++)
    {
        if(m_System == System1080_50i && (nDIFSeqNum == 23 || nDIFSeqNum == 35 || nDIFSeqNum == 47))
            continue;
        if ((m_System == System720_50p) &&((nDIFSeqNum == 10)|| (nDIFSeqNum == 11) || (nDIFSeqNum == 22) || (nDIFSeqNum == 23)))
            continue;

        nChannelNum = nDIFSeqNum / nDIFSeqInChannel;
        for(nVideoSegmentNum=0; nVideoSegmentNum < 27; nVideoSegmentNum++)
        {
            Ipp32s nMBNum, nDCTBlockNum, bl_index, eob;
            Ipp16s *pCurrDCTBlock;
            Ipp8u *pVideoSegmentStart = m_pStreamStart +
                                        nDIFSeqNum * DIFSequenceLength +
                                        //nChannelNum * ChannelLength +
                                        //(nDIFSeqNum % nDIFSeqInChannel) * DIFSequenceLength +
                                        (6 + (nVideoSegmentNum/3 + 1) + nVideoSegmentNum*5) * 80;

            memset(pDecodedDCTBlocks, 0, DV100_VideoSegmentSize);
            ippiHuffmanDecodeSegment_DV100_8u16s(pVideoSegmentStart,
                                                 DVVideoDecoder::_INTERNAL_DEZIGZAG_TABLE_0,//ZigzagTable,
                                                 m_pHuffTable,
                                                 pDecodedDCTBlocks,
                                                 BlParamBuffer);

            pCurrDCTBlock = pDecodedDCTBlocks;
            for(nMBNum = 0; nMBNum < 5; nMBNum++)
            {
                Ipp8u QNO = BlParam[nMBNum * 8].qno;
                Ipp8u M0 = BlParam[nMBNum * 8].m0;// In contrast to DVSD in dv100 the same DCT mode
                //(8-8-frame or 8-8-field) is applied to all DCT blocks in a Macro block. The DCT
                //mode is stored in the FIRST DCT BLOCK of the macro block. m0 values of other
                //DCT blocks ARE IGNORED.

                for(nDCTBlockNum = 0; nDCTBlockNum < 8; nDCTBlockNum++)
                {
                    Ipp8u ClassNumber = BlParam[nMBNum * 8 + nDCTBlockNum].cl;
                    Ipp32s QuantStep = QuantizationSteps[QNO*4 + ClassNumber];
                    bl_index = (BlParamBuffer[nMBNum * 8 + nDCTBlockNum] >> 8) & 0xff;
                    eob = BlParamBuffer[nMBNum * 8 + nDCTBlockNum]  & 0x01;

                    //Ipp32s ElemNum;
                    const Ipp16s *pQuantizeTable;

                    //Dequantize block
                    if ((m_System == System720_60p) || (m_System == System720_50p))
                        pQuantizeTable = (nDCTBlockNum < 4) ? LumaQuantizeMatrix_720System : ChromaQuantizeMatrix_720System;
                    else
                        pQuantizeTable = (nDCTBlockNum < 4) ? LumaQuantizeMatrix_1080System : ChromaQuantizeMatrix_1080System;

                    //Do quantization and weighting
                    ippiQuantWeightBlockInv_DV100_16s_C1I(pCurrDCTBlock, (Ipp16s *)pQuantizeTable, QuantStep);

                    //Do inverse DCT
                    if ((eob == 0)||( 10 > bl_index))
                    {
                        ippiDCT8x8Inv_4x4_16s_C1I(pCurrDCTBlock);
                    }
                    else
                        ippiDCT8x8Inv_16s_C1I(pCurrDCTBlock);

                    pCurrDCTBlock += 64;
                }//for nDCTBlockNum = 0 to 7

                if(M0 == 1)
                {
                    Ipp16s x,y;

                    //Rearrange pixeles in vertically adjacent DCT blocks
                     for(nDCTBlockNum =0; nDCTBlockNum < 4; nDCTBlockNum++)
                    {
                        Ipp16s *pUpperDCTBlock, *pLowerDCTBlock;
                        if(nDCTBlockNum < 2)
                        {
                            pUpperDCTBlock = pDecodedDCTBlocks + (8*nMBNum + nDCTBlockNum)*64;
                            pLowerDCTBlock = pUpperDCTBlock + 2*64;
                        }
                        else
                        {
                            pUpperDCTBlock = pDecodedDCTBlocks + (8*nMBNum + nDCTBlockNum*2)*64;
                            pLowerDCTBlock = pUpperDCTBlock + 64;
                        }
                        memcpy(TempBlock, pUpperDCTBlock, 64*sizeof(Ipp16s));
                        for(y=0; y<4; y++)
                        {
                            for(x=0; x<8; x++)
                            {
                                pUpperDCTBlock[ y*2*8 + x]    = TempBlock[y*8 + x];
                                pUpperDCTBlock[(y*2+1)*8 + x] = pLowerDCTBlock[y*8 + x];
                            }
                        }

                        for(y=0; y<4; y++)
                        {
                            for(x=0; x<8; x++)
                            {
                                pLowerDCTBlock[ y*2*8 + x]    = TempBlock[(4+y)*8 + x];
                                pLowerDCTBlock[(y*2+1)*8 + x] = pLowerDCTBlock[(4+y)*8 + x];
                            }
                        }

                    }
                }

            }//for nMBNum = 0 to 4

            if ((m_System == System720_60p) || (m_System == System720_50p))
            {
                Store_System720_60p_Segment(pDecodedDCTBlocks, nChannelNum + m_nSystem720_LastDecodedChannel, (nDIFSeqNum % nDIFSeqInChannel), nVideoSegmentNum);
            }
            else if(m_System == System1080_50i)
            {
                Store_System1080_50i_Segment(pDecodedDCTBlocks, nChannelNum, (nDIFSeqNum % nDIFSeqInChannel), nVideoSegmentNum);
            }
            else
            {
                Store_System1080_60i_Segment(pDecodedDCTBlocks, nChannelNum, (nDIFSeqNum % nDIFSeqInChannel), nVideoSegmentNum);
            }

        }//for nVideoSegmentNum = 0 to 26
    }//for nDIFSeqNum = 0 to nDIFSeqInChannel-1 (9 or 11)
    //}//for nChannelNum = 0 to 1 or 3
}


Ipp32u DV100VideoDecoder::ThreadWorkingRoutine(void *lpv)
{

    THREAD_ID *pThreadId;
    DV100VideoDecoder *pOwner;

    // check error(s)
    if (NULL == lpv)
        return 0x0bad;

    pThreadId = reinterpret_cast<THREAD_ID *> (lpv);
    pOwner = reinterpret_cast<DV100VideoDecoder *> (pThreadId->m_lpOwner);

    // wait for start
    vm_event_wait(pOwner->m_pStartEvents + pThreadId->m_nNumber);

    while (VM_TIMEOUT == vm_event_timed_wait(&(pOwner->m_Quit), 0))
    {
        // decompress part of frame
        pOwner->DecomressDIFSequences(pThreadId->m_nNumber);

        // set finish
        vm_event_signal(pOwner->m_pStopEvents + pThreadId->m_nNumber);

        // wait for start
        vm_event_wait(pOwner->m_pStartEvents + pThreadId->m_nNumber);
    };

    return pThreadId->m_nNumber;
}
// Get decoder performance
Status DV100VideoDecoder::GetPerformance(Ipp64f *perf)
{
    if (perf != NULL)
        *perf = 1.0;

    return UMC_OK;
}

// Reset decoder into initial state
Status DV100VideoDecoder::Reset()
{
   if (!m_bInitSuccess)
        return UMC_ERR_NOT_INITIALIZED;
    else
        return UMC_OK;
}

Status DV100VideoDecoder::GetInfo(BaseCodecParams* info)
{
    VideoDecoderParams *pParams;
    if(info == NULL)
        return UMC_ERR_NULL_PTR;

    if (m_bInitSuccess == false)
        return UMC_ERR_NOT_INITIALIZED;

    pParams = DynamicCast<VideoDecoderParams> (info);

    if ((NULL != pParams) && (m_bInitSuccess == true) ) {
        pParams->info = m_ClipInfo;
        pParams->lpMemoryAllocator = m_pMemoryAllocator;
        pParams->pPostProcessing = m_PostProcessing;
        pParams->numThreads = m_nNumberOfThreads;
    }
    return UMC_OK;

} // Status DV100VideoDecoder::GetInfo(void)

}//namespace UMC

⌨️ 快捷键说明

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