Before progress was measured in number of elements (frames/blocks) to
process for those readers that could provide that information without
processing the whole file (e.g. MP4, AVI). As those elements could
have wildly varying sizes, each reader's `get_progress()` function
returned its progres as a number in the range `[0..100]`.
This meant, though, that the effort/time required to reach 100% could
not be gauged from outside the reader. In situations such as appending
files, mkvmerge's core had to guess which readers to use for
progress. It did so looking for the longest chain of appended files
and using its readers and their progress reports.
This is obviously wrong even for simple cases: e.g. you have a single,
huge M2TS and two text subtitle files. You append the two subtitle
files and add the M2TS. The time for muxing was clearly dominated by
the M2TS — but the progress was reported according to the tiny text
subtitle files.
After the rewrite the total progress is simply the total number of
bytes of all source files. The current progress is roughly the sum of
the number of bytes that have been processed for each source file.
Fixes#2150 and #2330.
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.
Only applies to the packetizers for the following formats: AAC, AC-3,
DTS, MP3 and TrueHD. The other packetizers were already keeping the
value.
Fixes#2296.