[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