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

📄 umc_vc1_video_decoder.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        if(m_dataBuffer==NULL)
        {
            Close();
            return UMC_ERR_ALLOC;
        }
    }

    memset(m_dataBuffer,0,bufferSize+4);
    m_pContext->m_pBufferStart  = (Ipp8u*)m_dataBuffer;
    m_pContext->m_bitstream.pBitstream       = (Ipp32u*)(m_pContext->m_pBufferStart);

    //for slice, field start code
    if(m_stCodes == NULL)
    {
        m_stCodes = (MediaDataEx::_MediaDataEx *)ippsMalloc_8u(START_CODE_NUMBER*2*sizeof(Ipp32s)+sizeof(MediaDataEx::_MediaDataEx));
    }

    memset(m_stCodes, 0, (START_CODE_NUMBER*2*sizeof(Ipp32s)+sizeof(MediaDataEx::_MediaDataEx)));
    m_stCodes->count      = 0;
    m_stCodes->index      = 0;
    m_stCodes->bstrm_pos  = 0;
    m_stCodes->offsets    = (Ipp32u*)((Ipp8u*)m_stCodes +
                                    sizeof(MediaDataEx::_MediaDataEx));
    m_stCodes->values     = (Ipp32u*)((Ipp8u*)m_stCodes->offsets +
                                    START_CODE_NUMBER*sizeof( Ipp32u));

    if(m_frameData == NULL)
        m_frameData = new UMC::MediaDataEx();

    m_frameData->SetBufferPointer(m_dataBuffer, bufferSize);
    m_frameData->SetDataSize(bufferSize);
    m_frameData->SetExData(m_stCodes);

    return UMC_OK;
}

Status VC1VideoDecoder::GetStartCodes (MediaData* in, MediaDataEx* out, Ipp32u* readSize)
{
    Ipp8u* readPos = (Ipp8u*)in->GetDataPointer();
    Ipp32u readBufSize = (Ipp32u)in->GetDataSize();
    Ipp8u* readBuf = (Ipp8u*)in->GetDataPointer();

    Ipp8u* currFramePos = (Ipp8u*)out->GetBufferPointer();
    Ipp32u frameSize = 0;
    Ipp32u frameBufSize = (Ipp32u)out->GetBufferSize();
    MediaDataEx::_MediaDataEx *stCodes = out->GetExData();

    Ipp32u size = 0;
    Ipp8u* ptr = NULL;
    Ipp32u readDataSize = 0;
    Ipp32u zeroNum = 0;
    Ipp32u a = 0x0000FF00 | (*readPos);
    Ipp32u b = 0xFFFFFFFF;
    Ipp32u FrameNum = 0;

    stCodes->count = 0;

    memset(stCodes->offsets, 0,START_CODE_NUMBER*sizeof(Ipp32s));
    memset(stCodes->values, 0,START_CODE_NUMBER*sizeof(Ipp32s));

    while(readPos < (readBuf + readBufSize))
    {
        //find sequence of 0x000001 or 0x000003
        while(!( b == 0x00000001 || b == 0x00000003 )
            &&(readPos < (readBuf + readBufSize)))
        {
            readPos++;
            a = (a<<8)| (Ipp32s)(*readPos);
            b = a & 0x00FFFFFF;
        }

        //check end of read buffer
        if(readPos < (readBuf + readBufSize - 1))
        {
            if(*readPos == 0x01)
            {
                if((*(readPos + 1) == VC1_Slice) || (*(readPos + 1) == VC1_Field)
                    /*|| (FrameNum)*/)
                {
                    readPos+=2;
                    ptr = readPos - 5;
                    //trim zero bytes
                    while ( (*ptr==0) && (ptr > readBuf) )
                        ptr--;

                    //slice or field size
                    size = (Ipp32u)(ptr - readBuf - readDataSize+1);

                    if(frameSize + size > frameBufSize)
                        return UMC_ERR_NOT_ENOUGH_BUFFER;

                    ippsCopy_8u(readBuf + readDataSize, currFramePos, size);

                    currFramePos = currFramePos + size;
                    frameSize = frameSize + size;

                    zeroNum = frameSize - 4*((frameSize)/4);
                    if(zeroNum!=0)
                        zeroNum = 4 - zeroNum;

                    memset(currFramePos, 0, zeroNum);

                    //set write parameters
                    currFramePos = currFramePos + zeroNum;
                    frameSize = frameSize + zeroNum;

                    stCodes->offsets[stCodes->count] = frameSize;
                    stCodes->values[stCodes->count]  = ((*(readPos-1))<<24) + ((*(readPos-2))<<16) + ((*(readPos-3))<<8) + (*(readPos-4));

                    readDataSize = (Ipp32u)(readPos - readBuf - 4);

                    a = 0x00010b00 |(Ipp32s)(*readPos);
                    b = a & 0x00FFFFFF;

                    zeroNum = 0;
                    stCodes->count++;
                }
                else
                {
                    if(FrameNum)
                    {
                        readPos+=2;
                        ptr = readPos - 5;
                        //trim zero bytes
                        while ( (*ptr==0) && (ptr > readBuf) )
                            ptr--;

                        //slice or field size
                        size = (Ipp32u)(readPos - readBuf - readDataSize - 4);

                        if(frameSize + size > frameBufSize)
                            return UMC_ERR_NOT_ENOUGH_BUFFER;

                        ippsCopy_8u(readBuf + readDataSize, currFramePos, size);

                        //currFramePos = currFramePos + size;
                        frameSize = frameSize + size;

                        stCodes->offsets[stCodes->count] = frameSize;
                        stCodes->values[stCodes->count]  = ((*(readPos-1))<<24) + ((*(readPos-2))<<16) + ((*(readPos-3))<<8) + (*(readPos-4));

                        stCodes->count++;

                        out->SetDataSize(frameSize);
                        readDataSize = readDataSize + size;
                        *readSize = readDataSize;
                        return UMC_OK;
                    }
                    else
                    {
                        //beginning of frame
                        readPos++;
                        a = 0x00000100 |(Ipp32s)(*readPos);
                        b = a & 0x00FFFFFF;

                        stCodes->offsets[stCodes->count] = (Ipp32u)(0);
                        stCodes->values[stCodes->count]  = ((*(readPos))<<24) + ((*(readPos-1))<<16) + ((*(readPos-2))<<8) + (*(readPos-3));

                        stCodes->count++;
                        zeroNum = 0;
                        FrameNum++;
                    }
                }
            }
            else //if(*readPos == 0x03)
            {
                //000003
                if((*(readPos + 1) <  0x04))
                {
                    size = (Ipp32u)(readPos - readBuf - readDataSize);
                    if(frameSize + size > frameBufSize)
                        return UMC_ERR_NOT_ENOUGH_BUFFER;

                    ippsCopy_8u(readBuf + readDataSize, currFramePos, size);
                    frameSize = frameSize + size;
                    currFramePos = currFramePos + size;
                    zeroNum = 0;

                    readPos++;
                    a = (a<<8)| (Ipp32s)(*readPos);
                    b = a & 0x00FFFFFF;

                    readDataSize = readDataSize + size + 1;
                }
                else
                {
                    readPos++;
                    a = (a<<8)| (Ipp32s)(*readPos);
                    b = a & 0x00FFFFFF;
                }
            }

        }
        else
        {
            //end of stream
            size = (Ipp32u)(readPos- readBuf - readDataSize);

            if(frameSize + size > frameBufSize)
            {
                return UMC_ERR_NOT_ENOUGH_BUFFER;
            }

            ippsCopy_8u(readBuf + readDataSize, currFramePos, size);
            out->SetDataSize(frameSize + size);

            readDataSize = readDataSize + size;
             *readSize = readDataSize;
            return UMC_OK;
        }
    }
    return UMC_OK;
}


void VC1VideoDecoder::GetFrameSize(MediaData* in)
{
    Ipp32s frameSize = 0;
    Ipp8u* ptr = m_pContext->m_pBufferStart;
    Ipp32u i = 0;
    Ipp32u* offset = m_pContext->m_Offsets;
    Ipp32u* value = m_pContext->m_values;

    m_pContext->m_FrameSize = (Ipp32u)in->GetDataSize();

    if(m_pContext->m_seqLayerHeader->PROFILE == VC1_PROFILE_ADVANCED)
    {
        value++;
        i++;
        while((*value == 0x0B010000)||(*value == 0x0C010000))
        {
            value ++;
            i++;
        }
        if(*value != 0x00000000)
        {
            m_pContext->m_FrameSize = offset[i];
        }
    }
    else
    {
        if ((*m_pContext->m_bitstream.pBitstream&0xFF) == 0xC5) // sequence header
            frameSize = 36; // size of seq header for .rcv format
        else
        {
            frameSize  = ((*(ptr))<<24) + ((*(ptr + 1))<<16) + ((*(ptr + 2))<<8) + *(ptr + 3);
            frameSize &= 0x0fffffff;
            frameSize += 8;
        }
    }
}
Status VC1VideoDecoder::VC1DecodeFrame(VC1VideoDecoder* pDec,MediaData* in, VideoData* out_data)
{
    if (pDec != this)
        return UMC_ERR_INIT;

    Status umcRes = UMC_OK;
    Status umcWRes = UMC_OK;

    VC1FrameDescriptor *pCurrDescriptor = NULL;
    Ipp32u i;

    m_pStore->GetReadyDS(&pCurrDescriptor);

    if (NULL == pCurrDescriptor)
        throw vc1_exception(internal_pipeline_error);

    try // check input frame for valid
    {
        umcRes = pCurrDescriptor->preProcData(m_pContext->m_pBufferStart,
                                             (Ipp32u)in->GetDataSize(),
                                              m_lFrameCount,
                                              m_bIsWMPSplitter);

        ProcessPrevFrame(in, out_data);
        pCurrDescriptor->m_pContext->typeOfPreviousFrame =  m_pContext->typeOfPreviousFrame;
    }
    catch (vc1_exception ex)
    {
        if (invalid_stream == ex.get_exception_type())
        {
            if (fast_err_detect == vc1_except_profiler::GetEnvDescript().m_Profile)
                m_pStore->AddInvalidPerformedDS(pCurrDescriptor);
            else if (fast_decoding == vc1_except_profiler::GetEnvDescript().m_Profile)
                m_pStore->ResetPerformedDS(pCurrDescriptor);
            // for smart decoding we should decode and reconstrcu frame according to standart pipeline
        }
    }

    //if (umcRes != UMC_ERR_INVALID_STREAM)
    if (!pCurrDescriptor->isEmpty())//check descriptor correctness
        pCurrDescriptor->VC1FrameDescriptor::processFrame(m_pContext->m_Offsets,m_pContext->m_values);
    //else
    //{
    //    m_pStore->ResetDS(pCurrDescriptor);
    //    --m_lFrameCount;
    //}

    if (umcRes == UMC_WRN_INVALID_STREAM)
        m_bIsWarningStream = true;


    // for Intensity compensation om multi-threading model
    if (VC1_IS_REFERENCE(pCurrDescriptor->m_pContext->m_picLayerHeader->PTYPE))
    {
        m_pContext->m_bIntensityCompensation = pCurrDescriptor->m_pContext->m_bIntensityCompensation;
    }
    //else
    //    pCurrDescriptor->m_pContext->m_bIntensityCompensation = m_pContext->m_bIntensityCompensation;



    if (!pCurrDescriptor->isEmpty())//check descriptor correctness
    {
        if (m_pContext->m_seqLayerHeader->PROFILE == VC1_PROFILE_ADVANCED)
            m_pStore->SetDstForFrameAdv(pCurrDescriptor,&m_iRefFramesDst,&m_iBFramesDst);
        else
            m_pStore->SetDstForFrame(pCurrDescriptor,&m_iRefFramesDst,&m_iBFramesDst);
    }



    // Wake Upppp
    m_pStore->WakeUP();

    if (m_lFrameCount == 1)
    {
        m_pStore->StartDecoding();
        m_bLastFrameNeedDisplay = true;
        for (i = 1;i < m_iThreadDecoderNum;i += 1)
             m_pdecoder[i]->StartProcessing();
    }


STATISTICS_END_TIME(m_timeStatistics->ThreadPrep_StartTime,
                    m_timeStatistics->ThreadPrep_EndTime,
                    m_timeStatistics->ThreadPrep_TotalTime);

    if ((m_pStore->GetProcFramesNumber() == m_iMaxFramesInProcessing)&&
        (umcRes != UMC_ERR_INVALID_STREAM))
    {
        m_bIsFrameToOut = true;
        m_pdecoder[0]->processMainThread(); // need to change - special function to 0-th decoder
    }
    else
        m_bIsFrameToOut = false;

    if (VC1_IS_REFERENCE(pCurrDescriptor->m_pContext->m_picLayerHeader->PTYPE))
        m_pContext->typeOfPreviousFrame = pCurrDescriptor->m_pContext->m_picLayerHeader->FCM;

    if (m_bIsFrameToOut)
    {
        if (m_pStore->GetPerformedDS(&pCurrDescriptor))
        {

            if (!pCurrDescriptor->isDescriptorValid())
            {
                umcRes = UMC_ERR_FAILED;
            }
            else
            {

                if (VC1_IS_REFERENCE(pCurrDescriptor->m_pContext->m_InitPicLayer->PTYPE))
                {

⌨️ 快捷键说明

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