Skip to content

Commit

Permalink
[mmal] Move the image pool from decoder to renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
popcornmix committed Apr 18, 2015
1 parent 32a93cb commit 4ca5e8a
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 40 deletions.
5 changes: 5 additions & 0 deletions xbmc/cores/VideoRenderers/BaseRenderer.h
Expand Up @@ -112,6 +112,11 @@ class CBaseRenderer

static void SettingOptionsRenderMethodsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current, void *data);

/**
* Magic api for communicating between codec and renderer
*/
virtual void *PassCookie(void *cookie) { return NULL; }

protected:
void ChooseBestResolution(float fps);
bool FindResolutionFromOverride(float fps, float& weight, bool fallback);
Expand Down
78 changes: 65 additions & 13 deletions xbmc/cores/VideoRenderers/MMALRenderer.cpp
Expand Up @@ -40,6 +40,50 @@
#define MMAL_DEBUG_VERBOSE
#endif



void CMMALRenderer::Prime()
{
#if defined(MMAL_DEBUG_VERBOSE)
CLog::Log(LOGDEBUG, "%s::%s format:%d dec:%p pool:%p", CLASSNAME, __func__, m_format, m_mmal_video, m_vout_input_pool);
#endif

if (m_format != RENDER_FMT_MMAL || !m_vout_input_pool)
return;

MMAL_BUFFER_HEADER_T *buffer;
while (buffer = mmal_queue_get(m_vout_input_pool->queue), buffer)
{
CLog::Log(LOGDEBUG, "%s::%s buffer:%p mmal_video:%p", CLASSNAME, __func__, buffer, m_mmal_video);
if (m_mmal_video)
{
m_mmal_video->Recycle(buffer);
}
else
{
mmal_buffer_header_release(buffer);
break;
}
}
}

void *CMMALRenderer::PassCookie(void *cookie)
{
m_mmal_video = (CMMALVideo *)cookie;
#if defined(MMAL_DEBUG_VERBOSE)
CLog::Log(LOGDEBUG, "%s::%s cookie:%p", CLASSNAME, __func__, cookie);
#endif

if (m_mmal_video)
{
bool formatChanged = m_format != RENDER_FMT_MMAL;
m_format = RENDER_FMT_MMAL;
m_bConfigured = init_vout(formatChanged);
Prime();
}
return NULL;
}

static void vout_control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
mmal_buffer_header_release(buffer);
Expand Down Expand Up @@ -164,25 +208,29 @@ bool CMMALRenderer::init_vout(ERenderFormat format)
return false;
}

if (m_format == RENDER_FMT_YUV420P)
m_vout_input_pool = mmal_port_pool_create(m_vout_input , m_vout_input->buffer_num, m_vout_input->buffer_size);
if (!m_vout_input_pool)
{
m_vout_input_pool = mmal_pool_create(m_vout_input->buffer_num, m_vout_input->buffer_size);
if (!m_vout_input_pool)
{
CLog::Log(LOGERROR, "%s::%s Failed to create pool for decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
return false;
}
CLog::Log(LOGERROR, "%s::%s Failed to create pool for decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
return false;
}
return true;
}

void CMMALRenderer::Process()
{
MMAL_BUFFER_HEADER_T *buffer;
while (buffer = mmal_queue_wait(m_release_queue), buffer && buffer != &m_quit_packet)
while (buffer = mmal_queue_timedwait(m_release_queue, 100), buffer != &m_quit_packet)
{
CMMALVideoBuffer *omvb = (CMMALVideoBuffer *)buffer->user_data;
omvb->Release();
if (buffer)
{
CMMALVideoBuffer *omvb = (CMMALVideoBuffer *)buffer->user_data;
omvb->Release();
}
else
{
Prime();
}
}
m_sync.Set();
}
Expand All @@ -199,6 +247,7 @@ CMMALRenderer::CMMALRenderer()
m_release_queue = mmal_queue_create();
m_iFlags = 0;
m_format = RENDER_FMT_NONE;
m_mmal_video = NULL;
m_iYV12RenderBuffer = 0;
Create();
}
Expand Down Expand Up @@ -382,7 +431,7 @@ void CMMALRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
#endif
// we only want to upload frames once
if (omvb->mmal_buffer->flags & MMAL_BUFFER_HEADER_FLAG_USER1)
return;
goto done;
omvb->Acquire();
omvb->mmal_buffer->flags |= MMAL_BUFFER_HEADER_FLAG_USER1 | MMAL_BUFFER_HEADER_FLAG_USER2;
mmal_port_send_buffer(m_vout_input, omvb->mmal_buffer);
Expand All @@ -397,7 +446,7 @@ void CMMALRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
{
// we only want to upload frames once
if (buffer->mmal_buffer->flags & MMAL_BUFFER_HEADER_FLAG_USER1)
return;
goto done;
// sanity check it is not on display
buffer->mmal_buffer->flags |= MMAL_BUFFER_HEADER_FLAG_USER1 | MMAL_BUFFER_HEADER_FLAG_USER2;
mmal_port_send_buffer(m_vout_input, buffer->mmal_buffer);
Expand All @@ -406,6 +455,8 @@ void CMMALRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
CLog::Log(LOGDEBUG, "%s::%s - No buffer to update", CLASSNAME, __func__);
}
else assert(0);
done:
Prime();
}

void CMMALRenderer::FlipPage(int source)
Expand Down Expand Up @@ -467,6 +518,8 @@ void CMMALRenderer::UnInitMMAL()
m_vout_input = NULL;
}

ReleaseBuffers();

if (m_vout_input_pool)
{
mmal_pool_destroy(m_vout_input_pool);
Expand All @@ -478,7 +531,6 @@ void CMMALRenderer::UnInitMMAL()
mmal_component_release(m_vout);
m_vout = NULL;
}
ReleaseBuffers();

m_RenderUpdateCallBackFn = NULL;
m_RenderUpdateCallBackCtx = NULL;
Expand Down
4 changes: 4 additions & 0 deletions xbmc/cores/VideoRenderers/MMALRenderer.h
Expand Up @@ -40,6 +40,7 @@

class CBaseTexture;
class CMMALVideoBuffer;
class CMMALVideo;

struct DVDVideoPicture;

Expand Down Expand Up @@ -90,6 +91,7 @@ class CMMALRenderer : public CBaseRenderer, public CThread
virtual bool IsGuiLayer() { return false; }

void vout_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
virtual void *PassCookie(void *cookie);
protected:
int m_iYV12RenderBuffer;
int m_NumYV12Buffers;
Expand All @@ -116,8 +118,10 @@ class CMMALRenderer : public CBaseRenderer, public CThread
MMAL_QUEUE_T *m_release_queue;
CEvent m_sync;
MMAL_BUFFER_HEADER_T m_quit_packet;
CMMALVideo *m_mmal_video;

bool init_vout(ERenderFormat format);
void ReleaseBuffers();
void UnInitMMAL();
void Prime();
};
8 changes: 8 additions & 0 deletions xbmc/cores/VideoRenderers/RenderManager.cpp
Expand Up @@ -949,6 +949,14 @@ unsigned int CXBMCRenderManager::GetOptimalBufferSize()
return m_pRenderer->GetMaxBufferSize();
}

void *CXBMCRenderManager::PassCookie(void *cookie)
{
if (m_pRenderer)
return m_pRenderer->PassCookie(cookie);
assert(0);
}


// Supported pixel formats, can be called before configure
std::vector<ERenderFormat> CXBMCRenderManager::SupportedFormats()
{
Expand Down
5 changes: 5 additions & 0 deletions xbmc/cores/VideoRenderers/RenderManager.h
Expand Up @@ -195,6 +195,11 @@ class CXBMCRenderManager
*/
void DiscardBuffer();

/**
* Magic api for communicating between codec and renderer
*/
void *PassCookie(void *cookie);

protected:

void PresentSingle(bool clear, DWORD flags, DWORD alpha);
Expand Down
30 changes: 5 additions & 25 deletions xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp
Expand Up @@ -111,7 +111,6 @@ CMMALVideo::CMMALVideo()
m_dec_input = NULL;
m_dec_output = NULL;
m_dec_input_pool = NULL;
m_dec_output_pool = NULL;

m_deint = NULL;
m_deint_connection = NULL;
Expand Down Expand Up @@ -162,10 +161,6 @@ CMMALVideo::~CMMALVideo()
mmal_pool_destroy(m_dec_input_pool);
m_dec_input_pool = NULL;

if (m_dec_output_pool)
mmal_pool_destroy(m_dec_output_pool);
m_dec_output_pool = NULL;

if (m_deint)
mmal_component_destroy(m_deint);
m_deint = NULL;
Expand Down Expand Up @@ -421,7 +416,7 @@ bool CMMALVideo::CreateDeinterlace(EINTERLACEMETHOD interlace_method)

m_dec_output = m_deint->output[0];
m_interlace_method = interlace_method;
Prime();

return true;
}

Expand Down Expand Up @@ -477,7 +472,7 @@ bool CMMALVideo::DestroyDeinterlace()

m_dec_output = m_dec->output[0];
m_interlace_method = VS_INTERLACEMETHOD_NONE;
Prime();

return true;
}

Expand Down Expand Up @@ -708,28 +703,22 @@ bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVide
return false;
}

m_dec_output_pool = mmal_port_pool_create(m_dec_output, m_dec_output->buffer_num, m_dec_output->buffer_size);
if(!m_dec_output_pool)
{
CLog::Log(LOGERROR, "%s::%s Failed to create pool for decode output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
return false;
}

if (!SendCodecConfigData())
return false;

Prime();
m_startframe = false;
m_preroll = !m_hints.stills;
m_speed = DVD_PLAYSPEED_NORMAL;

g_renderManager.PassCookie(this);
return true;
}

void CMMALVideo::Dispose()
{
// we are happy to exit, but let last shared pointer being deleted trigger the destructor
bool done = false;
g_renderManager.PassCookie(NULL);
m_finished = true;
Reset();
pthread_mutex_lock(&m_output_mutex);
Expand Down Expand Up @@ -905,13 +894,6 @@ int CMMALVideo::Decode(uint8_t* pData, int iSize, double dts, double pts)
return ret;
}

void CMMALVideo::Prime()
{
MMAL_BUFFER_HEADER_T *buffer;
while (buffer = mmal_queue_get(m_dec_output_pool->queue), buffer)
Recycle(buffer);
}

void CMMALVideo::Reset(void)
{
if (g_advancedSettings.CanLogComponent(LOGVIDEO))
Expand Down Expand Up @@ -957,10 +939,8 @@ void CMMALVideo::Reset(void)
pthread_mutex_unlock(&m_output_mutex);

if (!m_finished)
{
SendCodecConfigData();
Prime();
}

m_startframe = false;
m_decoderPts = DVD_NOPTS_VALUE;
m_preroll = !m_hints.stills && (m_speed == DVD_PLAYSPEED_NORMAL || m_speed == DVD_PLAYSPEED_PAUSE);
Expand Down
2 changes: 0 additions & 2 deletions xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h
Expand Up @@ -103,7 +103,6 @@ class CMMALVideo
void QueryCodec(void);
bool CreateDeinterlace(EINTERLACEMETHOD interlace_method);
bool DestroyDeinterlace();
void Prime();

// Video format
int m_decoded_width;
Expand Down Expand Up @@ -141,7 +140,6 @@ class CMMALVideo
MMAL_PORT_T *m_dec_input;
MMAL_PORT_T *m_dec_output;
MMAL_POOL_T *m_dec_input_pool;
MMAL_POOL_T *m_dec_output_pool;

MMAL_ES_FORMAT_T *m_es_format;
MMAL_COMPONENT_T *m_deint;
Expand Down

0 comments on commit 4ca5e8a

Please sign in to comment.