Skip to content

Commit

Permalink
[mmal] Separate the buffers from the decoder so decoder can be destro…
Browse files Browse the repository at this point in the history
…yed first
  • Loading branch information
popcornmix committed Apr 18, 2015
1 parent 730f798 commit 1e4ae4c
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 55 deletions.
4 changes: 3 additions & 1 deletion xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@ CDVDVideoCodecMMAL::~CDVDVideoCodecMMAL()
{
CLog::Log(LOGDEBUG, "%s::%s %p\n", CLASSNAME, __func__, this);
Dispose();
delete m_decoder;
m_decoder = NULL;
}

bool CDVDVideoCodecMMAL::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
{
return m_decoder->Open(hints, options, m_decoder);
return m_decoder->Open(hints, options);
}

const char* CDVDVideoCodecMMAL::GetName(void)
Expand Down
2 changes: 1 addition & 1 deletion xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class CDVDVideoCodecMMAL : public CDVDVideoCodec
virtual void SetSpeed(int iSpeed);

protected:
MMALVideoPtr m_decoder;
CMMALVideo *m_decoder;
};

#endif
63 changes: 15 additions & 48 deletions xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ long CMMALVideoBuffer::Release()
CLog::Log(LOGDEBUG, "%s::%s %p (%p) ref:%ld", CLASSNAME, __func__, this, mmal_buffer, count);
if (count == 0)
{
m_omv->ReleaseBuffer(this);
mmal_buffer_header_release(mmal_buffer);
delete this;
}
else assert(count > 0);
return count;
Expand Down Expand Up @@ -117,7 +118,6 @@ CMMALVideo::CMMALVideo()

m_codingType = 0;

m_output_busy = 0;
m_demux_queue_length = 0;
m_es_format = mmal_format_alloc();
m_preroll = true;
Expand Down Expand Up @@ -261,7 +261,6 @@ void CMMALVideo::dec_output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf
omvb->height = m_decoded_height;
omvb->m_aspect_ratio = m_aspect_ratio;
pthread_mutex_lock(&m_output_mutex);
m_output_busy++;
m_output_ready.push(omvb);
pthread_mutex_unlock(&m_output_mutex);
kept = true;
Expand Down Expand Up @@ -505,7 +504,7 @@ bool CMMALVideo::SendCodecConfigData()
return true;
}

bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVideoPtr myself)
bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
{
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);
Expand All @@ -518,7 +517,6 @@ bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVide
MMAL_STATUS_T status;
MMAL_PARAMETER_BOOLEAN_T error_concealment;

m_myself = myself;
m_decoded_width = hints.width;
m_decoded_height = hints.height;

Expand Down Expand Up @@ -716,21 +714,9 @@ bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVide

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);
if (!m_output_busy)
done = true;
pthread_mutex_unlock(&m_output_mutex);
if (g_advancedSettings.CanLogComponent(LOGVIDEO))
CLog::Log(LOGDEBUG, "%s::%s ready_queue(%d) busy_queue(%d) done:%d", CLASSNAME, __func__, m_output_ready.size(), m_output_busy, done);
if (done)
{
m_myself.reset();
}
}

void CMMALVideo::SetDropState(bool bDrop)
Expand All @@ -742,8 +728,8 @@ void CMMALVideo::SetDropState(bool bDrop)
int CMMALVideo::Decode(uint8_t* pData, int iSize, double dts, double pts)
{
//if (g_advancedSettings.CanLogComponent(LOGVIDEO))
// CLog::Log(LOGDEBUG, "%s::%s - %-8p %-6d dts:%.3f pts:%.3f ready_queue(%d) busy_queue(%d)",
// CLASSNAME, __func__, pData, iSize, dts == DVD_NOPTS_VALUE ? 0.0 : dts*1e-6, pts == DVD_NOPTS_VALUE ? 0.0 : pts*1e-6, m_output_ready.size(), m_output_busy);
// CLog::Log(LOGDEBUG, "%s::%s - %-8p %-6d dts:%.3f pts:%.3f ready_queue(%d)",
// CLASSNAME, __func__, pData, iSize, dts == DVD_NOPTS_VALUE ? 0.0 : dts*1e-6, pts == DVD_NOPTS_VALUE ? 0.0 : pts*1e-6, m_output_ready.size());

unsigned int demuxer_bytes = 0;
uint8_t *demuxer_content = NULL;
Expand Down Expand Up @@ -819,8 +805,8 @@ int CMMALVideo::Decode(uint8_t* pData, int iSize, double dts, double pts)
buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;

if (g_advancedSettings.CanLogComponent(LOGVIDEO))
CLog::Log(LOGDEBUG, "%s::%s - %-8p %-6d/%-6d dts:%.3f pts:%.3f flags:%x ready_queue(%d) busy_queue(%d) demux_queue(%d) space(%d)",
CLASSNAME, __func__, buffer, buffer->length, demuxer_bytes, dts == DVD_NOPTS_VALUE ? 0.0 : dts*1e-6, pts == DVD_NOPTS_VALUE ? 0.0 : pts*1e-6, buffer->flags, m_output_ready.size(), m_output_busy, m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size);
CLog::Log(LOGDEBUG, "%s::%s - %-8p %-6d/%-6d dts:%.3f pts:%.3f flags:%x ready_queue(%d) demux_queue(%d) space(%d)",
CLASSNAME, __func__, buffer, buffer->length, demuxer_bytes, dts == DVD_NOPTS_VALUE ? 0.0 : dts*1e-6, pts == DVD_NOPTS_VALUE ? 0.0 : pts*1e-6, buffer->flags, m_output_ready.size(), m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size);
assert((int)buffer->length > 0);
status = mmal_port_send_buffer(m_dec_input, buffer);
if (status != MMAL_SUCCESS)
Expand Down Expand Up @@ -887,8 +873,8 @@ int CMMALVideo::Decode(uint8_t* pData, int iSize, double dts, double pts)
if (!ret)
{
if (g_advancedSettings.CanLogComponent(LOGVIDEO))
CLog::Log(LOGDEBUG, "%s::%s - Nothing to do: ready_queue(%d) busy_queue(%d) demux_queue(%d) space(%d) preroll(%d)",
CLASSNAME, __func__, m_output_ready.size(), m_output_busy, m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size, m_preroll);
CLog::Log(LOGDEBUG, "%s::%s - Nothing to do: ready_queue(%d) demux_queue(%d) space(%d) preroll(%d)",
CLASSNAME, __func__, m_output_ready.size(), m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size, m_preroll);
Sleep(10); // otherwise we busy spin
}
return ret;
Expand Down Expand Up @@ -927,7 +913,10 @@ void CMMALVideo::Reset(void)
}
pthread_mutex_unlock(&m_output_mutex);
if (buffer)
ReleaseBuffer(buffer);
{
buffer->Acquire();
buffer->Release();
}
else
break;
}
Expand Down Expand Up @@ -970,8 +959,8 @@ void CMMALVideo::Recycle(MMAL_BUFFER_HEADER_T *buffer)
mmal_buffer_header_reset(buffer);
buffer->cmd = 0;
if (g_advancedSettings.CanLogComponent(LOGVIDEO))
CLog::Log(LOGDEBUG, "%s::%s Send buffer %p from pool to decoder output port %p ready_queue(%d) busy_queue(%d)", CLASSNAME, __func__, buffer, m_dec_output,
m_output_ready.size(), m_output_busy);
CLog::Log(LOGDEBUG, "%s::%s Send buffer %p from pool to decoder output port %p ready_queue(%d)", CLASSNAME, __func__, buffer, m_dec_output,
m_output_ready.size());
status = mmal_port_send_buffer(m_dec_output, buffer);
if (status != MMAL_SUCCESS)
{
Expand All @@ -980,28 +969,6 @@ void CMMALVideo::Recycle(MMAL_BUFFER_HEADER_T *buffer)
}
}

void CMMALVideo::ReleaseBuffer(CMMALVideoBuffer *buffer)
{
// remove from busy list
pthread_mutex_lock(&m_output_mutex);
assert(m_output_busy > 0);
m_output_busy--;
pthread_mutex_unlock(&m_output_mutex);
// sanity check it is not on display
assert(!(buffer->mmal_buffer->flags & MMAL_BUFFER_HEADER_FLAG_USER2));
Recycle(buffer->mmal_buffer);
bool done = false;
pthread_mutex_lock(&m_output_mutex);
if (m_finished && !m_output_busy)
done = true;
pthread_mutex_unlock(&m_output_mutex);
if (done)
m_myself.reset();
if (g_advancedSettings.CanLogComponent(LOGVIDEO))
CLog::Log(LOGDEBUG, "%s::%s %p (%p) ready_queue(%d) busy_queue(%d) done:%d", CLASSNAME, __func__, buffer, buffer->mmal_buffer, m_output_ready.size(), m_output_busy, done);
delete buffer;
}

bool CMMALVideo::GetPicture(DVDVideoPicture* pDvdVideoPicture)
{
if (!m_output_ready.empty())
Expand Down
6 changes: 1 addition & 5 deletions xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
#include "cores/VideoRenderers/BaseRenderer.h"

class CMMALVideo;
typedef std::shared_ptr<CMMALVideo> MMALVideoPtr;

// a mmal video frame
class CMMALVideoBuffer
Expand Down Expand Up @@ -77,7 +76,7 @@ class CMMALVideo
virtual ~CMMALVideo();

// Required overrides
virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVideoPtr myself);
virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options);
virtual void Dispose(void);
virtual int Decode(uint8_t *pData, int iSize, double dts, double pts);
virtual void Reset(void);
Expand All @@ -91,7 +90,6 @@ class CMMALVideo
virtual void SetSpeed(int iSpeed);

// MMAL decoder callback routines.
void ReleaseBuffer(CMMALVideoBuffer *buffer);
void Recycle(MMAL_BUFFER_HEADER_T *buffer);

// MMAL decoder callback routines.
Expand All @@ -111,14 +109,12 @@ class CMMALVideo
bool m_finished;
float m_aspect_ratio;
const char *m_pFormatName;
MMALVideoPtr m_myself;

std::queue<mmal_demux_packet> m_demux_queue;
unsigned m_demux_queue_length;

// mmal output buffers (video frames)
pthread_mutex_t m_output_mutex;
int m_output_busy;
std::queue<CMMALVideoBuffer*> m_output_ready;

// initialize mmal and get decoder component
Expand Down

0 comments on commit 1e4ae4c

Please sign in to comment.