📄 umc_mpeg2_dec.cpp
字号:
frame_buffer.retrieve = -1;
frame_buffer.ind_his_p = 0;
frame_buffer.ind_his_b = 1;
frame_buffer.ind_his_free = 2;
frame_buffer.frame_p_c_n[0].frame_time = -1;
frame_buffer.frame_p_c_n[1].frame_time = -1;
frame_buffer.frame_p_c_n[0].duration = 0;
frame_buffer.frame_p_c_n[1].duration = 0;
sequenceHeader.stream_time_temporal_reference = -1;
sequenceHeader.stream_time = 0;
return UMC_OK;
}
Status MPEG2VideoDecoderBase::FlushBuffer(MediaData* data, bool threaded)
{
IppVideoContext *video = Video[0]; // it decodes tail of frame
Ipp8u* plast = GET_BYTE_PTR(video->bs);
Ipp8u* pend = GET_END_PTR(video->bs);
if (plast > pend)
plast = pend;
return data->MoveDataPointer(plast - (Ipp8u*)data->GetDataPointer());
}
Status MPEG2VideoDecoderBase::PrepareBuffer(MediaData* data)
{
IppVideoContext *video = Video[0];
Ipp8u *ptr;
Ipp32s size;
if (data == 0) {
return UMC_OK;
}
ptr = (Ipp8u*)data->GetDataPointer();
size = data->GetDataSize();
INIT_BITSTREAM(video->bs, ptr, ptr + size);
return UMC_OK;
}
bool MPEG2VideoDecoderBase::IsPictureToSkip()
{
if (NONE_PICTURE >= PictureHeader.picture_coding_type ||
B_PICTURE < PictureHeader.picture_coding_type)
{
if(!(PictureHeader.picture_coding_type == D_PICTURE &&
m_ClipInfo.stream_type == MPEG1_VIDEO))
{
return true;
}
}
if(frame_buffer.field_buffer_index == 0) // not for second field
{
sequenceHeader.stream_time_temporal_reference++;
if(PictureHeader.picture_coding_type == I_PICTURE)
{
sequenceHeader.bdied = 0;
if(sequenceHeader.first_i_occure)
sequenceHeader.first_p_occure = 1;
sequenceHeader.first_i_occure = 1;
}
else if(!sequenceHeader.first_i_occure) {
return true;
}
else if(PictureHeader.picture_coding_type == P_PICTURE) {
sequenceHeader.bdied = 0;
sequenceHeader.first_p_occure = 1;
}
else if(PictureHeader.picture_coding_type == B_PICTURE) {
if(!sequenceHeader.first_p_occure &&
(!sequenceHeader.closed_gop || sequenceHeader.broken_link )) {
return true;
}
}
}
if(PictureHeader.picture_coding_type == 3 && sequenceHeader.is_skipped_b ||
!sequenceHeader.first_p_occure ||
((PictureHeader.picture_coding_type == 3) && m_bNoBframes) ||
((PictureHeader.picture_coding_type == 2) && m_bNoPframes))
{
if(sequenceHeader.bdied && sequenceHeader.first_p_occure &&
!(((PictureHeader.picture_coding_type == 3) && m_bNoBframes) ||
((PictureHeader.picture_coding_type == 2) && m_bNoPframes)))
{
sequenceHeader.bdied = 0;
} else {
if(sequenceHeader.is_skipped_b > 0)
sequenceHeader.is_skipped_b--;
if(sequenceHeader.first_p_occure)
{
sequenceHeader.num_of_skipped++;
sequenceHeader.bdied = 1;
return true;
}
}
}
return false;
}
Status MPEG2VideoDecoderBase::GetFrame(MediaData* input, MediaData* output)
{
Status umcRes;
if ((NULL == input) || (NULL == input->GetDataPointer()))
{
Ipp64f dTime;
if (output == 0) {
return UMC_ERR_NULL_PTR;
}
if (m_decodedFrameNum <= 0) {
return UMC_ERR_NOT_ENOUGH_DATA;
}
CalculateFrameTime(frame_buffer.frame_p_c_n[frame_buffer.next_index].frame_time, &dTime);
m_decodedFrameNum--;
frame_buffer.retrieve = frame_buffer.next_index;
return SaveFrame(frame_buffer.next_index,
dTime,
output);
}
if (NULL == output) {
return UMC_ERR_NULL_PTR;
}
PrepareBuffer(input);
umcRes = DecodeFrame(Video[0], input->GetTime(), output);
FlushBuffer(input, m_ClipInfo.stream_type == MPEG2_VIDEO); // ?
return umcRes;
}
Status MPEG2VideoDecoderBase::DecodeFrame(IppVideoContext *video,
Ipp64f currentTime,
MediaData *output)
{
Status umcRes = UMC_OK;
Ipp32u code;
if (!sequenceHeader.is_decoded) {
if(UMC_OK != FindSequenceHeader(Video[0]))
return (UMC_ERR_NOT_ENOUGH_DATA);
umcRes = DecodeSequenceHeader(Video[0]);
if(UMC_OK != umcRes)
return umcRes;
}
SHOW_BITS(video->bs, 32, code);
do {
GET_START_CODE(video->bs, code);
// some headers are possible here
if(code == (Ipp32u)UMC_ERR_NOT_ENOUGH_DATA)
if(GET_OFFSET(video->bs) > 0) // some data was decoded
return UMC_ERR_NOT_ENOUGH_DATA;
else // no start codes found
return UMC_ERR_SYNC;
if(code == SEQUENCE_END_CODE)
continue;
if(code != PICTURE_START_CODE) {
if (DecodeHeader(code, video) == UMC_ERR_NOT_ENOUGH_DATA) {
return (UMC_ERR_NOT_ENOUGH_DATA);
}
}
} while (code != PICTURE_START_CODE);
umcRes = DecodeHeader(PICTURE_START_CODE, video);
if(umcRes != UMC_OK)
return (umcRes);
// We don't advance PTS for input data - we don't want to guess it
// without decoding.
Ipp64f dTime;
CalculateFrameTime(currentTime, &dTime);
if (IsPictureToSkip()) {
return UMC_ERR_NOT_ENOUGH_DATA;
}
umcRes = DecodePicture();
if (UMC_OK != umcRes)
{ // Error in DecodePicture()
return umcRes;
}
if (PictureHeader.picture_structure != IPPVC_FRAME_PICTURE &&
frame_buffer.field_buffer_index == 1)
{
return UMC_ERR_NOT_ENOUGH_DATA;
}
m_decodedFrameNum++; // full frame decoded
if (frame_buffer.retrieve < 0) {
return UMC_ERR_NOT_ENOUGH_DATA;
}
m_decodedFrameNum--; // frame retrieved
return SaveFrame(frame_buffer.retrieve, dTime, output);
}
// Close decoding
Status MPEG2VideoDecoderBase::Close()
{
Ipp32s i;
DeleteTables();
m_dPlaybackRate = 1;
if (m_lpThreads)
{
for (i = 1; i < m_nNumberOfAllocatedThreads;i += 1)
vm_event_signal(m_lpQuit + i);
for (i = 1; i < m_nNumberOfAllocatedThreads;i += 1)
vm_event_signal(m_lpStartEvent + i);
for (i = 1; i < m_nNumberOfAllocatedThreads;i += 1)
{
if (vm_thread_is_valid(m_lpThreads + i))
vm_thread_wait(m_lpThreads + i);
}
}
// delete all threading tools
if (m_lpQuit)
{
for (i = 1;i < m_nNumberOfAllocatedThreads;i += 1)
{
if (vm_event_is_valid(m_lpQuit + i))
{
vm_event_destroy(m_lpQuit + i);
vm_event_set_invalid(m_lpQuit + i);
}
}
delete [] m_lpQuit;
m_lpQuit = NULL;
}
if (m_lpThreads)
{
for (i = 1;i < m_nNumberOfAllocatedThreads;i += 1)
vm_thread_set_invalid(m_lpThreads + i);
delete [] m_lpThreads;
m_lpThreads = NULL;
}
if (m_lpStartEvent)
{
for (i = 1;i < m_nNumberOfAllocatedThreads;i += 1)
{
if (vm_event_is_valid(m_lpStartEvent + i))
{
vm_event_destroy(m_lpStartEvent + i);
vm_event_set_invalid(m_lpStartEvent + i);
}
}
delete [] m_lpStartEvent;
m_lpStartEvent = NULL;
}
if (m_lpStopEvent)
{
for (i = 1;i < m_nNumberOfAllocatedThreads;i += 1)
{
if (vm_event_is_valid(m_lpStopEvent + i))
{
vm_event_destroy(m_lpStopEvent + i);
vm_event_set_invalid(m_lpStopEvent + i);
}
}
delete [] m_lpStopEvent;
m_lpStopEvent = NULL;
}
if (m_lpThreadsID)
{
delete [] m_lpThreadsID;
m_lpThreadsID = NULL;
}
if (m_pCCData)
{
delete m_pCCData;
m_pCCData = NULL;
}
return UMC_OK;
}
MPEG2VideoDecoderBase::MPEG2VideoDecoderBase()
{
Video = NULL;
m_decodedFrameNum = 0;
m_lFlags = 0;
m_ClipInfo.framerate = 0;
m_ClipInfo.clip_info.width =
m_ClipInfo.clip_info.height= 100;
memset(&sequenceHeader, 0, sizeof(sequenceHeader));
memset(&PictureHeader, 0, sizeof(PictureHeader));
memset(&frame_buffer, 0, sizeof(frame_buffer));
m_ClipInfo.stream_type = UNDEF_VIDEO;
sequenceHeader.profile = MPEG2_PROFILE_MAIN;
sequenceHeader.level = MPEG2_LEVEL_MAIN;
frame_buffer.allocated_mb_width = 0;
frame_buffer.allocated_mb_height = 0;
frame_buffer.allocated_cformat = NONE;
frame_buffer.mid_context_data = MID_INVALID;
frame_buffer.ptr_context_data = NULL; // internal buffer not allocated
m_nNumberOfThreads = 1;
m_nNumberOfAllocatedThreads = 1;
m_lpQuit = NULL;
m_lpThreads = NULL;
m_lpStartEvent = NULL;
m_lpStopEvent = NULL;
m_lpThreadsID = NULL;
//m_pStartCodesData = NULL;
m_pCCData = NULL;
m_dPlaybackRate = 1;
vlcMBAdressing.table0 = vlcMBAdressing.table1 = NULL;
vlcMBType[0].table0 = vlcMBType[0].table1 = NULL;
vlcMBType[1].table0 = vlcMBType[1].table1 = NULL;
vlcMBType[2].table0 = vlcMBType[2].table1 = NULL;
vlcMBPattern.table0 = vlcMBPattern.table1 = NULL;
vlcMotionVector.table0 = vlcMotionVector.table1 = NULL;
}
MPEG2VideoDecoderBase::~MPEG2VideoDecoderBase()
{
Close();
}
Status MPEG2VideoDecoderBase::ResetSkipCount()
{
AdjustSpeed(-10);
return UMC_OK;
}
Status MPEG2VideoDecoderBase::SkipVideoFrame(Ipp32s count)
{
AdjustSpeed(count);
return UMC_OK;
}
bool MPEG2VideoDecoderBase::AdjustSpeed(Ipp32s nframe)
{
if (nframe>0) IncreaseSpeedN(nframe);
if (nframe<0) DecreaseSpeed(-(Ipp64f)nframe/
(Ipp64f)m_ClipInfo.framerate);
return true;
}
Ipp32s MPEG2VideoDecoderBase::IncreaseSpeedN (Ipp32s numoffr)
{
sequenceHeader.is_skipped_b+=numoffr;
return numoffr;
}
Ipp32s MPEG2VideoDecoderBase::DecreaseSpeed(Ipp64f delta)
{
Ipp32s num_skipp_frames = (Ipp32s)(delta * m_ClipInfo.framerate);
if(num_skipp_frames <= 3)
num_skipp_frames = 1;
if(!num_skipp_frames)
return 0;
if(sequenceHeader.is_skipped_b > 0)
sequenceHeader.is_skipped_b-=num_skipp_frames;
if(sequenceHeader.is_skipped_b < 0)
sequenceHeader.is_skipped_b = 0;
return num_skipp_frames;
}
Ipp32s MPEG2VideoDecoderBase::IncreaseSpeed(Ipp64f delta)
{
// IppVideoContext* video = &pContext->Video[0];
Ipp32s num_skipp_frames = (Ipp32s)(delta * m_ClipInfo.framerate);
if(num_skipp_frames <= 3)
num_skipp_frames = 1;
if(num_skipp_frames > 5)
num_skipp_frames = 5;
sequenceHeader.is_skipped_b+=num_skipp_frames;
return num_skipp_frames;
}
bool MPEG2VideoDecoderBase::AdjustSpeed(Ipp64f delta)
{
if (delta>0) IncreaseSpeed(delta);
if (delta<0) DecreaseSpeed(-delta);
return true;
}
Ipp32u MPEG2VideoDecoderBase::GetNumOfSkippedFrames()
{
return sequenceHeader.num_of_skipped;
}
Status MPEG2VideoDecoderBase::Reset()
{
sequenceHeader.first_i_occure = 0;
sequenceHeader.first_p_occure = 0;
sequenceHeader.bdied = 0;
sequenceHeader.broken_link = 0;
sequenceHeader.closed_gop = 0;
sequenceHeader.gop_picture = 0;
sequenceHeader.gop_second = 0;
sequenceHeader.stream_time = 0; //-sequenceHeader.delta_frame_time;
sequenceHeader.frame_rate_extension_d = 0;
sequenceHeader.frame_rate_extension_n = 0;
PictureHeader.intra_vlc_format = 0;
PictureHeader.curr_intra_dc_multi = intra_dc_multi[0];
m_decodedFrameNum = 0;
m_bNoBframes = false;
m_bNoPframes = false;
m_bOwnAllocator = false;
frame_buffer.prev_index = 0;
frame_buffer.curr_index = 0;
frame_buffer.next_index = 1;
frame_buffer.retrieve = -1;
frame_buffer.ind_his_p = 0;
frame_buffer.ind_his_b = 1;
frame_buffer.ind_his_free = 2;
frame_buffer.frame_p_c_n[0].frame_time = -1;
frame_buffer.frame_p_c_n[1].frame_time = -1;
frame_buffer.frame_p_c_n[0].duration = 0;
frame_buffer.frame_p_c_n[1].duration = 0;
frame_buffer.field_buffer_index = 0;
if (m_pCCData)
{
m_ccCurrData.SetBufferPointer(0,0);
m_pCCData->Reset();
}
return UMC_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -