📄 umc_spl_base.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) 2007 Intel Corporation. All Rights Reserved.
//
*/
#include <ipps.h>
#include "ippdefs.h"
#include "vm_semaphore.h"
#include "vm_thread.h"
#include "vm_types.h"
#include "vm_time.h"
#include "bstream.h"
#include "umc_media_data.h"
#include "umc_cyclic_buffer.h"
#include "umc_spl_base.h"
enum
{
#ifndef _WIN32_WCE
TIME_TO_SLEEP = 5,
#else
TIME_TO_SLEEP = 0,
#endif
};
namespace UMC
{
struct ReadESThreadParam
{
Ipp32s uiPin;
SplitterBase* pThis;
};
SplitterBase::SplitterBase():
m_pDataReader(NULL),
m_ReaderMutex(),
m_pTrackIndex(NULL),
m_ppMediaBuffer(NULL),
m_ppLockedFrame(NULL),
m_bFlagStop(true),
m_pReadESThread(NULL),
m_pInfo(NULL),
m_pReader(NULL)
{
}
SplitterBase::~SplitterBase()
{
Close();
}
Status SplitterBase::Init(SplitterParams &init_params)
{
Status umcRes;
m_pReader = init_params.m_pDataReader;
umcRes = m_ReaderMutex.Init();
return umcRes;
}
Status SplitterBase::Close()
{
StopSplitter();
m_pReader = NULL;
m_ReaderMutex.Close();
return UMC_OK;
}
Status SplitterBase::StopSplitter()
{
if (m_bFlagStop)
return UMC_OK;
if (m_pReader == NULL)
return UMC_ERR_NOT_INITIALIZED;
Status umcRes;
IndexEntry entry;
Ipp32u i;
m_bFlagStop = true;
for (i = 0; i < m_pInfo->m_nOfTracks; i++) {
if (vm_thread_is_valid(&m_pReadESThread[i])) {
vm_thread_wait(&m_pReadESThread[i]);
vm_thread_close(&m_pReadESThread[i]);
vm_thread_set_invalid(&m_pReadESThread[i]);
}
if (m_ppMediaBuffer[i]) {
umcRes = m_ppMediaBuffer[i]->Reset();
UMC_CHECK_STATUS(umcRes)
}
if (m_ppLockedFrame[i]) {
umcRes = m_ppLockedFrame[i]->Reset();
UMC_CHECK_STATUS(umcRes)
}
}
return UMC_OK;
}
Status SplitterBase::GetInfo(SplitterInfo** ppInfo)
{
ppInfo[0] = m_pInfo;
return UMC_OK;
}
void SplitterBase::ReadES(Ipp32u uiPin)
{
Status umcRes;
TrackIndex *pIndex = &m_pTrackIndex[uiPin];
IndexEntry m_Frame;
MediaData in;
int i;
if (m_pInfo->m_dRate == 0)
return;
umcRes = pIndex->Get(m_Frame);
while (umcRes == UMC_OK && !m_bFlagStop) {
umcRes = m_ppMediaBuffer[uiPin]->LockInputBuffer(&in);
while (umcRes == UMC_ERR_NOT_ENOUGH_BUFFER) {
if (m_bFlagStop) {
return;
}
vm_time_sleep(TIME_TO_SLEEP);
umcRes = m_ppMediaBuffer[uiPin]->LockInputBuffer(&in);
}
m_ReaderMutex.Lock();
m_pReader->SetPosition((Ipp64u)m_Frame.stPosition);
m_pReader->GetData(in.GetDataPointer(), &m_Frame.uiSize);
m_ReaderMutex.Unlock();
in.SetDataSize(m_Frame.uiSize);
in.SetTime(m_Frame.dPts, m_Frame.dDts);
in.SetFrameType(NONE_PICTURE);
if (TRACK_ANY_VIDEO & m_pInfo->m_ppTrackInfo[uiPin]->m_Type)
in.SetFrameType((FrameType)m_Frame.uiFlags);
m_ppMediaBuffer[uiPin]->UnLockInputBuffer(&in);
vm_time_sleep(0);
if (m_pInfo->m_dRate == 1) {
umcRes = pIndex->Next(m_Frame);
} else if (m_pInfo->m_dRate > 0) {
for (i = 0; i < m_pInfo->m_dRate; i++) {
umcRes = pIndex->Next(m_Frame);
if (umcRes != UMC_OK)
break;
}
if (umcRes == UMC_OK)
umcRes = pIndex->NextKey(m_Frame);
} else { /*** m_pInfo->m_dRate < 0 ***/
for (i = 0; i < -m_pInfo->m_dRate; i++) {
umcRes = pIndex->Prev(m_Frame);
if (umcRes != UMC_OK)
break;
}
if (umcRes == UMC_OK)
umcRes = pIndex->PrevKey(m_Frame);
}
}
if (umcRes != UMC_OK) {
m_ppMediaBuffer[uiPin]->UnLockInputBuffer(NULL, UMC_ERR_END_OF_STREAM);
}
}
Ipp32u SplitterBase::ReadESThreadCallback(void* ptr)
{
VM_ASSERT(NULL != ptr);
ReadESThreadParam* m_pParam = (ReadESThreadParam*)ptr;
m_pParam->pThis->ReadES(m_pParam->uiPin);
delete ptr;
return 0;
}
Status SplitterBase::Run()
{
if (!m_bFlagStop)
return UMC_OK;
Ipp32u i;
int res;
m_bFlagStop = false;
for (i = 0; i < m_pInfo->m_nOfTracks; i++) {
if (((m_pInfo->m_dRate == 1.0) ||
(m_pInfo->m_ppTrackInfo[i]->m_Type & TRACK_ANY_VIDEO)) &&
(m_pInfo->m_ppTrackInfo[i]->m_isSelected)) {
ReadESThreadParam* m_pESParam = new ReadESThreadParam;
m_pESParam->uiPin = i;
m_pESParam->pThis = this;
res = vm_thread_create(&m_pReadESThread[i], (vm_thread_callback)ReadESThreadCallback, (void *)m_pESParam);
if (res != 1) {
return UMC_ERR_FAILED;
}
}
}
return UMC_OK;
}
Status SplitterBase::GetNextData(MediaData* data, Ipp32u nTrack)
{
Status umcRes;
if ((nTrack < 0) || (nTrack > m_pInfo->m_nOfTracks))
return UMC_ERR_FAILED;
if (!m_ppMediaBuffer[nTrack] || !m_pInfo->m_ppTrackInfo[nTrack]->m_isSelected)
return UMC_ERR_FAILED;
if (m_ppLockedFrame[nTrack]->GetDataSize()) {
m_ppLockedFrame[nTrack]->SetDataSize(0);
m_ppMediaBuffer[nTrack]->UnLockOutputBuffer(m_ppLockedFrame[nTrack]);
}
umcRes = m_ppMediaBuffer[nTrack]->LockOutputBuffer(data);
if (umcRes == UMC_OK) {
*(m_ppLockedFrame[nTrack]) = *data;
}
return umcRes;
}
Status SplitterBase::CheckNextData(MediaData* data, Ipp32u nTrack)
{
Status umcRes;
if ((nTrack < 0) || (nTrack > m_pInfo->m_nOfTracks))
return UMC_ERR_FAILED;
if (!m_ppMediaBuffer[nTrack] || !m_pInfo->m_ppTrackInfo[nTrack]->m_isSelected)
return UMC_ERR_FAILED;
umcRes = m_ppMediaBuffer[nTrack]->LockOutputBuffer(data);
if (umcRes == UMC_OK) {
// this is to prevent END_OF_STREAM occasionally returned by SampleBuffer
m_ppMediaBuffer[nTrack]->UnLockOutputBuffer(data);
}
return umcRes;
}
Status SplitterBase::SetTimePosition(Ipp64f position)
{
IndexEntry entry;
Ipp32u i;
StopSplitter(); /* close read threads and reset buffers */
// tune up time position using one of video tracks
for (i = 0; i < m_pInfo->m_nOfTracks; i++) {
if (m_pInfo->m_ppTrackInfo[i]->m_Type & TRACK_ANY_VIDEO &&
m_pInfo->m_ppTrackInfo[i]->m_isSelected) {
m_pTrackIndex[i].First(entry);
// add origin time stamp
position += entry.GetTimeStamp();
m_pTrackIndex[i].Get(entry, position);
if (I_PICTURE != entry.uiFlags)
m_pTrackIndex[i].PrevKey(entry);
// save time stamp of nearest previous key frame
position = entry.GetTimeStamp();
break;
}
}
// position all tracks to one time position
for (i = 0; i < m_pInfo->m_nOfTracks; i++)
m_pTrackIndex[i].Get(entry, position);
return UMC_OK;
}
Status SplitterBase::GetTimePosition(Ipp64f& position)
{
IndexEntry entry;
Ipp32u i;
/* get TimePos of the first selected video track */
for (i = 0; i < m_pInfo->m_nOfTracks; i++) {
if (m_pInfo->m_ppTrackInfo[i]->m_Type & TRACK_ANY_VIDEO &&
m_pInfo->m_ppTrackInfo[i]->m_isSelected) {
m_pTrackIndex[i].Get(entry);
break;
}
}
/* if no video get TimePos of the first selected track */
if (i == m_pInfo->m_nOfTracks) {
for (i = 0; i < m_pInfo->m_nOfTracks; i++) {
if (m_pInfo->m_ppTrackInfo[i]->m_isSelected) {
m_pTrackIndex[i].Get(entry);
break;
}
}
}
position = entry.GetTimeStamp();
return UMC_OK;
}
Status SplitterBase::SetRate(Ipp64f rate)
{
if (m_pReader == NULL)
return UMC_ERR_NOT_INITIALIZED;
m_pInfo->m_dRate = (Ipp32s)rate;
StopSplitter();
return UMC_OK;
}
} // namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -