📄 umc_mpeg2_dec.cpp
字号:
video = &Video[0]; // tail of the frame is decoded here stDataLeft = GET_REMAINED_BYTES(video->bs); GET_BITS32(video->bs, code) while(stDataLeft > 0 && (code != PICTURE_START_CODE) && (code != SEQUENCE_END_CODE)) { if(UMC_NOT_ENOUGH_DATA == umcRes) { stDataLeft = 0; } else { DecodeHeader(code, 0); GET_START_CODE(video->bs, code); if(code == (unsigned int)UMC_NOT_ENOUGH_DATA) { stDataLeft = 0; break; } stDataLeft = GET_REMAINED_BYTES(video->bs); } } stDataLeft -= 4; //we have got last start code, but did not count // Suppose the last data can't be next MPEG2 frame if (0x10 > stDataLeft) { //assume padding bytes after PSC stDataLeft = 0; } else VM_ASSERT(0); return data->MoveDataPointer(data->GetDataSize()-stDataLeft);}Status MPEG2VideoDecoderBase::PrepareBuffer(MediaData* data){ IppVideoContext *video = &Video[0]; Ipp8u *ptr; int size; if (data == 0) { return UMC_OK; } ptr = (Ipp8u*)data->GetDataPointer(); size = data->GetDataSize(); INIT_BITSTREAM(video->bs, ptr, ptr + size); return UMC_OK;}Status MPEG2VideoDecoderBase::GetFrame(MediaData* data, MediaData* out){ Status umcRes; if(!data) { if(m_decodedFrameNum > 0) { m_decodedFrameNum--; return RetrieveLastFrame(out); } else return UMC_NULL_PTR; } PrepareBuffer(data); umcRes = GetNextFrame(data, out); if (NULL != data) { FlushBuffer(data, sequenceHeader.stream_type == MPEG2_VIDEO); // ? } return umcRes;}Status MPEG2VideoDecoderBase::GetInfo(BaseCodecParams *pbInfo){ Status umcRes = UMC_OK; VideoDecoderParams *pInfo = DynamicCast<VideoDecoderParams> (pbInfo); // check error(s) if (NULL == pInfo) { umcRes = UMC_NULL_PTR; } if (UMC_OK == umcRes) { umcRes = VideoDecoder::GetInfo(pbInfo); } pInfo->info = m_ClipInfo; if (UMC_OK == umcRes) { if(ulResized) { pInfo->info.clip_info.width /= ulResized; pInfo->info.clip_info.height /= ulResized; } else { pInfo->info.clip_info.width = m_Convert.ConversionInit.SizeDest.width; pInfo->info.clip_info.height = m_Convert.ConversionInit.SizeDest.height; } } return umcRes;}// Close decodingStatus MPEG2VideoDecoderBase::Close(){ int i; m_pConverter = NULL; 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_lpConverter = NULL; m_decodedFrameNum = 0; m_maxThreads = 1; m_lFlags = 0; m_ClipInfo.framerate = 0; m_ClipInfo.clip_info.width = m_ClipInfo.clip_info.height= 100; m_uiEndian = 2; memset(&sequenceHeader, 0, sizeof(sequenceHeader)); memset(&PictureHeader, 0, sizeof(PictureHeader)); sequenceHeader.stream_type = UNDEF_VIDEO; 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_bTwoPictures = 0; m_dPlaybackRate = 1;}MPEG2VideoDecoderBase::~MPEG2VideoDecoderBase(){ Close();}Status MPEG2VideoDecoderBase::ResetSkipCount(){ AdjustSpeed(-10); return UMC_OK;}Status MPEG2VideoDecoderBase::SkipVideoFrame(int count){ AdjustSpeed(count); return UMC_OK;}bool MPEG2VideoDecoderBase::AdjustSpeed(int nframe){ if (nframe>0) IncreaseSpeedN(nframe); if (nframe<0) DecreaseSpeed(-(double)nframe/ (double)m_ClipInfo.framerate); return true;}int MPEG2VideoDecoderBase::IncreaseSpeedN (int numoffr){ sequenceHeader.is_skipped_b+=numoffr; return numoffr;}int MPEG2VideoDecoderBase::DecreaseSpeed(double delta){ int num_skipp_frames = (int)(delta / sequenceHeader.delta_frame_time); 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;}int MPEG2VideoDecoderBase::IncreaseSpeed(double delta){ int num_skipp_frames = (int)(delta / sequenceHeader.delta_frame_time); 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(double delta){ if (delta>0) IncreaseSpeed(delta); if (delta<0) DecreaseSpeed(-delta); return true;}vm_var32 MPEG2VideoDecoderBase::GetSkipedFrame(){ return sequenceHeader.num_of_skipped;}Status MPEG2VideoDecoderBase::Reset(){ IppVideoContext* video = &Video[0]; if(Video) { video->frame_buffer.prev_index = 0; video->frame_buffer.curr_index = 0; video->frame_buffer.next_index = 1; video->frame_buffer.retrieve = -1; video->frame_buffer.ind_his_p = 0; video->frame_buffer.ind_his_b = 1; video->frame_buffer.ind_his_free = 2; 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; m_decodedFrameNum = 0; PictureHeader.field_buffer_index = 0; video->frame_buffer.frame_p_c_n[0].frame_time = -1; video->frame_buffer.frame_p_c_n[1].frame_time = -1; return UMC_OK; } return UMC_NOT_INITIALIZED;}Status MPEG2VideoDecoderBase::GetPerformance (double * /*perf*/){ return UMC_OK;}Status MPEG2VideoDecoderBase::RetrieveLastFrame (MediaData* output){ IppVideoContext* video = &Video[0]; VideoData *lpVData = DynamicCast<VideoData, MediaData> (output); if (NULL != lpVData) { // set dest pointer(s) for slice conversion m_Convert.lpDest0 = (Ipp8u *) (lpVData->m_lpDest[0]); m_Convert.lpDest1 = (Ipp8u *) (lpVData->m_lpDest[1]); m_Convert.lpDest2 = (Ipp8u *) (lpVData->m_lpDest[2]); m_Convert.PitchDest0 = lpVData->m_lPitch[0]; m_Convert.PitchDest1 = lpVData->m_lPitch[1]; m_Convert.PitchDest2 = lpVData->m_lPitch[2]; lpVData->SetColorFormat(m_Convert.ConversionInit.FormatDest); lpVData->SetFrameType(video->frame_buffer.frame_p_c_n[video->frame_buffer.next_index].frame_type); lpVData->SetTime(video->frame_buffer.frame_p_c_n[video->frame_buffer.next_index].frame_time); m_Convert.lpSource0 = video->frame_buffer.frame_p_c_n[video->frame_buffer.next_index].Y_comp_data; m_Convert.lpSource2 = video->frame_buffer.frame_p_c_n[video->frame_buffer.next_index].U_comp_data; m_Convert.lpSource1 = video->frame_buffer.frame_p_c_n[video->frame_buffer.next_index].V_comp_data; m_Convert.PitchSource0 = video->frame_buffer.Y_comp_pitch; m_Convert.PitchSource2 = video->frame_buffer.U_comp_pitch; m_Convert.PitchSource1 = video->frame_buffer.V_comp_pitch; if (NULL != m_lpConverter) { return m_lpConverter->ConvertFrame(&m_Convert); } else { lpVData->SetDest( m_Convert.lpSource0, m_Convert.lpSource2, m_Convert.lpSource1); lpVData->SetPitch( m_Convert.PitchSource0, m_Convert.PitchSource2, m_Convert.PitchSource1); return UMC_OK; } } return UMC_NULL_PTR;}void MPEG2VideoDecoderBase::ReadCCData(){ unsigned int code; IppVideoContext* video = &Video[0]; Status umcRes = UMC_OK; MediaData ccData; umcRes = m_pCCData->LockInputBuffer(&ccData); if(umcRes == UMC_OK) { int counter = 3; Ipp8u* ptr = (Ipp8u*)ccData.GetBufferPointer(); int size = ccData.GetBufferSize(); SHOW_BITS_LONG(video->bs,24,code) ptr[0] = 0; ptr[1] = 0; ptr[2] = 1; ptr[3] = 0xb2; while(code != 0x000001 && counter < size) { GET_TO9BITS(video->bs, 8, code) counter++; ptr[counter] = (Ipp8u)code; SHOW_BITS_LONG(video->bs,24,code) } ccData.SetDataSize(counter+1); umcRes = m_pCCData->UnLockInputBuffer(&ccData); }}MPEG2VideoDecoder::MPEG2VideoDecoder(){ m_pDec = NULL;}MPEG2VideoDecoder::~MPEG2VideoDecoder(void){ Close();}Status MPEG2VideoDecoder::Init(BaseCodecParams *init){ Close(); m_pDec = new MPEG2VideoDecoderBase; if(!m_pDec) return UMC_ALLOC; return m_pDec->Init(init);}Status MPEG2VideoDecoder::GetFrame(MediaData* in, MediaData* out){ if(m_pDec) { return m_pDec->GetFrame(in, out); } return UMC_NOT_INITIALIZED;}Status MPEG2VideoDecoder::Close(){ if(m_pDec) { m_pDec->Close(); delete m_pDec; m_pDec = NULL; return UMC_OK; } return UMC_NOT_INITIALIZED;}Status MPEG2VideoDecoder::Reset(){ if(m_pDec) { return m_pDec->Reset(); } return UMC_NOT_INITIALIZED;}Status MPEG2VideoDecoder::GetInfo(BaseCodecParams* ininfo){ if(m_pDec) { return m_pDec->GetInfo(ininfo); } return UMC_NOT_INITIALIZED;}Status MPEG2VideoDecoder::GetPerformance(double *perf){ if(m_pDec) { return m_pDec->GetPerformance(perf); } return UMC_NOT_INITIALIZED;}Status MPEG2VideoDecoder::ResetSkipCount(){ if(m_pDec) { return m_pDec->ResetSkipCount(); } return UMC_NOT_INITIALIZED;}Status MPEG2VideoDecoder::SkipVideoFrame(int count){ if(m_pDec) { return m_pDec->SkipVideoFrame(count); } return UMC_NOT_INITIALIZED;}vm_var32 MPEG2VideoDecoder::GetSkipedFrame(){ if(m_pDec) { return m_pDec->GetSkipedFrame(); } return (vm_var32)(-1); // nobody check for -1 really}Status MPEG2VideoDecoder::GetClosedCaptureData(MediaData* pCC){ if(m_pDec) { return m_pDec->GetClosedCaptureData(pCC); } return UMC_NOT_INITIALIZED;}Status MPEG2VideoDecoder::SetParams(BaseCodecParams* params){ if(m_pDec) { return m_pDec->SetParams(params); } return UMC_NOT_INITIALIZED;}Status MPEG2VideoDecoderBase::SetParams(BaseCodecParams* params){ VideoDecoderParams *pParams = DynamicCast<VideoDecoderParams>(params); if (NULL == pParams) return UMC_NULL_PTR; if (pParams->lFlags & FLAG_VDEC_CHANGE_PLAY_RATE) m_dPlaybackRate = pParams->dPlaybackRate; return UMC_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -