diff --git a/ChangeLog b/ChangeLog index b4942043d..09825ade9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2007-03-08 Moritz Bunkus + * mkvmerge: The MPEG program stream reader will now sort the + tracks it finds first by their type (video > audio > subs) and + then by their stream ID. + + * mkvmerge: Disabled the support for DTS tracks in MPEG program + streams because DTS HD is not supported yet. + * mkvmerge: enhancement: Implemented a major speed-up for reading MPEG-1/2 and AVC/h.264 tracks from MPEG program streams. diff --git a/src/input/r_mpeg.cpp b/src/input/r_mpeg.cpp index d74b1ae2d..f48bec51a 100644 --- a/src/input/r_mpeg.cpp +++ b/src/input/r_mpeg.cpp @@ -242,6 +242,12 @@ mpeg_es_reader_c::identify() { #define PS_PROBE_SIZE 1 * 1024 * 1024 +static bool +operator <(const mpeg_ps_track_ptr &a, + const mpeg_ps_track_ptr &b) { + return a->sort_key < b->sort_key; +} + int mpeg_ps_reader_c::probe_file(mm_io_c *io, int64_t size) { @@ -375,36 +381,8 @@ mpeg_ps_reader_c::mpeg_ps_reader_c(track_info_c &_ti) } catch (...) { } - mxverb(2, "mpeg_ps: Streams found: "); - for (i = 0; i < 256; i++) - if (id2idx[i] != -1) - mxverb(2, "%02x ", i); - for (i = 256 ; i < 512; i++) - if (id2idx[i] != -1) - mxverb(2, "bd(%02x) ", i - 256); - mxverb(2, "\n"); - - // Calculate by how much the timecodes have to be offset - if (tracks.size() > 0) { - int64_t min_timecode; - - min_timecode = tracks[0]->timecode_offset; - for (i = 1; i < tracks.size(); i++) - if (tracks[i]->timecode_offset < min_timecode) - min_timecode = tracks[i]->timecode_offset; - for (i = 0; i < tracks.size(); i++) - tracks[i]->timecode_offset -= min_timecode; - - mxverb(2, "mpeg_ps: Timecode offset: min was " LLD " ", min_timecode); - for (i = 0; i < tracks.size(); i++) - if (tracks[i]->id > 0xff) - mxverb(2, "bd(%02x)=" LLD " ", tracks[i]->id - 256, - tracks[i]->timecode_offset); - else - mxverb(2, "%02x=" LLD " ", tracks[i]->id, - tracks[i]->timecode_offset); - mxverb(2, "\n"); - } + sort_tracks(); + calculate_global_timecode_offset(); io->setFilePointer(0, seek_beginning); @@ -416,6 +394,56 @@ mpeg_ps_reader_c::~mpeg_ps_reader_c() { delete io; } +void +mpeg_ps_reader_c::sort_tracks() { + int i; + + for (i = 0; tracks.size() > i; ++i) + tracks[i]->sort_key = + ('v' == tracks[i]->type ? 0x00000 : + 'a' == tracks[i]->type ? 0x10000 : + 's' == tracks[i]->type ? 0x20000 : 0x30000) + + (256 > tracks[i]->id ? tracks[i]->id + 256 : tracks[i]->id); + sort(tracks.begin(), tracks.end()); + for (i = 0; tracks.size() > i; ++i) + id2idx[tracks[i]->id] = i; + + mxverb(2, "mpeg_ps: Supported streams, sorted by ID: "); + for (i = 0; tracks.size() > i; ++i) + if (256 > tracks[i]->id) + mxverb(2, "%02x ", tracks[i]->id); + else + mxverb(2, "bd(%02x) ", tracks[i]->id - 256); + mxverb(2, "\n"); +} + +void +mpeg_ps_reader_c::calculate_global_timecode_offset() { + // Calculate by how much the timecodes have to be offset + if (tracks.empty()) + return; + + int64_t min_timecode; + int i; + + min_timecode = tracks[0]->timecode_offset; + for (i = 1; i < tracks.size(); i++) + if (tracks[i]->timecode_offset < min_timecode) + min_timecode = tracks[i]->timecode_offset; + for (i = 0; i < tracks.size(); i++) + tracks[i]->timecode_offset -= min_timecode; + + mxverb(2, "mpeg_ps: Timecode offset: min was " LLD " ", min_timecode); + for (i = 0; i < tracks.size(); i++) + if (tracks[i]->id > 0xff) + mxverb(2, "bd(%02x)=" LLD " ", tracks[i]->id - 256, + tracks[i]->timecode_offset); + else + mxverb(2, "%02x=" LLD " ", tracks[i]->id, + tracks[i]->timecode_offset); + mxverb(2, "\n"); +} + bool mpeg_ps_reader_c::read_timestamp(int c, int64_t ×tamp) { @@ -920,8 +948,8 @@ mpeg_ps_reader_c::found_new_stream(int id) { else if (track->fourcc == FOURCC('A', 'C', '3', ' ')) new_stream_a_ac3(id, buf, length, track); - else if (track->fourcc == FOURCC('D', 'T', 'S', ' ')) - new_stream_a_dts(id, buf, length, track); +// else if (track->fourcc == FOURCC('D', 'T', 'S', ' ')) +// new_stream_a_dts(id, buf, length, track); else // Unsupported track type diff --git a/src/input/r_mpeg.h b/src/input/r_mpeg.h index 6cfcd7620..c518c8ced 100644 --- a/src/input/r_mpeg.h +++ b/src/input/r_mpeg.h @@ -56,7 +56,7 @@ struct mpeg_ps_track_t { int ptzr; char type; // 'v' for video, 'a' for audio, 's' for subs - int id; + int id, sort_key; uint32_t fourcc; int64_t timecode_offset; @@ -76,7 +76,7 @@ struct mpeg_ps_track_t { int buffer_usage, buffer_size; mpeg_ps_track_t(): - ptzr(-1), type(0), fourcc(0), timecode_offset(-1), + ptzr(-1), type(0), id(0), sort_key(0), fourcc(0), timecode_offset(-1), skip_bytes(0), v_version(0), v_width(0), v_height(0), v_dwidth(0), v_dheight(0), v_frame_rate(0), v_aspect_ratio(0), @@ -160,6 +160,8 @@ private: int length, mpeg_ps_track_ptr &track); virtual bool resync_stream(uint32_t &header); virtual file_status_e finish(); + void sort_tracks(); + void calculate_global_timecode_offset(); }; #endif // __R_MPEG_H