mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-01-05 21:55:37 +01:00
wavdec: RIFX file format support
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
committed by
Michael Niedermayer
parent
e8714f6f93
commit
00d7555f34
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user