[vlc-devel] [RFC PATCH 12/13] omxil: new way to wait for omxbuffers to be returned
Thomas Guillem
guillem at archos.com
Thu Jun 26 14:06:00 CEST 2014
Add OMX_BUFFER_COUNT_* macro: Increment count when we send a buffer to OMX
(FillThisBuffer/EmptyThisBuffer). Decrement count on
FillBufferDone/EmptyBufferDone callback. On FreeBuffers, wait for buffer count
to be zero.
---
modules/codec/omxil/omxil.c | 44 ++++++++++++++++++++++++++++++-------
modules/codec/omxil/omxil.h | 9 ++++++++
modules/codec/omxil/omxil_utils.h | 30 +++++++++++++++++++++++++
3 files changed, 75 insertions(+), 8 deletions(-)
diff --git a/modules/codec/omxil/omxil.c b/modules/codec/omxil/omxil.c
index 0d634fb..f90ffc5 100644
--- a/modules/codec/omxil/omxil.c
+++ b/modules/codec/omxil/omxil.c
@@ -430,20 +430,34 @@ static OMX_ERRORTYPE FreeBuffers(decoder_t *p_dec, OmxPort *p_port)
msg_Dbg( p_dec, "FreeBuffers(%d)", def->eDir );
#endif
- for(i = 0; i < p_port->i_buffers; i++)
- {
+ /* wait for all omx buffers to be returned */
+ OMX_BUFFER_COUNT_WAIT_ZERO( &p_port->omx_count );
+
+ /* empty the OMX_FIFO */
+ while (1) {
+ OMX_FIFO_PEEK(&p_port->fifo, p_buffer);
+ if (!p_buffer) break;
+
OMX_FIFO_GET(&p_port->fifo, p_buffer);
- if (p_buffer->pAppPrivate != NULL)
- decoder_DeletePicture( p_dec, p_buffer->pAppPrivate );
if (p_buffer->nFlags & SENTINEL_FLAG) {
free(p_buffer);
- i--;
continue;
}
- omx_error = OMX_FreeBuffer( p_port->omx_handle,
- p_port->i_port_index, p_buffer );
+ }
+
+ for(i = 0; i < p_port->i_buffers; i++)
+ {
+ p_buffer = p_port->pp_buffers[i];
+ if( p_buffer )
+ {
+ if (p_buffer->pAppPrivate != NULL)
+ decoder_DeletePicture( p_dec, p_buffer->pAppPrivate );
- if(omx_error != OMX_ErrorNone) break;
+ omx_error = OMX_FreeBuffer( p_port->omx_handle,
+ p_port->i_port_index, p_buffer );
+
+ if(omx_error != OMX_ErrorNone) break;
+ }
}
if( omx_error != OMX_ErrorNone )
msg_Err( p_dec, "OMX_FreeBuffer failed (%x, %i, %i)",
@@ -939,10 +953,12 @@ static int OpenGeneric( vlc_object_t *p_this, bool b_encode )
p_sys->b_enc = b_encode;
InitOmxEventQueue(&p_sys->event_queue);
OMX_FIFO_INIT (&p_sys->in.fifo, pOutputPortPrivate );
+ OMX_BUFFER_COUNT_INIT( &p_sys->in.omx_count);
p_sys->in.b_direct = false;
p_sys->in.b_flushed = true;
p_sys->in.p_fmt = &p_dec->fmt_in;
OMX_FIFO_INIT (&p_sys->out.fifo, pInputPortPrivate );
+ OMX_BUFFER_COUNT_INIT( &p_sys->out.omx_count);
p_sys->out.b_direct = false;
p_sys->out.b_flushed = true;
p_sys->out.p_fmt = &p_dec->fmt_out;
@@ -1098,6 +1114,7 @@ static int OpenGeneric( vlc_object_t *p_this, bool b_encode )
p_header->nFlags = OMX_BUFFERFLAG_CODECCONFIG | OMX_BUFFERFLAG_ENDOFFRAME;
msg_Dbg(p_dec, "sending codec config data %p, %p, %i", p_header,
p_header->pBuffer, (int)p_header->nFilledLen);
+ OMX_BUFFER_COUNT_INC( &p_sys->in.omx_count );
OMX_EmptyThisBuffer(p_sys->omx_handle, p_header);
}
@@ -1304,6 +1321,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
#ifdef OMXIL_EXTRA_DEBUG
msg_Dbg( p_dec, "FillThisBuffer %p, %p", p_header, p_header->pBuffer );
#endif
+ OMX_BUFFER_COUNT_INC( &p_sys->out.omx_count );
OMX_FillThisBuffer(p_sys->omx_handle, p_header);
}
@@ -1364,6 +1382,7 @@ more_input:
msg_Dbg( p_dec, "EmptyThisBuffer %p, %p, %i, %"PRId64, p_header, p_header->pBuffer,
(int)p_header->nFilledLen, FromOmxTicks(p_header->nTimeStamp) );
#endif
+ OMX_BUFFER_COUNT_INC( &p_sys->in.omx_count );
OMX_EmptyThisBuffer(p_sys->omx_handle, p_header);
p_sys->in.b_flushed = false;
if (decode_more)
@@ -1478,6 +1497,7 @@ block_t *DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
msg_Dbg( p_dec, "FillThisBuffer %p, %p", p_header, p_header->pBuffer );
#endif
OMX_FIFO_GET(&p_sys->out.fifo, p_header);
+ OMX_BUFFER_COUNT_INC( &p_sys->out.omx_count );
OMX_FillThisBuffer(p_sys->omx_handle, p_header);
}
@@ -1521,6 +1541,7 @@ block_t *DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
msg_Dbg( p_dec, "EmptyThisBuffer %p, %p, %i", p_header, p_header->pBuffer,
(int)p_header->nFilledLen );
#endif
+ OMX_BUFFER_COUNT_INC( &p_sys->in.omx_count );
OMX_EmptyThisBuffer(p_sys->omx_handle, p_header);
p_sys->in.b_flushed = false;
*pp_block = NULL; /* Avoid being fed the same packet again */
@@ -1589,6 +1610,7 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pic )
msg_Dbg( p_dec, "EmptyThisBuffer %p, %p, %i", p_header, p_header->pBuffer,
(int)p_header->nFilledLen );
#endif
+ OMX_BUFFER_COUNT_INC( &p_sys->in.omx_count );
OMX_EmptyThisBuffer(p_sys->omx_handle, p_header);
p_sys->in.b_flushed = false;
}
@@ -1634,6 +1656,7 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pic )
#ifdef OMXIL_EXTRA_DEBUG
msg_Dbg( p_dec, "FillThisBuffer %p, %p", p_header, p_header->pBuffer );
#endif
+ OMX_BUFFER_COUNT_INC( &p_sys->out.omx_count );
OMX_FillThisBuffer(p_sys->omx_handle, p_header);
}
@@ -1659,7 +1682,10 @@ static void CloseGeneric( vlc_object_t *p_this )
DeinitOmxEventQueue(&p_sys->event_queue);
OMX_FIFO_DESTROY( &p_sys->in.fifo );
+ OMX_BUFFER_COUNT_DESTROY( &p_sys->in.omx_count);
+
OMX_FIFO_DESTROY( &p_sys->out.fifo );
+ OMX_BUFFER_COUNT_DESTROY( &p_sys->out.omx_count);
free( p_sys );
}
@@ -1739,6 +1765,7 @@ static OMX_ERRORTYPE OmxEmptyBufferDone( OMX_HANDLETYPE omx_handle,
omx_header->pAppPrivate = 0;
}
OMX_FIFO_PUT(&p_sys->in.fifo, omx_header);
+ OMX_BUFFER_COUNT_DEC( &p_sys->in.omx_count );
return OMX_ErrorNone;
}
@@ -1760,6 +1787,7 @@ static OMX_ERRORTYPE OmxFillBufferDone( OMX_HANDLETYPE omx_handle,
omx_header->pBuffer = omx_header->pOutputPortPrivate;
}
OMX_FIFO_PUT(&p_sys->out.fifo, omx_header);
+ OMX_BUFFER_COUNT_DEC( &p_sys->out.omx_count );
return OMX_ErrorNone;
}
diff --git a/modules/codec/omxil/omxil.h b/modules/codec/omxil/omxil.h
index 6cb7abf..2921e90 100644
--- a/modules/codec/omxil/omxil.h
+++ b/modules/codec/omxil/omxil.h
@@ -51,6 +51,14 @@ typedef struct OmxFifo
} OmxFifo;
+typedef struct OmxBufferCount
+{
+ vlc_mutex_t lock;
+ vlc_cond_t wait;
+ unsigned int i_count;
+
+} OmxBufferCount;
+
typedef struct OmxPort
{
bool b_valid;
@@ -67,6 +75,7 @@ typedef struct OmxPort
OMX_BUFFERHEADERTYPE **pp_buffers;
OmxFifo fifo;
+ OmxBufferCount omx_count;
OmxFormatParam format_param;
diff --git a/modules/codec/omxil/omxil_utils.h b/modules/codec/omxil/omxil_utils.h
index a1d564b..47e213e 100644
--- a/modules/codec/omxil/omxil_utils.h
+++ b/modules/codec/omxil/omxil_utils.h
@@ -128,6 +128,36 @@ static inline OMX_TICKS ToOmxTicks(int64_t value)
vlc_mutex_unlock( &(p_fifo)->lock ); } while(0)
/*****************************************************************************
+ * OMX buffer counter macros
+ *****************************************************************************/
+#define OMX_BUFFER_COUNT_INIT(p_count) \
+ do { vlc_mutex_init( &(p_count)->lock ); \
+ vlc_cond_init( &(p_count)->wait ); \
+ (p_count)->i_count = 0; } while(0)
+
+#define OMX_BUFFER_COUNT_DESTROY(p_count) \
+ do { vlc_mutex_destroy( &(p_count)->lock ); \
+ vlc_cond_destroy( &(p_count)->wait ); } while(0)
+
+#define OMX_BUFFER_COUNT_INC(p_count) \
+ do { vlc_mutex_lock (&(p_count)->lock); \
+ (p_count)->i_count++; \
+ vlc_cond_signal( &(p_count)->wait ); \
+ vlc_mutex_unlock( &(p_count)->lock ); } while(0)
+
+#define OMX_BUFFER_COUNT_DEC(p_count) \
+ do { vlc_mutex_lock (&(p_count)->lock); \
+ (p_count)->i_count--; \
+ vlc_cond_signal( &(p_count)->wait ); \
+ vlc_mutex_unlock( &(p_count)->lock ); } while(0)
+
+#define OMX_BUFFER_COUNT_WAIT_ZERO(p_count) \
+ do { vlc_mutex_lock( &(p_count)->lock ); \
+ while( (p_count)->i_count != 0 ) \
+ vlc_cond_wait( &(p_count)->wait, &(p_count)->lock ); \
+ vlc_mutex_unlock( &(p_count)->lock ); } while(0)
+
+/*****************************************************************************
* OMX format parameters
*****************************************************************************/
typedef union {
--
1.7.10.4
--
This email and any files transmitted with it are confidential and are
intended solely for the use of the individual or entity to which they are
addressed. Access to this e-mail by anyone else is unauthorised. If you are
not the intended recipient, any disclosure, copying, distribution or any
action taken or omitted to be taken in reliance on it, is prohibited.
E-mail messages are not necessarily secure. Archos does not accept
responsibility for any changes made to this message after it was sent.
More information about the vlc-devel
mailing list