Re: [PATCH RFC 1/2] media: docs: Clarify V4L2_FMT_FLAG_DYN_RESOLUTION usage

From: Nicolas Dufresne

Date: Wed Jun 10 2026 - 10:02:06 EST


Le mercredi 10 juin 2026 à 08:15 +0200, Hans Verkuil a écrit :
> > The more natural fix would be to add V4L2_EVENT_SOURCE_CHANGE for the
> > initial resolution case as well, then properly report
> > V4L2_FMT_FLAG_DYN_RESOLUTION through VIDIOC_ENUM_FMT. If all existing
> > drivers that support mid-stream DRC can similarly be updated to fire the
> > event for initial resolution, then perhaps the spec change to split the
> > flag isn't strictly necessary - drivers just need to be fixed to comply
> > with the current definition.
> >
> > I'd appreciate hearing others' thoughts on whether this unified approach
> > is practical across all existing drivers.
>
> Just a quick reply to mention that the s5p-mfc driver predates a lot of the
> newer uAPIs for stateful codecs. It's why it behaves in a not-quite-standard
> way. So there is history here. The resolution change support was added in
> commit 0520e4cc3bb9d back in 2014, three years after the driver was first
> added to the kernel. The stateful decoder spec as we have today was only
> introduced in 2019.

Fair point. Now, some clarification about the initial event. When this was re-
implemented in GStreamer, we explicitly don't prepare the capture queue (no
REQBUFS/CREATE_BUF, its not streaming). So effectively, the driver is forced to
start with only the output queue, and that was assumed to force the initial
event. The src_ch event indicates that the driver is stuck until the capture
queue has been reconfigured (or configured in this cased).

I think you make a good point that this is not very clearly stated, but it was
also intentional to use that flag as a boundary before expecting this very
strict behaviour. From a HW stand point, it does make quite some sense, since
the parsing of header and discovery should happen separately from the capture
buffer requirement. This is the main difference between stateless and stateful.
In userspace, this workflow allowed to better decouple the output and capture
threads, which very typically is a independent threads (true for GStreamer and
Chromium at minimum).

In the legacy path in gstreamer, the capture queue format is guessed, allocated
and set to streaming. In that case, the driver only have to emit the initial
event if the capture queue configuration miss-match its requirements. I believe
that was done so it aligned with some legacy flow. In theory this should work
with earlier implementation of SOURCE_CHANGE, but remains a best effort. CODA960
being the only legacy implementation I kept testing over time. With CODA today,
if the guessed allocation failed, everything fails, which seems to be a bug or
limitation from you analyses. Fixing it can be tricky, as we need to ensure we
maintain backward compatibility with older userspace. Specially for CODA which
is massively deployed. A lot of strangeness in CODA comes from its reversed
engineered nature. Note that, I do have spec for this one these days, and can
answer questions. I do know that we actually get a subset of the SPS, which
should fully cover the needs for the DYN_RESOLUTION.

The thing that also comes with V4L2_FMT_FLAG_DYN_RESOLUTION, is also the drain
flow. There was just no drain flow prior to this and the matching decoder spec.
So to drain the capture queue on SOURCE_CHANGE, we had to track the state of the
queue, and avoid going back into polling once the queue was drained (since
polling previously blocked). That tracking have simply never been implemented in
GStreamer. The only legacy draining flow we had, was the infamous zero sized
buffer, which was ambiguous, since there was 3 possibilities instead of 2:

- Failed decode
- Failed decode and drained
- Drained

If a decode failed at entropy decode, the resulting failed buffer would be
signalled and confused with the drain. And so the other infamous LAST flag was
added. But then MFC signals the drain state independently, not at the same time
as the last buffer, and so EPIPE on DQBUF was introduced. With the new spec, we
forced this drain flow onto both draining on end-of-stream (CMD_STOP) and to
happen somewhere after any SOURCE_CHANGE, and if you use
V4L2_FMT_FLAG_DYN_RESOLUTION you must follow the DRC flow from the new spec.

I don't know if sharing the drain mechanism for DRC and actual CMD_STOP was the
best idea in the world, but it is what is it now, and for sure, old or
unmaintained drivers endup with highly inconsistent state. I'm happy with the
idea to improve the spec, and to improve the drivers concistency too, as long as
we can actually test, since it too complex to change without testing. I think,
if something could help, it would be to implement couple of the legacy flow in
vivid driver, so we could test virtually.

Nicolas

Attachment: signature.asc
Description: This is a digitally signed message part