📄 umc_avs_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) 2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined(UMC_ENABLE_AVS_SPLITTER)
#include "umc_avs_splitter.h"
#include "umc_avs_splitter_buffer.h"
#include "umc_avs_sequence_header.h"
#include "umc_avs_dec_byte_stream.h"
#include "vm_time.h"
namespace UMC
{
enum
{
AVS_SPLITTER_TIME_TO_SLEEP = 5
};
AVSSplitter::AVSSplitter(void)
{
m_bQuit = false;
m_pVideoBuffer = NULL;
m_pDataReader = NULL;
} // AVSSplitter::AVSSplitter(void)
AVSSplitter::~AVSSplitter(void)
{
Close();
} // AVSSplitter::~AVSSplitter(void)
Status AVSSplitter::Close(void)
{
// delete & close all resources
m_bQuit = true;
if (m_hThread.IsValid())
{
m_hThread.Wait();
m_hThread.Close();
}
if (m_pVideoBuffer)
{
delete m_pVideoBuffer;
}
// reset all resources
m_bQuit = false;
m_pVideoBuffer = NULL;
m_pDataReader = NULL;
if(m_info.m_ppTrackInfo)
{
if(m_info.m_ppTrackInfo[0])
{
if(m_info.m_ppTrackInfo[0]->m_pStreamInfo)
{
delete m_info.m_ppTrackInfo[0]->m_pStreamInfo;
m_info.m_ppTrackInfo[0]->m_pStreamInfo = NULL;
}
delete m_info.m_ppTrackInfo[0];
m_info.m_ppTrackInfo[0] = NULL;
}
delete m_info.m_ppTrackInfo;
m_info.m_ppTrackInfo = NULL;
}
// here we should call the parent's method,
// but the parent class does not have this implementation
// Splitter::Close();
return UMC_OK;
} // Status AVSSplitter::Close(void)
Status AVSSplitter::Init(SplitterParams &initParams)
{
Status umcRes;
MediaBufferParams bufferParams;
// check incompatible flag(s)
if (0 == (initParams.m_lFlags & VIDEO_SPLITTER))
return UMC_ERR_INVALID_STREAM;
//for simple_player
//if (initParams.m_lFlags & AUDIO_SPLITTER)
// return UMC_ERR_INVALID_STREAM;
if (initParams.m_lFlags & FLAG_VSPL_NO_INTERNAL_THREAD)
return UMC_ERR_INVALID_STREAM;
// check parameter(s)
if (NULL == initParams.m_pDataReader)
return UMC_ERR_NULL_PTR;
// close all resources before initialization
Close();
// here we should call the parent's method,
// but the parent class does not have this implementation
// umcRes = Splitter::Init(initParams);
// if (UMC_OK != umcRes)
// return umcRes;
m_pDataReader = initParams.m_pDataReader;
// allocate resources
// allocate sample buffer
m_pVideoBuffer = new AVSSampleBuffer();
if (NULL == m_pVideoBuffer)
return UMC_ERR_ALLOC;
umcRes = m_pVideoBuffer->Init(&bufferParams);
if (UMC_OK != umcRes)
return umcRes;
// create an internal thread
umcRes = m_hThread.Create(AVSSplitter::InternalThreadRoutine, this);
if (UMC_OK != umcRes)
return umcRes;
// wait for first sequence header
umcRes = PrepareStreamInfo();
if (UMC_OK != umcRes)
return umcRes;
// return specific information
if ((initParams.m_lFlags & FLAG_VSPL_VIDEO_HEADER_REQ) ||
(initParams.m_lFlags & FLAG_VSPL_VIDEO_FRAME_REQ))
{
/* DEBUG: need to develop */
}
return UMC_OK;
} // Status AVSSplitter::Init(SplitterParams &initParams)
Status AVSSplitter::GetNextData(MediaData *pDst, Ipp32u)
{
Status umcRes;
// check error(s)
if (NULL == pDst)
return UMC_ERR_NULL_PTR;
if (false == m_pVideoBuffer)
return UMC_ERR_NOT_INITIALIZED;
// skip the previous sample
if (m_latestSample.GetBufferPointer())
{
// move data pointer and skip used source
m_latestSample.MoveDataPointer((Ipp32s) m_latestSample.GetDataSize());
m_pVideoBuffer->UnLockOutputBuffer(&m_latestSample);
m_latestSample.SetBufferPointer(NULL, 0);
}
// lock the next portion of source data
umcRes = m_pVideoBuffer->LockOutputBuffer(&m_latestSample);
if (UMC_OK != umcRes)
return umcRes;
// provide buffer to caller
pDst->SetBufferPointer((Ipp8u *) m_latestSample.GetBufferPointer(), m_latestSample.GetDataSize());
pDst->SetDataSize(m_latestSample.GetDataSize());
return UMC_OK;
} // Status AVSSplitter::GetNextData(MediaData *pDst, Ipp32u)
Status AVSSplitter::GetInfo(SplitterInfo **pSplitterInfo)
{
// copy pointer to info
*pSplitterInfo = &m_info;
return UMC_OK;
} // Status AVSSplitter::GetInfo(SplitterInfo *pSplitterInfo)
Status AVSSplitter::PrepareStreamInfo(void)
{
Status umcRes;
// lock the first portion of source data
do
{
umcRes = m_pVideoBuffer->LockOutputBuffer(&m_latestSample);
if (UMC_OK == umcRes)
break;
vm_time_sleep(AVS_SPLITTER_TIME_TO_SLEEP);
} while (UMC_ERR_NOT_ENOUGH_DATA == umcRes);
if (UMC_OK != umcRes)
return umcRes;
// first header should be a sequence header
umcRes = UpdateSplitterInfo((Ipp8u *) m_latestSample.GetDataPointer(),
m_latestSample.GetDataSize());
if (UMC_OK != umcRes)
return umcRes;
// we need to unlock source to avoid it's dropping
m_pVideoBuffer->UnLockOutputBuffer(&m_latestSample);
// and set data size to 0 to avoid it's skipping
m_latestSample.SetBufferPointer(NULL, 0);
return UMC_OK;
} // Status AVSSplitter::PrepareStreamInfo(void)
static
struct AVSAspectRatio
{
Ipp32u horz;
Ipp32u vert;
} AVSAspectRatios[] =
{
{1, 1},
{1, 1},
{4, 3},
{16, 9},
{221, 100},
{1, 1},
{1, 1},
{1, 1},
{1, 1},
{1, 1},
{1, 1},
{1, 1},
{1, 1},
{1, 1},
{1, 1},
{1, 1}
};
Status AVSSplitter::UpdateSplitterInfo(Ipp8u *pSource, size_t srcSize)
{
AVS_SEQUENCE_HEADER seqHeader;
Status umcRes;
// decode sequence header
umcRes = DecodeAVSSequenceHeader(&seqHeader, pSource, srcSize);
if (UMC_OK != umcRes)
return umcRes;
// set default information
m_info.m_splitter_flags = VIDEO_SPLITTER;
m_info.number_audio_tracks = 0;
m_info.number_video_tracks = 1;
m_info.m_system_info.stream_type = AVS_PURE_VIDEO_STREAM;
m_info.m_SystemType = AVS_PURE_VIDEO_STREAM;
m_info.m_nOfTracks = 1;
// fill information into the structure
m_info.m_video_info.clip_info.width = seqHeader.horizontal_size;
m_info.m_video_info.clip_info.height = seqHeader.vertical_size;
m_info.m_video_info.bitrate = (seqHeader.bit_rate_upper << 18) + seqHeader.bit_rate_lower;
m_info.m_video_info.aspect_ratio_width = AVSAspectRatios[seqHeader.aspect_ratio].horz;
m_info.m_video_info.aspect_ratio_height = AVSAspectRatios[seqHeader.aspect_ratio].vert;
m_info.m_video_info.framerate = seqHeader.frame_rate;
m_info.m_video_info.interlace_type = (seqHeader.progressive_sequence) ?
(PROGRESSIVE) :
(INTERLEAVED_TOP_FIELD_FIRST);
m_info.m_video_info.stream_type = AVS_VIDEO;
m_info.m_video_info.streamPID = 0;
m_info.m_ppTrackInfo = new TrackInfo*[1];
if(m_info.m_ppTrackInfo == NULL)
{
Close();
return UMC_ERR_ALLOC;
}
m_info.m_ppTrackInfo[0] = new TrackInfo;
if(m_info.m_ppTrackInfo[0] == NULL)
{
Close();
return UMC_ERR_ALLOC;
}
m_info.m_ppTrackInfo[0]->m_Type = TRACK_AVS;
m_info.m_ppTrackInfo[0]->m_isSelected = 1;
m_info.m_ppTrackInfo[0]->m_pStreamInfo = new VideoStreamInfo;
if(m_info.m_ppTrackInfo[0]->m_pStreamInfo == NULL)
{
Close();
return UMC_ERR_ALLOC;
}
VideoStreamInfo* video_info = (VideoStreamInfo *)m_info.m_ppTrackInfo[0]->m_pStreamInfo;
*video_info= m_info.m_video_info;
return UMC_OK;
} // Status AVSSplitter::UpdateSplitterInfo(Ipp8u *pSource, size_t srcSize)
} // namespace UMC
#endif // #if defined(UMC_ENABLE_AVS_SPLITTER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -