📄 umc_avi_splitter.cpp
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
// 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(¶ms);
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 + -