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

📄 umc_demuxer.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:

    if (NULL == data || NULL == pTrack)
        return UMC_ERR_NULL_PTR;

    if (m_bPSIWasChanged)
    {
        // CheckNextData was called after notification about PSI changes
        // destroy all frame constructors
        Ipp32u i;
        for(i = 0; i < m_uiTracks; i++)
        {
            // invalidate allocated TrackInfo structure (instead of deleting them)
            if (m_SplInfo.m_ppTrackInfo[i])
                ((Mpeg2TrackInfo *)m_SplInfo.m_ppTrackInfo[i])->m_iFirstFrameOrder = -1;

            // destroy allocated frame constructors
            if (m_pFC[i])
            {
                delete m_pFC[i];
                m_pFC[i] = NULL;
            }
        }

        m_uiTracks = 0;
        m_bPSIWasChanged = false;
    }

    if (m_dRate < 0.0)
        umcRes = CheckNextDataBackward(&sample, pTrack);
    else
        umcRes = CheckNextDataForward(&sample, pTrack);

    if (UMC_ERR_END_OF_STREAM == umcRes)
    {
        // if end of stream occurs, deliver END_OF_STREAM to all FCs
        Ipp32u i = 0;
        for (i = 0; i < m_uiTracks; i++)
        {
            if (m_pFC[i])
                umcRes = m_pFC[i]->UnLockInputBuffer(NULL, UMC_ERR_END_OF_STREAM);
            if (umcRes == UMC_OK)
            {
                *pTrack = m_iCurTrack = i;
                break;
            }
        }

        if (UMC_OK != umcRes)
            m_bEndOfStream = true;
    }

    if (UMC_OK == umcRes)
    {
        SplMediaData *pMediaSampleData = DynamicCast<SplMediaData>(data);
        if (pMediaSampleData)
            *pMediaSampleData = sample;
        else
            *data = *((MediaData *)&sample);
    }

    return umcRes;
}

Status Demuxer::GetNextData(MediaData *data, Ipp32u *pTrack)
{
    Status umcRes = UMC_ERR_END_OF_STREAM;
    Ipp32s i;

    // parse one frame (exactly)
    umcRes = CheckNextData(data, pTrack);
    if (UMC_OK == umcRes)
    {
        // if OK, get parsed frame and return it
        umcRes = m_pFC[m_iCurTrack]->LockOutputBuffer(data);

        if (UMC_OK == umcRes)
            m_pFC[m_iCurTrack]->UnLockOutputBuffer(data);
    }

    if (UMC_OK != umcRes)
    {
        // in case of error try to find frame in buffers
        for (i = 0; i < (Ipp32s)m_uiTracks; i++)
        {
            if (m_pFC[i])
            {
                umcRes = m_pFC[i]->LockOutputBuffer(data);
                if (UMC_OK == umcRes)
                {
                    umcRes = m_pFC[i]->UnLockOutputBuffer(data);
                    *pTrack = i;
                    break;
                }
            }
        }
    }

    return umcRes;
}

Status Demuxer::CheckNextDataForward(SplMediaData *data, Ipp32u *pTrack)
{
    Status umcRes = UMC_OK;
    SplMediaData chunk;
    Mpeg2TrackInfo *pInfo = NULL;
    bool bFrameFound = false;

    chunk.SetBufferPointer((Ipp8u *)1, 0);

    // try to find next frame in last used buffer
    if (-1 != m_iCurTrack)
    {
        umcRes = m_pFC[m_iCurTrack]->UnLockInputBuffer(NULL);
        if (UMC_OK == umcRes)
        {
            bFrameFound = true;
            *pTrack = m_iCurTrack;
        }
        else
            m_iCurTrack = -1;
    }

    while (!bFrameFound)
    {
        // check current data chunk
        umcRes = m_pParser->CheckNextData(&chunk, pTrack);
        if (UMC_OK != umcRes)
        {
            if (UMC_WRN_INVALID_STREAM == umcRes)
            {
                Ipp32u i;
                for(i = 0; i < m_uiTracks; i++)
                {
                    if (m_pFC[i])
                        m_pFC[i]->UnLockInputBuffer(NULL, UMC_ERR_END_OF_STREAM);
                }

                m_iCurTrack = -1;
                m_iRefTrack = -1;
                m_bPSIWasChanged = true;
            }
            return umcRes;
        }

        m_iCurTrack = *pTrack;

        // check and if stream is new try to register it
        if (NULL == m_pFC[m_iCurTrack])
            umcRes = CreateFrameConstructor(m_iCurTrack);

        if (m_pFC[m_iCurTrack])
            pInfo = m_pFC[m_iCurTrack]->GetInfo();

        // pass data from parser to frame constructor
        if ((!m_pFC[m_iCurTrack]) ||
            (!pInfo->m_isSelected && pInfo->m_iFirstFrameOrder >= 0) ||
            (m_dRate > 1.0 && m_iCurTrack != m_iRefTrack))
        {
            // skip when frame constructor was failed to be created
            // skip packets from all except reference track at non-normal playback
            // skip packets from unselected tracks for those first frame was constructed
            umcRes = m_pParser->MoveToNextHeader();
            if (UMC_OK != umcRes) return umcRes;
        }
        else
        {
            // order space for chunk in FC's buffer
            umcRes = m_pFC[m_iCurTrack]->LockInputBuffer(&chunk);
            if (UMC_OK != umcRes)
            {
                m_bBufFilled = true;
                return umcRes;
            }

            // copy chunk from parser to FC's buffer
            umcRes = m_pParser->GetNextData(&chunk, pTrack);
            if (UMC_OK != umcRes)
                return umcRes;

            // ask for whole frame
            umcRes = m_pFC[m_iCurTrack]->UnLockInputBuffer(&chunk);
            if (UMC_OK == umcRes)
                bFrameFound = true;
        }
    }

    m_pFC[m_iCurTrack]->GetLastFrame(data);
    if (m_pFC[m_iCurTrack]->GetInfo()->m_iFirstFrameOrder < 0)
    {
        m_pFC[m_iCurTrack]->GetInfo()->m_iFirstFrameOrder = m_uiTracksReady;
        m_uiTracksReady += 1;
    }
    if (m_iCurTrack == m_iRefTrack)
    {
        m_uiTotalSize += data->GetDataSize();
        m_uiNOfFrames++;
    }

    // very fast forward adaptive jump
    if (m_uiSourceSize > 0 && -1 != m_iCurTrack && m_dRate > 4.0 && m_dBytesPerSec > 0.0)
    {
        Ipp64u pos, newPos;
        Ipp64f frameRate = ((VideoStreamInfo *)m_pFC[m_iRefTrack]->GetInfo()->m_pStreamInfo)->framerate;
        Ipp32s bytesPerFrame = (Ipp32s)(0.5 * m_dBytesPerSec / ((frameRate > 0.0) ? frameRate : 30.0));
        pos = m_pParser->GetPosition();
        newPos = pos + (Ipp32s)(bytesPerFrame * (m_dRate - 1.0) * m_uiAdaptiveFactor);
        m_pParser->SetPosition(newPos);

        if (-1 != m_iRefTrack)
            m_pFC[m_iRefTrack]->SoftReset();
    }

    return umcRes;
}

Status Demuxer::CheckNextDataBackward(SplMediaData *data, Ipp32u *pTrack)
{
    Status umcRes = UMC_OK;
    for (;;)
    {
        // pull next segment
        umcRes = m_Segmentator.PullSegment(data);
        if (UMC_OK != umcRes && UMC_ERR_NOT_ENOUGH_DATA != umcRes)
            return umcRes;

        // check if at least one sample is available
        if (UMC_OK == m_pFC[m_iRefTrack]->LockOutputBuffer(data))
            break;
    }

    if (UMC_OK == umcRes && m_uiSourceSize > 0 && m_dRate < -4.0 && m_dBytesPerSec > 0.0)
    {
        Ipp64f frameRate = ((VideoStreamInfo *)m_pFC[m_iRefTrack]->GetInfo()->m_pStreamInfo)->framerate;
        Ipp32s bytesPerFrame = (Ipp32s)(1.0 * m_dBytesPerSec / ((frameRate > 0.0) ? frameRate : 30.0));
        m_Segmentator.AdditionalJump((Ipp32s)(bytesPerFrame * (m_dRate + 1.0) * m_uiAdaptiveFactor));
    }

    pTrack[0] = m_iRefTrack;
    return UMC_OK;
}

Status Demuxer::CheckNextData(MediaData* data, Ipp32u uiTrack)
{
    if (NULL == data)
        return UMC_ERR_NULL_PTR;

    if (uiTrack >= m_uiTracks)
        return UMC_ERR_FAILED;

    if (!m_pFC[uiTrack] || !m_pFC[uiTrack]->GetInfo()->m_isSelected)
        return UMC_ERR_FAILED;

    return m_pFC[uiTrack]->LockOutputBuffer(data);
}

Status Demuxer::GetNextData(MediaData* data, Ipp32u uiTrack)
{
    if (NULL == data)
        return UMC_ERR_NULL_PTR;

    if (uiTrack >= m_uiTracks)
        return UMC_ERR_FAILED;

    if (!m_pFC[uiTrack] || !m_pFC[uiTrack]->GetInfo()->m_isSelected)
        return UMC_ERR_FAILED;

    m_pFC[uiTrack]->UnLockOutputBuffer(m_pPrevData[uiTrack]);
    Status umcRes = m_pFC[uiTrack]->LockOutputBuffer(data);
    if (UMC_OK == umcRes)
        m_pPrevData[uiTrack][0] = data[0];

#ifdef DUMP_SOMETHING
    if (UMC_OK == umcRes)
        DumpSample(uiTrack);
#endif //DUMP_SOMETHING

    return umcRes;
}

Ipp32s Demuxer::GetTrackByPid(Ipp32u uiPid)
{
    return m_pParser ? m_pParser->GetTrackByPid(uiPid) : -1;
}

void Demuxer::AlterQuality(Ipp64f time)
{
    if (time > 0.0)
        if (time > m_dPrevTimeGap)
            m_uiAdaptiveFactor++;
    m_dPrevTimeGap = time;

    vm_debug_trace2(VM_DEBUG_PROGRESS, VM_STRING("Demuxer::AlterQuality(time=%f), new adaptive factor is %d\n"), time, m_uiAdaptiveFactor);
}

Status Demuxer::CreateFrameConstructor(Ipp32s iTrack)
{
    Status umcRes = UMC_OK;
    Ipp32u size = AUDIO_BUFFER_SIZE;
    m_uiTracks = m_pParser->GetNumberOfTracks();

    Mpeg2TrackInfo *pInfo = m_pParser->GetTrackInfo(iTrack);
    if (!pInfo)
        return UMC_ERR_FAILED;

    m_pFC[iTrack] = NULL;
    if (m_bEncryptedData)
    {
        m_pFC[iTrack] = new PesFrameConstructor;
        size = AUDIO_BUFFER_SIZE;
        if (m_iRefTrack < 0)
            m_iRefTrack = iTrack;
    }
    else if (pInfo->m_Type & TRACK_ANY_VIDEO)
    {
        if ((TRACK_MPEG1V | TRACK_MPEG2V) & pInfo->m_Type)
            m_pFC[iTrack] = new Mpeg2FrameConstructor;
        else if (TRACK_MPEG4V == pInfo->m_Type)
            m_pFC[iTrack] = new Mpeg4FrameConstructor;
        else if (TRACK_H261 == pInfo->m_Type)
            m_pFC[iTrack] = new H261FrameConstructor;
        else if (TRACK_H263 == pInfo->m_Type)
            m_pFC[iTrack] = new H263FrameConstructor;
        else if (TRACK_H264 == pInfo->m_Type)
            m_pFC[iTrack] = new H264FrameConstructor;
        else
            m_pFC[iTrack] = new FrameConstructor;

        if (NULL == m_pFC[iTrack])
            return UMC_ERR_ALLOC;

        if (-1 == m_iRefTrack || !(m_pParser->GetTrackInfo(m_iRefTrack)->m_Type & TRACK_ANY_VIDEO))
            m_iRefTrack = iTrack;

        size = VIDEO_BUFFER_SIZE;
    }
    else if (pInfo->m_Type & TRACK_ANY_AUDIO)
    {
        if (MPEGx_PURE_AUDIO_STREAM == m_SplInfo.m_SystemType ||
            WAVE_STREAM             == m_SplInfo.m_SystemType ||
            AVI_STREAM              == m_SplInfo.m_SystemType)
            m_pFC[iTrack] = new PureAudioFrameConstructor;
        else
        {
            if (AAC_MPEG4_STREAM == ((AudioStreamInfo *)pInfo->m_pStreamInfo)->stream_type)
                m_pFC[iTrack] = new TimeStampedAudioFrameConstructor;
            else
                m_pFC[iTrack] = new BufferedAudioFrameConstructor;
        }

        if (NULL == m_pFC[iTrack])
            return UMC_ERR_ALLOC;

        if (-1 == m_iRefTrack)
            m_iRefTrack = iTrack;
    }
    else if (pInfo->m_Type & TRACK_ANY_VBI)
    {
        m_pFC[iTrack] = new TimeStampedAudioFrameConstructor;
        if (NULL == m_pFC[iTrack])
            return UMC_ERR_ALLOC;
    }
    else if (pInfo->m_Type & TRACK_ANY_SPECIAL)
    {
        m_pFC[iTrack] = new FrameConstructor;
        if (NULL == m_pFC[iTrack])
            return UMC_ERR_ALLOC;
    }
    else // TRACK_UNKNOWN
    {
        return UMC_OK;
    }

    FrameConstructorParams fcParams;
    fcParams.m_nOfFrames = 10;
    fcParams.m_lBufferSize = size;
    fcParams.m_pInfo = pInfo;
    fcParams.m_pMemoryAllocator = m_pMemoryAllocator;

    umcRes = m_pFC[iTrack]->Init((MediaReceiverParams *)&fcParams);
    if (UMC_OK != umcRes)
        return umcRes;

    if (!m_pPrevData[iTrack])
        m_pPrevData[iTrack] = new MediaData;
    m_pPrevData[iTrack]->SetBufferPointer(NULL, 0);
    return umcRes;
}

Ipp64f Demuxer::GetDuration(void)
{
    // first, check if parser provides duration
    if (m_pParser->GetDuration() >= 0.0)
    {
        m_dDuration = m_pParser->GetDuration();
        return m_dDuration;

⌨️ 快捷键说明

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