libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
pixelmemlayout.h
Go to the documentation of this file.
1
8#pragma once
9
10#include <promeki/config.h>
11#if PROMEKI_ENABLE_PROAV
12#include <cstddef>
13#include <promeki/namespace.h>
14#include <promeki/string.h>
15#include <promeki/list.h>
16#include <promeki/error.h>
17#include <promeki/result.h>
18#include <promeki/datatype.h>
19
20PROMEKI_NAMESPACE_BEGIN
21
22class DataStream;
23
113class PixelMemLayout {
114 public:
115 PROMEKI_DATATYPE(PixelMemLayout, DataTypePixelMemLayout, 1)
116
117
118 Error writeToStream(DataStream &s) const;
120 template <uint32_t V> static Result<PixelMemLayout> readFromStream(DataStream &s);
121
122 static constexpr size_t MaxComps = 8;
123 static constexpr size_t MaxPlanes = 4;
124
132 enum ID {
133 Invalid = 0,
134
135 // -- Interleaved 4:4:4 (byte-aligned) --
136 I_4x8 = 1,
137 I_3x8 = 2,
138
139 // -- Interleaved 4:4:4 (DPX/Cineon packed) --
140 I_3x10_DPX = 3,
141
142 // -- Interleaved 4:2:2 YUYV --
143 I_422_3x8 = 4,
144 I_422_3x10 = 5,
145
146 // -- Interleaved 4:2:2 UYVY --
147 I_422_UYVY_3x8 = 6,
148 I_422_UYVY_3x10_LE = 7,
149 I_422_UYVY_3x10_BE = 8,
150 I_422_UYVY_3x12_LE = 9,
151 I_422_UYVY_3x12_BE = 10,
152
153 // -- Interleaved 4:2:2 v210 --
154 I_422_v210 = 11,
155
156 // -- Planar 4:2:2 --
157 P_422_3x8 = 12,
158 P_422_3x10_LE = 13,
159 P_422_3x10_BE = 14,
160 P_422_3x12_LE = 15,
161 P_422_3x12_BE = 16,
162
163 // -- Planar 4:2:0 --
164 P_420_3x8 = 17,
165 P_420_3x10_LE = 18,
166 P_420_3x10_BE = 19,
167 P_420_3x12_LE = 20,
168 P_420_3x12_BE = 21,
169
170 // -- Semi-planar 4:2:0 (NV12) --
171 SP_420_8 = 22,
172 SP_420_10_LE = 23,
173 SP_420_10_BE = 24,
174 SP_420_12_LE = 25,
175 SP_420_12_BE = 26,
176
177 // -- Interleaved 4:4:4 (10/12/16-bit in 16-bit words) --
178 I_4x10_LE = 27,
179 I_4x10_BE = 28,
180 I_3x10_LE = 29,
181 I_3x10_BE = 30,
182 I_4x12_LE = 31,
183 I_4x12_BE = 32,
184 I_3x12_LE = 33,
185 I_3x12_BE = 34,
186 I_4x16_LE = 35,
187 I_4x16_BE = 36,
188 I_3x16_LE = 37,
189 I_3x16_BE = 38,
190
191 // -- Monochrome (single component) --
192 I_1x8 = 39,
193 I_1x10_LE = 40,
194 I_1x10_BE = 41,
195 I_1x12_LE = 42,
196 I_1x12_BE = 43,
197 I_1x16_LE = 44,
198 I_1x16_BE = 45,
199
200 // -- Float half-precision (16-bit IEEE 754) --
201 I_4xF16_LE = 46,
202 I_4xF16_BE = 47,
203 I_3xF16_LE = 48,
204 I_3xF16_BE = 49,
205 I_1xF16_LE = 50,
206 I_1xF16_BE = 51,
207
208 // -- Float single-precision (32-bit IEEE 754) --
209 I_4xF32_LE = 52,
210 I_4xF32_BE = 53,
211 I_3xF32_LE = 54,
212 I_3xF32_BE = 55,
213 I_1xF32_LE = 56,
214 I_1xF32_BE = 57,
215
216 // -- 10:10:10:2 packed (3x10-bit + 1x2-bit in 32 bits) --
217 I_10_10_10_2_LE = 58,
218 I_10_10_10_2_BE = 59,
219
220 // -- Semi-planar 4:2:0 NV21 (CrCb order) --
221 SP_420_NV21_8 = 60,
222 SP_420_NV21_10_LE = 61,
223 SP_420_NV21_10_BE = 62,
224 SP_420_NV21_12_LE = 63,
225 SP_420_NV21_12_BE = 64,
226
227 // -- Semi-planar 4:2:2 (NV16) --
228 SP_422_8 = 65,
229 SP_422_10_LE = 66,
230 SP_422_10_BE = 67,
231 SP_422_12_LE = 68,
232 SP_422_12_BE = 69,
233
234 // -- Planar 4:1:1 --
235 P_411_3x8 = 70,
236
237 // -- 16-bit YCbCr additions --
238 P_422_3x16_LE = 71,
239 P_422_3x16_BE = 72,
240 P_420_3x16_LE = 73,
241 P_420_3x16_BE = 74,
242 SP_420_16_LE = 75,
243 SP_420_16_BE = 76,
244 I_422_UYVY_3x16_LE = 77,
245 I_422_UYVY_3x16_BE = 78,
246
247 // -- Planar 4:4:4 (RGB / YUV 4:4:4) --
248 P_444_3x8 = 79,
249 P_444_3x10_LE = 81,
250 P_444_3x12_LE = 94,
251
252 // -- DPX Method B packed --
253 I_3x10_DPX_B = 80,
254
255 // -- Semi-planar 4:2:2 16-bit (NV16, P216 wire) --
256 SP_422_16_LE = 82,
257 SP_422_16_BE = 83,
258
259 // -- ST 2110-20 wire-format pgroups (big-endian sample-packed) --
260 //
261 // These layouts describe the on-the-wire byte stream
262 // emitted by an ST 2110-20 sender as the RFC 4175
263 // SRD payload. Samples are MSB-first big-endian and
264 // packed tightly across byte boundaries inside each
265 // pgroup (§6.1.1 / §6.2). The CompDesc::byteOffset
266 // and bits fields are descriptive of the per-sample
267 // bit width only — the actual bit positions live in
268 // the dedicated pack / unpack kernels (mirroring how
269 // I_3x10_DPX_B and I_422_v210 are modelled).
270 //
271 // 8-bit and 16/16f cases collapse to existing
272 // layouts (I_3x8, I_3x16_BE, I_3xF16_BE,
273 // I_422_UYVY_3x8, I_422_UYVY_3x16_BE, I_1x8,
274 // I_1x16_BE, I_1xF16_BE, SP_420_8) and are not
275 // re-registered; the bridge declares the existing
276 // layout as the wire layout for those depths.
277 I_3x10_BE_2110 = 84,
278 I_3x12_BE_2110 = 85,
279 I_422_UYVY_3x10_BE_2110 = 86,
280 I_422_UYVY_3x12_BE_2110 = 87,
281 I_422_UYVY_3xF16_BE = 88,
282 I_420_BE_2110_10 = 89,
283 I_420_BE_2110_12 = 90,
284 I_1x10_BE_2110 = 91,
285 I_1x12_BE_2110 = 92,
286 I_420_BE_2110_8 = 93,
287
288 UserDefined = 1024
289 };
290
292 enum Sampling {
293 SamplingUndefined = 0,
294 Sampling444,
295 Sampling422,
296 Sampling411,
297 Sampling420
298 };
299
301 enum ChromaSitingH {
302 ChromaHUndefined = 0,
303 ChromaHLeft,
304 ChromaHCenter
305 };
306
308 enum ChromaSitingV {
309 ChromaVUndefined = 0,
310 ChromaVTop,
311 ChromaVCenter
312 };
313
315 using IDList = ::promeki::List<ID>;
316
318 struct CompDesc {
319 int plane;
320 size_t bits;
321 size_t byteOffset;
322 };
323
325 struct PlaneDesc {
326 String name;
327 size_t hSubsampling = 1;
328 size_t vSubsampling = 1;
329 size_t bytesPerSample = 0;
330 };
331
333 struct Data {
334 ID id = Invalid;
335 String name;
336 String desc;
337 Sampling sampling = SamplingUndefined;
338 size_t pixelsPerBlock = 0;
339 size_t bytesPerBlock = 0;
340 size_t compCount = 0;
341 CompDesc comps[MaxComps] = {};
342 size_t planeCount = 0;
343 PlaneDesc planes[MaxPlanes] = {};
344 ChromaSitingH chromaSitingH = ChromaHUndefined;
345 ChromaSitingV chromaSitingV = ChromaVUndefined;
346
356 size_t (*lineStrideFunc)(const Data *d, size_t planeIdx, size_t width, size_t linePad,
357 size_t lineAlign) = nullptr;
358
369 size_t (*planeSizeFunc)(const Data *d, size_t planeIdx, size_t width, size_t height,
370 size_t linePad, size_t lineAlign) = nullptr;
371 };
372
381 static ID registerType();
382
392 static void registerData(Data &&data);
393
401 static IDList registeredIDs();
402
416 static PixelMemLayout lookup(const String &name);
417
435 static PixelMemLayout lookup(const String &name, Error *err);
436
444 static Result<PixelMemLayout> fromString(const String &name) {
445 Error err;
446 PixelMemLayout p = lookup(name, &err);
447 if (err.isError()) return makeError<PixelMemLayout>(err);
448 return makeResult(p);
449 }
450
455 inline PixelMemLayout(ID id = Invalid);
456
458 bool isValid() const { return d != nullptr && d->id != Invalid; }
459
461 ID id() const { return d->id; }
462
464 const String &name() const { return d->name; }
465
467 String toString() const { return d->name; }
468
470 const String &desc() const { return d->desc; }
471
473 Sampling sampling() const { return d->sampling; }
474
476 ChromaSitingH chromaSitingH() const { return d->chromaSitingH; }
477
479 ChromaSitingV chromaSitingV() const { return d->chromaSitingV; }
480
482 size_t pixelsPerBlock() const { return d->pixelsPerBlock; }
483
485 size_t bytesPerBlock() const { return d->bytesPerBlock; }
486
488 size_t compCount() const { return d->compCount; }
489
495 const CompDesc &compDesc(size_t index) const { return d->comps[index]; }
496
498 size_t planeCount() const { return d->planeCount; }
499
505 const PlaneDesc &planeDesc(size_t index) const { return d->planes[index]; }
506
508 bool isValidPlane(size_t index) const { return index < d->planeCount; }
509
518 size_t lineStride(size_t planeIndex, size_t width, size_t linePad = 0, size_t lineAlign = 1) const {
519 if (!isValidPlane(planeIndex) || d->lineStrideFunc == nullptr) return 0;
520 return d->lineStrideFunc(d, planeIndex, width, linePad, lineAlign);
521 }
522
532 size_t planeSize(size_t planeIndex, size_t width, size_t height, size_t linePad = 0,
533 size_t lineAlign = 1) const {
534 if (!isValidPlane(planeIndex) || d->planeSizeFunc == nullptr) return 0;
535 return d->planeSizeFunc(d, planeIndex, width, height, linePad, lineAlign);
536 }
537
539 bool operator==(const PixelMemLayout &o) const { return d == o.d; }
540
542 bool operator!=(const PixelMemLayout &o) const { return d != o.d; }
543
545 const Data *data() const { return d; }
546
547 private:
548 const Data *d = nullptr;
549 static const Data *lookupData(ID id);
550};
551
552inline PixelMemLayout::PixelMemLayout(ID id) : d(lookupData(id)) {}
553
554PROMEKI_NAMESPACE_END
555
556#endif // PROMEKI_ENABLE_PROAV