[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