[vlc-devel] [PATCH 2/3] stream_filter: sliptags: extract and store tags

Francois Cartegnie fcvlcdev at free.fr
Thu Jul 13 14:05:20 CEST 2017


---
 modules/stream_filter/skiptags.c | 105 +++++++++++++++++++++++++++++----------
 1 file changed, 79 insertions(+), 26 deletions(-)

diff --git a/modules/stream_filter/skiptags.c b/modules/stream_filter/skiptags.c
index b33966f..63a9c79 100644
--- a/modules/stream_filter/skiptags.c
+++ b/modules/stream_filter/skiptags.c
@@ -31,13 +31,37 @@
 #include <vlc_plugin.h>
 #include <vlc_stream.h>
 
+#define MAX_TAGS 16
+#define MAX_TAG_SIZE (1<<17)
+
 struct skiptags_sys_t
 {
     uint64_t header_skip;
     /* TODO? also discard trailer tags? */
+    uint8_t *tags[MAX_TAGS];
+    int tagsizes[MAX_TAGS];
+    int tags_count;
 };
 
-static int SkipID3Tag(stream_t *s)
+static struct skiptags_sys_t * skiptags_sys_New(void)
+{
+    struct skiptags_sys_t *sys = malloc(sizeof (*sys));
+    if(sys)
+    {
+        sys->header_skip = 0;
+        sys->tags_count = 0;
+    }
+    return sys;
+}
+
+static void skiptags_sys_Delete(struct skiptags_sys_t *sys)
+{
+    for(int i=0; i<sys->tags_count; i++)
+        free(sys->tags[i]);
+    free(sys);
+}
+
+static uint_fast32_t SkipID3Tag(stream_t *s)
 {
     const uint8_t *peek;
 
@@ -56,13 +80,11 @@ static int SkipID3Tag(stream_t *s)
     /* Skip the entire tag */
     msg_Dbg(s, "ID3v2.%"PRIuFAST8" revision %"PRIuFAST8" tag found, "
             "skipping %"PRIuFAST32" bytes", version, revision, size);
-    if (vlc_stream_Read(s, NULL, size) < (ssize_t)size)
-        return -1;
 
-    return 1;
+    return size;
 }
 
-static int SkipAPETag(stream_t *s)
+static uint_fast32_t SkipAPETag(stream_t *s)
 {
     const uint8_t *peek;
 
@@ -87,26 +109,47 @@ static int SkipAPETag(stream_t *s)
     if (flags & (1u << 30))
         size += 32;
 
-    /* Skip the entire tag */
-    if (vlc_stream_Read(s, NULL, size) < (ssize_t)size)
-        return -1;
-
     msg_Dbg(s, "AP2 v%"PRIuFAST32" tag found, "
             "skipping %"PRIuFAST32" bytes", version / 1000, size);
-    return 1;
+    return size;
 }
 
-static bool SkipTag(stream_t *s, int (*skipper)(stream_t *))
+static bool SkipTag(stream_t *s, uint_fast32_t (*skipper)(stream_t *), struct skiptags_sys_t **pp_sys)
 {
     uint_fast64_t offset = vlc_stream_Tell(s);
-    int val = skipper(s);
-    if (unlikely(val < 0))
-    {   /* I/O error, try to restore offset. If it fails, screwed. */
-        if (vlc_stream_Seek(s, offset))
-            msg_Err(s, "seek failure");
-        return false;
+    uint_fast32_t size = skipper(s);
+    if(size> 0)
+    {
+        uint8_t *p_tag = NULL;
+        int *pi_tagsize;
+        if(*pp_sys || (*pp_sys = skiptags_sys_New()))
+        {
+            if((*pp_sys)->tags_count < MAX_TAGS && size < MAX_TAG_SIZE)
+            {
+                p_tag = (*pp_sys)->tags[(*pp_sys)->tags_count] = malloc(size);
+                pi_tagsize = &(*pp_sys)->tagsizes[(*pp_sys)->tags_count];
+                *pi_tagsize = 0; /* incomplete or failed will be set to 0 */
+                (*pp_sys)->tags_count++;
+            }
+        }
+
+        /* Skip the entire tag */
+        ssize_t read = vlc_stream_Read(s, p_tag, size);
+        if(read < (ssize_t)size)
+        {
+            if (unlikely(read < 0))
+            {   /* I/O error, try to restore offset. If it fails, screwed. */
+                if (vlc_stream_Seek(s, offset))
+                    msg_Err(s, "seek failure");
+                return false;
+            }
+        }
+        else if(p_tag)
+        {
+            *pi_tagsize = size;
+        }
     }
-    return val != 0;
+    return size != 0;
 }
 
 static ssize_t Read(stream_t *stream, void *buf, size_t buflen)
@@ -131,9 +174,18 @@ static int Seek(stream_t *stream, uint64_t offset)
 
 static int Control(stream_t *stream, int query, va_list args)
 {
+    const struct skiptags_sys_t *sys = stream->p_sys;
     /* In principles, we should return the meta-data embedded in the skipped
      * tags in STREAM_GET_META. But the meta engine is devoted to that already.
      */
+    if( query == STREAM_GET_TAGS && sys->tags_count )
+    {
+        *va_arg( args, const uint8_t *** ) = (const uint8_t **) sys->tags;
+        *va_arg( args, const int ** ) = sys->tagsizes;
+        *va_arg( args, int * ) = sys->tags_count;
+        return VLC_SUCCESS;
+    }
+
     return vlc_stream_vaControl(stream->p_source, query, args);
 }
 
@@ -141,17 +193,18 @@ static int Open(vlc_object_t *obj)
 {
     stream_t *stream = (stream_t *)obj;
     stream_t *s = stream->p_source;
+    struct skiptags_sys_t *sys = NULL;
 
-    while (SkipTag(s, SkipID3Tag));
-    SkipTag(s, SkipAPETag);
+    while (SkipTag(s, SkipID3Tag, &sys));
+    SkipTag(s, SkipAPETag, &sys);
 
     uint_fast64_t offset = vlc_stream_Tell(s);
     if (offset == 0)
+    {
+        if(sys)
+            skiptags_sys_Delete(sys);
         return VLC_EGENERIC; /* nothing to do */
-
-    struct skiptags_sys_t *sys = malloc(sizeof (*sys));
-    if (unlikely(sys == NULL))
-        return VLC_ENOMEM;
+    }
 
     sys->header_skip = offset;
     stream->p_sys = sys;
@@ -165,9 +218,9 @@ static int Open(vlc_object_t *obj)
 static void Close(vlc_object_t *obj)
 {
     stream_t *stream = (stream_t *)obj;
-    stream_sys_t *sys = stream->p_sys;
+    struct skiptags_sys_t *sys = (struct skiptags_sys_t *) stream->p_sys;
 
-    free(sys);
+    skiptags_sys_Delete(sys);
 }
 
 vlc_module_begin()
-- 
2.9.4



More information about the vlc-devel mailing list