# xyz2yuv tool Decode DCI XYZ' and apply conversions to your desired output colorspace. Supports Rec. 709 and Rec. 2020, with adjustable precision and gamma values. Supports AVX-512 and AVX2 targets, and a generic implementation in C and Go as well. See [go-dcp](https://git.gammaspectra.live/WeebDataHoarder/go-dcp) for a tool that can handle sample trailer DCPs. ## Dependencies * Go >= 1.22 * CGO enabled and working * libopenjp2-dev [OpenJPEG](https://github.com/uclouvain/openjpeg) * Necessary due to FFMPEG's JPEG2000 now default decoder being broken and producing corrupted output. * libavformat-dev * libavcodec-dev * libavutil-dev ## Build ```shell # initialize conv/simd_utils git submodules update --init # build binaries with specific Go toolchain path GOROOT=~/go/go1.22.4 ./build.sh ``` After building multiple tools will appear under `bin/`. These binaries are compiled with * `xyz2yuv`: Defaults to use the highest native features available. This includes 512-bit pipeline and AVX-512 usage if supported. * `xyz2yuv_avx2`: Disables AVX-512 and 512-bit pipelines. Prefer using the above on most systems as it will pick native features. * `xyz2yuv_2pump`: Executes two unrolled operations per loop. Might be faster on systems with only AVX2 or better superscalar support. * `xyz2yuv_4pump`: Executes four unrolled operations per loop. Might be faster on systems with only AVX2 or better superscalar support. * `xyz2yuv_8pump`: Executes eight unrolled operations per loop. Might be faster on systems with only AVX2 or better superscalar support. ## Usage The input file must include a video stream with codec JPEG2000 and with pixel format XYZ12. Other video inputs are unsupported. Any other tracks (audio/subtitles) will be ignored. Most containers that ffmpeg can support are valid, usually this will be MXF or Matroska. You need to select the color space that matches what you need. Sometimes custom gamma values are applied on mastering depending on viewing targets. Custom color spaces can be defined via JSON files. See `colorspace/config` for examples. Companding transfer functions require `-use-go-pipeline` Performance can be increased by using `-float` to reduce the precision of the conversion pipeline. This will cause precision issues. Low-resolution JPEG2000 decoding can be implemented via `-lowres` parameter. Value of zero equals original resolution. Default output is in the form of [YUVMPEG2](https://wiki.multimedia.cx/index.php/YUV4MPEG2) 16-bit 4:4:4 with full color range. Bit depth is configurable to 10/12/14/16 bit, and you can request limited range output. It can output to a file or stdout for immediate consumption. ```shell ./bin/xyz2yuv -lowres=0 \ -in /path/to/input.mkv \ -colorspace "rec709_pure22" \ -out /path/to/output.y4m ``` ``` Usage of xyz2yuv: -colorspace string Path to JSON colorspace and parameters to convert into. Default templates: rec709, rec709_pure22, rec709_pure24, rec2020, rec2020_pure22, rec2020_pure24, srgb, dci-p3 (default "rec709_pure22") -decoder-threads uint Threads for JPEG2000 decoding. Defaults to number of logical CPU -depth int Output bit depth. Must be one of 10, 12, 14, 16 (default 16) -end uint End frame number exclusive (default 18446744073709551615) -float Use float pipeline instead of double, although less precise. Very fast. -hash Hash with SHA256 each output frame for accuracy comparisons -in string Input file -limited Output limited/tv YUV range instead of full/pc range -lowres uint Feed lowres parameter. Default is full resolution -out string Output file. Use - for stdout (default "-") -pipeline-threads uint Threads for colorspace conversion pipeline. Defaults to number of logical CPU -precision-rgb2yuv int RGB -> YUV conversion matrix precision. 0 = maximum -precision-xyz2rgb int XYZ -> RGB conversion matrix precision. 0 = maximum -progress Output progress and speed information -start uint Start frame number inclusive -use-go-pipeline Use Go pipeline, although slower. Does not support float mode. ``` ## Scripts ### MPV playback For convenience mpv playback scripts are included under `scripts/`. The first audio track from the input file will also be included in the playback. Playback will be loosely seekable as it decodes from pipe. 4 GiB of cache is default and recommended to keep a few seconds of buffer. #### Rec. 709 output ```shell ./scripts/playback-rec709_22-mpv.sh /path/to/input.mkv ``` #### Rec. 2020 output ```shell ./scripts/playback-rec2020_24-mpv.sh /path/to/input.mkv ``` ### ffmpeg FFV1 lossless encode