Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Thomas Volkert authored on 2014/12/17 20:04:37... | ... |
@@ -423,7 +423,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) |
423 | 423 |
|
424 | 424 |
st->codec->codec_type = type; |
425 | 425 |
if (type == AVMEDIA_TYPE_AUDIO) { |
426 |
- int ret = ff_get_wav_header(pb, st->codec, type_specific_size); |
|
426 |
+ int ret = ff_get_wav_header(pb, st->codec, type_specific_size, 0); |
|
427 | 427 |
if (ret < 0) |
428 | 428 |
return ret; |
429 | 429 |
if (is_dvr_ms_audio) { |
... | ... |
@@ -794,7 +794,7 @@ static int avi_read_header(AVFormatContext *s) |
794 | 794 |
// avio_skip(pb, size - 5 * 4); |
795 | 795 |
break; |
796 | 796 |
case AVMEDIA_TYPE_AUDIO: |
797 |
- ret = ff_get_wav_header(pb, st->codec, size); |
|
797 |
+ ret = ff_get_wav_header(pb, st->codec, size, 0); |
|
798 | 798 |
if (ret < 0) |
799 | 799 |
return ret; |
800 | 800 |
ast->dshow_block_align = st->codec->block_align; |
... | ... |
@@ -106,7 +106,7 @@ static int dxa_read_header(AVFormatContext *s) |
106 | 106 |
ast = avformat_new_stream(s, NULL); |
107 | 107 |
if (!ast) |
108 | 108 |
return AVERROR(ENOMEM); |
109 |
- ret = ff_get_wav_header(pb, ast->codec, fsize); |
|
109 |
+ ret = ff_get_wav_header(pb, ast->codec, fsize, 0); |
|
110 | 110 |
if (ret < 0) |
111 | 111 |
return ret; |
112 | 112 |
if (ast->codec->sample_rate > 0) |
... | ... |
@@ -1715,7 +1715,7 @@ static int matroska_parse_tracks(AVFormatContext *s) |
1715 | 1715 |
ffio_init_context(&b, track->codec_priv.data, |
1716 | 1716 |
track->codec_priv.size, |
1717 | 1717 |
0, NULL, NULL, NULL, NULL); |
1718 |
- ret = ff_get_wav_header(&b, st->codec, track->codec_priv.size); |
|
1718 |
+ ret = ff_get_wav_header(&b, st->codec, track->codec_priv.size, 0); |
|
1719 | 1719 |
if (ret < 0) |
1720 | 1720 |
return ret; |
1721 | 1721 |
codec_id = st->codec->codec_id; |
... | ... |
@@ -142,7 +142,7 @@ static int scan_file(AVFormatContext *avctx, AVStream *vst, AVStream *ast, int f |
142 | 142 |
vst->codec->codec_tag = MKTAG('B', 'I', 'T', 16); |
143 | 143 |
size -= 164; |
144 | 144 |
} else if (ast && type == MKTAG('W', 'A', 'V', 'I') && size >= 16) { |
145 |
- ret = ff_get_wav_header(pb, ast->codec, 16); |
|
145 |
+ ret = ff_get_wav_header(pb, ast->codec, 16, 0); |
|
146 | 146 |
if (ret < 0) |
147 | 147 |
return ret; |
148 | 148 |
size -= 16; |
... | ... |
@@ -714,7 +714,7 @@ static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
714 | 714 |
return 0; |
715 | 715 |
st = c->fc->streams[c->fc->nb_streams-1]; |
716 | 716 |
|
717 |
- if ((ret = ff_get_wav_header(pb, st->codec, atom.size)) < 0) |
|
717 |
+ if ((ret = ff_get_wav_header(pb, st->codec, atom.size, 0)) < 0) |
|
718 | 718 |
av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n"); |
719 | 719 |
|
720 | 720 |
return ret; |
... | ... |
@@ -62,7 +62,7 @@ void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *t |
62 | 62 |
int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags); |
63 | 63 |
|
64 | 64 |
enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps); |
65 |
-int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size); |
|
65 |
+int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size, int big_endian); |
|
66 | 66 |
|
67 | 67 |
extern const AVCodecTag ff_codec_bmp_tags[]; // exposed through avformat_get_riff_video_tags() |
68 | 68 |
extern const AVCodecTag ff_codec_wav_tags[]; |
... | ... |
@@ -80,23 +80,37 @@ static void parse_waveformatex(AVIOContext *pb, AVCodecContext *c) |
80 | 80 |
} |
81 | 81 |
} |
82 | 82 |
|
83 |
-int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) |
|
83 |
+/* "big_endian" values are needed for RIFX file format */ |
|
84 |
+int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size, int big_endian) |
|
84 | 85 |
{ |
85 | 86 |
int id; |
86 | 87 |
|
87 | 88 |
if (size < 14) |
88 | 89 |
avpriv_request_sample(codec, "wav header size < 14"); |
89 | 90 |
|
90 |
- id = avio_rl16(pb); |
|
91 | 91 |
codec->codec_type = AVMEDIA_TYPE_AUDIO; |
92 |
- codec->channels = avio_rl16(pb); |
|
93 |
- codec->sample_rate = avio_rl32(pb); |
|
94 |
- codec->bit_rate = avio_rl32(pb) * 8; |
|
95 |
- codec->block_align = avio_rl16(pb); |
|
92 |
+ if (!big_endian) { |
|
93 |
+ id = avio_rl16(pb); |
|
94 |
+ codec->channels = avio_rl16(pb); |
|
95 |
+ codec->sample_rate = avio_rl32(pb); |
|
96 |
+ codec->bit_rate = avio_rl32(pb) * 8; |
|
97 |
+ codec->block_align = avio_rl16(pb); |
|
98 |
+ } else { |
|
99 |
+ id = avio_rb16(pb); |
|
100 |
+ codec->channels = avio_rb16(pb); |
|
101 |
+ codec->sample_rate = avio_rb32(pb); |
|
102 |
+ codec->bit_rate = avio_rb32(pb) * 8; |
|
103 |
+ codec->block_align = avio_rb16(pb); |
|
104 |
+ } |
|
96 | 105 |
if (size == 14) { /* We're dealing with plain vanilla WAVEFORMAT */ |
97 | 106 |
codec->bits_per_coded_sample = 8; |
98 |
- } else |
|
99 |
- codec->bits_per_coded_sample = avio_rl16(pb); |
|
107 |
+ } else { |
|
108 |
+ if (!big_endian) { |
|
109 |
+ codec->bits_per_coded_sample = avio_rl16(pb); |
|
110 |
+ } else { |
|
111 |
+ codec->bits_per_coded_sample = avio_rb16(pb); |
|
112 |
+ } |
|
113 |
+ } |
|
100 | 114 |
if (id == 0xFFFE) { |
101 | 115 |
codec->codec_tag = 0; |
102 | 116 |
} else { |
... | ... |
@@ -106,6 +120,10 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) |
106 | 106 |
} |
107 | 107 |
if (size >= 18) { /* We're obviously dealing with WAVEFORMATEX */ |
108 | 108 |
int cbSize = avio_rl16(pb); /* cbSize */ |
109 |
+ if (big_endian) { |
|
110 |
+ avpriv_report_missing_feature(codec, "WAVEFORMATEX support for RIFX files\n"); |
|
111 |
+ return AVERROR_PATCHWELCOME; |
|
112 |
+ } |
|
109 | 113 |
size -= 18; |
110 | 114 |
cbSize = FFMIN(size, cbSize); |
111 | 115 |
if (cbSize >= 22 && id == 0xfffe) { /* WAVEFORMATEXTENSIBLE */ |
... | ... |
@@ -31,7 +31,7 @@ |
31 | 31 |
|
32 | 32 |
#define LIBAVFORMAT_VERSION_MAJOR 56 |
33 | 33 |
#define LIBAVFORMAT_VERSION_MINOR 15 |
34 |
-#define LIBAVFORMAT_VERSION_MICRO 105 |
|
34 |
+#define LIBAVFORMAT_VERSION_MICRO 106 |
|
35 | 35 |
|
36 | 36 |
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |
37 | 37 |
LIBAVFORMAT_VERSION_MINOR, \ |
... | ... |
@@ -57,14 +57,19 @@ typedef struct WAVDemuxContext { |
57 | 57 |
int smv_cur_pt; |
58 | 58 |
int smv_given_first; |
59 | 59 |
int unaligned; // e.g. if an odd number of bytes ID3 tag was prepended |
60 |
+ int rifx; // RIFX: integer byte order for parameters is big endian |
|
60 | 61 |
} WAVDemuxContext; |
61 | 62 |
|
62 | 63 |
#if CONFIG_WAV_DEMUXER |
63 | 64 |
|
64 |
-static int64_t next_tag(AVIOContext *pb, uint32_t *tag) |
|
65 |
+static int64_t next_tag(AVIOContext *pb, uint32_t *tag, int big_endian) |
|
65 | 66 |
{ |
66 | 67 |
*tag = avio_rl32(pb); |
67 |
- return avio_rl32(pb); |
|
68 |
+ if (!big_endian) { |
|
69 |
+ return avio_rl32(pb); |
|
70 |
+ } else { |
|
71 |
+ return avio_rb32(pb); |
|
72 |
+ } |
|
68 | 73 |
} |
69 | 74 |
|
70 | 75 |
/* 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) |
84 | 84 |
for (;;) { |
85 | 85 |
if (avio_feof(pb)) |
86 | 86 |
return AVERROR_EOF; |
87 |
- size = next_tag(pb, &tag); |
|
87 |
+ size = next_tag(pb, &tag, wav->rifx); |
|
88 | 88 |
if (tag == tag1) |
89 | 89 |
break; |
90 | 90 |
wav_seek_tag(wav, pb, size, SEEK_CUR); |
... | ... |
@@ -98,7 +103,7 @@ static int wav_probe(AVProbeData *p) |
98 | 98 |
if (p->buf_size <= 32) |
99 | 99 |
return 0; |
100 | 100 |
if (!memcmp(p->buf + 8, "WAVE", 4)) { |
101 |
- if (!memcmp(p->buf, "RIFF", 4)) |
|
101 |
+ if (!memcmp(p->buf, "RIFF", 4) || !memcmp(p->buf, "RIFX", 4)) |
|
102 | 102 |
/* Since the ACT demuxer has a standard WAV header at the top of |
103 | 103 |
* its own, the returned score is decreased to avoid a probe |
104 | 104 |
* conflict between ACT and WAV. */ |
... | ... |
@@ -121,6 +126,7 @@ static void handle_stream_probing(AVStream *st) |
121 | 121 |
static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st) |
122 | 122 |
{ |
123 | 123 |
AVIOContext *pb = s->pb; |
124 |
+ WAVDemuxContext *wav = s->priv_data; |
|
124 | 125 |
int ret; |
125 | 126 |
|
126 | 127 |
/* parse fmt header */ |
... | ... |
@@ -128,7 +134,7 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st) |
128 | 128 |
if (!*st) |
129 | 129 |
return AVERROR(ENOMEM); |
130 | 130 |
|
131 |
- ret = ff_get_wav_header(pb, (*st)->codec, size); |
|
131 |
+ ret = ff_get_wav_header(pb, (*st)->codec, size, wav->rifx); |
|
132 | 132 |
if (ret < 0) |
133 | 133 |
return ret; |
134 | 134 |
handle_stream_probing(*st); |
... | ... |
@@ -258,7 +264,8 @@ static int wav_read_header(AVFormatContext *s) |
258 | 258 |
tag = avio_rl32(pb); |
259 | 259 |
|
260 | 260 |
rf64 = tag == MKTAG('R', 'F', '6', '4'); |
261 |
- if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F')) |
|
261 |
+ wav->rifx = tag == MKTAG('R', 'I', 'F', 'X'); |
|
262 |
+ if (!rf64 && !wav->rifx && tag != MKTAG('R', 'I', 'F', 'F')) |
|
262 | 263 |
return AVERROR_INVALIDDATA; |
263 | 264 |
avio_rl32(pb); /* file size */ |
264 | 265 |
tag = avio_rl32(pb); |
... | ... |
@@ -288,7 +295,7 @@ static int wav_read_header(AVFormatContext *s) |
288 | 288 |
|
289 | 289 |
for (;;) { |
290 | 290 |
AVStream *vst; |
291 |
- size = next_tag(pb, &tag); |
|
291 |
+ size = next_tag(pb, &tag, wav->rifx); |
|
292 | 292 |
next_tag_ofs = avio_tell(pb) + size; |
293 | 293 |
|
294 | 294 |
if (avio_feof(pb)) |
... | ... |
@@ -328,7 +335,7 @@ static int wav_read_header(AVFormatContext *s) |
328 | 328 |
break; |
329 | 329 |
case MKTAG('f', 'a', 'c', 't'): |
330 | 330 |
if (!sample_count) |
331 |
- sample_count = avio_rl32(pb); |
|
331 |
+ sample_count = (!wav->rifx ? avio_rl32(pb) : avio_rb32(pb)); |
|
332 | 332 |
break; |
333 | 333 |
case MKTAG('b', 'e', 'x', 't'): |
334 | 334 |
if ((ret = wav_parse_bext_tag(s, size)) < 0) |
... | ... |
@@ -662,7 +669,7 @@ static int w64_read_header(AVFormatContext *s) |
662 | 662 |
|
663 | 663 |
if (!memcmp(guid, ff_w64_guid_fmt, 16)) { |
664 | 664 |
/* subtract chunk header size - normal wav file doesn't count it */ |
665 |
- ret = ff_get_wav_header(pb, st->codec, size - 24); |
|
665 |
+ ret = ff_get_wav_header(pb, st->codec, size - 24, 0); |
|
666 | 666 |
if (ret < 0) |
667 | 667 |
return ret; |
668 | 668 |
avio_skip(pb, FFALIGN(size, INT64_C(8)) - size); |
... | ... |
@@ -670,7 +670,7 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid, |
670 | 670 |
if (!st) |
671 | 671 |
return NULL; |
672 | 672 |
if (!ff_guidcmp(formattype, ff_format_waveformatex)) { |
673 |
- int ret = ff_get_wav_header(pb, st->codec, size); |
|
673 |
+ int ret = ff_get_wav_header(pb, st->codec, size, 0); |
|
674 | 674 |
if (ret < 0) |
675 | 675 |
return NULL; |
676 | 676 |
} else { |
... | ... |
@@ -75,7 +75,7 @@ static int xwma_read_header(AVFormatContext *s) |
75 | 75 |
if (!st) |
76 | 76 |
return AVERROR(ENOMEM); |
77 | 77 |
|
78 |
- ret = ff_get_wav_header(pb, st->codec, size); |
|
78 |
+ ret = ff_get_wav_header(pb, st->codec, size, 0); |
|
79 | 79 |
if (ret < 0) |
80 | 80 |
return ret; |
81 | 81 |
st->need_parsing = AVSTREAM_PARSE_NONE; |