[vlc-devel] [PATCH 2/3] stream_filter: sliptags: extract and store tags
Rémi Denis-Courmont
remi at remlab.net
Tue Jul 18 14:17:39 CEST 2017
On jeudi 13 juillet 2017 14:05:20 EEST Francois Cartegnie wrote:
> ---
> modules/stream_filter/skiptags.c | 105
> +++++++++++++++++++++++++++++---------- 1 file changed, 79 insertions(+),
> 26 deletions(-)
Typo in title.
I strongly suspect that using block_t and maybe block_t chain would be simpler
internally.
> 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()
--
Rémi Denis-Courmont
More information about the vlc-devel
mailing list