diff --git a/ChangeLog b/ChangeLog index 855215603..2999c1be3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-10-16 Moritz Bunkus + + * mkvmerge: bug fix: Timecodes for Vorbis were wrong on rare + occasions (when reading laced Vorbis from a Matroska file and + changing the lacing, e.g. when splitting for the second and all + following files). + 2004-10-10 Moritz Bunkus * mkvmerge/mkvinfo/mkvextract: bug fix: The chapter and tag diff --git a/src/output/p_vorbis.cpp b/src/output/p_vorbis.cpp index f7b7a4476..181ccb841 100644 --- a/src/output/p_vorbis.cpp +++ b/src/output/p_vorbis.cpp @@ -45,9 +45,11 @@ vorbis_packetizer_c::vorbis_packetizer_c(generic_reader_c *nreader, generic_packetizer_c(nreader, nti) { int i; - packetno = 0; last_bs = 0; samples = 0; + timecode_offset = 0; + last_samples_sum = 0; + last_timecode = 0; memset(headers, 0, 3 * sizeof(ogg_packet)); headers[0].packet = (unsigned char *)safememdup(d_header, l_header); headers[1].packet = (unsigned char *)safememdup(d_comments, l_comments); @@ -144,12 +146,17 @@ vorbis_packetizer_c::process(memory_c &mem, int64_t) { unsigned char zero[2]; ogg_packet op; - int64_t this_bs, samples_here, samples_needed; + int64_t this_bs, samples_here, samples_needed, expected_timecode, duration; + int64_t chosen_timecode; debug_enter("vorbis_packetizer_c::process"); + // Remember the very first timecode we received. + if ((samples == 0) && (timecode > 0)) + timecode_offset = timecode; + // Positive displacement, first packet? Well then lets create silence. - if ((packetno == 0) && (initial_displacement > 0)) { + if ((samples == 0) && (initial_displacement > 0)) { // Create a fake packet so we can use vorbis_packet_blocksize(). zero[0] = 0; zero[1] = 0; @@ -172,37 +179,47 @@ vorbis_packetizer_c::process(memory_c &mem, } } - // Recalculate the timecode if needed. - if (timecode == -1) { - if (initial_displacement > 0) - timecode = samples * 1000000000 / vi.rate; - else - timecode = samples * 1000000000 / vi.rate + initial_displacement; - } else - timecode += initial_displacement; - - // Handle the linear sync - simply multiply with the given factor. - timecode = (int64_t)((double)timecode * ti->async.linear); - // Update the number of samples we have processed so that we can // calculate the timecode on the next call. op.packet = mem.data; op.bytes = mem.size; this_bs = vorbis_packet_blocksize(&vi, &op); samples_here = (this_bs + last_bs) / 4; - samples += samples_here; last_bs = this_bs; + samples += samples_here; + + expected_timecode = last_timecode + last_samples_sum * 1000000000 / vi.rate + + timecode_offset; + if (initial_displacement < 0) + expected_timecode += initial_displacement; + + if (timecode > (expected_timecode + 100000000)) { + chosen_timecode = timecode; + duration = timecode - last_timecode; + last_timecode = timecode; + last_samples_sum = 0; + } else { + chosen_timecode = expected_timecode; + duration = (int64_t)(samples_here * 1000000000 * ti->async.linear / + vi.rate); + } + + last_samples_sum += samples_here; + + // Handle the linear sync - simply multiply with the given factor. + chosen_timecode = (int64_t)((double)chosen_timecode * ti->async.linear); // If a negative sync value was used we may have to skip this packet. - if (timecode < 0) { + if (chosen_timecode < 0) { debug_leave("vorbis_packetizer_c::process"); return EMOREDATA; } - mxverb(2, "Vorbis: samples_here: %lld\n", samples_here); - add_packet(mem, (int64_t)timecode, - (int64_t)(samples_here * 1000000000 * ti->async.linear / - vi.rate)); + mxverb(2, "Vorbis: samples_here at %lld (orig %lld expected %lld): %lld " + "(last_samples_sum: %lld)\n", + chosen_timecode, timecode, expected_timecode, + samples_here, last_samples_sum); + add_packet(mem, expected_timecode, duration); debug_leave("vorbis_packetizer_c::process"); diff --git a/src/output/p_vorbis.h b/src/output/p_vorbis.h index 7c1d8065a..89d9ca1ad 100644 --- a/src/output/p_vorbis.h +++ b/src/output/p_vorbis.h @@ -29,8 +29,7 @@ class vorbis_packetizer_c: public generic_packetizer_c { private: - int64_t last_bs, samples; - int packetno; + int64_t last_bs, samples, last_samples_sum, last_timecode, timecode_offset; vorbis_info vi; vorbis_comment vc; ogg_packet headers[3]; diff --git a/tests/results.txt b/tests/results.txt index d6f4a6718..79133cb59 100644 --- a/tests/results.txt +++ b/tests/results.txt @@ -17,14 +17,14 @@ T_016cuesheet:e2e88f91b6bf6ff411f4984ce7d89e35:passed:20040825-175700 T_017chapters:990b4b6b0931b7d52e589f715c919e10-4fff45a76f54708f881312aca04fd887:passed:20040825-175700 T_018attachments:bac27359516bab4984df3021aa295213-7e8e1f17615f157db0e98fba9ad88bad:passed:20040825-175700 T_019attachments2:8d9ba46c4edbf3daf50175f9de2f87b4-94349d68c9b7d493ec0d5a49f7291e40-8d9ba46c4edbf3daf50175f9de2f87b4-5c639e8a08cf526d051fdf64f856c0d2:passed:20040825-175700 -T_020languages:dc8b8792f86ac4e92e70154faef990a7:passed:20040825-234208 +T_020languages:7d853f21fe2d3e73b3ca0d29801e8d39:passed:20040825-234208 T_021aspect_ratio:f6e8aa4cfd776d99ff824f21d4e3c640-990a5f94678b5c8886dc8c3a5c6a22dd:passed:20040825-234244 T_022display_dimensions:108880396ffe5244465a3d25e8a57f93:passed:20040825-234339 -T_023no_x:0b7f257f1c801da7b2ef1976291e5d44-39f690e6a11bc2e32b54334e67374feb-2662148f7a3d60c152c92ad9a9d5e672:passed:20040825-234343 +T_023no_x:0b7f257f1c801da7b2ef1976291e5d44-49870185a891e8b3f6f265dca6f0e707-c43a34f68db19f5a318bd90c6f6446ab:passed:20040825-234343 T_024sync_mp3:a6c35d309947a52196d2a5428f87224a-6a638028d795bd48db95446f3521c302:passed:20040825-234344 -T_025sync_vorbis:e9d13a6b769cf6c2e4987bf6bd160698-51fcfab150642a66484d3c6bedff697a:passed:20040825-234344 +T_025sync_vorbis:e9d13a6b769cf6c2e4987bf6bd160698-51fcfab150642a66484d3c6bedff697a:failed:20040825-234344 T_026sync_pcm:f337f057c059d771128206c0da3d4807-9b559191edb65655e49186c302c4b815:passed:20040825-234346 -T_027default_track:e3177712483af5b129bbeb9cf0e6a820:passed:20040825-234348 +T_027default_track:5e3cdf80eff356e84a94c877f6514b02:passed:20040825-234348 T_028compression:f6c15855e42e5a0e80d22a2060ae13e8:passed:20040825-234348 T_029link:d92e5f123b799212f65bb7b394dd4f6e:passed:20040825-235039 T_032cues:f84c58a6380b3104434b6943e0eb87e3:passed:20040825-235040