Sort the tracks in MPEG PS files first by their category (video, audio, subs) and then by their stream IDs.

This commit is contained in:
Moritz Bunkus 2007-03-08 15:52:59 +00:00
parent 4051b80e44
commit 083b23e8a6
3 changed files with 71 additions and 34 deletions

View File

@ -1,5 +1,12 @@
2007-03-08 Moritz Bunkus <moritz@bunkus.org>
* 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.

View File

@ -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 &timestamp) {
@ -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

View File

@ -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