[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