Support WAV files that use other RIFF chunks than the usual "fmt " followed by "data" by simply skipping those.

This commit is contained in:
Moritz Bunkus 2005-04-29 08:56:01 +00:00
parent 9340c97515
commit 37910a3c8f
3 changed files with 44 additions and 16 deletions

View File

@ -1,3 +1,8 @@
2005-04-29 Moritz Bunkus <moritz@bunkus.org>
* mkvmerge: bug fix: Support WAV files that use other RIFF chunks
than the usual "fmt " followed by "data".
2005-04-18 Moritz Bunkus <moritz@bunkus.org> 2005-04-18 Moritz Bunkus <moritz@bunkus.org>
* mkvmerge: bug fix: Remuxing MPEG1/2 tracks resulted in a failing * mkvmerge: bug fix: Remuxing MPEG1/2 tracks resulted in a failing

View File

@ -51,16 +51,14 @@ wav_reader_c::probe_file(mm_io_c *io,
return 0; return 0;
try { try {
io->setFilePointer(0, seek_beginning); io->setFilePointer(0, seek_beginning);
if (io->read((char *)&wheader, sizeof(wheader)) != sizeof(wheader)) if (io->read(&wheader.riff, sizeof(wheader.riff)) != sizeof(wheader.riff))
return 0; return 0;
io->setFilePointer(0, seek_beginning); io->setFilePointer(0, seek_beginning);
} catch (...) { } catch (...) {
return 0; return 0;
} }
if (strncmp((char *)wheader.riff.id, "RIFF", 4) || if (strncmp((char *)wheader.riff.id, "RIFF", 4) ||
strncmp((char *)wheader.riff.wave_id, "WAVE", 4) || strncmp((char *)wheader.riff.wave_id, "WAVE", 4))
(strncmp((char *)wheader.data.id, "data", 4) &&
strncmp((char *)wheader.data.id, "PAD ", 4)))
return 0; return 0;
return 1; return 1;
@ -81,8 +79,18 @@ wav_reader_c::wav_reader_c(track_info_c &_ti)
} }
if (!wav_reader_c::probe_file(io, size)) if (!wav_reader_c::probe_file(io, size))
throw error_c("wav_reader: Source is not a valid WAVE file."); throw error_c("wav_reader: Source is not a valid WAVE file.");
if (io->read(&wheader, sizeof(wheader)) != sizeof(wheader))
if (io->read(&wheader.riff, sizeof(wheader.riff)) != sizeof(wheader.riff))
throw error_c("wav_reader: could not read WAVE header."); throw error_c("wav_reader: could not read WAVE header.");
if (!skip_to_chunk("fmt "))
throw error_c("wav_reader: No format chunk found.");
if ((io->read(&wheader.format, sizeof(wheader.format)) !=
sizeof(wheader.format)) ||
(io->read(&wheader.common, sizeof(wheader.common)) !=
sizeof(wheader.common)))
throw error_c("wav_reader: The format chunk could not be read.");
bps = get_uint16_le(&wheader.common.wChannels) * bps = get_uint16_le(&wheader.common.wChannels) *
get_uint16_le(&wheader.common.wBitsPerSample) * get_uint16_le(&wheader.common.wBitsPerSample) *
get_uint32_le(&wheader.common.dwSamplesPerSec) / 8; get_uint32_le(&wheader.common.dwSamplesPerSec) / 8;
@ -91,17 +99,11 @@ wav_reader_c::wav_reader_c(track_info_c &_ti)
ti.id = 0; // ID for this track. ti.id = 0; // ID for this track.
is_dts = false; is_dts = false;
while (1) { if (!skip_to_chunk("data"))
if (!strncmp((char *)wheader.data.id, "data", 4)) throw error_c("wav_reader: No data chunk was found.");
break;
if ((io->getFilePointer() + get_uint32_le(&wheader.data.len) + if (io->read(&wheader.data, sizeof(wheader.data)) != sizeof(wheader.data))
sizeof(struct chunk_struct)) > size) throw error_c("wav_reader: Could not read the data chunk header.");
throw error_c("wav_reader: No 'data' chunk found.");
io->setFilePointer(get_uint32_le(&wheader.data.len), seek_current);
if (io->read(&wheader.data, sizeof(struct chunk_struct)) !=
sizeof(struct chunk_struct))
throw error_c("wav_reader: No 'data' chunk found.");
}
if (verbose) if (verbose)
mxinfo(FMT_FN "Using the WAV demultiplexer.\n", ti.fname.c_str()); mxinfo(FMT_FN "Using the WAV demultiplexer.\n", ti.fname.c_str());
@ -244,6 +246,26 @@ wav_reader_c::read(generic_packetizer_c *,
return FILE_STATUS_DONE; return FILE_STATUS_DONE;
} }
bool
wav_reader_c::skip_to_chunk(const char *id) {
chunk_struct chunk;
while (true) {
if (io->read(&chunk, sizeof(chunk)) != sizeof(chunk))
return false;
if (!memcmp(&chunk.id, id, 4)) {
io->setFilePointer(-(int)sizeof(chunk), seek_current);
break;
}
if (!io->setFilePointer2(get_uint32_le(&chunk.len), seek_current))
return false;
}
return true;
}
int int
wav_reader_c::get_progress() { wav_reader_c::get_progress() {
return 100 * bytes_processed / (get_uint32_le(&wheader.riff.len) - return 100 * bytes_processed / (get_uint32_le(&wheader.riff.len) -

View File

@ -49,6 +49,7 @@ public:
virtual file_status_e read(generic_packetizer_c *ptzr, bool force = false); virtual file_status_e read(generic_packetizer_c *ptzr, bool force = false);
virtual void identify(); virtual void identify();
virtual void create_packetizer(int64_t tid); virtual void create_packetizer(int64_t tid);
virtual bool skip_to_chunk(const char *id);
virtual int get_progress(); virtual int get_progress();