Always regenerate Vorbis timecodes. This is necessary because Vorbis is laced, and when reading it from Matroska the timestamps might come out wrong if the output has different lacing, e.g. when splitting is active.

This commit is contained in:
Moritz Bunkus 2004-10-16 13:46:34 +00:00
parent c24aa9ca9b
commit cbd9c7bf01
4 changed files with 50 additions and 27 deletions

View File

@ -1,3 +1,10 @@
2004-10-16 Moritz Bunkus <moritz@bunkus.org>
* 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 <moritz@bunkus.org>
* mkvmerge/mkvinfo/mkvextract: bug fix: The chapter and tag

View File

@ -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");

View File

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

View File

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