Loading...
Searching...
No Matches
GStreamerCompatibility.hpp
1#pragma once
2#include <Media/Libav.hpp>
3#if SCORE_HAS_LIBAV
4#include <ossia/detail/hash_map.hpp>
5
6#include <QDebug>
7
8#include <score_plugin_media_export.h>
9
10#include <array>
11#include <string>
12#include <string_view>
13
14extern "C" {
15#include <libavformat/avformat.h>
16#include <libavutil/imgutils.h>
17#include <libavutil/pixdesc.h>
18}
19
20namespace Video
21{
22
23inline const ossia::hash_map<std::string, AVPixelFormat>& gstreamerToLibav()
24{
25 static const auto map = [] {
26 ossia::hash_map<std::string, AVPixelFormat> format_map;
27
28 /*
29 * @GST_VIDEO_FORMAT_I420: planar 4:2:0 YUV
30 * @GST_VIDEO_FORMAT_YV12: planar 4:2:0 YVU (like I420 but UV planes swapped)
31 * @GST_VIDEO_FORMAT_YUY2: packed 4:2:2 YUV (Y0-U0-Y1-V0 Y2-U2-Y3-V2 Y4 ...)
32 * @GST_VIDEO_FORMAT_UYVY: packed 4:2:2 YUV (U0-Y0-V0-Y1 U2-Y2-V2-Y3 U4 ...)
33 * @GST_VIDEO_FORMAT_VYUY: packed 4:2:2 YUV (V0-Y0-U0-Y1 V2-Y2-U2-Y3 V4 ...)
34 * @GST_VIDEO_FORMAT_AYUV: packed 4:4:4 YUV with alpha channel (A0-Y0-U0-V0 ...)
35 * @GST_VIDEO_FORMAT_RGBx: sparse rgb packed into 32 bit, space last
36 * @GST_VIDEO_FORMAT_BGRx: sparse reverse rgb packed into 32 bit, space last
37 * @GST_VIDEO_FORMAT_xRGB: sparse rgb packed into 32 bit, space first
38 * @GST_VIDEO_FORMAT_xBGR: sparse reverse rgb packed into 32 bit, space first
39 * @GST_VIDEO_FORMAT_RGBA: rgb with alpha channel last
40 * @GST_VIDEO_FORMAT_BGRA: reverse rgb with alpha channel last
41 * @GST_VIDEO_FORMAT_ARGB: rgb with alpha channel first
42 * @GST_VIDEO_FORMAT_ABGR: reverse rgb with alpha channel first
43 * @GST_VIDEO_FORMAT_RGB: RGB packed into 24 bits without padding (`R-G-B-R-G-B`)
44 * @GST_VIDEO_FORMAT_BGR: reverse RGB packed into 24 bits without padding (`B-G-R-B-G-R`)
45 * @GST_VIDEO_FORMAT_Y41B: planar 4:1:1 YUV
46 * @GST_VIDEO_FORMAT_Y42B: planar 4:2:2 YUV
47 * @GST_VIDEO_FORMAT_YVYU: packed 4:2:2 YUV (Y0-V0-Y1-U0 Y2-V2-Y3-U2 Y4 ...)
48 * @GST_VIDEO_FORMAT_Y444: planar 4:4:4 YUV
49 * @GST_VIDEO_FORMAT_v210: packed 4:2:2 10-bit YUV, complex format
50 * @GST_VIDEO_FORMAT_v216: packed 4:2:2 16-bit YUV, Y0-U0-Y1-V1 order
51 * @GST_VIDEO_FORMAT_NV12: planar 4:2:0 YUV with interleaved UV plane
52 * @GST_VIDEO_FORMAT_NV21: planar 4:2:0 YUV with interleaved VU plane
53 * @GST_VIDEO_FORMAT_NV12_10LE32: 10-bit variant of @GST_VIDEO_FORMAT_NV12, packed into 32bit words (MSB 2 bits padding) (Since: 1.14)
54 * @GST_VIDEO_FORMAT_GRAY8: 8-bit grayscale
55 * @GST_VIDEO_FORMAT_GRAY10_LE32: 10-bit grayscale, packed into 32bit words (2 bits padding) (Since: 1.14)
56 * @GST_VIDEO_FORMAT_GRAY16_BE: 16-bit grayscale, most significant byte first
57 * @GST_VIDEO_FORMAT_GRAY16_LE: 16-bit grayscale, least significant byte first
58 * @GST_VIDEO_FORMAT_v308: packed 4:4:4 YUV (Y-U-V ...)
59 * @GST_VIDEO_FORMAT_IYU2: packed 4:4:4 YUV (U-Y-V ...) (Since: 1.10)
60 * @GST_VIDEO_FORMAT_RGB16: rgb 5-6-5 bits per component
61 * @GST_VIDEO_FORMAT_BGR16: reverse rgb 5-6-5 bits per component
62 * @GST_VIDEO_FORMAT_RGB15: rgb 5-5-5 bits per component
63 * @GST_VIDEO_FORMAT_BGR15: reverse rgb 5-5-5 bits per component
64 * @GST_VIDEO_FORMAT_UYVP: packed 10-bit 4:2:2 YUV (U0-Y0-V0-Y1 U2-Y2-V2-Y3 U4 ...)
65 * @GST_VIDEO_FORMAT_A420: planar 4:4:2:0 AYUV
66 * @GST_VIDEO_FORMAT_RGB8P: 8-bit paletted RGB
67 * @GST_VIDEO_FORMAT_YUV9: planar 4:1:0 YUV
68 * @GST_VIDEO_FORMAT_YVU9: planar 4:1:0 YUV (like YUV9 but UV planes swapped)
69 * @GST_VIDEO_FORMAT_IYU1: packed 4:1:1 YUV (Cb-Y0-Y1-Cr-Y2-Y3 ...)
70 * @GST_VIDEO_FORMAT_ARGB64: rgb with alpha channel first, 16 bits per channel
71 * @GST_VIDEO_FORMAT_AYUV64: packed 4:4:4 YUV with alpha channel, 16 bits per channel (A0-Y0-U0-V0 ...)
72 * @GST_VIDEO_FORMAT_r210: packed 4:4:4 RGB, 10 bits per channel
73 * @GST_VIDEO_FORMAT_I420_10BE: planar 4:2:0 YUV, 10 bits per channel
74 * @GST_VIDEO_FORMAT_I420_10LE: planar 4:2:0 YUV, 10 bits per channel
75 * @GST_VIDEO_FORMAT_I422_10BE: planar 4:2:2 YUV, 10 bits per channel
76 * @GST_VIDEO_FORMAT_I422_10LE: planar 4:2:2 YUV, 10 bits per channel
77 * @GST_VIDEO_FORMAT_Y444_10BE: planar 4:4:4 YUV, 10 bits per channel (Since: 1.2)
78 * @GST_VIDEO_FORMAT_Y444_10LE: planar 4:4:4 YUV, 10 bits per channel (Since: 1.2)
79 * @GST_VIDEO_FORMAT_GBR: planar 4:4:4 RGB, 8 bits per channel (Since: 1.2)
80 * @GST_VIDEO_FORMAT_GBR_10BE: planar 4:4:4 RGB, 10 bits per channel (Since: 1.2)
81 * @GST_VIDEO_FORMAT_GBR_10LE: planar 4:4:4 RGB, 10 bits per channel (Since: 1.2)
82 * @GST_VIDEO_FORMAT_NV16: planar 4:2:2 YUV with interleaved UV plane (Since: 1.2)
83 * @GST_VIDEO_FORMAT_NV16_10LE32: 10-bit variant of @GST_VIDEO_FORMAT_NV16, packed into 32bit words (MSB 2 bits padding) (Since: 1.14)
84 * @GST_VIDEO_FORMAT_NV24: planar 4:4:4 YUV with interleaved UV plane (Since: 1.2)
85 * @GST_VIDEO_FORMAT_NV12_64Z32: NV12 with 64x32 tiling in zigzag pattern (Since: 1.4)
86 * @GST_VIDEO_FORMAT_A420_10BE: planar 4:4:2:0 YUV, 10 bits per channel (Since: 1.6)
87 * @GST_VIDEO_FORMAT_A420_10LE: planar 4:4:2:0 YUV, 10 bits per channel (Since: 1.6)
88 * @GST_VIDEO_FORMAT_A422_10BE: planar 4:4:2:2 YUV, 10 bits per channel (Since: 1.6)
89 * @GST_VIDEO_FORMAT_A422_10LE: planar 4:4:2:2 YUV, 10 bits per channel (Since: 1.6)
90 * @GST_VIDEO_FORMAT_A444_10BE: planar 4:4:4:4 YUV, 10 bits per channel (Since: 1.6)
91 * @GST_VIDEO_FORMAT_A444_10LE: planar 4:4:4:4 YUV, 10 bits per channel (Since: 1.6)
92 * @GST_VIDEO_FORMAT_NV61: planar 4:2:2 YUV with interleaved VU plane (Since: 1.6)
93 * @GST_VIDEO_FORMAT_P010_10BE: planar 4:2:0 YUV with interleaved UV plane, 10 bits per channel (Since: 1.10)
94 * @GST_VIDEO_FORMAT_P010_10LE: planar 4:2:0 YUV with interleaved UV plane, 10 bits per channel (Since: 1.10)
95 * @GST_VIDEO_FORMAT_GBRA: planar 4:4:4:4 ARGB, 8 bits per channel (Since: 1.12)
96 * @GST_VIDEO_FORMAT_GBRA_10BE: planar 4:4:4:4 ARGB, 10 bits per channel (Since: 1.12)
97 * @GST_VIDEO_FORMAT_GBRA_10LE: planar 4:4:4:4 ARGB, 10 bits per channel (Since: 1.12)
98 * @GST_VIDEO_FORMAT_GBR_12BE: planar 4:4:4 RGB, 12 bits per channel (Since: 1.12)
99 * @GST_VIDEO_FORMAT_GBR_12LE: planar 4:4:4 RGB, 12 bits per channel (Since: 1.12)
100 * @GST_VIDEO_FORMAT_GBRA_12BE: planar 4:4:4:4 ARGB, 12 bits per channel (Since: 1.12)
101 * @GST_VIDEO_FORMAT_GBRA_12LE: planar 4:4:4:4 ARGB, 12 bits per channel (Since: 1.12)
102 * @GST_VIDEO_FORMAT_I420_12BE: planar 4:2:0 YUV, 12 bits per channel (Since: 1.12)
103 * @GST_VIDEO_FORMAT_I420_12LE: planar 4:2:0 YUV, 12 bits per channel (Since: 1.12)
104 * @GST_VIDEO_FORMAT_I422_12BE: planar 4:2:2 YUV, 12 bits per channel (Since: 1.12)
105 * @GST_VIDEO_FORMAT_I422_12LE: planar 4:2:2 YUV, 12 bits per channel (Since: 1.12)
106 * @GST_VIDEO_FORMAT_Y444_12BE: planar 4:4:4 YUV, 12 bits per channel (Since: 1.12)
107 * @GST_VIDEO_FORMAT_Y444_12LE: planar 4:4:4 YUV, 12 bits per channel (Since: 1.12)
108 * @GST_VIDEO_FORMAT_NV12_10LE40: Fully packed variant of NV12_10LE32 (Since: 1.16)
109 * @GST_VIDEO_FORMAT_Y210: packed 4:2:2 YUV, 10 bits per channel (Since: 1.16)
110 * @GST_VIDEO_FORMAT_Y410: packed 4:4:4 YUV, 10 bits per channel(A-V-Y-U...) (Since: 1.16)
111 * @GST_VIDEO_FORMAT_VUYA: packed 4:4:4 YUV with alpha channel (V0-U0-Y0-A0...) (Since: 1.16)
112 * @GST_VIDEO_FORMAT_BGR10A2_LE: packed 4:4:4 RGB with alpha channel(B-G-R-A), 10 bits for R/G/B channel and MSB 2 bits for alpha channel (Since: 1.16)
113 * @GST_VIDEO_FORMAT_RGB10A2_LE: packed 4:4:4 RGB with alpha channel(R-G-B-A), 10 bits for R/G/B channel and MSB 2 bits for alpha channel (Since: 1.18)
114 * @GST_VIDEO_FORMAT_Y444_16BE: planar 4:4:4 YUV, 16 bits per channel (Since: 1.18)
115 * @GST_VIDEO_FORMAT_Y444_16LE: planar 4:4:4 YUV, 16 bits per channel (Since: 1.18)
116 * @GST_VIDEO_FORMAT_P016_BE: planar 4:2:0 YUV with interleaved UV plane, 16 bits per channel (Since: 1.18)
117 * @GST_VIDEO_FORMAT_P016_LE: planar 4:2:0 YUV with interleaved UV plane, 16 bits per channel (Since: 1.18)
118 * @GST_VIDEO_FORMAT_P012_BE: planar 4:2:0 YUV with interleaved UV plane, 12 bits per channel (Since: 1.18)
119 * @GST_VIDEO_FORMAT_P012_LE: planar 4:2:0 YUV with interleaved UV plane, 12 bits per channel (Since: 1.18)
120 * @GST_VIDEO_FORMAT_Y212_BE: packed 4:2:2 YUV, 12 bits per channel (Y-U-Y-V) (Since: 1.18)
121 * @GST_VIDEO_FORMAT_Y212_LE: packed 4:2:2 YUV, 12 bits per channel (Y-U-Y-V) (Since: 1.18)
122 * @GST_VIDEO_FORMAT_Y412_BE: packed 4:4:4:4 YUV, 12 bits per channel(U-Y-V-A...) (Since: 1.18)
123 * @GST_VIDEO_FORMAT_Y412_LE: packed 4:4:4:4 YUV, 12 bits per channel(U-Y-V-A...) (Since: 1.18)
124 * @GST_VIDEO_FORMAT_NV12_4L4: NV12 with 4x4 tiles in linear order (Since: 1.18)
125 * @GST_VIDEO_FORMAT_NV12_32L32: NV12 with 32x32 tiles in linear order (Since: 1.18)
126 * @GST_VIDEO_FORMAT_RGBP: planar 4:4:4 RGB, 8 bits per channel (Since: 1.20)
127 * @GST_VIDEO_FORMAT_BGRP: planar 4:4:4 RGB, 8 bits per channel (Since: 1.20)
128 * @GST_VIDEO_FORMAT_AV12: Planar 4:2:0 YUV with interleaved UV plane with alpha as 3rd plane (Since: 1.20)
129 */
130
131 format_map["A420"] = AV_PIX_FMT_YUVA420P;
132 format_map["A420_10BE"] = AV_PIX_FMT_YUVA420P10BE;
133 format_map["A420_10LE"] = AV_PIX_FMT_YUVA420P10LE;
134 format_map["A422_10BE"] = AV_PIX_FMT_YUVA422P10BE;
135 format_map["A422_10LE"] = AV_PIX_FMT_YUVA422P10LE;
136 format_map["A444_10BE"] = AV_PIX_FMT_YUVA444P10BE;
137 format_map["A444_10LE"] = AV_PIX_FMT_YUVA444P10LE;
138 format_map["ABGR"] = AV_PIX_FMT_ABGR;
139 // format_map["ABGR64_BE"] = AV_PIX_FMT_ABGR64BE;
140 // format_map["ABGR64_LE"] = AV_PIX_FMT_ABGR64LE;
141 format_map["ARGB"] = AV_PIX_FMT_ARGB;
142 // format_map["ARGB64"] = AV_PIX_FMT_ARGB64;
143 // format_map["ARGB64_BE"] = AV_PIX_FMT_ARGB64BE;
144 // format_map["ARGB64_LE"] = AV_PIX_FMT_ARGB64LE;
145 // format_map["AV12"] = AV_PIX_FMT_AV12;
146 // format_map["AYUV"] = AV_PIX_FMT_AYUV;
147 format_map["AYUV64"] = AV_PIX_FMT_AYUV64;
148 // format_map["BGR"] = AV_PIX_FMT_BGR;
149 // format_map["BGR10A2_LE"] = AV_PIX_FMT_BGR10A2LE;
150 // format_map["BGR15"] = AV_PIX_FMT_BGR15;
151 // format_map["BGR16"] = AV_PIX_FMT_BGR16;
152 format_map["BGRA"] = AV_PIX_FMT_BGRA;
153 // format_map["BGRA64_BE"] = AV_PIX_FMT_BGRA64BE;
154 // format_map["BGRA64_LE"] = AV_PIX_FMT_BGRA64LE;
155 // format_map["BGRP"] = AV_PIX_FMT_BGRP;
156 format_map["BGRx"] = AV_PIX_FMT_BGR0;
157 // format_map["ENCODED"] = AV_PIX_FMT_ENCODED;
158 format_map["GBR"] = AV_PIX_FMT_GBRP;
159 format_map["GBRA"] = AV_PIX_FMT_GBRAP;
160 // format_map["GBRA_10BE"] = AV_PIX_FMT_GBRA_10BE;
161 // format_map["GBRA_10LE"] = AV_PIX_FMT_GBRA_10LE;
162 // format_map["GBRA_12BE"] = AV_PIX_FMT_GBRA_12BE;
163 // format_map["GBRA_12LE"] = AV_PIX_FMT_GBRA_12LE;
164 // format_map["GBR_10BE"] = AV_PIX_FMT_GBR_10BE;
165 // format_map["GBR_10LE"] = AV_PIX_FMT_GBR_10LE;
166 // format_map["GBR_12BE"] = AV_PIX_FMT_GBR_12BE;
167 // format_map["GBR_12LE"] = AV_PIX_FMT_GBR_12LE;
168 // format_map["GRAY10_LE32"] = AV_PIX_FMT_GRAY10_LE32;
169 format_map["GRAY16_BE"] = AV_PIX_FMT_GRAY16BE;
170 format_map["GRAY16_LE"] = AV_PIX_FMT_GRAY16LE;
171 format_map["GRAY8"] = AV_PIX_FMT_GRAY8;
172 format_map["I420"] = AV_PIX_FMT_YUV420P;
173 format_map["I420_10BE"] = AV_PIX_FMT_YUV420P10BE;
174 format_map["I420_10LE"] = AV_PIX_FMT_YUV420P10LE;
175 format_map["I420_12BE"] = AV_PIX_FMT_YUV420P12BE;
176 format_map["I420_12LE"] = AV_PIX_FMT_YUV420P12LE;
177 format_map["I422_10BE"] = AV_PIX_FMT_YUV422P10BE;
178 format_map["I422_10LE"] = AV_PIX_FMT_YUV422P10LE;
179 format_map["I422_12BE"] = AV_PIX_FMT_YUV422P12BE;
180 format_map["I422_12LE"] = AV_PIX_FMT_YUV422P12LE;
181 // format_map["IYU1"] = AV_PIX_FMT_IYU1;
182 // format_map["IYU2"] = AV_PIX_FMT_IYU2;
183 format_map["NV12"] = AV_PIX_FMT_NV12;
184 // format_map["NV12_10LE32"] = AV_PIX_FMT_NV12_10LE32;
185 // format_map["NV12_10LE40"] = AV_PIX_FMT_NV12_10LE40;
186 // format_map["NV12_32L32"] = AV_PIX_FMT_NV12_32L32;
187 // format_map["NV12_4L4"] = AV_PIX_FMT_NV12_4L4;
188 // format_map["NV12_64Z32"] = AV_PIX_FMT_NV12_64Z32;
189 format_map["NV16"] = AV_PIX_FMT_NV16;
190 // format_map["NV16_10LE32"] = AV_PIX_FMT_NV16_10LE32;
191 format_map["NV21"] = AV_PIX_FMT_NV21;
192 format_map["NV24"] = AV_PIX_FMT_NV24;
193 // format_map["NV61"] = AV_PIX_FMT_NV61;
194 format_map["P010_10BE"] = AV_PIX_FMT_P010BE;
195 format_map["P010_10LE"] = AV_PIX_FMT_P010LE;
196 // format_map["P012_BE"] = AV_PIX_FMT_P012BE;
197 // format_map["P012_LE"] = AV_PIX_FMT_P012LE;
198 format_map["P016_BE"] = AV_PIX_FMT_P016BE;
199 format_map["P016_LE"] = AV_PIX_FMT_P016LE;
200 // format_map["R210"] = AV_PIX_FMT_R210;
201 format_map["RGB"] = AV_PIX_FMT_RGB24;
202 // format_map["RGB10A2_LE"] = AV_PIX_FMT_RGB10A2LE;
203 // format_map["RGB15"] = AV_PIX_FMT_RGB15;
204 // format_map["RGB16"] = AV_PIX_FMT_RGB16;
205 // format_map["RGB8P"] = AV_PIX_FMT_RGB8P;
206 format_map["RGBA"] = AV_PIX_FMT_RGBA;
207 format_map["RGBA64_BE"] = AV_PIX_FMT_RGBA64BE;
208 format_map["RGBA64_LE"] = AV_PIX_FMT_RGBA64LE;
209 // GStreamer RGBP is PLANAR: three separate R, G, B planes. libav has no
210 // R-G-B plane order, only GBRP -- see gstreamerPlaneOrder().
211 format_map["RGBP"] = AV_PIX_FMT_GBRP;
212 format_map["RGBx"] = AV_PIX_FMT_RGB0;
213 // format_map["UNKNOWN"] = AV_PIX_FMT_UNKNOWN;
214 // format_map["UYVP"] = AV_PIX_FMT_UYVP;
215 format_map["UYVY"] = AV_PIX_FMT_UYVY422;
216 // format_map["V210"] = AV_PIX_FMT_V210;
217 // format_map["V216"] = AV_PIX_FMT_V216;
218 // format_map["V308"] = AV_PIX_FMT_V308;
219 // format_map["VUYA"] = AV_PIX_FMT_VUYA;
220 // format_map["VYUY"] = AV_PIX_FMT_VYUY;
221 format_map["xBGR"] = AV_PIX_FMT_0BGR;
222 format_map["xRGB"] = AV_PIX_FMT_0RGB;
223 format_map["Y210"] = AV_PIX_FMT_Y210;
224 // format_map["Y212_BE"] = AV_PIX_FMT_Y212BE;
225 // format_map["Y212_LE"] = AV_PIX_FMT_Y212LE;
226 // GStreamer Y410 is PACKED 4:4:4 10-bit (A-V-Y-U in one 32-bit word).
227 // AV_PIX_FMT_XV30 is libav's name for it with the alpha left undefined;
228 // AV_PIX_FMT_YUV410P is planar 4:1:0 8-bit, i.e. GStreamer "YUV9".
229#if defined(AV_PIX_FMT_XV30)
230 format_map["Y410"] = AV_PIX_FMT_XV30;
231#endif
232 // format_map["Y412_BE"] = AV_PIX_FMT_Y412BE;
233 // format_map["Y412_LE"] = AV_PIX_FMT_Y412LE;
234 format_map["Y41B"] = AV_PIX_FMT_YUV411P;
235 format_map["Y42B"] = AV_PIX_FMT_YUV422P;
236 format_map["Y444"] = AV_PIX_FMT_YUV444P;
237 format_map["Y444_10BE"] = AV_PIX_FMT_YUV444P10BE;
238 format_map["Y444_10LE"] = AV_PIX_FMT_YUV444P10LE;
239 format_map["Y444_12BE"] = AV_PIX_FMT_YUV444P12BE;
240 format_map["Y444_12LE"] = AV_PIX_FMT_YUV444P12LE;
241 format_map["Y444_16BE"] = AV_PIX_FMT_YUV444P16BE;
242 format_map["Y444_16LE"] = AV_PIX_FMT_YUV444P16LE;
243 // format_map["YUV9"] = AV_PIX_FMT_YUV9;
244 format_map["YUY2"] = AV_PIX_FMT_YUYV422;
245 // format_map["YV12"] = AV_PIX_FMT_YV12;
246 // format_map["YVU9"] = AV_PIX_FMT_YVU9;
247 format_map["YVYU"] = AV_PIX_FMT_YVYU422;
248
249 return format_map;
250 }();
251
252 return map;
253}
254
255// Where libav plane N lives in the GStreamer buffer, when the two disagree on
256// plane ORDER for the same set of planes. Identity for every format whose only
257// libav counterpart already agrees.
258//
259// GStreamer RGBP is R,G,B; the only libav planar 8-bit RGB is GBRP, which is
260// G,B,R. Same three planes, same strides, rotated by one.
261using PlaneOrder = std::array<int, 4>;
262inline constexpr PlaneOrder identityPlaneOrder{0, 1, 2, 3};
263
264inline PlaneOrder gstreamerPlaneOrder(std::string_view gstFormat) noexcept
265{
266 if(gstFormat == "RGBP")
267 return {1, 2, 0, 3};
268 return identityPlaneOrder;
269}
270
271// Lays out the planes of `frame` over a flat buffer of `sz` bytes, for the
272// input devices that hand us pixels with no stride information at all.
273//
274// `align` is the row alignment the producer used: 1 for a tightly packed
275// buffer, 4 for the row padding GStreamer applies in its default layout.
276// libav owns every stride and every plane offset here -- av_image_fill_arrays()
277// rounds subsampled planes UP, which is what a frame of odd width needs, and
278// knows the plane count of the semi-planar and packed families.
279[[nodiscard]]
280inline bool
281initFrameFromRawData(AVFrame* frame, uint8_t* p, std::size_t sz, int align)
282{
283 const auto fmt = (AVPixelFormat)frame->format;
284 const int needed
285 = av_image_get_buffer_size(fmt, frame->width, frame->height, align);
286 if(needed < 0 || std::size_t(needed) > sz)
287 {
288 qDebug() << "unhandled video format" << av_get_pix_fmt_name(fmt) << ":" << sz
289 << "bytes for a buffer that needs" << needed;
290 return false;
291 }
292
293 if(av_image_fill_arrays(
294 frame->data, frame->linesize, p, fmt, frame->width, frame->height, align)
295 < 0)
296 {
297 qDebug() << "could not lay out video format" << av_get_pix_fmt_name(fmt);
298 return false;
299 }
300 return true;
301}
302
303[[nodiscard]]
304inline bool initFrameFromRawData(AVFrame* frame, uint8_t* p, std::size_t sz)
305{
306 return initFrameFromRawData(frame, p, sz, 1);
307}
308
309}
310#endif