Hevc vaapi encoder - #101
Conversation
0.0.13 is the current release of the safe libva bindings; nothing in this crate needs adapting for it. Note that neither 0.0.13 nor cros-libva git HEAD compiles against libva 1.22 or newer system headers: those moved seg_id_block_size and va_reserved8 into VAEncPictureParameterBufferVP9, and cros-libva writes an exhaustive struct literal for it, so the vaapi feature fails to build with E0063 on such a system until that one-line cros-libva fix (submitted separately) is released.
After emitting an emulation prevention byte, the byte that triggered it was dropped from the two byte lookbehind, so a run of five or more zeroes was only escaped once and the output contained a byte aligned 0x00 0x00 0x00 sequence, which 7.4.2 forbids. Keep the triggering byte pending instead, so that it counts towards the next pair, and cover the case in the unit test.
A bitstream writer with optional emulation prevention, mirroring the H.264 one. The only difference is the NALU header, which is two bytes long in H.265 (7.3.1.2).
Builders for the parameter sets an encoder produces, covering the syntax elements it is expected to set and leaving everything else at its specification default. SpsBuilder and PpsBuilder inherit what the parameter set they refer to already decided, and their build() repeats the derivations the parser performs, so that a built parameter set compares equal to a parsed one.
Serializes VPS, SPS and PPS structures back into NALUs, following the read order of the parser field for field. Multi-layer coding, the SCC extension, non uniform tile spacing and inter RPS prediction are refused, as the parser does not retain what they would need. The unit tests build the parameter sets, synthesize them, parse them back and compare, and re-synthesize the parameter sets of two test streams to check the output against encoders other than this one.
Mirror the H.264 encoder configuration so that the rate control, framerate and quality bounds a stream starts with can be given up front, and let EncodeError carry a H.265 synthesizer error.
Add the stateless H.265 codec definition, its backend request and DPB entry types, and the LowDelay prediction structure delegate. The delegate builds the VPS, SPS and PPS with the builders from codec/h265 and synthesizes them into the coded output when they change. The backend request carries the slice type rather than a parsed slice header, because codec/h265 has no slice header builder yet.
Fill VAEncSequenceParameterBufferHEVC, VAEncPictureParameterBufferHEVC and VAEncSliceParameterBufferHEVC from the backend request and submit a single slice segment covering the picture. Map Main and Main10 onto the matching VA profiles and the rate control variants onto CQP and CBR, leaving it to the driver to reject a combination it does not implement.
Let the C2 VAAPI encoder instantiate the stateless H.265 encoder, and teach ccenc to ask for it with --codec h265. Like H.264, the elementary stream is written as a plain Annex B byte stream rather than wrapped in IVF.
The synthesized parameter sets promised three things a VA-API backend does
not keep, each of which desyncs CABAC and leaves the rest of the picture read
as coefficient data:
- max_transform_hierarchy_depth_intra/_inter defaulted to 0, which says
split_transform_flag is never coded and a decoder infers no split. A
hardware encoder splits transform trees wherever the residual asks for
it, so its split flags were read as residual from the first CTU on.
- cu_qp_delta_enabled_flag was off, so cu_qp_delta_abs had nowhere to be
coded, while the driver's rate controller moves the QP between coding
tree blocks and codes the delta regardless.
- the picture was declared aligned to MinCbSizeY, so a 1080 line picture
claimed a 56 line bottom CTB row where the encoder had coded a full 64.
It is now declared at CtbSizeY and cropped back with the conformance
window, as the reference VA-API encoders do.
Measured on radeonsi/VCN at 1080p, each in isolation against the source:
depth 0 scores SSIM 0.17 with 371 decoder complaints, cu_qp_delta off 0.17,
the MinCbSizeY alignment 0.22; all three fixed scores 0.98 with a silent
decoder. Flat synthetic input passes either way, which is why this was not
caught by a round trip that only counts frames.
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
Hi, we already have HEVC VA-API encoder implementation in the Google internal branch. We are actively developing cros-codecs in the internal branch. I apologize for the inconvenience. |
|
Hi, I understand. Thank you. |
I don't know if you guys are active and want to add new things but here is hevc vaapi encoder