[vlc-commits] bluray: add "VLC Escape" support

Julien Navas git at videolan.org
Tue Mar 24 11:54:12 CET 2020


vlc/vlc-3.0 | branch: master | Julien Navas <ju at videolan.org> | Thu Dec 12 16:47:19 2019 +0100| [3296c59eebb6e3b8ffcaa706a9691eb3e8c63834] | committer: Jean-Baptiste Kempf

bluray: add "VLC Escape" support

Co-Authored-By: Thomas Guillem <thomas at gllm.fr>
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

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

 modules/access/bluray.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 182 insertions(+), 1 deletion(-)

diff --git a/modules/access/bluray.c b/modules/access/bluray.c
index fc55b6c5de..dff49e4a38 100644
--- a/modules/access/bluray.c
+++ b/modules/access/bluray.c
@@ -205,6 +205,7 @@ struct  demux_sys_t
     /* TS stream */
     es_out_t            *p_tf_out;
     es_out_t            *p_out;
+    es_out_t            *p_esc_out;
     bool                b_spu_enable;       /* enabled / disabled */
     vlc_demux_chained_t *p_parser;
     bool                b_flushed;
@@ -371,6 +372,7 @@ static const char *DemuxGetLanguageCode( demux_t *p_demux, const char *psz_var )
  * Local prototypes
  *****************************************************************************/
 static es_out_t *esOutNew(vlc_object_t*, es_out_t *, void *);
+static es_out_t *escape_esOutNew(vlc_object_t *, es_out_t *);
 
 static int   blurayControl(demux_t *, int, va_list);
 static int   blurayDemux(demux_t *);
@@ -956,7 +958,17 @@ static int blurayOpen(vlc_object_t *object)
     if(unlikely(!p_sys->p_tf_out))
         goto error;
 
-    p_sys->p_out = esOutNew(VLC_OBJECT(p_demux), p_sys->p_tf_out, p_demux);
+    es_out_t *out_id = p_sys->p_tf_out;
+    if (unlikely(disc_info->udf_volume_id &&
+                 !strncmp(disc_info->udf_volume_id, "VLC Escape", strlen("VLC Escape"))))
+    {
+        p_sys->p_esc_out = escape_esOutNew(VLC_OBJECT(p_demux), p_sys->p_tf_out);
+        out_id = p_sys->p_esc_out;
+    }
+    else
+        p_sys->p_esc_out = NULL;
+
+    p_sys->p_out = esOutNew(VLC_OBJECT(p_demux), out_id, p_demux);
     if (unlikely(p_sys->p_out == NULL))
         goto error;
 
@@ -1017,6 +1029,8 @@ static void blurayClose(vlc_object_t *object)
 
     if (p_sys->p_out != NULL)
         es_out_Delete(p_sys->p_out);
+    if (p_sys->p_esc_out != NULL)
+        es_out_Delete(p_sys->p_esc_out);
     if(p_sys->p_tf_out)
         timestamps_filter_es_out_Delete(p_sys->p_tf_out);
 
@@ -3020,3 +3034,170 @@ static int blurayDemux(demux_t *p_demux)
 
     return VLC_DEMUXER_SUCCESS;
 }
+
+/*****************************************************************************
+ * bluray Escape es_out
+ *****************************************************************************/
+struct escape_es_id
+{
+    es_out_id_t *es;
+    bool drop_first;
+    mtime_t first_dts;
+};
+
+struct escape_esout_sys
+{
+    es_out_t *dst_out;
+    mtime_t   offset_pcr;
+
+    vlc_array_t es_ids; /* escape_es_id */
+};
+
+static es_out_id_t *escape_esOutAdd(es_out_t *out, const es_format_t *fmt)
+{
+    struct escape_esout_sys *esout_sys = (struct escape_esout_sys *)out->p_sys;
+
+    struct escape_es_id *esc_id = malloc(sizeof(*esc_id));
+    if (!esc_id)
+        return NULL;
+    esc_id->es = es_out_Add(esout_sys->dst_out, fmt);
+    if (!esc_id->es)
+    {
+        free(esc_id);
+        return NULL;
+    }
+    esc_id->first_dts = -1;
+    esc_id->drop_first = fmt->i_cat == VIDEO_ES;
+    if (vlc_array_append(&esout_sys->es_ids, esc_id) != VLC_SUCCESS)
+    {
+        es_out_Del(esout_sys->dst_out, esc_id->es);
+        free(esc_id);
+        return NULL;
+    }
+    return esc_id->es;
+}
+
+static struct escape_es_id *escape_GetEscOutId(es_out_t *out, es_out_id_t *es,
+                                               size_t *out_idx)
+{
+    struct escape_esout_sys *esout_sys = (struct escape_esout_sys *)out->p_sys;
+
+    for (size_t i = 0; i < vlc_array_count(&esout_sys->es_ids); ++i)
+    {
+        struct escape_es_id *esc_id = vlc_array_item_at_index(&esout_sys->es_ids, i);
+        if (esc_id->es == es)
+        {
+            if (out_idx)
+                *out_idx = i;
+            return esc_id;
+        }
+    }
+    return NULL;
+}
+
+static int escape_esOutSend(es_out_t *out, es_out_id_t *es, block_t *block)
+{
+    struct escape_esout_sys *esout_sys = (struct escape_esout_sys *)out->p_sys;
+    struct escape_es_id *esc_id = escape_GetEscOutId(out, es, NULL);
+    if (esc_id == NULL)
+        return VLC_EGENERIC;
+
+    if (esout_sys->offset_pcr != -1)
+    {
+        if (esc_id->first_dts == -1)
+        {
+            esc_id->first_dts = block->i_dts;
+            if (esc_id->drop_first)
+                block->i_flags |= BLOCK_FLAG_PREROLL;
+        }
+        mtime_t offset = esout_sys->offset_pcr - esc_id->first_dts;
+        block->i_pts += offset;
+        block->i_dts += offset;
+    }
+
+    return es_out_Send(esout_sys->dst_out, es, block);
+}
+
+static void escape_esOutDel(es_out_t *out, es_out_id_t *es)
+{
+    struct escape_esout_sys *esout_sys = (struct escape_esout_sys *)out->p_sys;
+    size_t index;
+    struct escape_es_id *esc_id = escape_GetEscOutId(out, es, &index);
+    if (esc_id == NULL)
+        return;
+
+    vlc_array_remove(&esout_sys->es_ids, index);
+    es_out_Del(esout_sys->dst_out, es);
+    free(esc_id);
+}
+
+static int escape_esOutControl(es_out_t *p_out, int query, va_list args)
+{
+    struct escape_esout_sys *esout_sys = (struct escape_esout_sys *)p_out->p_sys;
+    int ret;
+
+    switch (query)
+    {
+        case ES_OUT_RESET_PCR:
+            for (size_t i = 0; i < vlc_array_count(&esout_sys->es_ids); ++i)
+            {
+                struct escape_es_id *esc_id = vlc_array_item_at_index(&esout_sys->es_ids, i);
+                esc_id->first_dts = -1;
+            }
+            esout_sys->offset_pcr = -1;
+
+            ret = es_out_vaControl(esout_sys->dst_out, query, args);
+            break;
+        case ES_OUT_SET_GROUP_PCR:
+        {
+            int group = va_arg( args, int );
+            mtime_t pcr = va_arg( args, int64_t );
+
+            if (esout_sys->offset_pcr == -1)
+                esout_sys->offset_pcr = pcr;
+            ret = es_out_Control(esout_sys->dst_out, query, group, pcr);
+            break;
+        }
+        default:
+            ret = es_out_vaControl(esout_sys->dst_out, query, args);
+            break;
+    }
+    return ret;
+}
+
+static void escape_esOutDestroy(es_out_t *p_out)
+{
+    struct escape_esout_sys *esout_sys = (struct escape_esout_sys *)p_out->p_sys;
+
+    vlc_array_clear(&esout_sys->es_ids);
+    free(p_out->p_sys);
+    free(p_out);
+}
+
+static es_out_t *escape_esOutNew(vlc_object_t *p_obj, es_out_t *dst_out)
+{
+    es_out_t *out = malloc(sizeof(*out));
+    if (unlikely(out == NULL))
+        return NULL;
+
+    out->pf_add       = escape_esOutAdd;
+    out->pf_control   = escape_esOutControl;
+    out->pf_del       = escape_esOutDel;
+    out->pf_destroy   = escape_esOutDestroy;
+    out->pf_send      = escape_esOutSend;
+
+    struct escape_esout_sys *esout_sys = malloc(sizeof(*esout_sys));
+    if (unlikely(esout_sys == NULL))
+    {
+        free(out);
+        return NULL;
+    }
+    out->p_sys = (es_out_sys_t *) esout_sys;
+    vlc_array_init(&esout_sys->es_ids);
+    esout_sys->offset_pcr = -1;
+    esout_sys->dst_out = dst_out;
+
+    var_Create( p_obj, "ts-trust-pcr", VLC_VAR_BOOL );
+    var_SetBool( p_obj, "ts-trust-pcr", false );
+    return out;
+}



More information about the vlc-commits mailing list