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

📄 umc_avi_splitter.cpp

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

#include "vm_debug.h"
#include "vm_time.h"
#include "umc_media_data.h"
#include "umc_sample_buffer.h"
#include "umc_avi_splitter.h"

using namespace UMC;

namespace UMC
{
    Splitter *CreateAVISplitter() { return (new AVISplitter); }
}

AVISplitter::AVISplitter()
{
    m_pTrack = NULL;
    ippsZero_8u((Ipp8u *)&m_AviHdr, sizeof(MainAviHeader));
    m_bCheckVBRAudio = false;
    m_bIsVBRAudio = false;
}

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

Status AVISplitter::Init(SplitterParams& rInitParams)
{
    if (m_pReader) // already initialized
        return UMC_ERR_FAILED;

    Status umcRes = UMC_OK;
    // check non-suitable flag(s)
    m_flags = rInitParams.m_lFlags;
    if (m_flags & FLAG_VSPL_4BYTE_ACCESS)
        return UMC_ERR_INVALID_PARAMS;

    if (!rInitParams.m_pDataReader)
        return UMC_ERR_NULL_PTR;

    umcRes = SplitterBase::Init(rInitParams);
    if (UMC_OK != umcRes) return TerminateInit(umcRes);

    m_uiFlags = rInitParams.m_lFlags;
    m_pDataReader = rInitParams.m_pDataReader;
    umcRes = m_AviChunkReader.Init(m_pDataReader, &m_ReaderMutex);
    if (UMC_OK != umcRes) return TerminateInit(umcRes);

    umcRes = ReadFormat();
    if (UMC_OK != umcRes) return TerminateInit(umcRes);

    m_pTrackIndex = new TrackIndex[m_AviHdr.uiStreams];
    m_pReadESThread = new vm_thread[m_AviHdr.uiStreams];
    if (!m_pTrackIndex || !m_pReadESThread) return TerminateInit(UMC_ERR_ALLOC);

    m_ppMediaBuffer = (MediaBuffer **)new (SampleBuffer *[m_AviHdr.uiStreams]);
    if (!m_ppMediaBuffer) return TerminateInit(UMC_ERR_ALLOC);
    ippsZero_8u((Ipp8u *)m_ppMediaBuffer, m_AviHdr.uiStreams * sizeof(MediaBuffer *));

    umcRes = GenerateIndex();
    if (UMC_OK != umcRes) return TerminateInit(umcRes);

    umcRes = FillSplitterInfo();
    if (UMC_OK != umcRes) return TerminateInit(umcRes);

    m_ppLockedFrame = new (MediaData *[m_AviHdr.uiStreams]);
    if (!m_ppLockedFrame) return TerminateInit(UMC_ERR_ALLOC);

    Ipp32s i;
    IndexEntry entry;
    for (i = 0; i < (Ipp32s)m_AviHdr.uiStreams; i++)
    {
        m_pTrackIndex[i].First(entry);
        m_ppLockedFrame[i] = new MediaData;
        if (!m_ppLockedFrame[i]) return TerminateInit(UMC_ERR_ALLOC);
        vm_thread_set_invalid(&m_pReadESThread[i]);
    }

    umcRes = Run();
    if (UMC_OK != umcRes) return TerminateInit(umcRes);
    return UMC_OK;
}

Status AVISplitter::Run(void)
{
    if (!m_pDataReader)
        return UMC_ERR_NOT_INITIALIZED;

    if (!m_bFlagStop)
        return UMC_OK;

    Ipp32u i;
    for (i = 0; i < m_pInfo->m_nOfTracks; i++)
    {
        if (!m_ppMediaBuffer[i])
        {
            MediaBufferParams params;
            params.m_prefInputBufferSize = m_pTrack[i].m_uiMaxSampleSize;
            params.m_prefOutputBufferSize = m_pTrack[i].m_uiMaxSampleSize;
            params.m_numberOfFrames = 25;
            m_ppMediaBuffer[i] = new SampleBuffer;
            if (!m_ppMediaBuffer[i])
                return UMC_ERR_ALLOC;

            Status umcRes = m_ppMediaBuffer[i]->Init(&params);
            if (UMC_OK != umcRes)
                return umcRes;
        }
    }

    Status umcRes = SplitterBase::Run();
    if (UMC_OK != umcRes)
        return umcRes;

    for (i = 0; i < m_pInfo->m_nOfTracks; i++)
    {
        if (m_pInfo->m_ppTrackInfo[i]->m_isSelected)
        {
            MediaData data;
            while (!m_bFlagStop && UMC_ERR_NOT_ENOUGH_DATA == (umcRes = CheckNextData(&data, i)));
            if (UMC_OK != umcRes)
                return umcRes;
        }
    }

    return UMC_OK;
}

Status AVISplitter::TerminateInit(Status umcRes)
{
    Ipp32u i;
    for (i = 0; i < m_AviHdr.uiStreams; i++)
    {
        if (m_ppMediaBuffer)
            delete m_ppMediaBuffer[i];
        if (m_ppLockedFrame)
            delete m_ppLockedFrame[i];
        if (m_pInfo && m_pInfo->m_ppTrackInfo && m_pInfo->m_ppTrackInfo[i])
        {
            if (m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo)
                ippsFree(m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo);
            if (m_pInfo->m_ppTrackInfo[i]->m_pDecSpecInfo)
                ippsFree(m_pInfo->m_ppTrackInfo[i]->m_pDecSpecInfo);
        }
        if (m_pTrack && m_pTrack[i].m_pStreamFormat)
            ippsFree(m_pTrack[i].m_pStreamFormat);
        if (m_pTrack && m_pTrack[i].m_pIndex)
            ippsFree(m_pTrack[i].m_pIndex);
    }
    delete[] m_ppMediaBuffer;
    m_ppMediaBuffer = NULL;
    delete[] m_ppLockedFrame;
    m_ppLockedFrame = NULL;
    delete[] m_pTrackIndex;
    m_pTrackIndex = NULL;
    delete[] m_pReadESThread;
    m_pReadESThread = NULL;
    delete[] m_ppMediaBuffer;
    m_ppMediaBuffer = NULL;
    delete[] m_pTrack;
    m_pTrack = NULL;
    if (m_pInfo)
        delete[] m_pInfo->m_ppTrackInfo;
    delete m_pInfo;
    m_pInfo = NULL;
    m_pReader = NULL;
    return umcRes;
}

Status AVISplitter::FillSplitterInfo(void)
{
    Status umcRes = UMC_OK;
    m_pInfo = new SplitterInfo;
    if (!m_pInfo)
        return UMC_ERR_ALLOC;

    m_pInfo->m_ppTrackInfo = new (TrackInfo *[m_AviHdr.uiStreams]);
    if (!m_pInfo->m_ppTrackInfo)
        return UMC_ERR_ALLOC;

    m_pInfo->m_dDuration = 0.0;
    m_pInfo->m_SystemType = AVI_STREAM;
    m_pInfo->m_splitter_flags = m_uiFlags;
    m_pInfo->m_nOfTracks = m_AviHdr.uiStreams;

    Ipp32u i;
    for (i = 0; i < m_AviHdr.uiStreams; i++)
    {
        m_pInfo->m_ppTrackInfo[i] = new TrackInfo;
        if (!m_pInfo->m_ppTrackInfo[i])
            return UMC_ERR_ALLOC;

        m_pInfo->m_ppTrackInfo[i]->m_PID = i;
        if (AVI_FOURCC_auds == m_pTrack[i].m_StreamHeader.fccType)
        {
            if (m_flags & AUDIO_SPLITTER)
                m_pInfo->m_ppTrackInfo[i]->m_isSelected = 1;
            m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo = (AudioStreamInfo *)ippsMalloc_8u(sizeof(AudioStreamInfo));
            if (!m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo)
                return UMC_ERR_ALLOC;
            ippsZero_8u((Ipp8u *)m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo, sizeof(AudioStreamInfo));

            umcRes = FillAudioStreamInfo(i, m_pInfo->m_ppTrackInfo[i]);
            if (UMC_OK != umcRes)
                return umcRes;

            m_pInfo->m_dDuration = IPP_MAX(m_pInfo->m_dDuration, ((AudioStreamInfo *)m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo)->duration);
        }
        else if (AVI_FOURCC_vids == m_pTrack[i].m_StreamHeader.fccType ||
                 AVI_FOURCC_iavs == m_pTrack[i].m_StreamHeader.fccType ||
                 AVI_FOURCC_ivas == m_pTrack[i].m_StreamHeader.fccType)
        {
            if (m_flags & VIDEO_SPLITTER)
                m_pInfo->m_ppTrackInfo[i]->m_isSelected = 1;
            m_pInfo->m_ppTrackInfo[i]->m_isSelected = 1;
            m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo = (VideoStreamInfo *)ippsMalloc_8u(sizeof(VideoStreamInfo));
            if (!m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo)
                return UMC_ERR_ALLOC;
            ippsZero_8u((Ipp8u *)m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo, sizeof(VideoStreamInfo));

            if (AVI_FOURCC_vids == m_pTrack[i].m_StreamHeader.fccType)
                umcRes = FillVideoStreamInfo(i, m_pInfo->m_ppTrackInfo[i]);
            else
                umcRes = FillDvStreamInfo(i, m_pInfo->m_ppTrackInfo[i]);
            if (UMC_OK != umcRes)
                return umcRes;

            m_pInfo->m_dDuration = IPP_MAX(m_pInfo->m_dDuration, ((VideoStreamInfo *)m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo)->duration);
        }
    }

    return UMC_OK;
}

Status AVISplitter::Close()
{
    SplitterBase::Close();

    if (m_pReadESThread)
    {
        delete[] m_pReadESThread;
        m_pReadESThread = NULL;
    }

    Ipp32u i;
    for (i = 0; i < m_AviHdr.uiStreams; i++)
    {
        if (m_ppMediaBuffer[i])
            delete m_ppMediaBuffer[i];
        if (m_ppLockedFrame[i])
            delete m_ppLockedFrame[i];
        if (m_pInfo && m_pInfo->m_ppTrackInfo[i])
        {
            if (m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo)
                ippsFree(m_pInfo->m_ppTrackInfo[i]->m_pStreamInfo);
            if (m_pInfo->m_ppTrackInfo[i]->m_pDecSpecInfo)
                ippsFree(m_pInfo->m_ppTrackInfo[i]->m_pDecSpecInfo);
        }
        if (m_pTrack && m_pTrack[i].m_pStreamFormat)
            ippsFree(m_pTrack[i].m_pStreamFormat);
        if (m_pTrack && m_pTrack[i].m_pIndex)
            ippsFree(m_pTrack[i].m_pIndex);
    }

    if (m_pTrackIndex)
    {
        delete[] m_pTrackIndex;
        m_pTrackIndex = NULL;
    }

    if (m_ppMediaBuffer)
    {
        delete[] m_ppMediaBuffer;
        m_ppMediaBuffer = NULL;
    }

    if (m_ppLockedFrame)
    {
        delete[] m_ppLockedFrame;
        m_ppLockedFrame = NULL;
    }

    if (m_pInfo)
    {
        if (m_pInfo->m_ppTrackInfo)
            delete[] m_pInfo->m_ppTrackInfo;
        delete m_pInfo;
        m_pInfo = NULL;
    }

    if (m_pTrack)
    {
        delete[] m_pTrack;
        m_pTrack = NULL;
    }

    memset(&m_AviHdr, 0, sizeof(MainAviHeader));
    m_bCheckVBRAudio = false;
    m_bIsVBRAudio = false;
    return UMC_OK;
}

Status AVISplitter::ReadFormat()
{
    m_pDataReader->Reset();
    Status umcRes = m_AviChunkReader.DescendRIFF(AVI_FOURCC_AVI_);
    if (UMC_OK != umcRes)
        return umcRes;

    umcRes = m_AviChunkReader.DescendLIST(AVI_FOURCC_HDRL);
    if (UMC_OK != umcRes)
        return umcRes;

    umcRes = m_AviChunkReader.DescendChunk(AVI_FOURCC_AVIH);
    if (UMC_OK != umcRes)
        return umcRes;

    umcRes = m_AviChunkReader.GetData((Ipp8u *)&m_AviHdr, sizeof(MainAviHeader));
    if (UMC_OK != umcRes)
        return umcRes;

    // ascend from avih
    m_AviHdr.SwapBigEndian();
    umcRes = m_AviChunkReader.Ascend();
    if (UMC_OK != umcRes)
        return umcRes;

    m_pTrack = new AviTrack[m_AviHdr.uiStreams];
    if (!m_pTrack)
        return UMC_ERR_ALLOC;

    Ipp32u i;
    for (i = 0; i < m_AviHdr.uiStreams; i++)
    {
        umcRes = ReadStreamsInfo(i);
        if (UMC_OK != umcRes)
            return umcRes;
    }

    //  Ascend from hdrl
    umcRes = m_AviChunkReader.Ascend();
    if (UMC_OK != umcRes)
        return umcRes;

    //  Ascend from avi_
    umcRes = m_AviChunkReader.Ascend();
    if (UMC_OK != umcRes)
        return umcRes;

    // go to the beginning of file
    m_AviChunkReader.GoChunkHead();
    return UMC_OK;
}

Status AVISplitter::ReadStreamsInfo(Ipp32u uiTrack)
{
    AviTrack &track = m_pTrack[uiTrack];
    Status umcRes = m_AviChunkReader.DescendLIST(AVI_FOURCC_STRL);

    umcRes = m_AviChunkReader.DescendChunk(AVI_FOURCC_STRH);
    if (UMC_OK != umcRes)
        return umcRes;

    umcRes = m_AviChunkReader.GetData((Ipp8u *)&track.m_StreamHeader, sizeof(AviStreamHeader));
    if (UMC_OK != umcRes)
        return umcRes;
    track.m_StreamHeader.SwapBigEndian();

    umcRes = m_AviChunkReader.Ascend();
    if (UMC_OK != umcRes)
        return umcRes;

    umcRes = m_AviChunkReader.DescendChunk(AVI_FOURCC_STRF);
    if (UMC_OK != umcRes)
        return umcRes;

    // reader stream format
    track.m_uiStreamFormatSize = m_AviChunkReader.GetChunkSize();
    track.m_pStreamFormat = ippsMalloc_8u(track.m_uiStreamFormatSize);
    if (!track.m_pStreamFormat)
        return UMC_ERR_ALLOC;
    umcRes = m_AviChunkReader.GetData((Ipp8u *)track.m_pStreamFormat, track.m_uiStreamFormatSize);
    if (UMC_OK != umcRes)
        return umcRes;

⌨️ 快捷键说明

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