diff --git a/ChangeLog b/ChangeLog index 34d5401ac..c1f1bfdf7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-01-09 Moritz Bunkus + + * mkvmerge: bug fix: The VobSub handling was on occasion putting + SPU packets for the wrong MPEG stream into the current stream + resulting in that particular entity not being displayed. + 2004-01-06 Moritz Bunkus * Released v0.8.1. diff --git a/configure.in b/configure.in index a071d96f1..2d29088da 100644 --- a/configure.in +++ b/configure.in @@ -15,6 +15,8 @@ SAVED_CXXFLAGS="$CXXFLAGS" AC_PROG_CXX CXXFLAGS="$SAVED_CXXFLAGS" AC_PROG_MAKE_SET +AC_DISABLE_STATIC +AC_PROG_LIBTOOL AC_CHECK_TOOL(RANLIB, ranlib, :) AC_CHECK_TOOL(STRIP, strip, :) AC_CHECK_TOOL(AR, ar, :) diff --git a/src/common/common.h b/src/common/common.h index 2ee7f5d16..a4b27ea54 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -78,6 +78,12 @@ using namespace std; #define MXMSG_ERROR 4 #define MXMSG_DEBUG 8 +#define FMT_TIMECODE "%02d:%02d:%02d.%03d" +#define ARG_TIMECODE(t) (int32_t)(t) / 60 / 60 / 1000, \ + (int32_t)((t) / 60 / 1000) % 60, \ + (int32_t)((t) / 1000) % 60, \ + (int32_t)(t) % 1000 + void fix_format(const char *fmt, string &new_fmt); #if defined(__GNUC__) void die(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); diff --git a/src/input/r_vobsub.cpp b/src/input/r_vobsub.cpp index 8e846f256..5019d1bee 100644 --- a/src/input/r_vobsub.cpp +++ b/src/input/r_vobsub.cpp @@ -301,9 +301,14 @@ void vobsub_reader_c::parse_headers() { for (i = 0; i < tracks.size(); i++) { mxinfo("vobsub_reader: Track number %u\n", i); for (k = 0; k < tracks[i]->positions.size(); k++) - mxinfo("vobsub_reader: %04u position: %12lld, size: %12lld, " - "timecode: " "%12lld\n", k, tracks[i]->positions[k], - tracks[i]->sizes[k], tracks[i]->timecodes[k]); + mxinfo("vobsub_reader: %04u position: %12lld (0x%04x%08x), " + "size: %12lld (0x%06x), timecode: %12lld (" FMT_TIMECODE + ")\n", k, tracks[i]->positions[k], + (uint32_t)(tracks[i]->positions[k] >> 32), + (uint32_t)(tracks[i]->positions[k] & 0xffffffff), + tracks[i]->sizes[k], (uint32_t)tracks[i]->sizes[k], + tracks[i]->timecodes[k], + ARG_TIMECODE(tracks[i]->timecodes[k])); } } } @@ -341,9 +346,13 @@ int vobsub_reader_c::read(generic_packetizer_c *ptzr) { flush_packetizers(); return 0; } - mxverb(2, PFX "track: %u, size: %lld, at: %lld, timecode: %lld, duration: " - "%lld\n", id, track->sizes[i], track->positions[i], - track->timecodes[i], track->durations[i]); + mxverb(2, PFX "track: %u, size: %lld (0x%06x), at: %lld (0x%04x%08x), " + "timecode: %lld (" FMT_TIMECODE "), duration: %lld\n", id, + track->sizes[i], (uint32_t)track->sizes[i], track->positions[i], + (uint32_t)(track->positions[i] >> 32), + (uint32_t)(track->positions[i] & 0xffffffff), + track->timecodes[i], ARG_TIMECODE(track->timecodes[i]), + track->durations[i]); track->packetizer->process(data, track->sizes[i], track->timecodes[i], track->durations[i]); safefree(data); diff --git a/src/mmg/tab_chapters.cpp b/src/mmg/tab_chapters.cpp index d3186e921..81d242ac7 100644 --- a/src/mmg/tab_chapters.cpp +++ b/src/mmg/tab_chapters.cpp @@ -350,21 +350,13 @@ wxString tab_chapters::create_chapter_label(KaxChapterAtom &chapter) { tstart = FindChild(chapter); if (tstart != NULL) { timestamp = uint64(*static_cast(tstart)) / 1000000; - s.Printf("%02d:%02d:%02d.%03d", - (int)(timestamp / 1000 / 60 / 60), - (int)((timestamp / 1000 / 60) % 60), - (int)((timestamp / 1000) % 60), - (int)(timestamp % 1000)); + s.Printf(FMT_TIMECODE, ARG_TIMECODE(timestamp)); label += s; tend = FindChild(chapter); if (tend != NULL) { timestamp = uint64(*static_cast(tend)) / 1000000; - s.Printf("%02d:%02d:%02d.%03d", - (int)(timestamp / 1000 / 60 / 60), - (int)((timestamp / 1000 / 60) % 60), - (int)((timestamp / 1000) % 60), - (int)(timestamp % 1000)); + s.Printf(FMT_TIMECODE, ARG_TIMECODE(timestamp)); label += " - " + s; } @@ -981,11 +973,7 @@ void tab_chapters::on_entry_selected(wxTreeEvent &evt) { tstart = FindChild(*t->chapter); if (tstart != NULL) { timestamp = uint64(*static_cast(tstart)) / 1000000; - label.Printf("%02d:%02d:%02d.%03d", - (int)(timestamp / 1000 / 60 / 60), - (int)((timestamp / 1000 / 60) % 60), - (int)((timestamp / 1000) % 60), - (int)(timestamp % 1000)); + label.Printf(FMT_TIMECODE, ARG_TIMECODE(timestamp)); tc_start_time->SetValue(label); } else tc_start_time->SetValue(""); @@ -993,11 +981,7 @@ void tab_chapters::on_entry_selected(wxTreeEvent &evt) { tend = FindChild(*t->chapter); if (tend != NULL) { timestamp = uint64(*static_cast(tend)) / 1000000; - label.Printf("%02d:%02d:%02d.%03d", - (int)(timestamp / 1000 / 60 / 60), - (int)((timestamp / 1000 / 60) % 60), - (int)((timestamp / 1000) % 60), - (int)(timestamp % 1000)); + label.Printf(FMT_TIMECODE, ARG_TIMECODE(timestamp)); tc_end_time->SetValue(label); } else tc_end_time->SetValue(""); @@ -1282,7 +1266,7 @@ int64_t tab_chapters::parse_time(string s) { c = s.c_str(); if (istimestamp(c)) { - sscanf(c, "%02d:%02d:%02d.%03d", &hour, &minutes, &seconds, &msecs); + sscanf(c, FMT_TIMECODE, &hour, &minutes, &seconds, &msecs); return ((int64_t)hour * 60 * 60 * 1000 + (int64_t)minutes * 60 * 1000 + (int64_t)seconds * 1000 + msecs) * 1000000; diff --git a/src/output/p_vobsub.cpp b/src/output/p_vobsub.cpp index ad027acb0..cc20fc4f3 100644 --- a/src/output/p_vobsub.cpp +++ b/src/output/p_vobsub.cpp @@ -49,6 +49,7 @@ vobsub_packetizer_c::vobsub_packetizer_c(generic_reader_c *nreader, packet_num = 0; spu_size = 0; overhead = 0; + aid = -1; mpeg_version_warning_printed = false; set_track_type(track_subtitle); @@ -73,12 +74,6 @@ void vobsub_packetizer_c::set_headers() { track_entry->EnableLacing(false); } -#define TIMECODE (timecode - initial_displacement) / 60 / 60 / 1000, \ - ((timecode - initial_displacement) / 60 / 1000) % 60, \ - ((timecode - initial_displacement) / 1000) % 60, \ - (timecode - initial_displacement) % 1000 -#define FMT_TIMECODE "%02lld:%02lld:%02lld.%03lld" - int vobsub_packetizer_c::extract_duration(unsigned char *data, int buf_size, int64_t timecode) { uint32_t date, control_start, next_off, start_off, off; @@ -98,7 +93,8 @@ int vobsub_packetizer_c::extract_duration(unsigned char *data, int buf_size, if (next_off < start_off) { mxwarn(PFX "Encountered broken SPU packet (next_off < start_off) at " "timecode " FMT_TIMECODE ". This packet might be displayed " - "incorrectly or not at all.\n", TIMECODE); + "incorrectly or not at all.\n", + ARG_TIMECODE(timecode - initial_displacement)); return -1; } mxverb(4, PFX "date = %u\n", date); @@ -169,7 +165,7 @@ int vobsub_packetizer_c::deliver_packet(unsigned char *buf, int size, duration = extract_duration(buf, size, timecode); if (duration == -1) { mxverb(3, PFX "Could not extract the duration for a SPU packet (timecode: " - FMT_TIMECODE ").\n", TIMECODE); + FMT_TIMECODE ").\n", ARG_TIMECODE(timecode - initial_displacement)); duration = default_duration; } if (duration != -2) { @@ -187,7 +183,7 @@ int vobsub_packetizer_c::process(unsigned char *srcbuf, int size, int64_t, int64_t) { unsigned char *dst_buf; uint32_t len, idx, version, packet_size, dst_size; - int c, aid; + int c, packet_aid; float pts; /* Goto start of a packet, it starts with 0x000001?? */ const unsigned char wanted[] = { 0, 0, 1 }; @@ -234,7 +230,8 @@ int vobsub_packetizer_c::process(unsigned char *srcbuf, int size, mxwarn(PFX "Unsupported MPEG version: 0x%02x in packet %lld for " "track %lld for timecode " FMT_TIMECODE ", assuming " "MPEG2. No further warnings will be printed for this " - "track.\n", c, packet_num, ti->id, TIMECODE); + "track.\n", c, packet_num, ti->id, + ARG_TIMECODE(timecode - initial_displacement)); mpeg_version_warning_printed = true; } version = 2; @@ -303,12 +300,23 @@ int vobsub_packetizer_c::process(unsigned char *srcbuf, int size, /* abort(); */ } in.setFilePointer2(dataidx, seek_beginning); - aid = in.getch(); - if (aid < 0) { - mxwarn(PFX "Bogus aid %d\n", aid); + packet_aid = in.getch(); + if (packet_aid < 0) { + mxwarn(PFX "Bogus aid %d\n", packet_aid); return deliver(); } packet_size = len - ((unsigned int)in.getFilePointer() - idx); + if (aid == -1) + aid = packet_aid; + else if (aid != packet_aid) { + // The packet does not belong to the current subtitle stream. + mxverb(3, PFX "skipping sub packet with aid %d (wanted aid: %d) " + "with size %d at %lld\n", packet_aid, aid, packet_size, + in.getFilePointer()); + in.skip(packet_size); + idx = len; + break; + } dst_buf = (unsigned char *)saferealloc(dst_buf, dst_size + packet_size); mxverb(3, PFX "sub packet data: aid: %d, pts: %.3fs, packet_size: " diff --git a/src/output/p_vobsub.h b/src/output/p_vobsub.h index 2c8ef689c..42f833fdd 100644 --- a/src/output/p_vobsub.h +++ b/src/output/p_vobsub.h @@ -30,7 +30,7 @@ class vobsub_packetizer_c: public generic_packetizer_c { private: unsigned char *idx_data; - int idx_data_size; + int idx_data_size, aid; bool extract_from_mpeg, mpeg_version_warning_printed; int64_t packet_num, spu_size, overhead;