diff --git a/ChangeLog b/ChangeLog index bdccb3669..f06e7fcb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-08-14 Moritz Bunkus + + * mkvmerge: The RealMedia reader takes the number of packets into + account when reading which results in better end-of-file detection. + 2003-08-12 Moritz Bunkus * Windows versions: Fixed a bug with files bigger than 2GB not diff --git a/src/r_real.cpp b/src/r_real.cpp index dc9106c09..341239f24 100644 --- a/src/r_real.cpp +++ b/src/r_real.cpp @@ -34,6 +34,11 @@ #include "p_passthrough.h" #include "p_video.h" +/* + * Description of the RealMedia file format: + * http://www.pcisys.net/~melanson/codecs/rmff.htm + */ + // {{{ structs #if __GNUC__ == 2 @@ -163,7 +168,6 @@ real_reader_c::real_reader_c(track_info_t *nti) throw (error_c): } last_timecode = -1; - act_wchar = 0; done = false; if (verbose) @@ -404,8 +408,10 @@ void real_reader_c::parse_headers() { } } else if (object_id == FOURCC('D', 'A', 'T', 'A')) { - io->skip(4); // num_packets + num_packets_in_chunk = io->read_uint32_be(); + num_packets = 0; io->skip(4); // next_data_header + printf("HEAD#: %lld\n", num_packets_in_chunk); break; // We're finished! @@ -541,22 +547,23 @@ int real_reader_c::read() { try { fpos = io->getFilePointer(); - object_version = io->read_uint16_be(); - length = io->read_uint16_be(); - object_id = object_version << 16 + length; + if (num_packets >= num_packets_in_chunk) { + object_id = io->read_uint32_be(); + if (object_id == FOURCC('I', 'N', 'D', 'X')) + return finish(); - if (object_id == FOURCC('I', 'N', 'D', 'X')) - return finish(); + if (object_id == FOURCC('D', 'A', 'T', 'A')) { + num_packets_in_chunk = io->read_uint32_be(); + num_packets = 0; + io->skip(4); // next_data_header - if (object_id == FOURCC('D', 'A', 'T', 'A')) { - io->skip(2); // object_version - io->skip(4); // num_packets - io->skip(4); // next_data_header - - return EMOREDATA; + } else + return finish(); } + object_version = io->read_uint16_be(); + length = io->read_uint16_be(); id = io->read_uint16_be(); timecode = io->read_uint32_be(); io->skip(1); // reserved @@ -585,6 +592,8 @@ int real_reader_c::read() { return finish(); } + num_packets++; + if (dmx->type == 'v') { assemble_packet(dmx, chunk, length, timecode, (flags & 2) == 2); safefree(chunk); @@ -650,15 +659,9 @@ int real_reader_c::display_priority() { return DISPLAYPRIORITY_MEDIUM; } -static char wchar[] = "-\\|/-\\|/-"; - void real_reader_c::display_progress() { - mxprint(stdout, "working... %c (%d%%)\r", wchar[act_wchar], - (int)(io->getFilePointer() * 100 / file_size)); - act_wchar++; - if (act_wchar == strlen(wchar)) - act_wchar = 0; - fflush(stdout); + mxprint(stdout, "progress: %lld/%lld packets (%lld%%)\r", num_packets, + num_packets_in_chunk, num_packets * 100 / num_packets_in_chunk); } void real_reader_c::set_headers() { diff --git a/src/r_real.h b/src/r_real.h index 764587a27..dd300c7b2 100644 --- a/src/r_real.h +++ b/src/r_real.h @@ -68,9 +68,9 @@ class real_reader_c: public generic_reader_c { private: mm_io_c *io; vector demuxers; - int act_wchar; int64_t file_size, last_timecode; bool done; + int64_t num_packets_in_chunk, num_packets; public: real_reader_c(track_info_t *nti) throw (error_c);