Skip to content

Task: VideoDecoderStreamConfig + InputBufferMetadata overrides — atomic stream-config batching + per-buffer container-derived overrides (from discussion #484) #539

Description

@Ulrond

Background

Tracks the agreed design from Discussion #484 (raised by @shafi12). Multiple Binder calls to set VideoDecoder properties (setMasteringDisplayInfo, setContentLightLevel, setColorimetry, setStreamResolution, setFrameRate, setDolbyVisionLayerFlags, setPixelAspectRatio, plus dynamic-range setters) cause:

  • IPC overhead — 7+ separate transactions per reconfiguration
  • Partial-state risk during reconfiguration — failure mid-batch leaves the decoder in an inconsistent state
  • No path for container-derived metadata changes mid-stream (ABR HDR profile change per DASH Period, SSAI, live→VOD)

Three weeks of discussion converged on a two-surface solution scoped by decoder lifecycle.

Proposed Solution — two surfaces

Surface 1 — VideoDecoderStreamConfig parcelable (READY-state, atomic setup batching)

A single all-optional parcelable that replaces the multi-call setup pattern. null field = "no change" / "use existing default".

@VintfStability
parcelable VideoDecoderStreamConfig {
    @nullable Resolution            resolution;           // {width, height}
    @nullable Fraction              frameRate;            // {numerator, denominator}
    @nullable Fraction              pixelAspectRatio;     // per #441 / #487
    @nullable Colorimetry           colorimetry;
    @nullable MasteringDisplayInfo  masteringDisplayInfo;
    @nullable ContentLightLevel     contentLightLevel;
    @nullable DolbyVisionLayerFlags dolbyVisionLayerFlags;
}

// On IVideoDecoderController:
void setStreamConfig(in VideoDecoderStreamConfig config);  // @pre State::READY

Properties:

  • Atomic — all fields land in one binder transaction
  • Partial — clients send only what changed (other fields stay null)
  • Type-safe — structured parcelables, no PropertyValue expansion
  • Discoverable — full set of stream-description fields in one place
  • Per-instance — lives on the controller; no VideoDecoderResourceIndex needed (the controller IS the per-instance handle)

The existing typed setters (setStreamResolution, setColorimetry, etc.) can either stay as convenience aliases or be deprecated and removed in the next major version (pre-restructure timing makes either viable).

Surface 2 — Extended InputBufferMetadata (STARTED-state, per-buffer overrides)

For container-derived metadata that changes mid-stream (ABR per-Period HDR, SSAI ad insertion, live→VOD), extend InputBufferMetadata with optional override fields:

@VintfStability
parcelable InputBufferMetadata {
    long nsPresentationTime;
    boolean endOfStream;
    boolean discontinuity;

    // NEW — optional overrides applied from this buffer onward.
    // null = no change. Bitstream-derived values still take precedence.
    @nullable MasteringDisplayInfo  masteringDisplayInfo;
    @nullable ContentLightLevel     contentLightLevel;
    @nullable Colorimetry           colorimetry;
    @nullable DolbyVisionLayerFlags dolbyVisionLayerFlags;
    @nullable Fraction              pixelAspectRatio;
    // Resolution / frameRate intentionally omitted — these are bitstream-driven
    // (SPS) on every modern codec; middleware shouldn't override them mid-stream.
}

Why per-buffer rather than a separate updateStreamConfig():

Coverage matrix

Scenario Solved by
Atomic initial config (the original #484 problem) Surface 1 — setStreamConfig()
ABR resolution / framerate change Already works — bitstream-derived (SPS), no API needed
ABR HDR profile change per DASH Period Surface 2 — per-buffer overrides
SSAI ad insertion (same codec, same encryption) Surface 2 — per-buffer overrides on the ad boundary frame
SSAI with codec or encryption-mode change Out of scope — decoder restart by middleware policy
Live→VOD transition Surface 2 — per-buffer overrides
In-stream HDR SEI changes Already works — decoder picks up from bitstream

Out of scope

  • Codec changes mid-stream — middleware orchestrates a teardown / IVideoDecoder.open() cycle.
  • Encryption-mode changes mid-stream (CENC → clear, etc.) — same. Decoder restart.
  • Audio-side equivalent — the same pattern likely applies for audiodecoder (ad with different audio codec / channel count) and audiomixer (input format changes). Worth raising as a parallel issue if there's interest — left out of this issue's scope to keep it focused on video.

Dependencies

Acceptance

Surface 1

  • VideoDecoderStreamConfig.aidl parcelable added under videodecoder/current/.
  • setStreamConfig(in VideoDecoderStreamConfig config) added to IVideoDecoderController, @pre State::READY.
  • Decision recorded on the existing 6 typed setters: keep as convenience aliases, or deprecate-and-remove. Documented in the AIDL doc-comments either way.
  • Regenerated C++ matches.
  • Build clean.
  • videodecoder/metadata.yaml version bumped per the subsume rule (likely generation since this is a structural addition + possible removal of the 6 setters; breaking).

Surface 2

Both

  • Tests / fixtures updated.
  • Documentation updated in videodecoder/current/docs/video_decoder.md.
  • Migration notes if the 6 typed setters are deprecated.

References

cc @shafi12 @hari22yuva @srinivasgtl

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    Resolved

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions