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
Surface 2
Both
References
cc @shafi12 @hari22yuva @srinivasgtl
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:Three weeks of discussion converged on a two-surface solution scoped by decoder lifecycle.
Proposed Solution — two surfaces
Surface 1 —
VideoDecoderStreamConfigparcelable (READY-state, atomic setup batching)A single all-optional parcelable that replaces the multi-call setup pattern.
nullfield = "no change" / "use existing default".Properties:
null)PropertyValueexpansionVideoDecoderResourceIndexneeded (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
InputBufferMetadatawith optional override fields:Why per-buffer rather than a separate
updateStreamConfig():decodeBufferWithMetadata()plumbing — no new methodCoverage matrix
setStreamConfig()Out of scope
IVideoDecoder.open()cycle.audiodecoder(ad with different audio codec / channel count) andaudiomixer(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.aidlparcelable added undervideodecoder/current/.setStreamConfig(in VideoDecoderStreamConfig config)added toIVideoDecoderController,@pre State::READY.videodecoder/metadata.yamlversion bumped per the subsume rule (likely generation since this is a structural addition + possible removal of the 6 setters; breaking).Surface 2
InputBufferMetadata.aidlextended with the 5 nullable override fields.Both
videodecoder/current/docs/video_decoder.md.References
setPixelAspectRatio()+ hint precedence. Dependency.pixelAspectRatiofield.colorimetryfield.cc @shafi12 @hari22yuva @srinivasgtl