Movies and web formats
Reading and writing movies (ProRes, DNxHR, H.264, HEVC, AV1, VP9, MXF) and web formats (WebM, GIF, animated WebP / AVIF): codecs, colour, timecode, presets and speed.
Oink reads and writes movies with the same Read and Write nodes as image sequences, and the
same knobs as Nuke's mov64 reader and writer. Reading and the picture side of writing run inside the app's engine, using FFmpeg libraries that the installer downloads (python3 install.py; an LGPL build). An ffmpeg program is still used for the encoders and a few special cases (below); it must be installed or pointed to with the OPENCOMP_FFMPEG environment variable.
Read a movie
Point a Read at a .mov, .mp4, .m4v, .mxf, .mkv, .webm, .avi, .gif, or an animated
.webp / .avif. The frame range becomes 1 to the number of frames in the movie. The
frame range, before / after, frame mode and offset knobs work as for sequences.
| Knob | What it does |
|---|---|
| ycbcr matrix | Rec 601, 709 or 2020. Default: the file's colour tag, else Rec 601 for SD video and Rec 709 for everything else |
| data range | Video range (16-235) or full range (0-255). Default: the file's tag, else by pixel format |
| decoder | auto, CPU or NVDEC (the NVIDIA GPU decoder, for H.264 / HEVC / AV1 / VP9). Not in Nuke |
| input transform | Default: from the file's transfer tag. Untagged or Rec.709 video = Rec.1886 (Nuke's Gamma 2.4), sRGB, PQ / HLG = Rec.2100, web images = sRGB |
- Any frame can be asked for in any order: the Read lands on exactly that frame, even in long-GOP H.264 with B-frames. This is tested against ffmpeg decoding the file from the start.
- While a movie plays, the frames after the current one are decoded ahead on background threads, and the colour conversion runs on the GPU. UHD ProRes and H.264 play at about 25 fps with no dropped frames, and scrubbing a long-GOP movie takes tens of milliseconds a frame. Pixels are identical to the older ffmpeg-program path.
- The
ffmpegprogram is used instead for rotated phone movies, VP9 with alpha, NVDEC decoding, GIF and variable-frame-rate files, and for any file the libraries cannot open. SetOPENCOMP_MOVIE_LIBAV=0to force it everywhere. - Each frame's metadata has the movie's timecode for that frame (
input/timecode), frame rate, codec, bit depth, colour tags and audio. A Write downstream uses the timecode as its start timecode. - 10- and 12-bit movies are read at 16 bits a channel. Alpha is read from ProRes 4444, PNG, Animation, VP9 WebM, GIF and animated WebP.
Write a movie
Set the Write's file type to mov (with mov / mp4 / mkv as the format), mxf, webm, gif,
webp (animated) or avif (animated). A render streams its frames into one file while it renders: no
temporary images.
| Codec | Profiles | Alpha | Containers |
|---|---|---|---|
| Apple ProRes | 422 Proxy, LT, 422, HQ, 4444, 4444 XQ | 4444, 4444 XQ | mov, mxf, mkv |
| Avid DNxHD | 36, 145, 220 (8-bit), 220x (10-bit); 1920x1080 only | mov, mxf | |
| Avid DNxHR | LB, SQ, HQ, HQX (10-bit), 444 (10-bit) | mov, mxf, mkv | |
| H.264 | High 4:2:0 8-bit, High 10 | mp4, mov, mkv | |
| H.265 / HEVC | Main, Main 10, 4:2:2 10-bit | mp4, mov, mkv | |
| AV1 | 10-bit | AVIF only | mp4, webm, mkv, avif |
| VP9 | 4:2:0 | yes | webm, mkv |
| Motion JPEG A, PNG (16-bit), Animation | PNG, Animation | mov | |
| GIF, animated WebP | GIF (1-bit) | gif, webp |
- quality (Low / Medium / High / Best), or limit bitrate with a bitrate; gop size and b frames for H.264, HEVC, AV1 and VP9.
- encoder: software (x264, x265, SVT-AV1) or NVENC, the NVIDIA GPU encoder, several times faster. If NVENC can't start, the software encoder is used and the Write says so.
- ycbcr matrix and data range as in Nuke; the file is tagged with them and with the output transform's primaries and transfer, so players and the Read decode the same colours.
- The default output transform is Rec.1886 (Nuke's Gamma 2.4 / Rec.709) for mov, mp4, mkv and mxf, and sRGB for webm, gif, webp and avif, which browsers show correctly.
- Movies are one file, so a frame is not renamed into place. Image-sequence frames are different: each is written to a hidden temp file and renamed when complete, so a half-written frame is never seen, and the render reports NaN, infinite or all-black frames.
- write timecode, start timecode (else the input's timecode), audio file, fast start,
fps work as in Nuke. The knobs round-trip through
.nkfiles.
Presets
The Render dialog has a Preset menu that sets the Write's knobs before rendering:
| Preset | What it writes |
|---|---|
| Review H.264 (fast, NVENC) | mp4, H.264 4:2:0 8-bit on the GPU encoder, 1 s GOP, fast start |
| Web AV1 | mp4, AV1 10-bit (SVT-AV1), sRGB tag |
| ProRes 422 HQ master | mov, ProRes 422 HQ, Rec.709, timecode |
| DNxHR HQX | mxf, DNxHR HQX 10-bit, timecode |
| WebM VP9 with alpha | webm, VP9 with alpha, sRGB (transparent in Chrome and Firefox) |
| Animated WebP preview | animated webp, sRGB |
| GIF preview | gif with a palette made for the shot |
Colour checks
These are measured by tests/test_movie_io.py, on NJR footage and a generated colour chart.
| Check | Result |
|---|---|
| Video range, 8-bit H.264: black / white luma codes | 16 / 235 |
| Full range H.264: black / white | 0 / 255, tagged pc |
| ProRes 10-bit: black / white | 64 / 940 |
| Chart read back (display values): black, white, ramp | within 1.5/255 (8-bit) and 1/255 (10-bit) |
| Rec 601 tagged file: bar colours with the tag / forced to Rec 709 | error < 0.01 / > 0.05 |
| Video-range file read as full range | black lifts to 16/255, as expected |
| Rec.1886 tag -> input transform -> scene linear | ramp mean error < 0.002 |
| WebM / GIF / WebP / AVIF | tagged sRGB, the Read picks sRGB |
| NJR movies (H.264 Main, full-range H.264 with timecode, MJPEG Rec 601, Animation, UHD playblast) | random frames identical to ffmpeg's own sequential decode |
Round trip of the NJR plate (1920x1080, random frames, display-referred PSNR):
| Codec | PSNR dB | Alpha |
|---|---|---|
| ProRes 422 Proxy / LT / 422 / HQ | 40.5 / 44.4 / 46.3 / 48.5 | |
| ProRes 4444 / 4444 XQ | 56.6 / 58.3 | mean error 0.0002 |
| DNxHD 145 / DNxHR LB / SQ / HQ / HQX / 444 | 45.2 / 41.9 / 45.2 / 45.5 / 49.2 / 56.2 | |
| H.264 crf 18 (mp4, mkv 10-bit, mov with B-frames) | 40.8-41.4 | |
| HEVC Main 10 / Main | 41.9 / 41.3 | |
| AV1 (mp4, webm, avif) | 40.2-40.3 | |
| VP9 webm | 40.2 | mean error 0.0014 |
| PNG 16-bit in mov | 107 (lossless) | exact |
| Animation (qtrle) | 58.9 | mean error 0.0017 |
| GIF / animated WebP | 33.0 / 37.7 |
Speed
Measured 2026-09-29 on the NJR "people" plate (001_017) encoded to each codec, and the NJR edit
movie. Machine: 64-thread CPU, RTX 4090 (driver 580), ffmpeg 7.1 (flatpak) / 5.1 (host), a shared
machine with other jobs running (load 10-14), so treat these as lower bounds.
Measured with tools/bench/movie_io_bench.py.
Decode, through the Read's movie path (sequential frames, float RGBA out):
| Movie | Size | CPU fps | NVDEC fps |
|---|---|---|---|
| H.264 8-bit | 1920x1080 | 89 | 74 |
| ProRes 422 HQ | 1920x1080 | 91 | - |
| HEVC 10-bit | 1920x1080 | 67 | 79 |
| AV1 10-bit | 1920x1080 | 73 | 67 |
| NJR edit v07, H.264 | 2048x1152 | 74 | 63 |
| H.264 8-bit | 3840x2160 | 27 | 24 |
| DNxHR HQ | 3840x2160 | 28 | - |
| HEVC 10-bit | 3840x2160 | 17 | 19 |
| AV1 10-bit | 3840x2160 | 18 | 18 |
| ProRes 422 HQ | 3840x2160 | 16 | - |
- A random frame (a new decoder seeking): 220 ms at 1080 H.264, 555 ms UHD H.264, 680 ms UHD ProRes.
- NVDEC is no faster here: the CPU decoders keep up, and the frame still comes back to the CPU for the conversion. At UHD the limit is the pipe (16-bit frames, ~1.3 GB/s) and swscale.
- In the app (E2E, 1080p H.264 with B-frames): the first pass plays at 15-23 fps on the loaded machine (about 80 ms a frame from request to screen); cached frames play at 24 fps.
Encode, 24 real frames streamed from the Write (movie_writer):
| Encoder | 1920x1080 fps | 3840x2160 fps |
|---|---|---|
| ProRes 422 HQ (prores_ks) | 26 | 6.6 |
| DNxHR HQ | 6.4 | 1.9 |
| H.264 x264 medium | 23 | 3.8 |
| HEVC x265 medium 10-bit | 12 | 4.7 |
| AV1 SVT-AV1 preset 8 10-bit | 15 | 3.6 |
| VP9 libvpx good / cpu-used 4 | 8.6 | 2.9 |
| H.264 NVENC (host ffmpeg, through the flatpak proxy) | 17 | 6.8 |
| HEVC NVENC 10-bit (same) | 18 | 6.2 |
The encoders alone (host ffmpeg, raw UHD YUV in, 210 frames): H.264 NVENC 58 fps, HEVC NVENC 63 fps, x264 medium 27 fps, x264 veryfast 48 fps, x265 medium 7.6 fps, SVT-AV1 preset 8 4.2 fps. Through the Write, the limit is the RGB -> YCbCr conversion and the 16-bit pipe, not the encoder: NVENC's gain only shows once that is moved to the GPU. AV1 NVENC was not available (host ffmpeg 5.1 has no av1_nvenc; the flatpak's 7.1 needs a newer driver): the Write fell back to SVT-AV1.
Licences
Reading uses FFmpeg libraries that are loaded only when they are an LGPL build (built without the GPL option and without x264 / x265); a GPL build is refused and the ffmpeg program is used instead. The encoders in the ffmpeg program you point to carry their own licences: the one found on most Linux systems is a GPL build. Apple ProRes and Avid DNx encoding, and software H.264 / HEVC encoding, carry patent or trademark terms that are reviewed before a release. See Licences and source offer.
Localization
Local copies of files that live on a slow network share: policies, preferences, the Cache menu and the Read node's bar.
Engines and the Blender bridge
The standalone engine is the default and needs no Blender. Blender is an optional bridge for EEVEE, .blend files and a few extra Cycles passes.