A disc rip is joined by the wrong ffmpeg mechanism #43
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A DVD rip is handed to ffmpeg as
-i concat:"a|b"where upstream writes aconcat config file and passes
-f concat -safe 0 -i <file>.Those are two different mechanisms.
concat:is a protocol that joins bytestreams;
-f concatis a demuxer reading a list of files with durations.EncodingHelper.GetInputArgumenttakes the second road forDvdandBluRay,building
<cache>/concat/<sourceId>.concatthroughGenerateConcatConfig,which probes each file for its duration first.
So the argument string this server builds is not upstream's on that branch, and
neither the response harness nor the ffmpeg corpus can see it: the corpus
generator refuses a DVD case outright —
DeclaredEncoderthrows "undeclared"for a folder — so there is nothing to diff against.
Porting it wants two things this does not have yet: a probe per playable file
for its duration, and a written file under the cache directory, which is adapter
work rather than argument building.
Wanted first: a rip to play. Nothing in either library here is one, so whether
the protocol form plays a DVD correctly is itself unmeasured.
A rip's files now reach ffmpeg through the concat demuxer, as upstream sends
them: a list written to
<cache>/concat/<sourceId>.concat, one stanza per filenaming where it is and how long it plays, passed as
-f concat -safe 0 -i.The protocol form this replaces joined the files as bytes. The demuxer re-bases
timestamps per file from the durations in the list, which the protocol cannot
do — and the selection rule groups by the part number a name ends with, so two
different title sets can land in one group and their timestamps restart at the
boundary.
The review turned up two things worth naming.
The duration was resting on an unverified assumption. It is
TimeSpan.TotalSecondsupstream, and .NET Framework scaled the ticks by aten-millionth where modern .NET divides them — the two differ in the last bit
for most values. Every duration in the tests happened to be one where both
agree, so nothing could have caught it either way. Settled by running the real
thing under
mcr.microsoft.com/dotnet/sdk:10.0:TimeSpan.FromTicks(12345678901) .TotalSecondsis1234.5678901, the division. That value is now the test, andit fails against a reader that scales instead.
The list was written while describing a source, which is every playlist and
every segment request. Upstream writes it only where an encoder is started. A
rip with one damaged part answered 500 from
master.m3u8where upstreamanswers 200 and fails at the transcode, and a cold playlist request blocked on
one ffprobe per VOB. Now written at the two places a transcode starts, and put
in place by a rename so two requests cannot hand ffmpeg a file cut short.
Also fixed: an encoder built with no cache configured named the list at the root
of the filesystem.
Not fixed, and true of upstream too: the list is written once and kept, so a
re-rip that changes a part's length keeps playing against the old durations.
Upstream ages its whole cache directory out on a schedule; this server has no
such task, so there it is stale until the file is removed by hand.
A Blu-ray still does not play. It takes this same branch upstream, but the list
is filled from the disc's own playlist, which nothing here reads — so the
argument names a file that is never written. Broken before this change and
broken after, now recorded in the test that says so.
Neither the harness nor the corpus can see any of this: the corpus generator
refuses a folder source, and no rip exists in either library. Whether ffmpeg
actually plays a rip from one of these lists is untested — the assertions are on
the argument and the bytes, not on a picture.