Repository navigation
Prepare for multi decoder support - #492
Merged
JeromeMartinez merged 15 commits intoOct 12, 2026
Merged
Conversation
Preparation for other FFV1 decoders: --decoder selects the FFV1 decoder used for decoding and checking. Only our decoder is available for the moment, so internal and auto use it.
If the video encoder is ffv1_vulkan, Vulkan is wanted, so the decoder used for checking (encoding with --check, or checking of a Matroska file) is auto if no decoder is provided. auto is kept for being resolved when a decoder is needed, it is our decoder only for the moment.
Each mkv file is decoded by our decoder, then by the decoder selected by --decoder auto with the Vulkan encoder (-c:v ffv1_vulkan), our decoder only for the moment.
Preparation for decoders using the frame data after the call: - Hold() keeps the current memory map until Release(), also after a Remap() or a Close() (memory map method only), - Readable_End() is the end of the bytes readable from the data, which may be after the end of the file with the other methods.
Preparation for decoders using the frame data after the call (decoding in other threads, data imported in GPU memory space) and reading after the frame data (FFmpeg), without copy in the decoders: - a wrapper tells the count of bytes its decoder reads after the frame data (Padding()), - the decoder receives a holder of the frame data, Hold() keeps the data until Release(), - the Matroska parser gives the data in the file map, kept as long as needed (memory map method), or a copy in reused buffers if the padding is not readable (end of the file), if the file map can not be kept (other methods) or if allocated memory is requested. Our decoder does not use them.
…ames Preparation for decoders running in their own threads: End() is called when there are no more frames, so a decoder may release its resources during the output of the last frames, and Remaining is the count of frames after the frame given to Decode() (if known).
…anges Planes were never created again, even if the frame size changed. Preparation for frames reused by decoders using different slice counts: planes are reused only if the frame size is the same and there is enough room for the line slices.
Preparation for thread pools with a lower priority.
Preparation for decoding frames in parallel by several decoders: keyframes can be decoded by any decoder.
Preparation for decoders outputting planar R, G, B, (A) samples (e.g. FFmpeg): Transform_Direct_Init() returns a function transforming a line of planar samples, not JPEG2000-RCT coded, to a line of the frame, for DPX RGB(A) 8-bit, RGB 10-bit method A, RGB(A) 12-bit method A and RGB(A) 16-bit flavors, and TIFF RGB(A) 8-bit, RGB 16-bit and RGBA 16-bit LE flavors (AVX2 for RGB 10-bit, 12-bit and 16-bit).
Transforms are deleted through a pointer to transform_base (e.g. by the FFV1 decoder), so its destructor is virtual (no undefined behavior, no compiler warning).
If the RAWCOOKED_TRACE environment variable is set, the processing stages of each thread (parsing, copies of frame data, decoding, outputs, hashes...) are recorded, with the CPU time of the thread during each stage, and counters (e.g. frames in flight). At the end, the trace is written in Chrome trace event format (JSON, e.g. for https://ui.perfetto.dev) to the file named by the variable, and a summary (count, wall and CPU time of each stage, busy and CPU time of each thread) is written to stderr. Without the variable, each instrumentation point only tests a boolean.
With a thread pool, our decoder returns when all slices of a frame are being decoded, and a callback is called at the end of the decoding of the frame, so the threads which would wait for the last slices of a frame decode the slices of the next frame, and the parsing of the next frame (including the remapping of the file) is done during the decoding. A keyframe uses a free set of slices, other frames use the set of the previous frame after its end (decoding states), and all previous frames are decoded first if there is no configuration record (parameters in slices). The frame data is kept by its holder until the end of the decoding. 3% faster with s1.mkv (i7-7800X).
If the frame is bigger than the cache (32 MiB or more), it would be read again from memory anyway, so the direct transforms of frames decoded by FFmpeg write it with non-temporal stores (after a scalar head for the alignment), without reading the destination in the cache first. Transform of 6464x4852 RGB 16-bit planes: 23% less CPU time (35% in a micro-benchmark, 8.2 ms instead of 12.6 ms with 4 threads).
With the microcode update for the Jump Conditional Code erratum (Intel Skylake and derived CPUs), jumps crossing or ending on 32-byte boundaries are slower, so the speed of the decoding depended on the code layout (variations of up to 10% between builds of the same decoder code). Jumps are now aligned (MSVC x64 Release: /QIntel-jcc-erratum, GNU: -Wa,-mbranches-within-32B-boundaries if the assembler supports it). Our decoder with s1.mkv on i7-7800X: 10% faster with MSVC, 7% with GCC, internal+vulkan 4% faster.
Contributor
|
Exciting!! |
Member
Author
@digitensions unfortunately still no help about AI GPUs, sorry... It will be a supporting in the same decoding CPU and general purpose GPU. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.