wavdec: RIFX file format support

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Thomas Volkert
2014-12-17 12:04:37 +01:00
committed by Michael Niedermayer
parent e8714f6f93
commit 00d7555f34
14 changed files with 54 additions and 28 deletions

View File

@@ -57,14 +57,19 @@ typedef struct WAVDemuxContext {
int smv_cur_pt;
int smv_given_first;
int unaligned; // e.g. if an odd number of bytes ID3 tag was prepended
int rifx; // RIFX: integer byte order for parameters is big endian
} WAVDemuxContext;
#if CONFIG_WAV_DEMUXER
static int64_t next_tag(AVIOContext *pb, uint32_t *tag)
static int64_t next_tag(AVIOContext *pb, uint32_t *tag, int big_endian)
{
*tag = avio_rl32(pb);
return avio_rl32(pb);
if (!big_endian) {
return avio_rl32(pb);
} else {
return avio_rb32(pb);
}
}
/* RIFF chunks are always at even offsets relative to where they start. */
@@ -84,7 +89,7 @@ static int64_t find_tag(WAVDemuxContext * wav, AVIOContext *pb, uint32_t tag1)
for (;;) {
if (avio_feof(pb))
return AVERROR_EOF;
size = next_tag(pb, &tag);
size = next_tag(pb, &tag, wav->rifx);
if (tag == tag1)
break;
wav_seek_tag(wav, pb, size, SEEK_CUR);
@@ -98,7 +103,7 @@ static int wav_probe(AVProbeData *p)
if (p->buf_size <= 32)
return 0;
if (!memcmp(p->buf + 8, "WAVE", 4)) {
if (!memcmp(p->buf, "RIFF", 4))
if (!memcmp(p->buf, "RIFF", 4) || !memcmp(p->buf, "RIFX", 4))
/* Since the ACT demuxer has a standard WAV header at the top of
* its own, the returned score is decreased to avoid a probe
* conflict between ACT and WAV. */
@@ -121,6 +126,7 @@ static void handle_stream_probing(AVStream *st)
static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
{
AVIOContext *pb = s->pb;
WAVDemuxContext *wav = s->priv_data;
int ret;
/* parse fmt header */
@@ -128,7 +134,7 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
if (!*st)
return AVERROR(ENOMEM);
ret = ff_get_wav_header(pb, (*st)->codec, size);
ret = ff_get_wav_header(pb, (*st)->codec, size, wav->rifx);
if (ret < 0)
return ret;
handle_stream_probing(*st);
@@ -258,7 +264,8 @@ static int wav_read_header(AVFormatContext *s)
tag = avio_rl32(pb);
rf64 = tag == MKTAG('R', 'F', '6', '4');
if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F'))
wav->rifx = tag == MKTAG('R', 'I', 'F', 'X');
if (!rf64 && !wav->rifx && tag != MKTAG('R', 'I', 'F', 'F'))
return AVERROR_INVALIDDATA;
avio_rl32(pb); /* file size */
tag = avio_rl32(pb);
@@ -288,7 +295,7 @@ static int wav_read_header(AVFormatContext *s)
for (;;) {
AVStream *vst;
size = next_tag(pb, &tag);
size = next_tag(pb, &tag, wav->rifx);
next_tag_ofs = avio_tell(pb) + size;
if (avio_feof(pb))
@@ -328,7 +335,7 @@ static int wav_read_header(AVFormatContext *s)
break;
case MKTAG('f', 'a', 'c', 't'):
if (!sample_count)
sample_count = avio_rl32(pb);
sample_count = (!wav->rifx ? avio_rl32(pb) : avio_rb32(pb));
break;
case MKTAG('b', 'e', 'x', 't'):
if ((ret = wav_parse_bext_tag(s, size)) < 0)
@@ -662,7 +669,7 @@ static int w64_read_header(AVFormatContext *s)
if (!memcmp(guid, ff_w64_guid_fmt, 16)) {
/* subtract chunk header size - normal wav file doesn't count it */
ret = ff_get_wav_header(pb, st->codec, size - 24);
ret = ff_get_wav_header(pb, st->codec, size - 24, 0);
if (ret < 0)
return ret;
avio_skip(pb, FFALIGN(size, INT64_C(8)) - size);