Skip to content

Commit

Permalink
renderer: Use a structure for information passed from renderer to codec
Browse files Browse the repository at this point in the history
I need an additional opaque pointer to be passed from renderer to codec
(to allow a pool owned by renderer to be used by decoder).

It was decided rather than adding an extra function/parameter that
entending the information to use a structure would be more maintainable.
  • Loading branch information
popcornmix committed May 8, 2015
1 parent 333e50d commit 58171c8
Show file tree
Hide file tree
Showing 18 changed files with 94 additions and 59 deletions.
6 changes: 2 additions & 4 deletions xbmc/cores/VideoRenderers/BaseRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,15 @@ class CBaseRenderer
/**
* Returns number of references a single buffer can retain when rendering a single frame
*/
virtual unsigned int GetOptimalBufferSize() { return 0; }
virtual unsigned int GetMaxBufferSize() { return 0; }
virtual void SetBufferSize(int numBuffers) { }
virtual void ReleaseBuffer(int idx) { }
virtual bool NeedBufferForRef(int idx) { return false; }
virtual bool IsGuiLayer() { return true; }

virtual bool Supports(ERENDERFEATURE feature) { return false; }

// Supported pixel formats, can be called before configure
std::vector<ERenderFormat> SupportedFormats() { return std::vector<ERenderFormat>(); }
// Render info, can be called before configure
virtual CRenderInfo GetRenderInfo() { return CRenderInfo(); }

virtual void RegisterRenderUpdateCallBack(const void *ctx, RenderUpdateCallBackFn fn);
virtual void RegisterRenderFeaturesCallBack(const void *ctx, RenderFeaturesCallBackFn fn);
Expand Down
12 changes: 8 additions & 4 deletions xbmc/cores/VideoRenderers/LinuxRendererGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3456,17 +3456,21 @@ void CLinuxRendererGL::UnBindPbo(YUVBUFFER& buff)
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
}

unsigned int CLinuxRendererGL::GetOptimalBufferSize()
CRenderInfo CLinuxRendererGL::GetRenderInfo()
{
CRenderInfo info;
info.formats = m_formats;
info.max_buffer_size = NUM_BUFFERS;
if(m_format == RENDER_FMT_CVBREF)
return 2;
info.optimal_buffer_size = 2;
else if (m_format == RENDER_FMT_VAAPI ||
m_format == RENDER_FMT_VAAPINV12 ||
m_format == RENDER_FMT_VDPAU ||
m_format == RENDER_FMT_VDPAU_420)
return 5;
info.optimal_buffer_size = 5;
else
return 3;
info.optimal_buffer_size = 3;
return info;
}

#ifdef HAVE_LIBVDPAU
Expand Down
4 changes: 1 addition & 3 deletions xbmc/cores/VideoRenderers/LinuxRendererGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,6 @@ class CLinuxRendererGL : public CBaseRenderer
virtual void Flush();
virtual void ReleaseBuffer(int idx);
virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; }
virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; }
virtual unsigned int GetOptimalBufferSize();

#ifdef HAVE_LIBVDPAU
virtual void AddProcessor(VDPAU::CVdpauRenderPicture* vdpau, int index);
Expand All @@ -158,7 +156,7 @@ class CLinuxRendererGL : public CBaseRenderer

virtual EINTERLACEMETHOD AutoInterlaceMethod();

virtual std::vector<ERenderFormat> SupportedFormats() { return m_formats; }
virtual CRenderInfo GetRenderInfo();

protected:
virtual void Render(DWORD flags, int renderBuffer);
Expand Down
14 changes: 10 additions & 4 deletions xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2980,18 +2980,24 @@ EINTERLACEMETHOD CLinuxRendererGLES::AutoInterlaceMethod()
#endif
}

unsigned int CLinuxRendererGLES::GetOptimalBufferSize()
CRenderInfo CLinuxRendererGLES::GetRenderInfo()
{
CRenderInfo info;
info.formats = m_formats;
info.max_buffer_size = NUM_BUFFERS;
if(m_format == RENDER_FMT_OMXEGL ||
m_format == RENDER_FMT_CVBREF ||
m_format == RENDER_FMT_EGLIMG ||
m_format == RENDER_FMT_MEDIACODEC)
return 2;
info.optimal_buffer_size = 2;
else if(m_format == RENDER_FMT_IMXMAP)
{
// Let the codec control the buffer size
return GetMaxBufferSize();
info.optimal_buffer_size = info.max_buffer_size;
}
else
return 3;
info.optimal_buffer_size = 3;
return info;
}

#ifdef HAVE_LIBOPENMAX
Expand Down
4 changes: 1 addition & 3 deletions xbmc/cores/VideoRenderers/LinuxRendererGLES.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,6 @@ class CLinuxRendererGLES : public CBaseRenderer
virtual void ReorderDrawPoints();
virtual void ReleaseBuffer(int idx);
virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; }
virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; }
virtual unsigned int GetOptimalBufferSize();
virtual bool IsGuiLayer();

virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255);
Expand All @@ -160,7 +158,7 @@ class CLinuxRendererGLES : public CBaseRenderer

virtual EINTERLACEMETHOD AutoInterlaceMethod();

virtual std::vector<ERenderFormat> SupportedFormats() { return m_formats; }
virtual CRenderInfo GetRenderInfo();

#ifdef HAVE_LIBOPENMAX
virtual void AddProcessor(COpenMax* openMax, DVDVideoPicture *picture, int index);
Expand Down
15 changes: 15 additions & 0 deletions xbmc/cores/VideoRenderers/MMALRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@
#define MMAL_DEBUG_VERBOSE
#endif

CRenderInfo CMMALRenderer::GetRenderInfo()
{
CRenderInfo info;

#if defined(MMAL_DEBUG_VERBOSE)
CLog::Log(LOGDEBUG, "%s::%s cookie:%p", CLASSNAME, __func__, (void *)m_vout_input_pool);
#endif

info.max_buffer_size = NUM_BUFFERS;
info.optimal_buffer_size = NUM_BUFFERS;
info.opaque_pointer = (void *)m_vout_input_pool;
info.formats = m_formats;
return info;
}

static void vout_control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
mmal_buffer_header_release(buffer);
Expand Down
4 changes: 1 addition & 3 deletions xbmc/cores/VideoRenderers/MMALRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class CMMALRenderer : public CBaseRenderer, public CThread
virtual void Flush();
virtual bool IsConfigured() { return m_bConfigured; }
virtual void AddProcessor(CMMALVideoBuffer *buffer, int index);
virtual std::vector<ERenderFormat> SupportedFormats() { return m_formats; }
virtual CRenderInfo GetRenderInfo();

virtual bool Supports(ERENDERFEATURE feature);
virtual bool Supports(EDEINTERLACEMODE mode);
Expand All @@ -84,8 +84,6 @@ class CMMALRenderer : public CBaseRenderer, public CThread
void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255);

virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; }
virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; }
virtual unsigned int GetOptimalBufferSize() { return NUM_BUFFERS; }
virtual void SetVideoRect(const CRect& SrcRect, const CRect& DestRect);
virtual bool IsGuiLayer() { return false; }

Expand Down
18 changes: 18 additions & 0 deletions xbmc/cores/VideoRenderers/RenderFormats.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
*
*/

#include <vector>

enum ERenderFormat {
RENDER_FMT_NONE = 0,
RENDER_FMT_YUV420P,
Expand All @@ -42,4 +44,20 @@ enum ERenderFormat {
RENDER_FMT_MMAL,
};

struct CRenderInfo
{
CRenderInfo()
{
optimal_buffer_size = 0;
max_buffer_size = 0;
opaque_pointer = NULL;
}
unsigned int optimal_buffer_size;
unsigned int max_buffer_size;
// Supported pixel formats, can be called before configure
std::vector<ERenderFormat> formats;
// Can be used for initialising video codec with information from renderer (e.g. a shared image pool)
void *opaque_pointer;
};

#endif
24 changes: 9 additions & 15 deletions xbmc/cores/VideoRenderers/RenderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,13 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi
lock2.Enter();
m_format = format;

int renderbuffers = m_pRenderer->GetOptimalBufferSize();
CRenderInfo info = m_pRenderer->GetRenderInfo();
int renderbuffers = info.optimal_buffer_size;
m_QueueSize = renderbuffers;
if (buffers > 0)
m_QueueSize = std::min(buffers, renderbuffers);
m_QueueSize = std::min(m_QueueSize, (int)m_pRenderer->GetMaxBufferSize());

m_QueueSize = std::min(m_QueueSize, (int)info.max_buffer_size);
m_QueueSize = std::min(m_QueueSize, NUM_BUFFERS);
if(m_QueueSize < 2)
{
Expand Down Expand Up @@ -936,25 +938,17 @@ void CXBMCRenderManager::UpdateResolution()
}
}


unsigned int CXBMCRenderManager::GetOptimalBufferSize()
// Get renderer info, can be called before configure
CRenderInfo CXBMCRenderManager::GetRenderInfo()
{
CSharedLock lock(m_sharedSection);
CRenderInfo info;
if (!m_pRenderer)
{
CLog::Log(LOGERROR, "%s - renderer is NULL", __FUNCTION__);
return 0;
return CRenderInfo();
}
return m_pRenderer->GetMaxBufferSize();
}

// Supported pixel formats, can be called before configure
std::vector<ERenderFormat> CXBMCRenderManager::SupportedFormats()
{
CSharedLock lock(m_sharedSection);
if (m_pRenderer)
return m_pRenderer->SupportedFormats();
return std::vector<ERenderFormat>();
return m_pRenderer->GetRenderInfo();
}

int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic)
Expand Down
6 changes: 2 additions & 4 deletions xbmc/cores/VideoRenderers/RenderManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,8 @@ class CXBMCRenderManager
CLinuxRenderer *m_pRenderer;
#endif

unsigned int GetOptimalBufferSize();

// Supported pixel formats, can be called before configure
std::vector<ERenderFormat> SupportedFormats();
// Get renderer info, can be called before configure
CRenderInfo GetRenderInfo();

void Recover(); // called after resolution switch if something special is needed

Expand Down
10 changes: 7 additions & 3 deletions xbmc/cores/VideoRenderers/WinRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1331,12 +1331,16 @@ EINTERLACEMETHOD CWinRenderer::AutoInterlaceMethod()
return VS_INTERLACEMETHOD_DEINTERLACE_HALF;
}

unsigned int CWinRenderer::GetOptimalBufferSize()
CRenderInfo CWinRenderer::GetRenderInfo()
{
CRenderInfo info;
info.formats = m_formats;
info.max_buffer_size = NUM_BUFFERS;
if (m_format == RENDER_FMT_DXVA && m_processor)
return m_processor->Size();
info.optimal_buffer_size = m_processor->Size();
else
return 3;
info.optimal_buffer_size = 3;
return info;
}

void CWinRenderer::ReleaseBuffer(int idx)
Expand Down
4 changes: 1 addition & 3 deletions xbmc/cores/VideoRenderers/WinRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class CWinRenderer : public CBaseRenderer
virtual bool IsConfigured() { return m_bConfigured; }
virtual void Flush();

virtual std::vector<ERenderFormat> SupportedFormats() { return m_formats; }
virtual CRenderInfo GetRenderInfo();

virtual bool Supports(ERENDERFEATURE feature);
virtual bool Supports(EDEINTERLACEMODE mode);
Expand All @@ -168,9 +168,7 @@ class CWinRenderer : public CBaseRenderer

void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255);

virtual unsigned int GetOptimalBufferSize();
virtual void SetBufferSize(int numBuffers) { m_neededBuffers = numBuffers; }
virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; }
virtual void ReleaseBuffer(int idx);
virtual bool NeedBufferForRef(int idx);

Expand Down
1 change: 1 addition & 0 deletions xbmc/cores/dvdplayer/DVDCodecs/DVDCodecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ class CDVDCodecOptions
public:
std::vector<CDVDCodecOption> m_keys;
std::vector<ERenderFormat> m_formats;
const void *m_opaque_pointer;
};
10 changes: 6 additions & 4 deletions xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,17 @@ CDVDOverlayCodec* CDVDFactoryCodec::OpenCodec(CDVDOverlayCodec* pCodec, CDVDStre
}


CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigned int surfaces, const std::vector<ERenderFormat>& formats)
CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, const CRenderInfo &info)
{
CDVDVideoCodec* pCodec = NULL;
CDVDCodecOptions options;

if(formats.empty())
if(info.formats.empty())
options.m_formats.push_back(RENDER_FMT_YUV420P);
else
options.m_formats = formats;
options.m_formats = info.formats;

options.m_opaque_pointer = info.opaque_pointer;

//when support for a hardware decoder is not compiled in
//only print it if it's actually available on the platform
Expand Down Expand Up @@ -338,7 +340,7 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne
}
#endif

std::string value = StringUtils::Format("%d", surfaces);
std::string value = StringUtils::Format("%d", info.optimal_buffer_size);
options.m_keys.push_back(CDVDCodecOption("surfaces", value));
if( (pCodec = OpenCodec(new CDVDVideoCodecFFmpeg(), hint, options)) ) return pCodec;

Expand Down
3 changes: 2 additions & 1 deletion xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <vector>
#include "cores/VideoRenderers/RenderFormats.h"
#include "cores/VideoRenderers/BaseRenderer.h"

class CDVDVideoCodec;
class CDVDAudioCodec;
Expand All @@ -35,7 +36,7 @@ class CDVDCodecOptions;
class CDVDFactoryCodec
{
public:
static CDVDVideoCodec* CreateVideoCodec(CDVDStreamInfo &hint, unsigned int surfaces = 0, const std::vector<ERenderFormat>& formats = std::vector<ERenderFormat>());
static CDVDVideoCodec* CreateVideoCodec(CDVDStreamInfo &hint, const CRenderInfo &info = CRenderInfo());
static CDVDAudioCodec* CreateAudioCodec(CDVDStreamInfo &hint );
static CDVDOverlayCodec* CreateOverlayCodec(CDVDStreamInfo &hint );

Expand Down
5 changes: 4 additions & 1 deletion xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "DVDClock.h"
#include "DVDStreamInfo.h"
#include "windowing/WindowingFactory.h"
#include "cores/dvdplayer/DVDCodecs/DVDCodecs.h"
#include "DVDVideoCodec.h"
#include "utils/log.h"
#include "utils/TimeUtils.h"
Expand Down Expand Up @@ -114,6 +115,7 @@ CMMALVideo::CMMALVideo()
m_dec_output = NULL;
m_dec_input_pool = NULL;
m_dec_output_pool = NULL;
m_vout_input_pool = NULL;

m_deint = NULL;
m_deint_connection = NULL;
Expand Down Expand Up @@ -508,13 +510,14 @@ bool CMMALVideo::SendCodecConfigData()
bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVideoPtr myself)
{
if (g_advancedSettings.CanLogComponent(LOGVIDEO))
CLog::Log(LOGDEBUG, "%s::%s usemmal:%d software:%d %dx%d", CLASSNAME, __func__, CSettings::Get().GetBool("videoplayer.usemmal"), hints.software, hints.width, hints.height);
CLog::Log(LOGDEBUG, "%s::%s usemmal:%d software:%d %dx%d pool:%p", CLASSNAME, __func__, CSettings::Get().GetBool("videoplayer.usemmal"), hints.software, hints.width, hints.height, options.m_opaque_pointer);

// we always qualify even if DVDFactoryCodec does this too.
if (!CSettings::Get().GetBool("videoplayer.usemmal") || hints.software)
return false;

m_hints = hints;
m_vout_input_pool = (MMAL_POOL_T *)options.m_opaque_pointer;
MMAL_STATUS_T status;
MMAL_PARAMETER_BOOLEAN_T error_concealment;

Expand Down
1 change: 1 addition & 0 deletions xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class CMMALVideo
MMAL_PORT_T *m_dec_output;
MMAL_POOL_T *m_dec_input_pool;
MMAL_POOL_T *m_dec_output_pool;
MMAL_POOL_T *m_vout_input_pool;

MMAL_ES_FORMAT_T *m_es_format;
MMAL_COMPONENT_T *m_deint;
Expand Down
12 changes: 5 additions & 7 deletions xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,19 +178,17 @@ double CDVDPlayerVideo::GetOutputDelay()

bool CDVDPlayerVideo::OpenStream( CDVDStreamInfo &hint )
{
unsigned int surfaces = 0;
std::vector<ERenderFormat> formats;
#ifdef HAS_VIDEO_PLAYBACK
surfaces = g_renderManager.GetOptimalBufferSize();
formats = g_renderManager.SupportedFormats();
#endif
CRenderInfo info;
#ifdef HAS_VIDEO_PLAYBACK
info = g_renderManager.GetRenderInfo();
#endif

m_pullupCorrection.ResetVFRDetection();
if(hint.flags & AV_DISPOSITION_ATTACHED_PIC)
return false;

CLog::Log(LOGNOTICE, "Creating video codec with codec id: %i", hint.codec);
CDVDVideoCodec* codec = CDVDFactoryCodec::CreateVideoCodec(hint, surfaces, formats);
CDVDVideoCodec* codec = CDVDFactoryCodec::CreateVideoCodec(hint, info);
if(!codec)
{
CLog::Log(LOGERROR, "Unsupported video codec");
Expand Down

0 comments on commit 58171c8

Please sign in to comment.