Re: [PATCH RFC 0/7] media: qcom: iris: add support for decoding 10bit formats
From: Dmitry Baryshkov
Date: Sat Apr 11 2026 - 13:19:13 EST
On Fri, Apr 10, 2026 at 06:25:55PM +0200, Neil Armstrong wrote:
> On 4/10/26 14:00, Neil Armstrong wrote:
> > On 4/9/26 15:19, Nicolas Dufresne wrote:
> > > Le jeudi 09 avril 2026 à 09:36 +0200, Neil Armstrong a écrit :
> > > > Hi,
> > > >
> > > > On 4/9/26 03:04, Nicolas Dufresne wrote:
> > > > > Hi,
> > > > >
> > > > > Le jeudi 09 avril 2026 à 03:02 +0300, Dmitry Baryshkov a écrit :
> > > > > > On Wed, Apr 08, 2026 at 06:43:53PM +0200, Neil Armstrong wrote:
> > > > > > > This adds the plumbing to support decoding HEVC and AV1
> > > > > > > streams into 10bit pixel formats, linear and compressed.
> > > > > > >
> > > > > > > This has only been tested on SM8650 with HEVC, and was inspired by
> > > > > > > Venus and the downstream vidc driver for the buffer
> > > > > > > calculations and HFI messages.
> > > > > > >
> > > > > > > I was unable to get 10bit decoding working with Gstreamer
> > > > > > > and ffmpeg, but v4l2-ctl works with:
> > > > > >
> > > > > > Any particular errors? I assume Gstreamer needs to be taught about
> > > > > > Q10C. But P010 should (hopefully) work.
> > > > >
> > > > > P010 should work for both Gst and FFMPEG, its probably a user error, or there is
> > > > > a hidden bug in the driver that make it fail, v4l2-ctl is very permissive as it
> > > > > simply dump to disk. You should provide an updated fluster score, so you have to
> > > > > use one of these.
> > > >
> > > > I did run fluster and all main10 fails with Gstreamer and FFmpeg, I tried to manually
> > > > run the gst and ffmpeg commands with v4l2-tracer and logs but I can't explain the reason,
> > > > all returns from the driver seems valid but somehow they just error out with:
> > > >
> > > > FFmpeg:
> > > > $ ffmpeg -c:v hevc_v4l2m2m -i Big_Buck_Bunny_1080_10s_30MB_main10.h265 -y -f null -
> > > > ...
> > > > [hevc_v4l2m2m @ 0x55c0328aa0] Using device /dev/video-dec0
> > > > [hevc_v4l2m2m @ 0x55c0328aa0] driver 'iris_driver' on card 'iris_decoder' in mplane mode
> > > > [hevc_v4l2m2m @ 0x55c0328aa0] requesting formats: output=HEVC/none capture=NV12/yuv420p10le
> > > > ...
> > > > [hevc_v4l2m2m @ 0x55c0328aa0] An invalid frame was output by a decoder. This is a bug, please report it.
> > > > [vist#0:0/hevc @ 0x55c02dc9b0] [dec:hevc_v4l2m2m @ 0x55c029d510] Decoding error: Internal bug, should not have happened
> > > >
> > >
> > > This one needs further investigation for sure. This error can be various things,
> > > and it requires going up to the v4l2 code to figure-out:
> > >
> > >
> > > Case 1:
> > > if (!frame->buf[0] || frame->format < 0)
> > > goto fail;
> > >
> > > Case 2
> > > if (frame->width <= 0 || frame->height <= 0)
> > > goto fail;
> > >
> > > But a quick look lead me to think it case 1 (frame->format < 0) since I don't
> > > see P010 in the format map in ./libavcodec/v4l2_fmt.c (at least in mainline).
> > > Its also missing support for any opaque format, in fact I believe the DMABuf/DRM
> > > context is only in LibreELEC fork. But overall, it points toward ffmpeg for this
> > > error so far.
> >
> > Yeah I didn't find any ffmpeg for with P010 supported...
> >
> > >
> > >
> > > > The v4l2 trace shows a normal sequence with the driver returning P010 as G_FMT after the source change event,
> > > > and the capture planes dequeued but for an unknown reason the buffer is rejected by ffmpeg.
> > > >
> > > > Gst:
> > > > $ gst-launch-1.0 -v -m filesrc location=Big_Buck_Bunny_1080_10s_30MB_main10.h265 ! h265parse ! v4l2h265dec ! tee ! fakevideosink
> > > > Setting pipeline to PAUSED ...
> > > > Pipeline is PREROLLING ...
> > > > ...
> > > > Got message #37 from element "h265parse0" (latency): no message details
> > > > ERROR: from element /GstPipeline:pipeline0/GstH265Parse:h265parse0: Internal data stream error.
> > > > Redistribute latency...
> > > > Additional debug info:
> > > > ../gstreamer/subprojects/gstreamer/libs/gst/base/gstbaseparse.c(3702): gst_base_parse_loop (): /GstPipeline:pipeline0/GstH265Parse:h265parse0:
> > > > streaming stopped, reason not-negotiated (-4)
> > > > Got message #39 from pad "h265parse0:src" (property-notify): ERROR: pipeline doesn't want to preroll.
> > > > GstMessagePropertyNotify, property-name=(string)caps, property-value=(GstCaps)"video/x-h265\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ framerate\=\(fraction\)30/1\,\ chroma-format\=\(string\)4:2:0\,\ bit-depth-luma\=\(uint\)10\,\ bit-depth-chroma\=\(uint\)10\,\ parsed\=\(boolean\)true\,\ stream-format\=\(string\)byte-stream\,\ alignment\=\(string\)au\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ profile\=\(string\)main-10\,\ tier\=\(string\)main\,\ level\=\(string\)4";
> > > > /GstPipeline:pipeline0/GstH265Parse:h265parse0.GstPad:src: caps = video/x-h265, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, chroma-format=(string)4:2:0, bit-depth-luma=(uint)10, bit-depth-chroma=(uint)10, parsed=(boolean)true, stream-format=(string)byte-stream, alignment=(string)au, pixel-aspect-ratio=(fraction)1/1, profile=(string)main-10, tier=(string)main, level=(string)4
> > > > ...
> > >
> > > There is not a lot of details here, but I would start looking into
> > > V4L2_CID_MPEG_VIDEO_HEVC_PROFILE and V4L2_CID_MPEG_VIDEO_HEVC_LEVEL
> > > implementation. GStreamer (and Chromium too) will refuse to use a decoder that
> > > does not advertise the supported profile (though I see there is code for that,
> > > maybe its just some bug).
> > >
> > > >
> > > > In this case OUTPUT is not STREAMON and no OUTPUT buffers are queued, so I wonder why this one fails....
> > > >
> > > > My gstreamer and ffmpeg foo is bad and I probably missed something obvious...
> > > >
> > > >
> > > You may get a different hint with more traces, just enabling general warnings:
> > >
> > > export GST_DEBUG=2
> > >
> > > Or the full V4L2 traces too:
> > >
> > > export GST_DEBUG="v4l2*:7,2"
> > >
> > >
> > > I'm sure its just a bug (or two). Happy to help to find it.
> >
> > You were right, this did the trick:
> > diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> > index a9cdd93e77fd..debdd30a751e 100644
> > --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> > +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> > @@ -56,9 +56,10 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = {
> > {
> > .cap_id = PROFILE_HEVC,
> > .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
> > - .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE,
> > + .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
> > .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
> > - BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE),
> > + BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) |
> > + BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10),
> > .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
> > .hfi_id = HFI_PROP_PROFILE,
> > .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> >
> > But the gstreamer I'm using is too old and doesn't support P010... updating but it should work now,
> > and I'll test the QC10 in the same time.
>
> Tested with gstreamer git, it works fine now with P010.
>
> But I applied the QC10 change, but how am I supposed to test it ?
>
> The QC formats seems to be detected and the right modifier is used:
> 0:00:07.231474967 296677 296852 INFO v4l2 gstv4l2object.c:5544:gst_v4l2_object_probe_caps:<v4l2h265dec0:src> probed caps: video/x-raw(memory:DMABuf), format=(string)DMA_DRM, drm-format=(string){ NV12:0x0500000000000001, NV12 }, width=(int)[ 96, 8192 ], height=(int)[ 96, 8192 ], framerate=(fraction)[ 0/1, 2147483647/1 ], pixel-aspect-ratio=(fraction)1/1, colorimetry=(string){ bt601, 1:4:16:3, smpte240m, bt709, 1:3:5:1, 2:4:5:2, 2:4:5:3, 1:4:5:3, 1:4:7:1, 2:4:7:1, 2:4:12:8, bt2020, bt2100-pq, 2:0:0:0 }; video/x-raw, format=(string)NV12, width=(int)[ 96, 8192 ], height=(int)[ 96, 8192 ], framerate=(fraction)[ 0/1, 2147483647/1 ], pixel-aspect-ratio=(fraction)1/1, colorimetry=(string){ bt601, 1:4:16:3, smpte240m, bt709, 1:3:5:1, 2:4:5:2, 2:4:5:3, 1:4:5:3, 1:4:7:1, 2:4:7:1, 2:4:12:8, bt2020, bt2100-pq, 2:0:0:0 }; video/x-raw(memory:DMABuf), format=(string)DMA_DRM, drm-format=(string){ NV12:0x0500000000000001, NV12 }, width=(int)[ 96, 8192 ], height=(int)[ 96, 8192 ], framerate=(fraction)[ 0/1, 2147483647/1 ], pixel-aspect-ratio=(fraction)1/1; video/x-raw, format=(string)NV12, width=(int)[ 96, 8192 ], height=(int)[ 96, 8192 ], framerate=(fraction)[ 0/1, 2147483647/1 ], pixel-aspect-ratio=(fraction)1/1
> 0:00:07.224200523 304189 304365 INFO v4l2 gstv4l2object.c:5544:gst_v4l2_object_probe_caps:<v4l2h265dec0:src> probed caps: video/x-raw(memory:DMABuf), format=(string)DMA_DRM, drm-format=(string){ P010, P010:0x0500000000000001 }, width=(int)[ 96, 8192 ], height=(int)[ 96, 8192 ], framerate=(fraction)[ 0/1, 2147483647/1 ], pixel-aspect-ratio=(fraction)1/1, colorimetry=(string){ bt601, 1:4:16:3, smpte240m, bt709, 1:3:5:1, 2:4:5:2, 2:4:5:3, 1:4:5:3, 1:4:7:1, 2:4:7:1, 2:4:12:8, bt2020, bt2100-pq, 2:0:0:0 }; video/x-raw, format=(string)P010_10LE, width=(int)[ 96, 8192 ], height=(int)[ 96, 8192 ], framerate=(fraction)[ 0/1, 2147483647/1 ], pixel-aspect-ratio=(fraction)1/1, colorimetry=(string){ bt601, 1:4:16:3, smpte240m, bt709, 1:3:5:1, 2:4:5:2, 2:4:5:3, 1:4:5:3, 1:4:7:1, 2:4:7:1, 2:4:12:8, bt2020, bt2100-pq, 2:0:0:0 }; video/x-raw(memory:DMABuf), format=(string)DMA_DRM, drm-format=(string){ P010, P010:0x0500000000000001 }, width=(int)[ 96, 8192 ], height=(int)[ 96, 8192 ], framerate=(fraction)[ 0/1, 2147483647/1 ], pixel-aspect-ratio=(fraction)1/1; video/x-raw, format=(string)P010_10LE, width=(int)[ 96, 8192 ], height=(int)[ 96, 8192 ], framerate=(fraction)[ 0/1, 2147483647/1 ], pixel-aspect-ratio=(fraction)1/1
>
> But what's the proper way to validate ? I've been unable to run kmssink so far.
Unfrotunately the easiest way would be to get it to work with the
kmssink (or to dump the raw buffers and then get them displayed
manually).
--
With best wishes
Dmitry