<div dir="ltr"><div dir="ltr">On Wed, Sep 16, 2020 at 3:22 AM Rémi Denis-Courmont <<a href="mailto:remi@remlab.net">remi@remlab.net</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">        Hi,<br>
<br>
Le tiistaina 15. syyskuuta 2020, 17.26.39 EEST Zhao, Gang a écrit :<br>
> Parse INFO chunk and save meta data to vlc.<br>
> <br>
> Feature ticket: <a href="https://trac.videolan.org/vlc/ticket/6587" rel="noreferrer" target="_blank">https://trac.videolan.org/vlc/ticket/6587</a><br>
> <br>
> Signed-off-by: Zhao, Gang <<a href="mailto:gang.zhao.42@gmail.com" target="_blank">gang.zhao.42@gmail.com</a>><br>
> ---<br>
>  modules/demux/wav.c | 191 ++++++++++++++++++++++++++++++++++++++++++++<br>
>  1 file changed, 191 insertions(+)<br>
> <br>
> diff --git modules/demux/wav.c modules/demux/wav.c<br>
> index 52f9639ef9..e09734579a 100644<br>
> --- modules/demux/wav.c<br>
> +++ modules/demux/wav.c<br>
> @@ -36,6 +36,8 @@<br>
>  #include <vlc_demux.h><br>
>  #include <vlc_aout.h><br>
>  #include <vlc_codecs.h><br>
> +#include <vlc_charset.h><br>
> +#include <vlc_meta.h><br>
> <br>
>  #include "windows_audio_commons.h"<br>
> <br>
> @@ -58,12 +60,39 @@ typedef struct<br>
>      uint32_t i_channel_mask;<br>
>      uint8_t i_chans_to_reorder;            /* do we need channel reordering<br>
> */ uint8_t pi_chan_table[AOUT_CHAN_MAX];<br>
> +<br>
> +    vlc_meta_t    *p_meta;<br>
>  } demux_sys_t;<br>
> <br>
>  enum wav_chunk_id {<br>
> +    wav_chunk_id_list,<br>
>      wav_chunk_id_data,<br>
>      wav_chunk_id_ds64,<br>
>      wav_chunk_id_fmt,<br>
> +<br>
> +    wav_info_chunk_id_iarl,<br>
> +    wav_info_chunk_id_iart,<br>
> +    wav_info_chunk_id_icms,<br>
> +    wav_info_chunk_id_icmt,<br>
> +    wav_info_chunk_id_icop,<br>
> +    wav_info_chunk_id_icrd,<br>
> +    wav_info_chunk_id_icrp,<br>
> +    wav_info_chunk_id_idim,<br>
> +    wav_info_chunk_id_idpi,<br>
> +    wav_info_chunk_id_ieng,<br>
> +    wav_info_chunk_id_ignr,<br>
> +    wav_info_chunk_id_ikey,<br>
> +    wav_info_chunk_id_ilgt,<br>
> +    wav_info_chunk_id_imed,<br>
> +    wav_info_chunk_id_inam,<br>
> +    wav_info_chunk_id_iplt,<br>
> +    wav_info_chunk_id_iprd,<br>
> +    wav_info_chunk_id_isbj,<br>
> +    wav_info_chunk_id_isft,<br>
> +    wav_info_chunk_id_ishp,<br>
> +    wav_info_chunk_id_isrc,<br>
> +    wav_info_chunk_id_isrf,<br>
> +    wav_info_chunk_id_itch,<br>
>  };<br>
> <br>
>  struct wav_chunk_id_key<br>
> @@ -74,12 +103,54 @@ struct wav_chunk_id_key<br>
> <br>
>  static const struct wav_chunk_id_key wav_chunk_id_key_list[] =  {<br>
>      /* Alphabetical order */<br>
> +    { wav_chunk_id_list, "LIST" },<br>
>      { wav_chunk_id_data, "data" },<br>
>      { wav_chunk_id_ds64, "ds64" },<br>
>      { wav_chunk_id_fmt,  "fmt " },<br>
>  };<br>
>  static const size_t wav_chunk_id_key_count =<br>
> ARRAY_SIZE(wav_chunk_id_key_list);<br>
> <br>
> +static const struct wav_chunk_id_key wav_info_chunk_id_key_list[] =  {<br>
> +    /* Alphabetical order */<br>
> +    { wav_info_chunk_id_iarl, "IARL" },<br>
> +    { wav_info_chunk_id_iart, "IART" },<br>
> +    { wav_info_chunk_id_icms, "ICMS" },<br>
> +    { wav_info_chunk_id_icmt, "ICMT" },<br>
> +    { wav_info_chunk_id_icop, "ICOP" },<br>
> +    { wav_info_chunk_id_icrd, "ICRD" },<br>
> +    { wav_info_chunk_id_icrp, "ICRP" },<br>
> +    { wav_info_chunk_id_idim, "IDIM" },<br>
> +    { wav_info_chunk_id_idpi, "IDPI" },<br>
> +    { wav_info_chunk_id_ieng, "IENG" },<br>
> +    { wav_info_chunk_id_ignr, "IGNR" },<br>
> +    { wav_info_chunk_id_ikey, "IKEY" },<br>
> +    { wav_info_chunk_id_ilgt, "ILGT" },<br>
> +    { wav_info_chunk_id_imed, "IMED" },<br>
> +    { wav_info_chunk_id_inam, "INAM" },<br>
> +    { wav_info_chunk_id_iplt, "IPLT" },<br>
> +    { wav_info_chunk_id_iprd, "IPRD" },<br>
> +    { wav_info_chunk_id_isbj, "ISBJ" },<br>
> +    { wav_info_chunk_id_isft, "ISFT" },<br>
> +    { wav_info_chunk_id_ishp, "ISHP" },<br>
> +    { wav_info_chunk_id_isrc, "ISRC" },<br>
> +    { wav_info_chunk_id_isrf, "ISRF" },<br>
> +    { wav_info_chunk_id_itch, "ITCH" },<br>
> +};<br>
<br>
You could just as well use a table with designated initializers here.<br>
<br></blockquote><div>I think you meant this array could be created more easily. Could you please evaluate it ? </div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> +static const size_t wav_info_chunk_id_key_count =<br>
> ARRAY_SIZE(wav_info_chunk_id_key_list); +<br>
> +/* get string type of INFO chunk id from enum */<br>
> +static const char *wav_info_chunk_id_to_key(enum wav_chunk_id id)<br>
> +{<br>
> +    if ( id < wav_info_chunk_id_iarl || id > wav_info_chunk_id_itch )<br>
> +        return "";<br>
> +<br>
> +    for ( int i = 0; i < wav_info_chunk_id_key_count; i++)<br>
> +        if (wav_info_chunk_id_key_list[i].id == id)<br>
> +            return wav_info_chunk_id_key_list[i].key;<br>
<br>
Err, why use a linear search, when you could directly index the table?<br></blockquote><div><br></div><div>Yes you are right. The for loop can be changed to </div><div><br></div><div>return  wav_info_chunk_id_key_list[id - wav_info_chunk_id_iarl]</div><div><br></div><div>Will update in the next version.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> +<br>
> +    return "";<br>
> +}<br>
> +<br>
>  static int<br>
>  wav_chunk_CompareCb(const void *a, const void *b)<br>
>  {<br>
> @@ -320,6 +391,10 @@ static void Close ( vlc_object_t * p_this )<br>
>      demux_sys_t *p_sys   = p_demux->p_sys;<br>
> <br>
>      es_format_Clean( &p_sys->fmt );<br>
> +<br>
> +    if( p_sys->p_meta )<br>
> +        vlc_meta_Delete( p_sys->p_meta );<br>
> +<br>
>      free( p_sys );<br>
>  }<br>
> <br>
> @@ -594,6 +669,114 @@ error:<br>
>      return VLC_EGENERIC;<br>
>  }<br>
> <br>
> +static int ChunkParseINFO( demux_t *p_demux, uint32_t i_size )<br>
> +{<br>
> +    demux_sys_t *p_sys = p_demux->p_sys;<br>
> +    const uint8_t *p_peek;<br>
> +    enum wav_chunk_id id;<br>
> +    uint32_t chunk_size;<br>
> +    int meta_type;<br>
> +    char *meta_value;<br>
> +<br>
> +    if( (p_sys->p_meta = vlc_meta_New()) == NULL )<br>
<br>
Don't use assignment as truth value unless necessary.<br></blockquote><div><br></div><div>I can change this to:</div><div><br></div><div>p_sys->p_meta = vlc_meta_New();<br></div><div>if (p_sys->p_meta == NULL)</div><div><br></div><div>If this is what you meant.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> +    {<br>
> +        msg_Err( p_demux, "vlc_meta_New failed" );<br>
> +        return VLC_EGENERIC;<br>
> +    }<br>
> +<br>
> +    while (i_size > 0) {<br>
> +        int ret = ChunkGetNext( p_demux, &id, &chunk_size,<br>
> +                                wav_info_chunk_id_key_list,<br>
> +                                wav_info_chunk_id_key_count );<br>
> +        if ( ret != VLC_SUCCESS )<br>
> +            break;<br>
> +<br>
> +        /* chunk id(4 bytes) and chunk size(4 bytes) consumed by<br>
> ChunkGetNext */ +        i_size -= 8;<br>
> +<br>
> +        if( chunk_size == 0 )<br>
> +        {<br>
> +            msg_Err( p_demux, "invalid chunk with a size 0" );<br>
> +            return VLC_EGENERIC;<br>
> +        }<br>
> +<br>
> +        if( vlc_stream_Peek( p_demux->s, &p_peek, chunk_size ) !=<br>
> chunk_size ) +            return VLC_EGENERIC;<br>
> +<br>
> +        meta_value = strndup( (const char *)p_peek, chunk_size );<br>
> +        if (meta_value == NULL)<br>
> +            return VLC_EGENERIC;<br>
> +<br>
> +        EnsureUTF8( meta_value );<br>
> +<br>
> +        meta_type = -1;<br>
> +        switch( id )<br>
> +        {<br>
> +        case wav_info_chunk_id_iart:<br>
> +            meta_type = vlc_meta_Artist;<br>
> +            break;<br>
> +        case wav_info_chunk_id_icop:<br>
> +            meta_type = vlc_meta_Copyright;<br>
> +            break;<br>
> +        case wav_info_chunk_id_icrd:<br>
> +            meta_type = vlc_meta_Date;<br>
> +            break;<br>
> +        case wav_info_chunk_id_ignr:<br>
> +            meta_type = vlc_meta_Genre;<br>
> +            break;<br>
> +        case wav_info_chunk_id_inam:<br>
> +            meta_type = vlc_meta_Title;<br>
> +            break;<br>
> +        default:<br>
> +            /* no relevant meta type in vlc */<br>
> +            break;<br>
> +        }<br>
> +<br>
> +        msg_Dbg( p_demux, "id: %s meta_type: %d meta_value: %s\n",<br>
> +                 wav_info_chunk_id_to_key(id), meta_type, meta_value );<br>
> +<br>
> +        if (meta_type != -1)<br>
> +            vlc_meta_Set( p_sys->p_meta, meta_type, meta_value );<br>
> +        else<br>
> +            vlc_meta_AddExtra( p_sys->p_meta,<br>
> +                               wav_info_chunk_id_key_list[id].key,<br>
> meta_value ); +<br>
> +        free( meta_value );<br>
> +        if( ChunkSkip( p_demux, chunk_size ) != VLC_SUCCESS )<br>
> +            return VLC_EGENERIC;<br>
> +<br>
> +        i_size -= chunk_size;<br>
> +    }<br>
> +<br>
> +    return VLC_SUCCESS;<br>
> +}<br>
> +<br>
> +static int ChunkParseLIST( demux_t *p_demux, uint32_t i_size )<br>
> +{<br>
> +    const uint8_t *p_peek;<br>
> +<br>
> +    /* must have four bytes list type */<br>
> +    if( i_size < 4 )<br>
> +    {<br>
> +        msg_Err( p_demux, "invalid 'LIST' chunk" );<br>
> +        return VLC_EGENERIC;<br>
> +    }<br>
> +<br>
> +    if( vlc_stream_Peek( p_demux->s, &p_peek, 4 ) != 4 )<br>
> +        return VLC_EGENERIC;<br>
> +<br>
> +    /* only care about INFO chunk */<br>
> +    if ( memcmp(p_peek, "INFO", 4) != 0 ) {<br>
> +        return ChunkSkip( p_demux, i_size );<br>
> +    }<br>
> +<br>
> +    if ( vlc_stream_Read( p_demux->s, NULL, 4) != 4 )<br>
> +        return VLC_EGENERIC;<br>
> +<br>
> +    i_size -= 4;<br>
> +    return ChunkParseINFO( p_demux, i_size );<br>
> +}<br>
> +<br>
>  static int Open( vlc_object_t * p_this )<br>
>  {<br>
>      demux_t     *p_demux = (demux_t*)p_this;<br>
> @@ -684,6 +867,14 @@ static int Open( vlc_object_t * p_this )<br>
>                  if( ChunkParseFmt( p_demux, i_size ) != VLC_SUCCESS )<br>
>                      goto error;<br>
>                  break;<br>
> +            case wav_chunk_id_list:<br>
> +                if( ChunkParseLIST( p_demux, i_size ) != VLC_SUCCESS )<br>
> +                    goto error;<br>
> +                break;<br>
> +            default:<br>
> +                if( ChunkSkip( p_demux, i_size ) != VLC_SUCCESS )<br>
> +                    goto error;<br>
> +                break;<br>
>          }<br>
>      }<br>
<br>
<br>
-- <br>
レミ・デニ-クールモン<br>
<a href="http://www.remlab.net/" rel="noreferrer" target="_blank">http://www.remlab.net/</a><br>
<br>
<br>
<br>
_______________________________________________<br>
vlc-devel mailing list<br>
To unsubscribe or modify your subscription options:<br>
<a href="https://mailman.videolan.org/listinfo/vlc-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/listinfo/vlc-devel</a></blockquote></div></div>