mkvtoolnix/tests/test-645ogg_opus_first_timestamp_negative.rb
Moritz Bunkus 1762d4dc2e
Ogg Opus reader: calculate packet timestamps from granulepos
The prior algorithm summed up all Opus frame's number of samples and
calculated the expected timestamp from there. That expected timestamp
was compared to the Ogg page's granule position, and the discard
padding was calculated from that.

This lead to problems in several cases:

1. When the first packet's granule position was bigger than the number
   of samples in the Opus frame, the specs say that the first sample's
   timestamp is positive in that case. mkvmerge was wrongfully using 0
   as the timestamp and thought discard padding was needed in such a
   case.

2. When the first packet's granule position was smaller than the
   number of samples in the Opus frame (meaning the first sample's
   timestamp was negative), a technically invalid bitstream, mkvmerge
   was wrongfully forcing the first packet's timestamp up to 0 and
   inserting discard padding elements all over the place as its
   internal calculations got confused.

The new algorithm bases the calculation on the last known granule
position special-casing for certain Ogg packet numbers:

1. For the first Ogg page the timestamps of all packets is calculated
   by subtracting each packet's number of samples from the page's
   granule position in reverse order. This may result in the first
   packet's timestamp being positive, which mkvmerge now preserves.

   mkvmerge won't calculate a discard padding for this page.

2. For all other pages each packet's timestamp is calculated by adding
   each packet's number of samples to the previous Ogg page's end
   timestamp as given by its granule position.

   mkvmerge then calculates the discard padding for the last packet of
   the page by comparing the calculated end timestamp of that packet
   with the Ogg page's end timestamp as given by the granule
   position.

   As a workaround for certain rounding errors encountered in the
   wild, a discard padding of one sample will be treated as if no
   discard padding was present for all but the very last packet as
   indicated by the "end of stream" bit.

Fixes #2280.
2018-06-20 19:27:47 +02:00

7 lines
387 B
Ruby
Executable File

#!/usr/bin/ruby -w
# T_645ogg_opus_first_timestamp_negative
describe "mkvmerge / Ogg Opus with first granulepos being smaller than number of samples in packet = negative first timestamp"
test_merge "data/opus/first-timestamp-negative.opus", :args => "--timestamp-scale 1000000"
test_merge "data/opus/first-timestamp-negative.opus", :args => "--timestamp-scale 1000000 --disable-lacing"