📄 umc_threaded_demuxer.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) 2005-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "vm_time.h"
#include "vm_thread.h"
#include "umc_automatic_mutex.h"
#include "umc_threaded_demuxer.h"
#include "umc_demuxer.h"
#define TDEM_CHECK_INIT CHECK_OBJ_INIT(m_pDemuxer)
namespace UMC
{
Splitter *CreateMPEG2Splitter() { return (new ThreadedDemuxer()); }
struct SplInitPreset
{
Ipp32u uiRules;
const TrackRule *pRules;
};
const TrackRule SplInitPreset_1A_0V[1] = { TrackRule(TRACK_ANY_AUDIO, -1, 1, false) };
const TrackRule SplInitPreset_0A_1V[1] = { TrackRule(TRACK_ANY_VIDEO, -1, 1, false) };
const TrackRule SplInitPreset_1A_1V[2] = { TrackRule(TRACK_ANY_AUDIO, -1, 1, false),
TrackRule(TRACK_ANY_VIDEO, -1, 1, false) };
const TrackRule SplInitPreset_2A_1V[2] = { TrackRule(TRACK_ANY_AUDIO, -1, 2, false),
TrackRule(TRACK_ANY_VIDEO, -1, 1, false) };
const TrackRule SplInitPreset_AA_1V[2] = { TrackRule(TRACK_ANY_AUDIO, -1, -1, false),
TrackRule(TRACK_ANY_VIDEO, -1, 1, false) };
const TrackRule SplInitPreset_AA_AV[2] = { TrackRule(TRACK_ANY_AUDIO, -1, -1, false),
TrackRule(TRACK_ANY_VIDEO, -1, -1, false) };
#define ADD_SPL_INIT_PRESET(NAME) \
{ sizeof(NAME) / sizeof (TrackRule), NAME }
const SplInitPreset SplInitPresets[] = {
ADD_SPL_INIT_PRESET(SplInitPreset_1A_0V),
ADD_SPL_INIT_PRESET(SplInitPreset_0A_1V),
ADD_SPL_INIT_PRESET(SplInitPreset_1A_1V),
ADD_SPL_INIT_PRESET(SplInitPreset_2A_1V),
ADD_SPL_INIT_PRESET(SplInitPreset_AA_1V),
ADD_SPL_INIT_PRESET(SplInitPreset_AA_AV)
};
Ipp32u VM_THREAD_CALLCONVENTION ThreadRoutineStarter(void* u)
{
return ((UMC::ThreadedDemuxer*)u)->ThreadRoutine();
}
ThreadedDemuxer::ThreadedDemuxer()
{
m_pDemuxer = NULL;
}
ThreadedDemuxer::~ThreadedDemuxer()
{
Close();
}
Status ThreadedDemuxer::Close(void)
{
TDEM_CHECK_INIT;
Stop();
m_OnInit.Reset();
m_bStop = true;
m_bEndOfStream = true;
if (m_pRulesState)
{
if (m_pRulesState->m_pRules)
{
delete[] m_pRulesState->m_pRules;
m_pRulesState->m_pRules = NULL;
}
if (m_pRulesState->m_pRuleState)
{
ippsFree(m_pRulesState->m_pRuleState);
m_pRulesState->m_pRuleState = NULL;
}
delete m_pRulesState;
m_pRulesState = NULL;
}
if (m_pDemuxer)
{
delete m_pDemuxer;
m_pDemuxer = NULL;
}
return UMC_OK;
}
Status ThreadedDemuxer::Stop(void)
{
TDEM_CHECK_INIT;
m_bStop = true;
m_pDemuxer->Stop();
m_OnUnlock.Set();
if (m_DemuxerThread.IsValid())
m_DemuxerThread.Wait();
return UMC_OK;
}
Status ThreadedDemuxer::Run(void)
{
TDEM_CHECK_INIT;
if (!m_bStop)
return UMC_OK;
m_bStop = false;
m_OnInit.Reset();
Status umcRes = m_DemuxerThread.Create((vm_thread_callback)ThreadRoutineStarter,(void *)this);
if (UMC_OK != umcRes)
return umcRes;
m_OnInit.Wait();
return UMC_OK;
}
Status ThreadedDemuxer::GetInfo(SplitterInfo** ppInfo)
{
TDEM_CHECK_INIT;
if (!ppInfo)
return UMC_ERR_NULL_PTR;
m_OnAutoEnable.Lock();
Status umcRes = m_pDemuxer->GetInfo(ppInfo);
if (UMC_OK != umcRes)
return umcRes;
ppInfo[0]->m_splitter_flags = m_uiFlags;
if (m_bAutoEnable)
{
ppInfo[0]->m_splitter_flags |= FLAG_VSPL_NEW_TRACK;
m_bAutoEnable = false;
}
Ipp32u i;
for (i = 0; i < ppInfo[0]->m_nOfTracks; i++)
if (((Mpeg2TrackInfo *)ppInfo[0]->m_ppTrackInfo[i])->m_iFirstFrameOrder < 0)
ppInfo[0]->m_ppTrackInfo[i]->m_isSelected = false;
m_OnAutoEnable.Unlock();
return UMC_OK;
}
Status ThreadedDemuxer::Init(SplitterParams& init)
{
if (m_pDemuxer) // already initialized
return UMC_ERR_FAILED;
m_pRulesState = new RulesMatchingState;
if (!m_pRulesState)
{
TerminateInit();
return UMC_ERR_ALLOC;
}
m_uiFlags = init.m_lFlags;
Status umcRes = AnalyzeParams(&init);
if (UMC_OK != umcRes)
{
TerminateInit();
return umcRes;
}
m_pOnPSIChangeEvent = NULL;
if (DynamicCast<DemuxerParams>(&init))
m_pOnPSIChangeEvent = ((DemuxerParams &)init).m_pOnPSIChangeEvent;
m_pDemuxer = new Demuxer;
if (NULL == m_pDemuxer)
{
TerminateInit();
return UMC_ERR_ALLOC;
}
umcRes = m_pDemuxer->Init(init);
if (UMC_OK != umcRes)
{
TerminateInit();
return umcRes;
}
m_bStop = false;
m_bEndOfStream = false;
m_bAutoEnable = false;
m_pRulesState->Reset();
umcRes = m_OnUnlock.Init(1, 0);
if (UMC_OK != umcRes)
{
TerminateInit();
return umcRes;
}
umcRes = m_OnInit.Init(1, 0);
if (UMC_OK != umcRes)
{
TerminateInit();
return umcRes;
}
umcRes = m_OnAutoEnable.Init();
if (UMC_OK != umcRes)
{
TerminateInit();
return umcRes;
}
umcRes = m_DemuxerThread.Create((vm_thread_callback)ThreadRoutineStarter, (void *)this);
if (UMC_OK != umcRes)
{
TerminateInit();
return umcRes;
}
m_OnInit.Wait();
return UMC_OK;
}
Status ThreadedDemuxer::CheckNextData(MediaData *data, Ipp32u uiTrack)
{
TDEM_CHECK_INIT;
return m_pDemuxer->CheckNextData(data, uiTrack);
}
Status ThreadedDemuxer::GetNextData(MediaData *data, Ipp32u uiTrack)
{
TDEM_CHECK_INIT;
if ((Ipp32s)uiTrack == m_iBlockingPID || 0xFFFF == m_iBlockingPID)
{
m_OnUnlock.Set();
vm_debug_trace(VM_DEBUG_PROGRESS, VM_STRING("DEMUXER: m_ReleaseEvent signaled\n"));
}
return m_pDemuxer->GetNextData(data, uiTrack);
}
Status ThreadedDemuxer::SetRate(Ipp64f rate)
{
TDEM_CHECK_INIT;
Stop();
m_bEndOfStream = false;
Status umcRes = m_pDemuxer->SetRate(rate);
if (UMC_OK != umcRes)
return umcRes;
vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("ThreadedDemuxer: new rate = %f\n"), rate);
return UMC_OK;
}
Status ThreadedDemuxer::EnableTrack(Ipp32u nTrack, Ipp32s iState)
{
TDEM_CHECK_INIT;
Status umcRes = m_pDemuxer->EnableTrack(nTrack, iState);
if (UMC_OK != umcRes)
return umcRes;
// if manual track management cancel auto-enabling
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -