OpenAPV

Overview

OpenAPV provides professional grade visually lossless video suitable as a raw video format, designed and developed by Samsung. It is free and open source and this implementation was contributed by Samsung to the ASWF.

The codec specification allows:

  • Perceptually lossless video quality.
  • Support for high bit rate and resolution content (e.g. 8k)
  • Support for multiple decoding and re-encoding without severe visual quality degradation.
  • Support for up to 16-bit encoding.
  • Frame tiling for immersive content and for enabling parallel encoding and decoding.
  • Support multi-video video and auxiliary video like depth, alpha and preview.

There are three implementations:

  • OpenAPV library - https://github.com/AcademySoftwareFoundation/OpenAPV - which can encode a YCrCb stream to the apv format.
  • Native ffmpeg - FFmpeg has implemented their own decoder as part of the core ffmpeg app, they also have their own encoder using the OpenAPV library.
  • Android Open Source Project (AOSP) 16 - Android has added support of APV in v16. Android 16.

OpenAPV library

This implementation of the APV codec supports the following features:

  • 422 and 444 10-bit and 12 bit encoding/decoding.
  • Low complexity by optimization for ARM NEON and x86(64bit) SEE/AVX CPU
  • Supports tile-based multi-threading
  • Supports Various metadata including HDR10/10+ and user-defined format
  • Constant QP (CQP), average bitrate (ABR), and constant rate factor (CRF) are supported
  • Support for high bit rate and resolution content (e.g. 8k)
  • Support for multiple decoding and re-encoding without severe visual quality degradation

Possibly the easiest way to use it is to make a y4m file with ffmpeg and then use that as input to the oapv_app_enc
E.g.

ffmpeg -i INPUTFILE -pix_fmt yuv422p12le -strict -1 Y4MFILE.y4m  
oapv_app_enc -i Y4MFILE.y4m -o OUTPUTFILE.apv -qp 20

Note, the y4m format only works with 422, but it does give you access to some of the other options. This is not really recommended, since you dont really have control over the colorspace, nor wrapping the result in a mp4 or mov file, which ffmpeg can do below.

Ffmpeg

OpenAPV is included in the 8.0 version of ffmpeg.

There is a decoder which is impressively fast, and does support 422, 444 and 4444 at 10 and 12 bits.
The encoder uses the OpenAPV library, and currently supports 422, 444 and 4444 at 10 and 12 bits.

Example Encoding

ffmpeg -start_number 2500 -i “INPUT.%05d.dpx" -vframes 200 -c:v liboapv -qp 20 \
     -preset fast -pix_fmt yuv444p12le -oapv-params "profile=444-12" \
     -sws_flags spline+accurate_rnd+full_chroma_int \
     -vf "scale=in_range=full:in_color_matrix=bt709:out_range=tv:out_color_matrix=bt709" \
     -color_range tv -colorspace bt709 -color_primaries bt709 -color_trc iec61966-2-1 \
     -y "OUTPUT.mov"

Flags include:

-qp 20 Quantization parameter, for visually lossless you probably want 20 or lower in the range 0-63 for 10-bit 0-75 for 12-bit.
-preset fast Preset fast curiously appears to generate faster results at a better quality. Little reason to use medium or slower presets.
-b:v 250Mb The bitrate can be set, you can choose between -qp and bitrate.
-oapv-params “profile=444-12” This passes an additional parameter to the encoder, it is not needed for yuv422p10le but is needed for the others. See below

For the current version of ffmpeg, an additional parameter is required to be passed through the -oapv-params flag, this tells the encoder what media it expects to be passed from ffmpeg. Hopefully in the future by default this will be automatic. Values can be:

pix_fmt oapv-params notes
-pix_fmt yuv422p10le   None required
-pix_fmt yuv422p12le -oapv-params profile=422-12 YCbCr422 12-bit
-pix_fmt yuv444p10le -oapv-params profile=444-10 YCbCr444 10-bit
-pix_fmt yuv444p12le -oapv-params profile=444-12 YCbCr444 12-bit
-pix_fmt yuv444p10le -oapv-params profile=444-10 YCbCr444 10-bit
-pix_fmt yuv444p12le -oapv-params profile=444-12 YCbCr444 12-bit
-pix_fmt yuva444p10le -oapv-params profile=4444-10 YCbCr444 10-bit
-pix_fmt yuva444p12le -oapv-params profile=4444-12 YCbCr444 12-bit

Ffmpeg does default to 422-10, so if you are using that pix_fmt, the encode can be as simple as:

ffmpeg -start_number 2500 -i “INPUT.%05d.dpx" -vframes 200 -c:v liboapv -qp 20 \
     -preset fast -pix_fmt yuv422p10le -sws_flags spline+accurate_rnd+full_chroma_int \
     -vf "scale=in_range=full:in_color_matrix=bt709:out_range=tv:out_color_matrix=bt709" \
     -color_range tv -colorspace bt709 -color_primaries bt709 -color_trc iec61966-2-1 -y "OUTPUT.mov"

Presets

There are presets of:

  • Fastest
  • Fast
  • Medium
  • Slow
  • Placebo

Fastest and Fast are fairly similar, they have a higher quality than medium, and are twice as fast and better quality than medium, at the expense of a 3-5% increase in disk space.

Medium is the smallest file size, but also has the worst PSNR values by small amounts.

We recommend fast if encoding speed is an issue, or medium if file-size is an issue.


QP

There are two main adjustments, bitrate or QP.

QP (Quantization Parameter) is 0-40, the default being 30, for visually lossless values we recommend qp=20, there are small increases if you goto about 15, and above that the improvements are fairly minimal.

Bitrate

But in practice it does cap out at a quality above 300Mbps.

Note, if you look at the YUV Diff, particularly for 422p10 Comparing a bit rate of 250Mb/s vs, qp16 show using the qp value generates better results than using the bitrate flag.


Bitrate 250Mb/s qp16
File size - 241,363,608 214,007,491

This is a known issue that hopefully will be addressed in a future update. It’s worth stressing that this particular view does exaggerate extremely small changes, so if using bitrate is desirable, test to see if the results are acceptable.

Benchmarking

These benchmarks were for HD versions of the netflix chimera media (200 frame clips). This is running on a M2 Macbook Pro, so we can compare directly with the videotoolbox apple prores encode (NOTE, which has hardware assist). We have picked a couple of QP values, and mostly consider a QP value of 15 to be the most desirable rate, we were picking codec settings (where available) to approximately match the prores PSNR value, so we can compare the different file sizes and encode time.

This is showing different intraframe codecs against encoding time.
This is showing different intraframe codecs against file size.
This is showing different intraframe codecs against VMAF harmonic mean
This is showing different intraframe codecs against psnr y harmonic mean

The APV encoder is compariable in this case to ffmpeg with video-toolbox on an M2 Max (with encoder hardware), it is unknown how optimal the ffmpeg wrapper is. But there are definately improvements over DNxHD. HTJ2K is a little unfair in this context since it is a full RGB image, but clearly is slower at encoding. Also worth noting prores_ks is quite a bit slower.

For 444 testing:
Note, dnxhr and prores_ks are both encoding only to 10-bit, since they do not support 12-bit in ffmpeg.

This is showing different intraframe codecs against encoding time.
This is showing different intraframe codecs against file size.
This is showing different intraframe codecs against VMAF harmonic mean
This is showing different intraframe codecs against psnr y harmonic mean

Playback

For playback you need to at least be on ffmpeg 8.0. OpenRV does have a Pull-request to add 8.0 as an option to OpenRV. The changes are not specific to OpenAPV, but are related to updates to ffmpeg 8.0.

Playback performance

This is measuring playback performance using /Users/sam/git/ffapv/ffmpeg -hide_banner -benchmark -stream_loop 4 -i <FILENAME> as a way to test FPS without the display factor to compare one codec to another.

TODO Need to clean this data up….

origfile dnxhr dnxhr_hqx oapv_422p10le oapv_422p10le_qp15 oapv_422p10le_qp20 oapv_422p10le_qp25 prores_ks_hq prores_videotoolbox_yuv422p10le_hq
chimera_cars_srgb 315.6 305 454.6 298.2 341.9 476.2 280.4 281.8
chimera_coaster_srgb 342.2 314.7   299.4 351.9 465.8 306 301.5
chimera_fountains 327.7 329.3   220.9 249.2 331.5 297.8 276.3
chimera_wind_srgb   360.1   257.2 302.6 409.3 328.4 313.2
Grand Total 328.5 327.275 454.6 268.925 311.4 420.7 303.15 293.2

Copyright © 2022 ORI Contributors. Distributed under a CC BY 4.0 license.