Skip to content

Add PBU-based encoding APIs (encoder API set 1) #256

Description

@kpchoi

Summary

The decoder offers a PBU-based API set (API set 1: oapvd_info_pbu, oapvd_decode_frame, ...) that walks a bitstream PBU by PBU, but the encoder only offers whole-AU encoding through oapve_encode(). This adds the encoder-side counterpart: the application assembles an access unit itself — raw AU framing first, then frames appended as frame PBUs, then metadata appended as metadata PBUs.

Branch: https://github.com/AcademySoftwareFoundation/openapv/tree/add_enc_pbu_api

Design

Mirroring the decoder API set 1 conventions:

  • The application owns the AU framing: it writes the 4-byte au size and the aPv1 signature itself, exactly as the set-1 decoding application reads them.
  • Two new APIs (kept minimal on purpose; the oapve_pbu_ prefix is provisional and can be renamed before release):
int oapve_pbu_encode_frame(oapve_t eid, oapv_frm_t *ifrm, int frm_idx, oapvm_t mid,
                           oapv_bitb_t *bitb, oapve_stat_t *stat, oapv_frm_t *rfrm);
int oapve_pbu_encode_metadata(oapve_t eid, oapvm_t mid, int group_id,
                              oapv_bitb_t *bitb, oapve_stat_t *stat);
  • oapve_pbu_encode_frame() writes one frame PBU (pbu_size + pbu_header() + frame()) into the caller's bitstream buffer. frm_idx selects the per-frame parameter and rate control state slot, matching the OAPV_CFG_FRM() addressing of oapve_config(). When the frame hash is enabled, the hash payload is collected into mid, so the caller can then emit it with the metadata call — which is what makes the "metadata as separate PBUs" flow natural.
  • oapve_pbu_encode_metadata() writes the metadata of one group as one metadata PBU and returns OAPV_ERR_NOT_FOUND when the group has no metadata, so the caller can simply try each group.
  • No au_info writer was added since oapve_encode() does not emit access_unit_info PBUs either; it can be added later if a use case appears.

Internally the frame-PBU and metadata-PBU blocks of oapve_encode() were factored into shared helpers (enc_pbu_frame / enc_pbu_metadata), so both API sets run the identical code path.

Application

oapv_app_enc gains --api-set 0|1 like the decoding application. Set 1 assembles each AU with the new APIs (encode_au_apiset1()): framing, frame PBUs per input frame, then one metadata PBU per distinct frame group. The oapve_stat_t it reports is filled compatibly, so the rest of the app (PSNR, reconstruction output, statistics) is unchanged.

Verification

  • The refactor is bitstream-neutral: set-0 outputs are byte-identical to current main across CQP, ABR, fastest preset, and hash configurations.
  • API set 1 output is byte-identical to API set 0 across 7 configurations x 4 AUs each: plain CQP, --hash with reconstruction, ABR (--bitrate, exercising rate-control state continuity across AUs), --preset fastest at QP 0, --disable-tile-size-in-fh, a non-default tile geometry, and HDR metadata (--master-display/--max-cll plus color description).
  • Profile sweep (422-12, 444-10, 4444-10, 400-10, 422-10-UNCONST): set 0 == set 1, byte-identical.
  • A set-1-encoded stream decodes with hash:match on every frame, with both decoding API sets.
  • All 18 ctest cases pass; AddressSanitizer reports no findings on the set-1 path.

Notes for review

  • API naming (oapve_pbu_encode_*) is intentionally provisional.
  • Multi-frame AUs are supported by the API design (per-call frm_idx), while the reference app currently encodes one frame per AU as before.
  • The programmers guide gained a "PBU-based encoding (API set 1)" section with the assembly pseudo code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions