[vlc-commits] omxil: Use vlc_cond_timedwait when waiting for free input buffers

Martin Storsjö git at videolan.org
Tue Feb 12 10:58:07 CET 2013


vlc | branch: master | Martin Storsjö <martin at martin.st> | Tue Feb 12 11:37:33 2013 +0200| [bbf8c217d96e344fd5c5757cae1a599fc2eabbdd] | committer: Martin Storsjö

omxil: Use vlc_cond_timedwait when waiting for free input buffers

The structure of the decode functions are like this:

Decode() {
    if (got output buffer) {
        consume output buffer;
    }
    wait for input buffer;
    if (got input buffer) {
        fill input buffer and send to the codec;
    }
}

This makes the functions prone to deadlock, if all input buffers
have been consumed and won't be returned by the codec until we
consume some of the output buffers (and we don't get the output
buffers until we already are waiting for an input buffer).

By using a timeout in the wait for input buffers, we get out of the
deadlock and can consume an output buffer, allowing the codec to
proceed. By making the timeout relatively large, it won't trigger
during normal decoding, but gets us out of possible deadlocks
(noticed at startup with qualcomm audio decoders).

The alternative to timeouts would be to push dummy/sentinel buffers
into the fifo (as we already do at reconfiguration) each time we
receive an output buffer. This would add quite a bit of overhead
though, having to process (and skip) one item in the input buffer
fifo for each received output buffer.

Signed-off-by: Martin Storsjö <martin at martin.st>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=bbf8c217d96e344fd5c5757cae1a599fc2eabbdd
---

 modules/codec/omxil/omxil.c       |    4 ++--
 modules/codec/omxil/omxil_utils.h |   14 ++++++++++++++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/modules/codec/omxil/omxil.c b/modules/codec/omxil/omxil.c
index 7c925fc..740ae47 100644
--- a/modules/codec/omxil/omxil.c
+++ b/modules/codec/omxil/omxil.c
@@ -1368,7 +1368,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
     }
 
     /* Send the input buffer to the component */
-    OMX_FIFO_GET(&p_sys->in.fifo, p_header);
+    OMX_FIFO_GET_TIMEOUT(&p_sys->in.fifo, p_header, 200000);
 
     if (p_header && p_header->nFlags & SENTINEL_FLAG) {
         free(p_header);
@@ -1524,7 +1524,7 @@ block_t *DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
 
 
     /* Send the input buffer to the component */
-    OMX_FIFO_GET(&p_sys->in.fifo, p_header);
+    OMX_FIFO_GET_TIMEOUT(&p_sys->in.fifo, p_header, 200000);
 
     if (p_header && p_header->nFlags & SENTINEL_FLAG) {
         free(p_header);
diff --git a/modules/codec/omxil/omxil_utils.h b/modules/codec/omxil/omxil_utils.h
index 5bd8fe2..677eab4 100644
--- a/modules/codec/omxil/omxil_utils.h
+++ b/modules/codec/omxil/omxil_utils.h
@@ -72,6 +72,20 @@
          if( !(p_fifo)->p_first ) (p_fifo)->pp_last = &(p_fifo)->p_first; \
          vlc_mutex_unlock( &(p_fifo)->lock ); } while(0)
 
+#define OMX_FIFO_GET_TIMEOUT(p_fifo, p_buffer, timeout) \
+    do { vlc_mutex_lock( &(p_fifo)->lock ); \
+         mtime_t end = mdate() + timeout; \
+         if( !(p_fifo)->p_first ) \
+             vlc_cond_timedwait( &(p_fifo)->wait, &(p_fifo)->lock, end ); \
+         p_buffer = (p_fifo)->p_first; \
+         if( p_buffer ) { \
+             OMX_BUFFERHEADERTYPE **pp_next = (OMX_BUFFERHEADERTYPE **) \
+                 ((void **)p_buffer + (p_fifo)->offset); \
+             (p_fifo)->p_first = *pp_next; *pp_next = 0; \
+             if( !(p_fifo)->p_first ) (p_fifo)->pp_last = &(p_fifo)->p_first; \
+         } \
+         vlc_mutex_unlock( &(p_fifo)->lock ); } while(0)
+
 #define OMX_FIFO_PUT(p_fifo, p_buffer) \
     do { vlc_mutex_lock (&(p_fifo)->lock);              \
          OMX_BUFFERHEADERTYPE **pp_next = (OMX_BUFFERHEADERTYPE **) \



More information about the vlc-commits mailing list