PR #24429 opened by nyanmisaka
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24429
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24429.patch

# Summary of changes

Switch to using `ff_decode_{mastering_display,content_light}_new()`,
based on 6169bd0feaec518a6aacbb3497711052a707e3c2.

Otherwise, it will fail in `av_frame_side_data_clone()` during
subsequent video filter negotiation.

```
ffmpeg -hwaccel qsv -hwaccel_output_format qsv \
-c:v av1_qsv -i SAMPLE.mkv -an -sn -dn -f null -
...
[vf#0:0 @ 0000024bf775e740] Task finished with error code: -17 (File exists)
[vf#0:0 @ 0000024bf775e740] Terminating thread with return code -17 (File 
exists)
```

Fixes 473e84ad62a05e83bba5e00b4073980ee171a5bd

Signed-off-by: nyanmisaka <[email protected]>

Sample file: [SAMPLE.zip](/attachments/02caf9fd-a913-4c39-a5cc-de2fee263565), 
from [`Dolby Vision Profile 10 (Dolby Vision in 
AV1)`](https://kodi.wiki/view/Samples)

---

ffmpeg 7.1:
```
Stream mapping:
  Stream #0:0 -> #0:0 (av1 (av1_qsv) -> wrapped_avframe (native))
Press [q] to stop, [?] for help
[Parsed_showinfo_0 @ 000001cb525d14c0] config in time_base: 1/1000, frame_rate: 
24000/1001
[Parsed_showinfo_0 @ 000001cb525d14c0] config out time_base: 0/0, frame_rate: 
0/0
[Parsed_showinfo_0 @ 000001cb525d14c0] n:   0 pts:      0 pts_time:0       
duration:     41 duration_time:0.041   fmt:qsv cl:topleft sar:1/1 s:3840x1920 
i:P iskey:1 type:I checksum:00000000 plane_checksum:[00000000] mean:[] stdev:[]
[Parsed_showinfo_0 @ 000001cb525d14c0]   side data - Mastering display 
metadata: has_primaries:1 has_luminance:1 r(0.6800,0.3200) g(0.2650,0.6900) 
b(0.1500 0.0600) wp(0.3127, 0.3290) min_luminance=0.005000, 
max_luminance=1000.000000
[Parsed_showinfo_0 @ 000001cb525d14c0]   side data - Content light level 
metadata: MaxCLL=2010, MaxFALL=167
[Parsed_showinfo_0 @ 000001cb525d14c0]   side data - Mastering display 
metadata: has_primaries:1 has_luminance:1 r(0.6800,0.3200) g(0.2650,0.6900) 
b(0.1500 0.0600) wp(0.3127, 0.3290) min_luminance=0.005005, 
max_luminance=1000.000000
[Parsed_showinfo_0 @ 000001cb525d14c0]   side data - Content light level 
metadata: MaxCLL=2010, MaxFALL=167
[Parsed_showinfo_0 @ 000001cb525d14c0] color_range:tv color_space:bt2020nc 
color_primaries:bt2020 color_trc:smpte2084
```

ffmpeg 8.1~master:
```
Stream mapping:
  Stream #0:0 -> #0:0 (av1 (av1_qsv) -> wrapped_avframe (native))
Press [q] to stop, [?] for help
[vf#0:0 @ 0000018b2cd08540] Task finished with error code: -17 (File exists)
[vf#0:0 @ 0000018b2cd08540] Terminating thread with return code -17 (File 
exists)
[vost#0:0/wrapped_avframe @ 0000018b2e747840] [enc:wrapped_avframe @ 
0000018b2e747bc0] Could not open encoder before EOF
[vost#0:0/wrapped_avframe @ 0000018b2e747840] Task finished with error code: 
-22 (Invalid argument)
[vost#0:0/wrapped_avframe @ 0000018b2e747840] Terminating thread with return 
code -22 (Invalid argument)
[out#0/null @ 0000018b2cce5200] Nothing was written into output file, because 
at least one of its streams received no packets.
frame=    0 fps=0.0 q=0.0 Lsize=       0KiB time=N/A bitrate=N/A speed=N/A 
elapsed=0:00:00.19
Conversion failed!
```


>From 1072e498fb41efc342be92e567b2855c6d184289 Mon Sep 17 00:00:00 2001
From: nyanmisaka <[email protected]>
Date: Wed, 9 Sep 2026 21:07:01 +0800
Subject: [PATCH] avcodec/qsvdec: fix av1_qsv decoder exporting duplicate HDR
 side data

Switch to using `ff_decode_{mastering_display,content_light}_new()`,
based on 6169bd0feaec518a6aacbb3497711052a707e3c2.

Otherwise, it will fail in `av_frame_side_data_clone()` during
subsequent video filter negotiation.

```
ffmpeg -hwaccel qsv -hwaccel_output_format qsv \
-c:v av1_qsv -i SAMPLE.mkv -an -sn -dn -f null -
...
[vf#0:0 @ 0000024bf775e740] Task finished with error code: -17 (File exists)
[vf#0:0 @ 0000024bf775e740] Terminating thread with return code -17 (File 
exists)
```

Fixes 473e84ad62a05e83bba5e00b4073980ee171a5bd

Signed-off-by: nyanmisaka <[email protected]>
---
 libavcodec/qsvdec.c | 86 +++++++++++++++------------------------------
 1 file changed, 29 insertions(+), 57 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 5aacde9785..0f75a5a0ba 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -699,18 +699,36 @@ static int qsv_export_hdr_side_data(AVCodecContext 
*avctx, mfxExtMasteringDispla
 
     // The SDK reuses this flag for HDR SEI parsing
     if (mdcv->InsertPayloadToggle) {
-        AVMasteringDisplayMetadata *mastering;
-        const int mapping[3] = {2, 0, 1};
-        const int chroma_den = 50000;
-        const int luma_den = 10000;
-        int i;
+        AVMasteringDisplayMetadata *mastering = NULL;
+        int mapping[3] = { 0, 1, 2 };
+        int chroma_den;
+        int max_luma_den;
+        int min_luma_den;
+
+        switch (avctx->codec_id) {
+        case AV_CODEC_ID_HEVC:
+            mapping[0] = 2;
+            mapping[1] = 0;
+            mapping[2] = 1;
+            chroma_den = 50000;
+            max_luma_den = 10000;
+            min_luma_den = 10000;
+            break;
+        case AV_CODEC_ID_AV1:
+            chroma_den = 1 << 16;
+            max_luma_den = 1 << 8;
+            min_luma_den = 1 << 14;
+            break;
+        default:
+            return AVERROR(ENOSYS);
+        }
 
         ret = ff_decode_mastering_display_new(avctx, frame, &mastering);
         if (ret < 0)
             return ret;
 
         if (mastering) {
-            for (i = 0; i < 3; i++) {
+            for (int i = 0; i < 3; i++) {
                 const int j = mapping[i];
                 mastering->display_primaries[i][0] = 
av_make_q(mdcv->DisplayPrimariesX[j], chroma_den);
                 mastering->display_primaries[i][1] = 
av_make_q(mdcv->DisplayPrimariesY[j], chroma_den);
@@ -719,8 +737,8 @@ static int qsv_export_hdr_side_data(AVCodecContext *avctx, 
mfxExtMasteringDispla
             mastering->white_point[0] = av_make_q(mdcv->WhitePointX, 
chroma_den);
             mastering->white_point[1] = av_make_q(mdcv->WhitePointY, 
chroma_den);
 
-            mastering->max_luminance = 
av_make_q(mdcv->MaxDisplayMasteringLuminance, luma_den);
-            mastering->min_luminance = 
av_make_q(mdcv->MinDisplayMasteringLuminance, luma_den);
+            mastering->max_luminance = 
av_make_q(mdcv->MaxDisplayMasteringLuminance, max_luma_den);
+            mastering->min_luminance = 
av_make_q(mdcv->MinDisplayMasteringLuminance, min_luma_den);
 
             mastering->has_luminance = 1;
             mastering->has_primaries = 1;
@@ -729,7 +747,7 @@ static int qsv_export_hdr_side_data(AVCodecContext *avctx, 
mfxExtMasteringDispla
 
     // The SDK reuses this flag for HDR SEI parsing
     if (clli->InsertPayloadToggle) {
-        AVContentLightMetadata *light;
+        AVContentLightMetadata *light = NULL;
 
         ret = ff_decode_content_light_new(avctx, frame, &light);
         if (ret < 0)
@@ -743,46 +761,6 @@ static int qsv_export_hdr_side_data(AVCodecContext *avctx, 
mfxExtMasteringDispla
 
     return 0;
 }
-
-static int qsv_export_hdr_side_data_av1(AVCodecContext *avctx, 
mfxExtMasteringDisplayColourVolume *mdcv,
-                                        mfxExtContentLightLevelInfo *clli, 
AVFrame *frame)
-{
-    if (mdcv->InsertPayloadToggle) {
-        AVMasteringDisplayMetadata *mastering = 
av_mastering_display_metadata_create_side_data(frame);
-        const int chroma_den   = 1 << 16;
-        const int max_luma_den = 1 << 8;
-        const int min_luma_den = 1 << 14;
-
-        if (!mastering)
-            return AVERROR(ENOMEM);
-
-        for (int i = 0; i < 3; i++) {
-            mastering->display_primaries[i][0] = 
av_make_q(mdcv->DisplayPrimariesX[i], chroma_den);
-            mastering->display_primaries[i][1] = 
av_make_q(mdcv->DisplayPrimariesY[i], chroma_den);
-        }
-
-        mastering->white_point[0] = av_make_q(mdcv->WhitePointX, chroma_den);
-        mastering->white_point[1] = av_make_q(mdcv->WhitePointY, chroma_den);
-
-        mastering->max_luminance = 
av_make_q(mdcv->MaxDisplayMasteringLuminance, max_luma_den);
-        mastering->min_luminance = 
av_make_q(mdcv->MinDisplayMasteringLuminance, min_luma_den);
-
-        mastering->has_luminance = 1;
-        mastering->has_primaries = 1;
-    }
-
-    if (clli->InsertPayloadToggle) {
-        AVContentLightMetadata *light = 
av_content_light_metadata_create_side_data(frame);
-        if (!light)
-            return AVERROR(ENOMEM);
-
-        light->MaxCLL  = clli->MaxContentLightLevel;
-        light->MaxFALL = clli->MaxPicAverageLightLevel;
-    }
-
-    return 0;
-}
-
 #endif
 
 static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
@@ -909,15 +887,9 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
 #endif
 
 #if QSV_VERSION_ATLEAST(1, 35)
-        if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 35) && avctx->codec_id == 
AV_CODEC_ID_HEVC) {
+        if ((QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 35) && avctx->codec_id == 
AV_CODEC_ID_HEVC) ||
+            (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 2, 9)  && avctx->codec_id == 
AV_CODEC_ID_AV1)) {
             ret = qsv_export_hdr_side_data(avctx, &aframe.frame->mdcv, 
&aframe.frame->clli, frame);
-
-            if (ret < 0)
-                return ret;
-        }
-
-        if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 2, 9) && avctx->codec_id == 
AV_CODEC_ID_AV1) {
-            ret = qsv_export_hdr_side_data_av1(avctx, &aframe.frame->mdcv, 
&aframe.frame->clli, frame);
             if (ret < 0)
                 return ret;
         }
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to