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

📄 umc_demuxer.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  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) 2005-2007 Intel Corporation. All Rights Reserved.
//
*/

#include <ipps.h>
#include "umc_default_memory_allocator.h"
#include "umc_demuxer.h"
#include "umc_mpeg2ps_parser.h"
#include "umc_mpeg2ts_parser.h"

//#define DUMP_SOMETHING
//#define DUMP_VIDEO_1X_TXT
//#define DUMP_VIDEO_FF_TXT
//#define DUMP_VIDEO_BF_TXT
//#define DUMP_AUDIO_TXT
//#define DUMP_VIDEO_1X_BIN
//#define DUMP_VIDEO_FF_BIN
//#define DUMP_VIDEO_BF_BIN
//#define DUMP_AUDIO_BIN

#define DEM_CHECK_INIT CHECK_OBJ_INIT(m_pParser)

namespace UMC
{

Splitter *CreateMPEG2SplitterNT(void) { return (new Demuxer()); }

Demuxer::Demuxer()
{
    m_pParser = NULL;
}

Demuxer::~Demuxer()
{
    Close();
}

Status Demuxer::Run(void)
{
    DEM_CHECK_INIT;
    return UMC_OK;
}

Status Demuxer::Stop(void)
{
    DEM_CHECK_INIT;
    return UMC_OK;
}

Status Demuxer::Close(void)
{
    DEM_CHECK_INIT;

    Ipp32s i;
    for (i = 0; i < MAX_TRACK; i++)
    {
        if (m_pFC[i])
        {
            delete m_pFC[i];
            m_pFC[i] = NULL;
        }
        if (m_pPrevData[i])
        {
            delete m_pPrevData[i];
            m_pPrevData[i] = NULL;
        }
    }

    if (m_pParser)
    {
        delete m_pParser;
        m_pParser = NULL;
    }
    if (m_bInnerMemAllocator && m_pMemoryAllocator)
    {
        delete m_pMemoryAllocator;
        m_pMemoryAllocator = NULL;
        m_bInnerMemAllocator = false;
    }

    return UMC_OK;
}

Status Demuxer::Init(SplitterParams& init)
{
    if (m_pParser) // already initialized
        return UMC_ERR_FAILED;

    if (NULL == init.m_pDataReader)
        return UMC_ERR_NULL_PTR;

    m_pParser = NULL;
    m_pMemoryAllocator = NULL;

    // detect type of stream
    bool bEncrypted = (init.m_lFlags & FLAG_VSPL_ENCRYPTED_DATA) > 0;
    m_SplInfo.m_SystemType = bEncrypted ? MPEG2_TRANSPORT_STREAM : DetectSystem(init.m_pDataReader);

    // select stream parsers
    StreamParserParams *pParserParams = NULL;
    switch (m_SplInfo.m_SystemType)
    {
        case MPEG1_PROGRAMM_STREAM:
        case MPEG2_PROGRAMM_STREAM:
        case MPEG2_PES_PACKETS_STREAM:
            m_pParser = new Mpeg2PsParser;
            pParserParams = new StreamParserParams;
            break;
        case MPEG2_TRANSPORT_STREAM:
        case MPEG2_TRANSPORT_STREAM_TTS:
        case MPEG2_TRANSPORT_STREAM_TTS0:
            m_pParser = new Mpeg2TsParser;
            pParserParams = new Mpeg2TsParserParams;
            break;
        case WAVE_STREAM:
            m_pParser = new WaveParser;
            pParserParams = new StreamParserParams;
            break;
        case UNDEF_STREAM:
            return UMC_ERR_INIT;
        default: // pure streams
            m_pParser = new StreamParser;
            pParserParams = new StreamParserParams;
            break;
    }

    if (!m_pParser || !pParserParams)
    {
        TerminateInit(pParserParams);
        return UMC_ERR_ALLOC;
    }

    // prepare stream parser parameters
    pParserParams->m_pDataReader = init.m_pDataReader;
    pParserParams->m_SystemType = m_SplInfo.m_SystemType;
    if (DynamicCast<DemuxerParams>(&init) && DynamicCast<Mpeg2TsParserParams>(pParserParams) &&
        ((DemuxerParams *)&init)->m_pOnPSIChangeEvent)
        ((Mpeg2TsParserParams *)pParserParams)->m_bDetectPSIChanges = true;

    // initialize stream parser object
    Status umcRes = m_pParser->Init(*pParserParams);
    if (UMC_OK != umcRes)
    {
        TerminateInit(pParserParams);
        return umcRes;
    }

    // estimate duration
    m_dDuration = -1.0;
    m_uiSourceSize = m_pParser->GetSize();
    if (DynamicCast<Mpeg2PesParser>(m_pParser) && m_uiSourceSize > 0 && !bEncrypted)
    {
        m_Corrector.AttachParser((Mpeg2PesParser *)m_pParser);
        m_dDuration = GetExactDuration();
    }

    // initialize info fields
    m_SplInfo.m_dRate = 1.0;
    m_SplInfo.m_dDuration = -1.0;
    m_SplInfo.m_nOfTracks = 0;
    m_SplInfo.m_splitter_flags = 0;
    m_SplInfo.m_ppTrackInfo = m_pInfoStack;
    ippsZero_8u((Ipp8u *)m_pInfoStack, MAX_TRACK * sizeof(void *));

    // determine memory allocator
    m_bInnerMemAllocator = (init.m_pMemoryAllocator == NULL);
    m_pMemoryAllocator = m_bInnerMemAllocator ? new DefaultMemoryAllocator : init.m_pMemoryAllocator;
    if (!m_pMemoryAllocator)
    {
        TerminateInit(pParserParams);
        return UMC_ERR_ALLOC;
    }

    ippsZero_8u((Ipp8u *)m_pFC, MAX_TRACK * sizeof(void *));
    ippsZero_8u((Ipp8u *)m_pPrevData, MAX_TRACK * sizeof(void *));
    m_uiTracksReady = 0;
    m_uiTracks = 0;
    m_iCurTrack = -1;
    m_iRefTrack = -1;

    m_bEncryptedData = (init.m_lFlags & FLAG_VSPL_ENCRYPTED_DATA) > 0;
    m_bBufFilled = false;
    m_bPSIWasChanged = false;
    m_bEndOfStream = false;
    m_dRate = 1.0;
    m_dBytesPerSec = -1.0;
    m_uiNOfFrames = 0;
    m_uiTotalSize = 0;
    m_uiAdaptiveFactor = 1;
    m_dPrevTimeGap = -1.0;

    delete pParserParams;
    return umcRes;
}

Status Demuxer::EnableTrack(Ipp32u nTrack, Ipp32s iState)
{
    if (nTrack >= m_uiTracks)
        return UMC_ERR_FAILED;

    if (NULL == m_pFC[nTrack])
        return UMC_ERR_FAILED;

    // reset buffer if it was unselected before
    if (1 == iState && !m_pFC[nTrack]->GetInfo()->m_isSelected)
        m_pFC[nTrack]->Reset();

    m_pFC[nTrack]->GetInfo()->m_isSelected = iState;
    if (m_SplInfo.m_ppTrackInfo[nTrack])
        m_SplInfo.m_ppTrackInfo[nTrack]->m_isSelected = iState;

    if (m_iRefTrack < 0 || !m_pFC[m_iRefTrack]->GetInfo()->m_isSelected)
        AssignRefTrack();

    return UMC_OK;
}

Status Demuxer::SetRate(Ipp64f rate)
{
    Status umcRes = UMC_OK;

    m_dRate = rate;
    m_uiAdaptiveFactor = 1;
    m_dPrevTimeGap = -1.0;
    m_bEndOfStream = false;

    Ipp32s i;
    for (i = 0; i < (Ipp32s)m_uiTracks; i++)
    {
        if (NULL != m_pFC[i])
        {
            m_pFC[i]->Reset();
            m_pPrevData[i]->SetBufferPointer(NULL, 0);
            m_pFC[i]->SetRate(rate);
        }
    }

    if (m_dRate < 0.0 && m_iRefTrack >= 0 && m_pFC[m_iRefTrack]->GetInfo()->m_Type & TRACK_ANY_VIDEO)
        m_Segmentator.RestartSegmentation(m_pParser, m_iRefTrack, (VideoFrameConstructor *)m_pFC[m_iRefTrack]);
    return umcRes;
}

Status Demuxer::SetPosition(Ipp64u pos)
{
    Status umcRes = m_pParser->SetPosition(pos);
    if (UMC_OK != umcRes)
        return umcRes;

    m_iCurTrack = -1;
    m_bEndOfStream = false;

    Ipp32s i;
    for (i = 0; i < (Ipp32s)m_uiTracks; i++)
    {
        if (NULL != m_pFC[i])
        {
            m_pFC[i]->Reset();
            m_pPrevData[i]->SetBufferPointer(NULL, 0);
        }
    }

    if (m_dRate < 0.0 && m_iRefTrack >= 0 && m_pFC[m_iRefTrack]->GetInfo()->m_Type & TRACK_ANY_VIDEO)
        m_Segmentator.RestartSegmentation(m_pParser, m_iRefTrack, (VideoFrameConstructor *)m_pFC[m_iRefTrack]);
    return UMC_OK;
}

Status Demuxer::SetTimePosition(Ipp64f timePos)
{
    Status umcRes = UMC_OK;
    Ipp32s attempt;

    vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("Demuxer: seek at %.3f sec\n"), timePos);

    if (!DynamicCast<Mpeg2PesParser>(m_pParser) || 0 == m_uiSourceSize || m_dDuration <= 0.0)
    {
        Ipp64f duration = GetDuration();
        return SetPosition(duration > 0.0 ? (Ipp64u)(timePos * ((Ipp64s)m_uiSourceSize / duration)) : (Ipp64u)0);
    }

    timePos += m_Start.dTime;
    if (timePos < m_Start.dTime)
        timePos = m_Start.dTime;
    if (timePos > m_End.dTime)
        timePos = m_End.dTime;

    // reset streaming variables
    m_iCurTrack = -1;
    m_bEndOfStream = false;

    // reset buffers
    Ipp32u uiTrack;
    for (uiTrack = 0; uiTrack < m_uiTracks; uiTrack++)
    {
        if (m_pFC[uiTrack])
        {
            m_pFC[uiTrack]->Reset();
            m_pPrevData[uiTrack]->SetBufferPointer(NULL, 0);
        }
    }

    // step-by-step approximation
    CheckPoint checkPointA = m_Start;
    CheckPoint checkPointB = m_End;
    CheckPoint checkPointC;
    Ipp64f dLocalBytesPerSec;
    for (attempt = 0; attempt < 5; attempt++)
    {
        dLocalBytesPerSec = (Ipp64s)(checkPointB.uiPos - checkPointA.uiPos) / (checkPointB.dTime - checkPointA.dTime);
        checkPointC.uiPos = (Ipp64u)((Ipp64s)checkPointA.uiPos + (dLocalBytesPerSec * (timePos - checkPointA.dTime)));
        umcRes = m_pParser->SetPosition(checkPointC.uiPos);
        if (UMC_OK != umcRes) return umcRes;
        m_Corrector.ResetAfterReposition();

        umcRes = m_Corrector.GetSystemTime(checkPointC);
        if (UMC_OK != umcRes)
            return umcRes;

        // approximated point is coincide with one of ends (A or B)
        if (checkPointC.uiPos == checkPointA.uiPos || checkPointC.uiPos == checkPointB.uiPos)
            break;

        if (checkPointC.dTime < timePos)
            checkPointA = checkPointC;
        else
            checkPointB = checkPointC;

        vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("Demuxer: attempt %d \n"), attempt);
        vm_debug_trace2(VM_DEBUG_INFO, VM_STRING("at byte %d, sec %.3f\n"), (Ipp32s)checkPointC.uiPos, checkPointC.dTime);
        if (UMC_OK != umcRes || (timePos - checkPointC.dTime < 0.6 && timePos - checkPointC.dTime > -0.6))
            break;
    }

    umcRes = m_pParser->SetPosition(checkPointC.uiPos);
    if (m_dRate < 0.0 && m_iRefTrack >= 0 && m_pFC[m_iRefTrack]->GetInfo()->m_Type & TRACK_ANY_VIDEO)
        m_Segmentator.RestartSegmentation(m_pParser, m_iRefTrack, (VideoFrameConstructor *)m_pFC[m_iRefTrack]);

    vm_debug_trace(VM_DEBUG_INFO, VM_STRING("Demuxer: seeking finished\n"));
    return UMC_OK;
}

Status Demuxer::GetTimePosition(Ipp64f &)
{
    return UMC_ERR_NOT_IMPLEMENTED;
}

Status Demuxer::GetInfo(SplitterInfo **ppInfo)
{
    Ipp32u i;
    if (!ppInfo)
        return UMC_ERR_NULL_PTR;

    bool bDurationUpdated = false;
    m_SplInfo.m_dRate = m_dRate;
    if (m_SplInfo.m_dDuration < 0.0)
    {
        bDurationUpdated = true;
        m_SplInfo.m_dDuration = GetDuration();
    }

    m_SplInfo.m_SystemType = m_pParser->GetSystemStreamType();
    if (IsPure() && m_pFC[0])
    {
        if (TRACK_MPEG1V == m_pFC[0]->GetInfo()->m_Type)
            m_SplInfo.m_SystemType = MPEG1_PURE_VIDEO_STREAM;
    }

    m_SplInfo.m_nOfTracks = m_uiTracks;
    m_SplInfo.m_splitter_flags = 0;

    for (i = 0; i < m_SplInfo.m_nOfTracks; i++)
    {
        m_SplInfo.m_ppTrackInfo[i] = m_pFC[i] ? m_pFC[i]->GetInfo() : m_pParser->GetTrackInfo(i);
        ((Mpeg2TrackInfo *)m_SplInfo.m_ppTrackInfo[i])->SetDuration(m_SplInfo.m_dDuration);
    }

    ppInfo[0] = &m_SplInfo;
    return UMC_OK;
}

Status Demuxer::CheckNextData(MediaData *data, Ipp32u *pTrack)
{
    Status umcRes = UMC_OK;
    SplMediaData sample;

    if (NULL == m_pParser)
        return UMC_ERR_NOT_INITIALIZED;

    if (m_bEndOfStream)
        return UMC_ERR_END_OF_STREAM;

⌨️ 快捷键说明

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