📄 base_video_render.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) 2003-2005 Intel Corporation. All Rights Reserved.//*/#include "base_video_render.h"#include "umc_video_data.h"namespace UMC{BaseVideoRender::BaseVideoRender(): m_iBuffersNum(0), m_iReadIndex(-1), m_iWriteIndex(-1), m_bPrevIp(false), m_bShow(true), m_bReorder(false){ memset(m_Buffers, 0, sizeof(m_Buffers)); memset(&m_dst_rect, 0, sizeof(m_dst_rect)); memset(&m_src_rect, 0, sizeof(m_src_rect)); m_SrcInfo.width = m_SrcInfo.height = 10; m_bPrepareForReposition = false;} // BaseVideoRender::BaseVideoRender():BaseVideoRender::~BaseVideoRender(){ Close();} // BaseVideoRender::~BaseVideoRender()// Initialize the render, return false if failed, call Close anywayStatus BaseVideoRender::Init(MediaReceiverParams *pInit){ Status umcRes = UMC_OK; VideoRenderParams* pParams = DynamicCast<VideoRenderParams>(pInit); if (NULL == pParams) umcRes = UMC_NULL_PTR; m_bPrepareForReposition = false; m_bPrevIp = false; m_bStop = false; m_SrcInfo = pParams->info; m_bShow = true; m_iWriteIndex = -1; m_iReadIndex = -1; m_bReorder = pParams->lFlags & FLAG_VREN_REORDER; if (UMC_OK == umcRes) umcRes = m_SuncMut.Init(); assert(2 < MIN_FRAME_BUFFERS); if (UMC_OK == umcRes) umcRes = m_hDoneBufSema.Init(0); if (UMC_OK == umcRes) { umcRes = m_hFreeBufSema.Init(m_iBuffersNum - 2); m_hFreeBufSemaCount = m_iBuffersNum - 2; } if (UMC_OK == umcRes) umcRes = ResizeDisplay(pParams->disp, pParams->range); if (UMC_OK != umcRes) Close(); return umcRes;} // Status BaseVideoRender::Init(MediaReceiverParams *pInit)Status BaseVideoRender::LockInputBuffer(MediaData *pInData){ Status umcRes = UMC_OK; VideoData *pVideoData = DynamicCast<VideoData> (pInData); if (NULL == pInData) umcRes = UMC_NULL_PTR; if (UMC_OK == umcRes) umcRes = m_hFreeBufSema.Wait(MAX_FRAME_BUFFERS * 40); int iPitch = 0; vm_byte *pbVideoMemory = NULL; if (UMC_OK == umcRes) { m_SuncMut.Lock(); m_hFreeBufSemaCount--; if (++m_iWriteIndex >= m_iBuffersNum) m_iWriteIndex = 0; iPitch = LockSurface(&pbVideoMemory); m_SuncMut.Unlock(); if (0 == iPitch) umcRes = UMC_FAILED_TO_ALLOCATE_BUFFER; } if (UMC_OK == umcRes) { pVideoData->SetDest(pbVideoMemory); pVideoData->SetPitch(iPitch); } return umcRes;} // Status BaseVideoRender::LockInputBuffer(MediaData *pInData)// Reserve a frame buffer for decoding the current frameint BaseVideoRender::ReserveBuffer(unsigned char **ppucVidMem){ int iRes = 0; VideoData Data; if (UMC_OK == LockInputBuffer(&Data)) { iRes = Data.m_lPitch[0]; if (NULL != ppucVidMem) *ppucVidMem = Data.m_lpDest[0]; } return iRes;} // int BaseVideoRender::ReserveBuffer(unsigned char **ppucVidMem)Status BaseVideoRender::UnLockInputBuffer(MediaData* pInData, Status StreamStatus){ Status umcRes = (m_iWriteIndex >= 0) ? UMC_OK : UMC_NOT_INITIALIZED; VideoData *pVideoData = DynamicCast<VideoData> (pInData); if (NULL == pVideoData) return UMC_NULL_PTR; vm_var32 width = 0, height = 0; ColorFormat cf; pVideoData->GetVideoParameters(width, height, cf); if(m_SrcInfo.width != width) { m_SrcInfo.width = width; ResizeSource(); } if(m_SrcInfo.height != height) { m_SrcInfo.height = height; ResizeSource(); } if (UMC_OK == umcRes) { m_SuncMut.Lock(); double dfEndTime; pVideoData->GetTime(m_Buffers[m_iWriteIndex].frame_time, dfEndTime); m_Buffers[m_iWriteIndex].frame_type = pVideoData->m_FrameType; UnlockSurface(0); if (m_bReorder) { if (!m_bPrevIp) { if (pVideoData->m_FrameType == B_PICTURE) m_hDoneBufSema.Signal(); else m_bPrevIp = true; } else { if (pVideoData->m_FrameType == B_PICTURE) { int prev_index = (!m_iWriteIndex) ? (m_iBuffersNum - 1) : (m_iWriteIndex - 1); sFrameBuffer tmp = m_Buffers[m_iWriteIndex]; m_Buffers[m_iWriteIndex] = m_Buffers[prev_index]; m_Buffers[prev_index] = tmp; } m_hDoneBufSema.Signal(); } } else m_hDoneBufSema.Signal(); m_SuncMut.Unlock(); } if (UMC_END_OF_STREAM == StreamStatus) Stop(); return umcRes;} // Status BaseVideoRender::UnLockInputBuffer(MediaData* pInData, Status StreamStatus)// Buffer the decoded frameStatus BaseVideoRender::BufferReserved(double frame_time, FrameType frame_type){ VideoData VideoData; VideoData.SetFrameType(frame_type); VideoData.SetTime(frame_time); return UnLockInputBuffer(&VideoData);} // Status BaseVideoRender::BufferReserved(double frame_time, FrameType frame_type)Status BaseVideoRender::Stop(){ Status umcRes = UMC_OK; VideoData InData; if (m_bStop) return umcRes; m_SuncMut.Lock(); if (UMC_OK == umcRes) { if (m_iWriteIndex < 0) m_Buffers[0].frame_time = -1; else { //Lock buffer for end if (UMC_OK == umcRes) umcRes = m_hFreeBufSema.Wait(MAX_FRAME_BUFFERS * 40); if (UMC_OK == umcRes) { // m_SuncMut.Lock(); m_hFreeBufSemaCount--; if (++m_iWriteIndex >= m_iBuffersNum) m_iWriteIndex = 0; // m_SuncMut.Unlock(); } // Unlock it immidiatly // m_SuncMut.Lock(); m_Buffers[m_iWriteIndex].frame_time = -1; // m_SuncMut.Unlock(); } m_hDoneBufSema.Signal(); } m_bStop = true; m_SuncMut.Unlock(); return umcRes;} // Status BaseVideoRender::BufferReserved(double frame_time, FrameType frame_type)void BaseVideoRender::BufferEndOfClip(){ Stop();} // void BaseVideoRender::BufferEndOfClip()// Peek presentation of next frame, return presentation timedouble BaseVideoRender::GetRenderFrame(){ double dfRes = -1; while (VM_TIMEOUT == m_hDoneBufSema.Wait(MAX_FRAME_BUFFERS * 40) && !m_bStop && !m_bPrepareForReposition); //if(!m_bPrepareForReposition) { m_SuncMut.Lock(); if (++m_iReadIndex >= m_iBuffersNum) m_iReadIndex = 0; dfRes = m_Buffers[m_iReadIndex].frame_time; m_SuncMut.Unlock(); } return dfRes;} // double BaseVideoRender::GetRenderFrame()// Resize the display rectangularStatus BaseVideoRender::ResizeDisplay(UMC::RECT &disp, UMC::RECT &range){ m_SuncMut.Lock(); m_disp = disp; m_range= range; // Scale the display while keeping the size ratio double scaled_width = m_SrcInfo.width; double scaled_height = m_SrcInfo.height; short width = (short)(disp.right - disp.left); short height = (short)(disp.bottom - disp.top); double rxy = min((double)width/scaled_width,(double)height/scaled_height); scaled_width *= rxy; scaled_height *= rxy; UMC::RECT tmp_dst; tmp_dst.left = (short)(disp.left + (width - (short)scaled_width)/2); tmp_dst.right = (short)(tmp_dst.left + (short)scaled_width); tmp_dst.top = (short)(disp.top + (height - (short)scaled_height)/2); tmp_dst.bottom = (short)(tmp_dst.top + (short)scaled_height); UMC::RECT tmp_src; tmp_src.right = (short)m_SrcInfo.width; tmp_src.bottom = (short)m_SrcInfo.height; tmp_src.left= 0; tmp_src.top = 0; if(tmp_dst.left < 0) { tmp_dst.right -= tmp_dst.left; tmp_dst.left = 0; } if(m_disp.left < 0) { m_disp.right -= m_disp.left; m_disp.left = 0; } // Remove caption information from the clips if (tmp_src.bottom == 1088) tmp_src.bottom = 1080; if (tmp_src.bottom == 544) tmp_src.bottom = 540; if (tmp_src.bottom == 272) tmp_src.bottom = 270; // Adjust m_src_rect & m_dst_rect to the work area if (((tmp_dst.left + 15) & (~15)) >= range.right || (tmp_dst.right & (~15)) <= range.left || tmp_dst.top >= range.bottom || tmp_dst.bottom <= range.top) { // Out of screen m_bShow = false; } else { if (tmp_dst.left < range.left) { tmp_src.left = (short)(tmp_src.left + (range.left - tmp_dst.left) / rxy); tmp_dst.left = range.left; } if (tmp_dst.right > range.right) { tmp_src.right = (short)(tmp_src.right - (tmp_dst.right - range.right) / rxy); tmp_dst.right = range.right; } if (tmp_dst.top < range.top) { tmp_src.top = (short)(tmp_src.top + (range.top - tmp_dst.top) / rxy); tmp_dst.top = range.top; } if (tmp_dst.bottom > range.bottom) { tmp_src.bottom = (short)(tmp_src.bottom - (tmp_dst.bottom - range.bottom) / rxy); tmp_dst.bottom = range.bottom; } } // Align the width to multiples of 16 //tmp_src.left = (short)((tmp_src.left + 15) & (~15)); //tmp_src.right = (short)((tmp_src.right + 15) & (~15)); if ((tmp_dst.left & 15) < 8) tmp_dst.left = (short)(tmp_dst.left & (~15)); else tmp_dst.left = (short)((tmp_dst.left + 15) & (~15)); if ((tmp_dst.right & 15) < 8) tmp_dst.right = (short)(tmp_dst.right & (~15)); else tmp_dst.right = (short)((tmp_dst.right + 15) & (~15)); m_src_rect = tmp_src; m_dst_rect = tmp_dst; m_SuncMut.Unlock(); return UMC_OK;} // Status BaseVideoRender::ResizeDisplay(UMC::RECT &disp, UMC::RECT &range)Status BaseVideoRender::ResizeSource(){ m_SuncMut.Lock(); UMC::RECT disp = m_disp; UMC::RECT range = m_range; // Scale the display while keeping the size ratio double scaled_width = m_SrcInfo.width; double scaled_height = m_SrcInfo.height; short width = (short)(disp.right - disp.left); short height = (short)(disp.bottom - disp.top); double rxy = min((double)width/scaled_width,(double)height/scaled_height); scaled_width *= rxy; scaled_height *= rxy; UMC::RECT tmp_src; tmp_src.right = (short)m_SrcInfo.width; tmp_src.bottom = (short)m_SrcInfo.height; tmp_src.left= 0; tmp_src.top = 0; // Remove caption information from the clips if (tmp_src.bottom == 1088) tmp_src.bottom = 1080; if (tmp_src.bottom == 544) tmp_src.bottom = 540; if (tmp_src.bottom == 272) tmp_src.bottom = 270; // Align the width to multiples of 16 tmp_src.left = (short)((tmp_src.left + 15) & (~15)); tmp_src.right = (short)((tmp_src.right + 15) & (~15)); m_src_rect = tmp_src; m_SuncMut.Unlock(); return UMC_OK;} // Status BaseVideoRender::ResizeSource()// Show/Hide Surfacevoid BaseVideoRender::ShowSurface(){ m_bShow = true;} // void BaseVideoRender::ShowSurface()void BaseVideoRender::HideSurface(){ m_bShow = false;} // void BaseVideoRender::HideSurface()// Terminate the renderStatus BaseVideoRender::Close(){ m_SuncMut.LockIfInitialized(); m_iReadIndex = -1; m_iWriteIndex = -1; m_iBuffersNum = 0; m_bShow = true; m_bReorder = false; m_SuncMut.UnlockIfInitialized(); return UMC_OK;} // Status BaseVideoRender::Close()Status BaseVideoRender::Reset(){ m_bPrevIp = false; m_bStop = false; m_bShow = true; m_iWriteIndex = -1; m_iReadIndex = -1; m_hDoneBufSema.Init(0); for(int i = 0; i < 8; i++) m_Buffers[i].frame_time = -1; m_hFreeBufSema.Init(m_iBuffersNum - 2); m_hFreeBufSemaCount = m_iBuffersNum - 2; m_bPrepareForReposition = false; return UMC_OK;} // Status BaseVideoRender::Reset()}// namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -