Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VideoPlayer: drop FlipPage from RMs public interface #12500

Merged
merged 4 commits into from Jul 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 1 addition & 6 deletions xbmc/cores/RetroPlayer/RetroPlayerVideo.cpp
Expand Up @@ -210,14 +210,9 @@ void CRetroPlayerVideo::SendPicture(VideoPicture& picture)
{
std::atomic_bool bAbortOutput(false); //! @todo

int index = m_renderManager.AddVideoPicture(picture);
if (index < 0)
if (!m_renderManager.AddVideoPicture(picture, bAbortOutput, VS_INTERLACEMETHOD_NONE, false))
{
// Video device might not be done yet, drop the frame
m_droppedFrames++;
}
else
{
m_renderManager.FlipPage(bAbortOutput, 0.0, VS_INTERLACEMETHOD_NONE, FS_NONE, false);
}
}
2 changes: 1 addition & 1 deletion xbmc/cores/VideoPlayer/Process/VideoBuffer.cpp
Expand Up @@ -45,7 +45,7 @@ void CVideoBuffer::Acquire(std::shared_ptr<IVideoBufferPool> pool)

void CVideoBuffer::Release()
{
if (--m_refCount <= 0)
if (--m_refCount <= 0 && m_pool)
{
std::shared_ptr<IVideoBufferPool> pool = m_pool->GetPtr();
m_pool = nullptr;
Expand Down
61 changes: 20 additions & 41 deletions xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp
Expand Up @@ -387,7 +387,8 @@ void CVideoPlayerVideo::Process()
// Waiting timed out, output last picture
if (m_picture.videoBuffer)
{
OutputPicture(&m_picture, pts);
m_picture.pts = pts;
OutputPicture(&m_picture);
pts += frametime;
}

Expand Down Expand Up @@ -672,7 +673,8 @@ bool CVideoPlayerVideo::ProcessDecoderOutput(double &frametime, double &pts)
m_picture.iDuration += extraDelay;
}

int iResult = OutputPicture(&m_picture, pts + extraDelay);
m_picture.pts = pts + extraDelay;
int iResult = OutputPicture(&m_picture);

frametime = (double)DVD_TIME_BASE / m_fFrameRate;

Expand Down Expand Up @@ -793,7 +795,7 @@ std::string CVideoPlayerVideo::GetStereoMode()
return stereo_mode;
}

int CVideoPlayerVideo::OutputPicture(const VideoPicture* pPicture, double pts)
int CVideoPlayerVideo::OutputPicture(const VideoPicture* pPicture)
{
m_bAbortOutput = false;

Expand Down Expand Up @@ -841,7 +843,7 @@ int CVideoPlayerVideo::OutputPicture(const VideoPicture* pPicture, double pts)
int result = 0;

//try to calculate the framerate
m_ptsTracker.Add(pts);
m_ptsTracker.Add(pPicture->pts);
if (!m_stalled)
CalcFrameRate();

Expand All @@ -861,7 +863,7 @@ int CVideoPlayerVideo::OutputPicture(const VideoPicture* pPicture, double pts)
int lateframes;
double inputPts = m_droppingStats.m_lastPts;
m_renderManager.GetStats(lateframes, renderPts, queued, discard);
if (pts > renderPts || queued > 0)
if (pPicture->pts > renderPts || queued > 0)
{
if (inputPts >= renderPts)
{
Expand All @@ -870,7 +872,7 @@ int CVideoPlayerVideo::OutputPicture(const VideoPicture* pPicture, double pts)
}
return result | EOS_DROPPED;
}
else if (pts < iPlayingClock)
else if (pPicture->pts < iPlayingClock)
{
return result | EOS_DROPPED;
}
Expand All @@ -885,40 +887,24 @@ int CVideoPlayerVideo::OutputPicture(const VideoPicture* pPicture, double pts)

// estimate the time it will take for the next frame to get rendered
// drop the frame if it's late in regard to this estimation
double diff = pts - renderPts;
double diff = pPicture->pts - renderPts;
double mindiff = DVD_SEC_TO_TIME(1/m_fFrameRate) * (bufferLevel + 1);
if (diff < mindiff)
{
m_droppingStats.AddOutputDropGain(pts, 1);
m_droppingStats.AddOutputDropGain(pPicture->pts, 1);
return result | EOS_DROPPED;
}
}

if ((pPicture->iFlags & DVP_FLAG_DROPPED))
{
m_droppingStats.AddOutputDropGain(pts, 1);
m_droppingStats.AddOutputDropGain(pPicture->pts, 1);
CLog::Log(LOGDEBUG,"%s - dropped in output", __FUNCTION__);
return result | EOS_DROPPED;
}

// set fieldsync if picture is interlaced
EINTERLACEMETHOD deintMethod = EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE;
EFIELDSYNC mDisplayField = FS_NONE;
if (pPicture->iFlags & DVP_FLAG_INTERLACED)
{
deintMethod = CMediaSettings::GetInstance().GetCurrentVideoSettings().m_InterlaceMethod;
if (!m_processInfo.Supports(deintMethod))
deintMethod = m_processInfo.GetDeinterlacingMethodDefault();
if (deintMethod != EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE)
{
if (pPicture->iFlags & DVP_FLAG_TOP_FIELD_FIRST)
mDisplayField = FS_TOP;
else
mDisplayField = FS_BOT;
}
}
int timeToDisplay = DVD_TIME_TO_MSEC(pPicture->pts - iPlayingClock);

int timeToDisplay = DVD_TIME_TO_MSEC(pts - iPlayingClock);
// make sure waiting time is not negative
int maxWaitTime = std::min(std::max(timeToDisplay + 500, 50), 500);
// don't wait when going ff
Expand All @@ -927,30 +913,23 @@ int CVideoPlayerVideo::OutputPicture(const VideoPicture* pPicture, double pts)
int buffer = m_renderManager.WaitForBuffer(m_bAbortOutput, maxWaitTime);
if (buffer < 0)
{
m_droppingStats.AddOutputDropGain(pts, 1);
m_droppingStats.AddOutputDropGain(pPicture->pts, 1);
return EOS_DROPPED;
}

ProcessOverlays(pPicture, pts);
ProcessOverlays(pPicture, pPicture->pts);

int index = m_renderManager.AddVideoPicture(*pPicture);

// video device might not be done yet
while (index < 0 && !m_bAbortOutput &&
m_pClock->GetAbsoluteClock(false) < iCurrentClock + DVD_MSEC_TO_TIME(500))
{
Sleep(1);
index = m_renderManager.AddVideoPicture(*pPicture);
}
EINTERLACEMETHOD deintMethod = EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE;
deintMethod = CMediaSettings::GetInstance().GetCurrentVideoSettings().m_InterlaceMethod;
if (!m_processInfo.Supports(deintMethod))
deintMethod = m_processInfo.GetDeinterlacingMethodDefault();

if (index < 0)
if (!m_renderManager.AddVideoPicture(*pPicture, m_bAbortOutput, deintMethod, (m_syncState == ESyncState::SYNC_STARTING)))
{
m_droppingStats.AddOutputDropGain(pts, 1);
m_droppingStats.AddOutputDropGain(pPicture->pts, 1);
return EOS_DROPPED;
}

m_renderManager.FlipPage(m_bAbortOutput, pts, deintMethod, mDisplayField, (m_syncState == ESyncState::SYNC_STARTING));

return result;
}

Expand Down
2 changes: 1 addition & 1 deletion xbmc/cores/VideoPlayer/VideoPlayerVideo.h
Expand Up @@ -102,7 +102,7 @@ class CVideoPlayerVideo : public CThread, public IDVDStreamPlayerVideo
void SendMessageBack(CDVDMsg* pMsg, int priority = 0);
MsgQueueReturnCode GetMessage(CDVDMsg** pMsg, unsigned int iTimeoutInMilliSeconds, int &priority);

int OutputPicture(const VideoPicture* src, double pts);
int OutputPicture(const VideoPicture* src);
void ProcessOverlays(const VideoPicture* pSource, double pts);
void OpenStream(CDVDStreamInfo &hint, CDVDVideoCodec* codec);

Expand Down
Expand Up @@ -951,7 +951,13 @@ void CMMALRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
goto exit;
}

if (omvb && omvb->mmal_buffer)
if (omvb && omvb->m_state == MMALStateBypass)
{
// dummy buffer from omxplayer
if (VERBOSE && g_advancedSettings.CanLogComponent(LOGVIDEO))
CLog::Log(LOGDEBUG, "%s::%s - OMX: clear:%d flags:%x alpha:%d source:%d omvb:%p", CLASSNAME, __func__, clear, flags, alpha, source, omvb);
}
else if (omvb && omvb->mmal_buffer)
{
if (flags & RENDER_FLAG_TOP)
omvb->mmal_buffer->flags |= MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED | MMAL_BUFFER_HEADER_VIDEO_FLAG_TOP_FIELD_FIRST;
Expand Down
Expand Up @@ -44,7 +44,7 @@ namespace MMAL {

class CMMALBuffer;

enum MMALState { MMALStateNone, MMALStateHWDec, MMALStateFFDec, MMALStateDeint, };
enum MMALState { MMALStateNone, MMALStateHWDec, MMALStateFFDec, MMALStateDeint, MMALStateBypass, };

class CMMALPool : public IVideoBufferPool
{
Expand Down Expand Up @@ -127,7 +127,7 @@ class CMMALBuffer : public CVideoBuffer

void SetVideoDeintMethod(std::string method);
const char *GetStateName() {
static const char *names[] = { "MMALStateNone", "MMALStateHWDec", "MMALStateFFDec", "MMALStateDeint", };
static const char *names[] = { "MMALStateNone", "MMALStateHWDec", "MMALStateFFDec", "MMALStateDeint", "MMALStateBypass", };
if ((size_t)m_state < vcos_countof(names))
return names[(size_t)m_state];
else
Expand Down
24 changes: 19 additions & 5 deletions xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.cpp
Expand Up @@ -965,23 +965,37 @@ void CRenderManager::ToggleDebug()
m_debugTimer.SetExpired();
}

int CRenderManager::AddVideoPicture(const VideoPicture& pic)
bool CRenderManager::AddVideoPicture(const VideoPicture& picture, volatile std::atomic_bool& bStop, EINTERLACEMETHOD deintMethod, bool wait)
{
int index;
{
CSingleLock lock(m_presentlock);
if (m_free.empty())
return -1;
return false;
index = m_free.front();
}

CSingleLock lock(m_datalock);
if (!m_pRenderer)
return -1;
return false;

m_pRenderer->AddVideoPicture(pic, index, m_dvdClock.GetClock());
m_pRenderer->AddVideoPicture(picture, index, m_dvdClock.GetClock());

// set fieldsync if picture is interlaced
EFIELDSYNC displayField = FS_NONE;
if (picture.iFlags & DVP_FLAG_INTERLACED)
{
if (deintMethod != EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE)
{
if (picture.iFlags & DVP_FLAG_TOP_FIELD_FIRST)
displayField = FS_TOP;
else
displayField = FS_BOT;
}
}

return index;
FlipPage(bStop, picture.pts, deintMethod, displayField, wait);
return true;
}

void CRenderManager::AddOverlay(CDVDOverlay* o, double pts)
Expand Down
21 changes: 3 additions & 18 deletions xbmc/cores/VideoPlayer/VideoRenderers/RenderManager.h
Expand Up @@ -107,24 +107,7 @@ class CRenderManager
*/
bool Configure(const VideoPicture& picture, float fps, unsigned flags, unsigned int orientation, int buffers = 0);

int AddVideoPicture(const VideoPicture& picture);

/**
* Called by video player to flip render buffers
* If buffering is enabled this method does not block. In case of disabled buffering
* this method blocks waiting for the render thread to pass by.
* When buffering is used there might be no free buffer available after the call to
* this method. Player has to call WaitForBuffer. A free buffer will become
* available after the main thread has flipped front / back buffers.
*
* @param bStop reference to stop flag of calling thread
* @param timestamp of frame delivered with AddVideoPicture
* @param pts used for lateness detection
* @param method for deinterlacing
* @param sync signals frame, top, or bottom field
* @param wait: block until pic has been rendered
*/
void FlipPage(volatile std::atomic_bool& bStop, double pts, EINTERLACEMETHOD deintMethod, EFIELDSYNC sync, bool wait);
bool AddVideoPicture(const VideoPicture& picture, volatile std::atomic_bool& bStop, EINTERLACEMETHOD deintMethod, bool wait);

void AddOverlay(CDVDOverlay* o, double pts);

Expand Down Expand Up @@ -170,6 +153,8 @@ class CRenderManager
void UpdateDisplayLatency();
void CheckEnableClockSync();

void FlipPage(volatile std::atomic_bool& bStop, double pts, EINTERLACEMETHOD deintMethod, EFIELDSYNC sync, bool wait);

CBaseRenderer *m_pRenderer = nullptr;
OVERLAY::CRenderer m_overlays;
CDebugRenderer m_debugRenderer;
Expand Down
15 changes: 11 additions & 4 deletions xbmc/cores/omxplayer/OMXPlayerVideo.cpp
Expand Up @@ -39,6 +39,7 @@
#include "settings/Settings.h"
#include "settings/MediaSettings.h"
#include "cores/VideoPlayer/VideoRenderers/RenderFlags.h"
#include "cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h"
#include "guilib/GraphicContext.h"
#include "TimingConstants.h"

Expand Down Expand Up @@ -310,7 +311,15 @@ void OMXPlayerVideo::Output(double pts, bool bDropPacket)
ProcessOverlays(media_pts + preroll);

time += m_av_clock->GetAbsoluteClock();
m_renderManager.FlipPage(m_bAbortOutput, time/DVD_TIME_BASE, EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE, FS_NONE, false);

VideoPicture picture = {};
memset(&picture, 0, sizeof(VideoPicture));
picture.pts = time/DVD_TIME_BASE;
MMAL::CMMALBuffer *omvb = new MMAL::CMMALBuffer(0);
omvb->m_state = MMAL::MMALStateBypass;
picture.videoBuffer = omvb;

m_renderManager.AddVideoPicture(picture, m_bAbortOutput, EINTERLACEMETHOD::VS_INTERLACEMETHOD_NONE, (m_syncState == ESyncState::SYNC_STARTING));
}

bool OMXPlayerVideo::AcceptsData() const
Expand Down Expand Up @@ -772,9 +781,7 @@ void OMXPlayerVideo::ResolutionUpdateCallBack(uint32_t width, uint32_t height, f
CLog::Log(LOGDEBUG,"%s - change configuration. video:%dx%d. framerate: %4.2f. %dx%d format: BYPASS",
__FUNCTION__, video_width, video_height, m_fFrameRate, iDisplayWidth, iDisplayHeight);

VideoPicture picture;
memset(&picture, 0, sizeof(VideoPicture));

VideoPicture picture = {};
picture.iWidth = width;
picture.iHeight = height;
picture.iDisplayWidth = iDisplayWidth;
Expand Down