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
251 // -- DPX Method B packed --
252 I_3x10_DPX_B = 80,
253
254 // -- Semi-planar 4:2:2 16-bit (NV16, P216 wire) --
255 SP_422_16_LE = 82,
256 SP_422_16_BE = 83,
257
258 UserDefined = 1024
259 };
260
262 enum Sampling {
263 SamplingUndefined = 0,
264 Sampling444,
265 Sampling422,
266 Sampling411,
267 Sampling420
268 };
269
271 enum ChromaSitingH {
272 ChromaHUndefined = 0,
273 ChromaHLeft,
274 ChromaHCenter
275 };
276
278 enum ChromaSitingV {
279 ChromaVUndefined = 0,
280 ChromaVTop,
281 ChromaVCenter
282 };
283
285 using IDList = ::promeki::List<ID>;
286
288 struct CompDesc {
289 int plane;
290 size_t bits;
291 size_t byteOffset;
292 };
293
295 struct PlaneDesc {
296 String name;
297 size_t hSubsampling = 1;
298 size_t vSubsampling = 1;
299 size_t bytesPerSample = 0;
300 };
301
303 struct Data {
304 ID id = Invalid;
305 String name;
306 String desc;
307 Sampling sampling = SamplingUndefined;
308 size_t pixelsPerBlock = 0;
309 size_t bytesPerBlock = 0;
310 size_t compCount = 0;
311 CompDesc comps[MaxComps] = {};
312 size_t planeCount = 0;
313 PlaneDesc planes[MaxPlanes] = {};
314 ChromaSitingH chromaSitingH = ChromaHUndefined;
315 ChromaSitingV chromaSitingV = ChromaVUndefined;
316
326 size_t (*lineStrideFunc)(const Data *d, size_t planeIdx, size_t width, size_t linePad,
327 size_t lineAlign) = nullptr;
328
339 size_t (*planeSizeFunc)(const Data *d, size_t planeIdx, size_t width, size_t height,
340 size_t linePad, size_t lineAlign) = nullptr;
341 };
342
351 static ID registerType();
352
362 static void registerData(Data &&data);
363
371 static IDList registeredIDs();
372
386 static PixelMemLayout lookup(const String &name);
387
405 static PixelMemLayout lookup(const String &name, Error *err);
406
414 static Result<PixelMemLayout> fromString(const String &name) {
415 Error err;
416 PixelMemLayout p = lookup(name, &err);
417 if (err.isError()) return makeError<PixelMemLayout>(err);
418 return makeResult(p);
419 }
420
425 inline PixelMemLayout(ID id = Invalid);
426
428 bool isValid() const { return d != nullptr && d->id != Invalid; }
429
431 ID id() const { return d->id; }
432
434 const String &name() const { return d->name; }
435
437 String toString() const { return d->name; }
438
440 const String &desc() const { return d->desc; }
441
443 Sampling sampling() const { return d->sampling; }
444
446 ChromaSitingH chromaSitingH() const { return d->chromaSitingH; }
447
449 ChromaSitingV chromaSitingV() const { return d->chromaSitingV; }
450
452 size_t pixelsPerBlock() const { return d->pixelsPerBlock; }
453
455 size_t bytesPerBlock() const { return d->bytesPerBlock; }
456
458 size_t compCount() const { return d->compCount; }
459
465 const CompDesc &compDesc(size_t index) const { return d->comps[index]; }
466
468 size_t planeCount() const { return d->planeCount; }
469
475 const PlaneDesc &planeDesc(size_t index) const { return d->planes[index]; }
476
478 bool isValidPlane(size_t index) const { return index < d->planeCount; }
479
488 size_t lineStride(size_t planeIndex, size_t width, size_t linePad = 0, size_t lineAlign = 1) const {
489 if (!isValidPlane(planeIndex) || d->lineStrideFunc == nullptr) return 0;
490 return d->lineStrideFunc(d, planeIndex, width, linePad, lineAlign);
491 }
492
502 size_t planeSize(size_t planeIndex, size_t width, size_t height, size_t linePad = 0,
503 size_t lineAlign = 1) const {
504 if (!isValidPlane(planeIndex) || d->planeSizeFunc == nullptr) return 0;
505 return d->planeSizeFunc(d, planeIndex, width, height, linePad, lineAlign);
506 }
507
509 bool operator==(const PixelMemLayout &o) const { return d == o.d; }
510
512 bool operator!=(const PixelMemLayout &o) const { return d != o.d; }
513
515 const Data *data() const { return d; }
516
517 private:
518 const Data *d = nullptr;
519 static const Data *lookupData(ID id);
520};
521
522inline PixelMemLayout::PixelMemLayout(ID id) : d(lookupData(id)) {}
523
524PROMEKI_NAMESPACE_END
525
526#endif // PROMEKI_ENABLE_PROAV