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

Paul B Mahol onemda at gmail.com
Tue Nov 10 08:58:59 CET 2015


On 11/9/15, Michael Niedermayer <michael at niedermayer.cc> wrote:
> 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?

No, will check for that.

>
> [...]
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> Democracy is the form of government in which you can choose your dictator
>


More information about the ffmpeg-devel mailing list