[vlc-devel] [RFC PATCH] decoder: add decoder_QueuePicture

Thomas Guillem thomas at gllm.fr
Fri Oct 31 14:08:22 CET 2014


This function allow asynchronous decoders to queue a picture from an other
thread. Theses decoders should return NULL in pf_decode callback.

---

Tested with my patched mediacodec that use one thread for input and one
thread for output. It's working, but still WIP and not ready for submission.

 include/vlc_codec.h |  2 ++
 src/input/decoder.c | 91 ++++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 64 insertions(+), 29 deletions(-)

diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 429cfa5..d6ec6ce 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -217,6 +217,8 @@ VLC_API void decoder_LinkPicture( decoder_t *, picture_t * );
  */
 VLC_API void decoder_UnlinkPicture( decoder_t *, picture_t * );
 
+VLC_API int decoder_QueuePicture( decoder_t *, picture_t * );
+
 /**
  * This function notifies the audio output pipeline of a new audio output
  * format (fmt_out.audio). If there is currently no audio output or if the
diff --git a/src/input/decoder.c b/src/input/decoder.c
index fe8d669..f33b37c 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -1365,6 +1365,66 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
     *pi_lost_sum += i_tmp_lost;
 }
 
+static int DecoderPreparePlayVideo( decoder_t *p_dec, picture_t *p_pic )
+{
+    decoder_owner_sys_t *p_owner = p_dec->p_owner;
+    vout_thread_t  *p_vout = p_owner->p_vout;
+
+    if( p_owner->i_preroll_end > VLC_TS_INVALID && p_pic->date < p_owner->i_preroll_end )
+    {
+        vout_ReleasePicture( p_vout, p_pic );
+        return -1;
+    }
+
+    if( p_owner->i_preroll_end > VLC_TS_INVALID )
+    {
+        msg_Dbg( p_dec, "End of video preroll" );
+        if( p_vout )
+            vout_Flush( p_vout, VLC_TS_INVALID+1 );
+        /* */
+        p_owner->i_preroll_end = VLC_TS_INVALID;
+    }
+
+    if( p_dec->pf_get_cc &&
+        ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
+        DecoderGetCc( p_dec, p_dec );
+
+    return 0;
+}
+
+static void DecoderUpdateStatVideo( decoder_t *p_dec, int i_decoded,
+                                    int i_lost, int i_displayed )
+{
+    decoder_owner_sys_t *p_owner = p_dec->p_owner;
+    input_thread_t *p_input = p_owner->p_input;
+
+    /* Update ugly stat */
+    if( p_input != NULL && (i_decoded > 0 || i_lost > 0 || i_displayed > 0) )
+    {
+        vlc_mutex_lock( &p_input->p->counters.counters_lock );
+        stats_Update( p_input->p->counters.p_decoded_video, i_decoded, NULL );
+        stats_Update( p_input->p->counters.p_lost_pictures, i_lost , NULL);
+        stats_Update( p_input->p->counters.p_displayed_pictures,
+                      i_displayed, NULL);
+        vlc_mutex_unlock( &p_input->p->counters.counters_lock );
+    }
+}
+
+int decoder_QueuePicture( decoder_t *p_dec, picture_t *p_pic )
+{
+    int i_lost = 0;
+    int i_displayed = 0;
+
+    if( DecoderPreparePlayVideo( p_dec, p_pic ) != 0 )
+        return -1;
+
+    DecoderPlayVideo( p_dec, p_pic, &i_displayed, &i_lost );
+
+    DecoderUpdateStatVideo( p_dec, 1, i_lost, i_displayed );
+
+    return 0;
+}
+
 static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
 {
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
@@ -1387,40 +1447,13 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
 
         i_decoded++;
 
-        if( p_owner->i_preroll_end > VLC_TS_INVALID && p_pic->date < p_owner->i_preroll_end )
-        {
-            vout_ReleasePicture( p_vout, p_pic );
+        if( DecoderPreparePlayVideo( p_dec, p_pic ) != 0 )
             continue;
-        }
-
-        if( p_owner->i_preroll_end > VLC_TS_INVALID )
-        {
-            msg_Dbg( p_dec, "End of video preroll" );
-            if( p_vout )
-                vout_Flush( p_vout, VLC_TS_INVALID+1 );
-            /* */
-            p_owner->i_preroll_end = VLC_TS_INVALID;
-        }
-
-        if( p_dec->pf_get_cc &&
-            ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
-            DecoderGetCc( p_dec, p_dec );
 
         DecoderPlayVideo( p_dec, p_pic, &i_displayed, &i_lost );
     }
 
-    /* Update ugly stat */
-    input_thread_t *p_input = p_owner->p_input;
-
-    if( p_input != NULL && (i_decoded > 0 || i_lost > 0 || i_displayed > 0) )
-    {
-        vlc_mutex_lock( &p_input->p->counters.counters_lock );
-        stats_Update( p_input->p->counters.p_decoded_video, i_decoded, NULL );
-        stats_Update( p_input->p->counters.p_lost_pictures, i_lost , NULL);
-        stats_Update( p_input->p->counters.p_displayed_pictures,
-                      i_displayed, NULL);
-        vlc_mutex_unlock( &p_input->p->counters.counters_lock );
-    }
+    DecoderUpdateStatVideo( p_dec, i_decoded, i_lost, i_displayed );
 }
 
 static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic )
-- 
2.1.0




More information about the vlc-devel mailing list