[vlc-devel] [RFC PATCH 6/9] decoder: add decoder_RequestPacketizer

Thomas Guillem thomas at gllm.fr
Sat Jul 9 12:20:14 CEST 2016


A decoder can call decoder_RequestPacketizer() in Open() to query a specific
packetizer. The decoder should also release the requested packetizer in Close()
or if Open() fails.

Calling decoder_RequestPacketizer() from Open() will cause the p_dec->fmt_in to
change (updated by the packetizer).

If the requested packetizer is the same than the current one, the current one
will be used.
---
 include/vlc_codec.h | 12 +++++++++++
 src/input/decoder.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/libvlccore.sym  |  1 +
 3 files changed, 71 insertions(+)

diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 2d01d26..c953717 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -368,6 +368,18 @@ VLC_API block_t * decoder_NewAudioBuffer( decoder_t *, int i_size ) VLC_USED;
 VLC_API subpicture_t * decoder_NewSubpicture( decoder_t *, const subpicture_updater_t * ) VLC_USED;
 
 /**
+ * This function is used to query a specific packetizer.
+ *
+ * This must be called during open and close callbacks. The decoder fmt_in can
+ * change after this call.
+ *
+ * @param psz_packetizer_name if not NULL, request the specific packetizer. If
+ * null, release a previously requested packetizer
+ * @return VLC_SUCCESS on success, or a VLC error
+ */
+VLC_API int decoder_RequestPacketizer( decoder_t *, const char *psz_packetizer_name );
+
+/**
  * This function gives all input attachments at once.
  *
  * You MUST release the returned values
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 74e08de..de03dd6 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -72,6 +72,8 @@ struct decoder_owner_sys_t
 
     /* Some decoders require already packetized data (ie. not truncated) */
     decoder_t *p_packetizer;
+    decoder_t *p_packetizer_extra;
+    decoder_t *p_packetizer_orig;
     bool b_packetizer;
 
     /* Current format in use by the output */
@@ -604,6 +606,58 @@ subpicture_t *decoder_NewSubpicture( decoder_t *p_decoder,
     return p_subpicture;
 }
 
+int decoder_RequestPacketizer( decoder_t *p_dec, const char *psz_packetizer_name )
+{
+    decoder_owner_sys_t *p_owner = p_dec->p_owner;
+
+
+    if( psz_packetizer_name != NULL )
+    {
+        /* Must be called during Open(), and not twice */
+        assert( p_dec->p_module == NULL && p_owner->p_packetizer_extra == NULL
+             && p_owner->p_packetizer_orig == NULL );
+
+        p_owner->p_packetizer_extra =
+            CreateExtraPacketizer( p_dec, &p_dec->fmt_in, psz_packetizer_name );
+        if( p_owner->p_packetizer_extra == NULL )
+            return VLC_EGENERIC;
+
+        if( p_owner->p_packetizer != NULL
+         && p_owner->p_packetizer_extra->p_module
+         == p_owner->p_packetizer->p_module )
+        {
+            /* The requested packetizer is the same than the current one */
+            UnloadDecoder( p_owner->p_packetizer_extra );
+            vlc_object_release( p_owner->p_packetizer_extra );
+            p_owner->p_packetizer_extra = p_owner->p_packetizer;
+        }
+        else
+        {
+            /* Setup the new extra packetizer */
+            p_owner->p_packetizer_orig = p_owner->p_packetizer;
+            p_owner->p_packetizer = p_owner->p_packetizer_extra;
+            es_format_Copy( &p_dec->fmt_in, &p_owner->p_packetizer_extra->fmt_out );
+        }
+        return VLC_SUCCESS;
+    }
+    else
+    {
+        assert( p_owner->p_packetizer == p_owner->p_packetizer_extra
+             && p_owner->p_packetizer != NULL );
+
+        if( p_owner->p_packetizer_orig != NULL )
+        {
+            /* Remove the extra packetizer */
+            UnloadDecoder( p_owner->p_packetizer_extra );
+            vlc_object_release( p_owner->p_packetizer_extra );
+            p_owner->p_packetizer = p_owner->p_packetizer_orig;
+            p_owner->p_packetizer_orig = NULL;
+        }
+        p_owner->p_packetizer_extra = NULL;
+        return VLC_SUCCESS;
+    }
+}
+
 /* decoder_GetInputAttachments:
  */
 int decoder_GetInputAttachments( decoder_t *p_dec,
@@ -1597,6 +1651,8 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
     p_owner->p_sout = p_sout;
     p_owner->p_sout_input = NULL;
     p_owner->p_packetizer = NULL;
+    p_owner->p_packetizer_extra = NULL;
+    p_owner->p_packetizer_orig = NULL;
 
     p_owner->b_fmt_description = false;
     p_owner->p_description = NULL;
@@ -1709,6 +1765,8 @@ static void DeleteDecoder( decoder_t * p_dec )
 
     const bool b_flush_spu = p_dec->fmt_out.i_cat == SPU_ES;
     UnloadDecoder( p_dec );
+    assert( p_dec->p_owner->p_packetizer_orig == NULL
+         && p_dec->p_owner->p_packetizer_extra == NULL );
 
     /* Free all packets still in the decoder fifo. */
     block_FifoRelease( p_owner->p_fifo );
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 89e74f8..310ecd4 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -82,6 +82,7 @@ decoder_GetDisplayRate
 decoder_GetInputAttachments
 decoder_NewAudioBuffer
 decoder_NewSubpicture
+decoder_RequestPacketizer
 decoder_SynchroChoose
 decoder_SynchroDate
 decoder_SynchroDecode
-- 
2.8.1



More information about the vlc-devel mailing list