Skip to content
Permalink
Browse files

mmal: Move decoded picture pool from renderer to decoder

  • Loading branch information...
popcornmix committed Jul 11, 2016
1 parent 9fac3d2 commit e3f14217af0caca9a959a99ac6b40dfa9c3bc059
@@ -940,8 +940,9 @@ void CMMALVideo::Prime()
{
MMAL_BUFFER_HEADER_T *buffer;
assert(m_renderer);
// todo: Move to Open
if (!m_pool)
m_pool = m_renderer->GetPool(RENDER_FMT_MMAL, AV_PIX_FMT_YUV420P, true);
m_pool = std::make_shared<CMMALPool>(m_dec_output, m_dec_output->buffer_num, m_dec_output->buffer_size);
assert(m_pool);
MMAL_POOL_T *render_pool = m_pool->Get();
assert(render_pool);
@@ -226,6 +226,7 @@ CDecoder::~CDecoder()
if (g_advancedSettings.CanLogComponent(LOGVIDEO))
CLog::Log(LOGDEBUG, "%s::%s - destroy %p", CLASSNAME, __FUNCTION__, this);
Close();
DestroyDummyDecoder();
}

long CDecoder::Release()
@@ -368,6 +369,49 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame)
return VC_BUFFER;
}

bool CDecoder::CreateDummyDecoder()
{
MMAL_STATUS_T status;
// initialize mmal.
CLog::Log(LOGNOTICE, "%s::%s", CLASSNAME, __FUNCTION__);
status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &m_dec);
if (status != MMAL_SUCCESS)
{
CLog::Log(LOGERROR, "%s::%s Failed to create MMAL decoder component %s (status=%x %s)", CLASSNAME, __func__, MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, status, mmal_status_to_string(status));
return false;
}

m_dec_output = m_dec->output[0];

// set up initial decoded frame format - will likely change from this
m_dec_output->format->encoding = MMAL_ENCODING_I420;

status = mmal_port_parameter_set_boolean(m_dec_output, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE);
if (status != MMAL_SUCCESS)
CLog::Log(LOGERROR, "%s::%s Failed to enable zero copy mode on %s (status=%x %s)", CLASSNAME, __func__, m_dec_output->name, status, mmal_status_to_string(status));

status = mmal_port_format_commit(m_dec_output);
if (status != MMAL_SUCCESS)
{
CLog::Log(LOGERROR, "%s::%s Failed to commit decoder output format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
return false;
}
m_dec_output->buffer_size = m_dec_output->buffer_size_min;
m_dec_output->buffer_num = std::max(12U + NUM_BUFFERS, m_dec_output->buffer_num_recommended);
return true;
}

void CDecoder::DestroyDummyDecoder()
{
CLog::Log(LOGNOTICE, "%s::%s", CLASSNAME, __FUNCTION__);
m_dec_output = NULL;
if (m_dec)
mmal_component_destroy(m_dec);
m_dec = NULL;
}



bool CDecoder::GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture)
{
CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque;
@@ -380,7 +424,10 @@ bool CDecoder::GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture
return false;

if (!m_pool)
m_pool = m_renderer->GetPool(RENDER_FMT_MMAL, m_fmt, false);
{
if (CreateDummyDecoder())
m_pool = std::make_shared<CMMALPool>(m_dec_output, m_dec_output->buffer_num, 0);
}
assert(m_pool);
MMAL_POOL_T *render_pool = m_pool->Get();
assert(render_pool);
@@ -99,13 +99,17 @@ class CDecoder
static int FFGetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags);

protected:
bool CreateDummyDecoder();
void DestroyDummyDecoder();
AVCodecContext *m_avctx;
unsigned int m_shared;
CCriticalSection m_section;
CMMALRenderer *m_renderer;
std::shared_ptr<CMMALPool> m_pool;
CGPUPoolWrap m_gpu_pool;
enum AVPixelFormat m_fmt;
MMAL_COMPONENT_T *m_dec;
MMAL_PORT_T *m_dec_output;
};

};
@@ -40,16 +40,6 @@

#define VERBOSE 0

std::shared_ptr<CMMALPool> CMMALRenderer::GetPool(ERenderFormat format, AVPixelFormat pixfmt, bool opaque)
{
CSingleLock lock(m_sharedSection);
bool formatChanged = m_format != format || m_opaque != opaque;
if (!m_bMMALConfigured || formatChanged)
m_bMMALConfigured = init_vout(format, pixfmt, opaque);

return m_vout_input_pool;
}

CRenderInfo CMMALRenderer::GetRenderInfo()
{
CSingleLock lock(m_sharedSection);
@@ -222,7 +212,6 @@ CMMALRenderer::CMMALRenderer() : CThread("MMALRenderer"), m_processThread(this,
CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__);
m_vout = NULL;
m_vout_input = NULL;
m_vout_input_pool = NULL;
memset(m_buffers, 0, sizeof m_buffers);
m_iFlags = 0;
m_format = RENDER_FMT_NONE;
@@ -608,7 +597,7 @@ void CMMALRenderer::ReleaseBuffers()

void CMMALRenderer::UnInitMMAL()
{
CLog::Log(LOGDEBUG, "%s::%s pool(%p)", CLASSNAME, __func__, m_vout_input_pool ? m_vout_input_pool->Get() : nullptr);
CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__);
if (m_vout)
{
mmal_component_disable(m_vout);
@@ -643,8 +632,6 @@ void CMMALRenderer::UnInitMMAL()
mmal_queue_destroy(m_queue_process);
m_queue_process = nullptr;

m_vout_input_pool = NULL;

m_vout_input = NULL;

if (m_vout)
@@ -943,8 +930,5 @@ bool CMMALRenderer::CheckConfigurationVout(unsigned int width, unsigned int heig
assert(m_vout_input->format->encoding == MMAL_ENCODING_YUVUV128 || m_vout_input->format->es->video.height == aligned_height);
}

if (!m_vout_input_pool)
m_vout_input_pool = std::make_shared<CMMALPool>(m_vout_input, m_vout_input->buffer_num, m_opaque ? m_vout_input->buffer_size:0);

return true;
}
@@ -96,7 +96,6 @@ class CMMALRenderer : public CBaseRenderer, public CThread, public IRunnable
virtual bool IsGuiLayer() { return false; }

void vout_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
std::shared_ptr<CMMALPool> GetPool(ERenderFormat format, AVPixelFormat pixfmt, bool opaque);
protected:
int m_iYV12RenderBuffer;
int m_NumYV12Buffers;
@@ -123,7 +122,6 @@ class CMMALRenderer : public CBaseRenderer, public CThread, public IRunnable
CCriticalSection m_sharedSection;
MMAL_COMPONENT_T *m_vout;
MMAL_PORT_T *m_vout_input;
std::shared_ptr<CMMALPool> m_vout_input_pool;
MMAL_QUEUE_T *m_queue_render;
MMAL_QUEUE_T *m_queue_process;
CThread m_processThread;

0 comments on commit e3f1421

Please sign in to comment.
You can’t perform that action at this time.