Skip to content
Permalink
Browse files

mmal: Include buffer encoding in buffer objects

  • Loading branch information...
popcornmix committed Jul 12, 2016
1 parent a5cc453 commit 8ef538ae77b5141a3279da54a5cff01169031df3
@@ -67,6 +67,7 @@ CMMALVideoBuffer::CMMALVideoBuffer(CMMALVideo *omv, std::shared_ptr<CMMALPool> p
m_height = 0;
m_aligned_width = 0;
m_aligned_height = 0;
m_encoding = MMAL_ENCODING_UNKNOWN;
m_aspect_ratio = 0.0f;
m_refs = 0;
m_interlace_mode = MMAL_InterlaceProgressive;
@@ -285,6 +286,7 @@ void CMMALVideo::dec_output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf
omvb->m_aligned_height = m_decoded_aligned_height;
omvb->m_aspect_ratio = m_aspect_ratio;
omvb->m_interlace_mode = m_interlace_mode;
omvb->m_encoding = m_dec_output->format->encoding;
{
CSingleLock lock(m_output_mutex);
m_output_ready.push(omvb);
@@ -55,6 +55,7 @@ class CMMALBuffer : public IDVDResourceCounted<CMMALBuffer>
unsigned int m_height;
unsigned int m_aligned_width;
unsigned int m_aligned_height;
uint32_t m_encoding;
float m_aspect_ratio;
MMAL_INTERLACETYPE_T m_interlace_mode;
MMALState m_state;
@@ -43,14 +43,15 @@ using namespace MMAL;
#define CLASSNAME "CMMALYUVBuffer"

CMMALYUVBuffer::CMMALYUVBuffer(CGPUPool *gpu_pool, uint32_t mmal_encoding, uint32_t width, uint32_t height, uint32_t aligned_width, uint32_t aligned_height)
: m_gpu_pool(gpu_pool), m_mmal_encoding(mmal_encoding)
: m_gpu_pool(gpu_pool)
{
uint32_t size_pic = 0;
m_gpu_pool->Acquire();
m_width = width;
m_height = height;
m_aligned_width = aligned_width;
m_aligned_height = aligned_height;
m_encoding = mmal_encoding;
m_aspect_ratio = 0.0f;
mmal_buffer = nullptr;
m_interlace_mode = MMAL_InterlaceProgressive;
@@ -60,22 +61,22 @@ CMMALYUVBuffer::CMMALYUVBuffer(CGPUPool *gpu_pool, uint32_t mmal_encoding, uint3
size_pic = (m_aligned_width * m_aligned_height * 3) >> 1;
else if (mmal_encoding == MMAL_ENCODING_YUVUV128)
size_pic = 6<<20; //(m_aligned_width * m_aligned_height * 4) >> 0; // hack: find correct size
else if (m_mmal_encoding == MMAL_ENCODING_ARGB || m_mmal_encoding == MMAL_ENCODING_RGBA || m_mmal_encoding == MMAL_ENCODING_ABGR || m_mmal_encoding == MMAL_ENCODING_BGRA)
else if (m_encoding == MMAL_ENCODING_ARGB || m_encoding == MMAL_ENCODING_RGBA || m_encoding == MMAL_ENCODING_ABGR || m_encoding == MMAL_ENCODING_BGRA)
size_pic = (m_aligned_width << 2) * m_aligned_height;
else if (m_mmal_encoding == MMAL_ENCODING_RGB16)
else if (m_encoding == MMAL_ENCODING_RGB16)
size_pic = (m_aligned_width << 1) * m_aligned_height;
else assert(0);
gmem = m_gpu_pool->AllocateBuffer(size_pic);
if (gmem)
gmem->m_opaque = (void *)this;
if (g_advancedSettings.CanLogComponent(LOGVIDEO))
CLog::Log(LOGDEBUG, "%s::%s buf:%p gmem:%p mmal:%p", CLASSNAME, __FUNCTION__, this, gmem, mmal_buffer);
CLog::Log(LOGDEBUG, "%s::%s buf:%p gmem:%p mmal:%p %dx%d (%dx%d) %.4s", CLASSNAME, __FUNCTION__, this, gmem, mmal_buffer, m_width, m_height, m_aligned_width, m_aligned_height, (char *)&m_encoding);
}

CMMALYUVBuffer::~CMMALYUVBuffer()
{
if (g_advancedSettings.CanLogComponent(LOGVIDEO))
CLog::Log(LOGDEBUG, "%s::%s buf:%p gmem:%p mmal:%p", CLASSNAME, __FUNCTION__, this, gmem, mmal_buffer);
CLog::Log(LOGDEBUG, "%s::%s buf:%p gmem:%p mmal:%p %dx%d (%dx%d) %.4s", CLASSNAME, __FUNCTION__, this, gmem, mmal_buffer, m_width, m_height, m_aligned_width, m_aligned_height, (char *)&m_encoding);
if (gmem)
m_gpu_pool->ReleaseBuffer(gmem);
gmem = nullptr;
@@ -46,7 +46,6 @@ class CMMALYUVBuffer : public CMMALBuffer
CGPUMEM *gmem;
private:
CGPUPool *m_gpu_pool;
uint32_t m_mmal_encoding;
};

class CGPUPool
@@ -66,37 +66,6 @@ static void vout_input_port_cb_static(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *b
mmal->vout_input_port_cb(port, buffer);
}

static struct {
uint32_t encoding;
AVPixelFormat pixfmt;
} pixfmt_to_encoding_table[] =
{
{MMAL_ENCODING_I420, AV_PIX_FMT_YUV420P},
{MMAL_ENCODING_I422, AV_PIX_FMT_YUV422P},
{MMAL_ENCODING_I420, AV_PIX_FMT_YUVJ420P}, // FIXME
{MMAL_ENCODING_I422, AV_PIX_FMT_YUVJ422P}, // FIXME
{MMAL_ENCODING_RGB16, AV_PIX_FMT_RGB565},
{MMAL_ENCODING_RGB16, AV_PIX_FMT_RGB565LE},
{MMAL_ENCODING_BGR16, AV_PIX_FMT_BGR565},
{MMAL_ENCODING_RGB24, AV_PIX_FMT_RGB24},
{MMAL_ENCODING_BGR24, AV_PIX_FMT_BGR24},
{MMAL_ENCODING_ARGB, AV_PIX_FMT_ARGB},
{MMAL_ENCODING_RGBA, AV_PIX_FMT_RGBA},
{MMAL_ENCODING_ABGR, AV_PIX_FMT_ABGR},
{MMAL_ENCODING_BGRA, AV_PIX_FMT_BGRA},
{MMAL_ENCODING_BGRA, AV_PIX_FMT_BGR0},
{MMAL_ENCODING_UNKNOWN, AV_PIX_FMT_NONE}
};

static uint32_t pixfmt_to_encoding(AVPixelFormat pixfmt)
{
unsigned int i;
for (i = 0; pixfmt_to_encoding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++)
if (pixfmt_to_encoding_table[i].pixfmt == pixfmt)
break;
return pixfmt_to_encoding_table[i].encoding;
}

CMMALPool::CMMALPool(MMAL_PORT_T *input, uint32_t num_buffers, uint32_t buffer_size)
{
m_input = input;
@@ -115,14 +84,13 @@ CMMALPool::~CMMALPool()
m_input = nullptr;
}

bool CMMALRenderer::init_vout(ERenderFormat format, AVPixelFormat pixfmt, bool opaque)
bool CMMALRenderer::init_vout(ERenderFormat format, uint32_t encoding)
{
CSingleLock lock(m_sharedSection);
bool formatChanged = m_format != format || m_opaque != opaque || m_pixfmt != pixfmt;
bool formatChanged = m_format != format || m_encoding != encoding;
MMAL_STATUS_T status;
uint32_t encoding = pixfmt_to_encoding(pixfmt);

CLog::Log(LOGDEBUG, "%s::%s configured:%d format %d->%d pixfmt %x->%x opaque %d->%d", CLASSNAME, __func__, m_bConfigured, m_format, format, m_pixfmt, pixfmt, m_opaque, opaque);
CLog::Log(LOGDEBUG, "%s::%s configured:%d format %d->%d encoding %.4s->%.4s", CLASSNAME, __func__, m_bConfigured, m_format, format, (char *)&m_encoding, (char *)&encoding);

if (m_bMMALConfigured && formatChanged)
UnInitMMAL();
@@ -137,8 +105,7 @@ bool CMMALRenderer::init_vout(ERenderFormat format, AVPixelFormat pixfmt, bool o
}

m_format = format;
m_pixfmt = pixfmt;
m_opaque = opaque;
m_encoding = encoding;

/* Create video renderer */
status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &m_vout);
@@ -165,7 +132,7 @@ bool CMMALRenderer::init_vout(ERenderFormat format, AVPixelFormat pixfmt, bool o
es_format->es->video.width = m_sourceWidth;
es_format->es->video.height = m_sourceHeight;

es_format->encoding = m_opaque ? MMAL_ENCODING_OPAQUE : encoding;
es_format->encoding = encoding;

status = mmal_port_parameter_set_boolean(m_vout_input, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE);
if (status != MMAL_SUCCESS)
@@ -178,7 +145,7 @@ bool CMMALRenderer::init_vout(ERenderFormat format, AVPixelFormat pixfmt, bool o
return false;
}

m_vout_input->buffer_num = std::max(m_vout_input->buffer_num_recommended, (uint32_t)m_NumYV12Buffers+(m_opaque?0:12));
m_vout_input->buffer_num = std::max(m_vout_input->buffer_num_recommended, (uint32_t)m_NumYV12Buffers+(m_encoding == MMAL_ENCODING_OPAQUE ? 0:12));
m_vout_input->buffer_size = m_vout_input->buffer_size_recommended;

status = mmal_port_enable(m_vout_input, vout_input_port_cb_static);
@@ -195,7 +162,7 @@ bool CMMALRenderer::init_vout(ERenderFormat format, AVPixelFormat pixfmt, bool o
return false;
}

CheckConfigurationVout(32, 16, 32, 16);
CheckConfigurationVout(32, 16, 32, 16, MMAL_ENCODING_I420);

if (!CSettings::GetInstance().GetBool("videoplayer.usedisplayasclock"))
{
@@ -215,8 +182,7 @@ CMMALRenderer::CMMALRenderer() : CThread("MMALRenderer"), m_processThread(this,
memset(m_buffers, 0, sizeof m_buffers);
m_iFlags = 0;
m_format = RENDER_FMT_NONE;
m_pixfmt = AV_PIX_FMT_YUV420P;
m_opaque = true;
m_encoding = MMAL_ENCODING_I420;
m_bConfigured = false;
m_bMMALConfigured = false;
m_iYV12RenderBuffer = 0;
@@ -302,7 +268,7 @@ void CMMALRenderer::Process()
{
CMMALBuffer *omvb = (CMMALBuffer *)buffer->user_data;
assert(buffer == omvb->mmal_buffer);
CheckConfigurationVout(omvb->m_width, omvb->m_height, omvb->m_aligned_width, omvb->m_aligned_height);
CheckConfigurationVout(omvb->m_width, omvb->m_height, omvb->m_aligned_width, omvb->m_aligned_height, omvb->m_encoding);
status = mmal_port_send_buffer(m_vout_input, buffer);
}
if (status != MMAL_SUCCESS)
@@ -327,8 +293,8 @@ void CMMALRenderer::Run()

CMMALBuffer *omvb = (CMMALBuffer *)buffer->user_data;
if (VERBOSE && g_advancedSettings.CanLogComponent(LOGVIDEO))
CLog::Log(LOGDEBUG, "%s::%s %s omvb:%p mmal:%p dts:%.3f pts:%.3f len:%d cmd:%x flags:%x flight:%d", CLASSNAME, __func__,
omvb ? omvb->GetStateName():"", omvb, buffer, buffer->dts*1e-6, buffer->pts*1e-6, buffer->length, buffer->cmd, buffer->flags, m_inflight);
CLog::Log(LOGDEBUG, "%s::%s %s omvb:%p mmal:%p dts:%.3f pts:%.3f len:%d cmd:%x flags:%x encoding:%.4s flight:%d", CLASSNAME, __func__,
omvb ? omvb->GetStateName():"", omvb, buffer, buffer->dts*1e-6, buffer->pts*1e-6, buffer->length, buffer->cmd, buffer->flags, omvb ? (char *)omvb->m_encoding:"", m_inflight);

assert(omvb && buffer == omvb->mmal_buffer);
assert(buffer->cmd == 0);
@@ -420,7 +386,7 @@ bool CMMALRenderer::Configure(unsigned int width, unsigned int height, unsigned
SetViewMode(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode);
ManageRenderArea();

m_bMMALConfigured = init_vout(format, m_pixfmt, m_opaque);
m_bMMALConfigured = init_vout(format, m_encoding);
m_bConfigured = m_bMMALConfigured;
assert(m_bConfigured);
return m_bConfigured;
@@ -538,7 +504,7 @@ void CMMALRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
}
else
{
CheckConfigurationVout(omvb->m_width, omvb->m_height, omvb->m_aligned_width, omvb->m_aligned_height);
CheckConfigurationVout(omvb->m_width, omvb->m_height, omvb->m_aligned_width, omvb->m_aligned_height, omvb->m_encoding);
status = mmal_port_send_buffer(m_vout_input, omvb->mmal_buffer);
}
if (status != MMAL_SUCCESS)
@@ -864,7 +830,7 @@ void CMMALRenderer::SetVideoRect(const CRect& InSrcRect, const CRect& InDestRect
region.dest_rect.x, region.dest_rect.y, region.dest_rect.width, region.dest_rect.height, region.transform);
}

bool CMMALRenderer::CheckConfigurationVout(unsigned int width, unsigned int height, unsigned int aligned_width, unsigned int aligned_height)
bool CMMALRenderer::CheckConfigurationVout(unsigned int width, unsigned int height, unsigned int aligned_width, unsigned int aligned_height, uint32_t encoding)
{
MMAL_STATUS_T status;

@@ -878,11 +844,8 @@ bool CMMALRenderer::CheckConfigurationVout(unsigned int width, unsigned int heig

if (m_vout_input)
{
uint32_t new_encoding = MMAL_ENCODING_UNKNOWN;
new_encoding = m_opaque ? MMAL_ENCODING_OPAQUE : pixfmt_to_encoding(m_pixfmt);

// we need to disable port when encoding changes, but not if just resolution changes
if (m_vout_input->is_enabled && m_vout_input->format->encoding != new_encoding)
if (m_vout_input->is_enabled && m_vout_input->format->encoding != encoding)
{
status = mmal_port_disable(m_vout_input);
if (status != MMAL_SUCCESS)
@@ -902,7 +865,7 @@ bool CMMALRenderer::CheckConfigurationVout(unsigned int width, unsigned int heig
m_vout_input->format->es->video.width = aligned_width;
m_vout_input->format->es->video.height = aligned_height;

m_vout_input->format->encoding = new_encoding;
m_vout_input->format->encoding = encoding;

status = mmal_port_format_commit(m_vout_input);
if (status != MMAL_SUCCESS)
@@ -115,9 +115,8 @@ class CMMALRenderer : public CBaseRenderer, public CThread, public IRunnable
RENDER_STEREO_MODE m_display_stereo_mode;
bool m_StereoInvert;
int m_inflight;
bool m_opaque;
float m_sharpness;
AVPixelFormat m_pixfmt;
uint32_t m_encoding;

CCriticalSection m_sharedSection;
MMAL_COMPONENT_T *m_vout;
@@ -132,10 +131,10 @@ class CMMALRenderer : public CBaseRenderer, public CThread, public IRunnable
double m_frameIntervalDiff;
uint32_t m_vout_width, m_vout_height, m_vout_aligned_width, m_vout_aligned_height;

bool init_vout(ERenderFormat format, AVPixelFormat pixfmt, bool opaque);
bool init_vout(ERenderFormat format, uint32_t encoding);
void ReleaseBuffers();
void UnInitMMAL();
void UpdateFramerateStats(double pts);
virtual void Run() override;
bool CheckConfigurationVout(unsigned int width, unsigned int height, unsigned int aligned_width, unsigned int aligned_height);
bool CheckConfigurationVout(unsigned int width, unsigned int height, unsigned int aligned_width, unsigned int aligned_height, uint32_t encoding);
};

0 comments on commit 8ef538a

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