[FFmpeg-devel] [PATCH] avformat/wavdec: parse XMA2 tag

Michael Niedermayer michael at niedermayer.cc
Mon Nov 9 22:53:50 CET 2015


On Sat, Nov 07, 2015 at 05:33:07PM +0100, Paul B Mahol wrote:
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
>  libavformat/wavdec.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 54 insertions(+), 2 deletions(-)
> 
> diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
> index ef24e16..621d21f 100644
> --- a/libavformat/wavdec.c
> +++ b/libavformat/wavdec.c
> @@ -146,6 +146,49 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
>      return 0;
>  }
>  
> +static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, AVStream **st)
> +{
> +    AVIOContext *pb = s->pb;
> +    int num_streams, i, channels = 0;
> +
> +    if (size < 44)
> +        return AVERROR_INVALIDDATA;
> +
> +    *st = avformat_new_stream(s, NULL);
> +    if (!*st)
> +        return AVERROR(ENOMEM);
> +
> +    (*st)->codec->codec_type = AVMEDIA_TYPE_AUDIO;
> +    (*st)->codec->codec_id   = AV_CODEC_ID_XMA2;
> +    (*st)->need_parsing      = AVSTREAM_PARSE_FULL_RAW;
> +
> +    avio_skip(pb, 1);
> +    num_streams = avio_r8(pb);
> +    if (size < 40 + num_streams * 4)
> +        return AVERROR_INVALIDDATA;
> +    avio_skip(pb, 10);
> +    (*st)->codec->sample_rate = avio_rb32(pb);
> +    avio_skip(pb, 12);
> +    (*st)->duration = avio_rb32(pb);
> +    avio_skip(pb, 8);
> +
> +    for (i = 0; i < num_streams; i++) {
> +        channels += avio_r8(pb);
> +        avio_skip(pb, 3);
> +    }
> +    (*st)->codec->channels = channels;
> +
> +    if ((*st)->codec->channels <= 0 || (*st)->codec->sample_rate <= 0)
> +        return AVERROR_INVALIDDATA;
> +
> +    avpriv_set_pts_info(*st, 64, 1, (*st)->codec->sample_rate);
> +    if (ff_alloc_extradata((*st)->codec, 34))
> +        return AVERROR(ENOMEM);
> +    memset((*st)->codec->extradata, 0, 34);
> +
> +    return 0;
> +}
> +
>  static inline int wav_parse_bext_string(AVFormatContext *s, const char *key,
>                                          int length)
>  {
> @@ -254,7 +297,7 @@ static int wav_read_header(AVFormatContext *s)
>      AVIOContext *pb      = s->pb;
>      AVStream *st         = NULL;
>      WAVDemuxContext *wav = s->priv_data;
> -    int ret, got_fmt = 0;
> +    int ret, got_fmt = 0, got_xma2 = 0;
>      int64_t next_tag_ofs, data_ofs = -1;
>  
>      wav->unaligned = avio_tell(s->pb) & 1;
> @@ -326,8 +369,17 @@ static int wav_read_header(AVFormatContext *s)
>  
>              got_fmt = 1;
>              break;
> +        case MKTAG('X', 'M', 'A', '2'):
> +            /* only parse the first 'XMA2' tag found */
> +            if (!got_xma2 && (ret = wav_parse_xma2_tag(s, size, &st)) < 0) {
> +                return ret;
> +            } else if (got_xma2)
> +                av_log(s, AV_LOG_WARNING, "found more than one 'XMA2' tag\n");
> +
> +            got_xma2 = 1;
> +            break;

i think this would result in 2 streams if theres a fmt tag and a xma2 tag
is that intended?

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Democracy is the form of government in which you can choose your dictator
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20151109/6377bd00/attachment.sig>


More information about the ffmpeg-devel mailing list