12#include <promeki/config.h>
13#if PROMEKI_ENABLE_PROAV
23PROMEKI_NAMESPACE_BEGIN
39#define PROMEKI_WELL_KNOWN_RASTERS \
40 X(Raster_Invalid, "INV", 0, 0) \
41 X(Raster_SD525, "SD525", 720, 486) \
42 X(Raster_SD625, "SD625", 720, 576) \
43 X(Raster_HD720, "HD720", 1280, 720) \
44 X(Raster_HD, "HD", 1920, 1080) \
45 X(Raster_2K, "2K", 2048, 1080) \
46 X(Raster_QHD, "QHD", 2560, 1440) \
47 X(Raster_UHD, "UHD", 3840, 2160) \
48 X(Raster_4K, "4K", 4096, 2160) \
49 X(Raster_UHD8K, "UHD8K", 7680, 4320) \
50 X(Raster_8K, "8K", 8192, 4320)
73#define PROMEKI_WELL_KNOWN_VIDEO_FORMATS \
74 X(Smpte486i59_94, Raster_SD525, FPS_29_97, Interlaced, FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Sd) \
75 X(Smpte576i50, Raster_SD625, FPS_25, Interlaced, FormatFlag_Smpte | FormatFlag_Pal | FormatFlag_Sd) \
76 X(Smpte720p50, Raster_HD720, FPS_50, Progressive, FormatFlag_Smpte | FormatFlag_Pal | FormatFlag_Hd) \
77 X(Smpte720p59_94, Raster_HD720, FPS_59_94, Progressive, FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Hd) \
78 X(Smpte720p60, Raster_HD720, FPS_60, Progressive, FormatFlag_Smpte | FormatFlag_Hd) \
79 X(Smpte1080i50, Raster_HD, FPS_25, Interlaced, FormatFlag_Smpte | FormatFlag_Pal | FormatFlag_Hd) \
80 X(Smpte1080i59_94, Raster_HD, FPS_29_97, Interlaced, FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Hd) \
81 X(Smpte1080i60, Raster_HD, FPS_30, Interlaced, FormatFlag_Smpte | FormatFlag_Hd) \
82 X(Smpte1080p23_98, Raster_HD, FPS_23_98, Progressive, FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Hd) \
83 X(Smpte1080p24, Raster_HD, FPS_24, Progressive, FormatFlag_Smpte | FormatFlag_Hd) \
84 X(Smpte1080p25, Raster_HD, FPS_25, Progressive, FormatFlag_Smpte | FormatFlag_Pal | FormatFlag_Hd) \
85 X(Smpte1080p29_97, Raster_HD, FPS_29_97, Progressive, FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Hd) \
86 X(Smpte1080p30, Raster_HD, FPS_30, Progressive, FormatFlag_Smpte | FormatFlag_Hd) \
87 X(Smpte1080p50, Raster_HD, FPS_50, Progressive, FormatFlag_Smpte | FormatFlag_Pal | FormatFlag_Hd) \
88 X(Smpte1080p59_94, Raster_HD, FPS_59_94, Progressive, FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Hd) \
89 X(Smpte1080p60, Raster_HD, FPS_60, Progressive, FormatFlag_Smpte | FormatFlag_Hd) \
90 X(Smpte1080psf23_98, Raster_HD, FPS_23_98, PsF, FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Hd) \
91 X(Smpte1080psf24, Raster_HD, FPS_24, PsF, FormatFlag_Smpte | FormatFlag_Hd) \
92 X(Smpte1080psf25, Raster_HD, FPS_25, PsF, FormatFlag_Smpte | FormatFlag_Pal | FormatFlag_Hd) \
93 X(Smpte1080psf29_97, Raster_HD, FPS_29_97, PsF, FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Hd) \
94 X(Smpte1080psf30, Raster_HD, FPS_30, PsF, FormatFlag_Smpte | FormatFlag_Hd) \
95 X(Smpte2160p23_98, Raster_UHD, FPS_23_98, Progressive, FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Uhd) \
96 X(Smpte2160p24, Raster_UHD, FPS_24, Progressive, FormatFlag_Smpte | FormatFlag_Uhd) \
97 X(Smpte2160p25, Raster_UHD, FPS_25, Progressive, FormatFlag_Smpte | FormatFlag_Pal | FormatFlag_Uhd) \
98 X(Smpte2160p29_97, Raster_UHD, FPS_29_97, Progressive, FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Uhd) \
99 X(Smpte2160p30, Raster_UHD, FPS_30, Progressive, FormatFlag_Smpte | FormatFlag_Uhd) \
100 X(Smpte2160p50, Raster_UHD, FPS_50, Progressive, FormatFlag_Smpte | FormatFlag_Pal | FormatFlag_Uhd) \
101 X(Smpte2160p59_94, Raster_UHD, FPS_59_94, Progressive, FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Uhd) \
102 X(Smpte2160p60, Raster_UHD, FPS_60, Progressive, FormatFlag_Smpte | FormatFlag_Uhd) \
103 X(Smpte4320p23_98, Raster_UHD8K, FPS_23_98, Progressive, \
104 FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Uhd8k) \
105 X(Smpte4320p24, Raster_UHD8K, FPS_24, Progressive, FormatFlag_Smpte | FormatFlag_Uhd8k) \
106 X(Smpte4320p25, Raster_UHD8K, FPS_25, Progressive, FormatFlag_Smpte | FormatFlag_Pal | FormatFlag_Uhd8k) \
107 X(Smpte4320p29_97, Raster_UHD8K, FPS_29_97, Progressive, \
108 FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Uhd8k) \
109 X(Smpte4320p30, Raster_UHD8K, FPS_30, Progressive, FormatFlag_Smpte | FormatFlag_Uhd8k) \
110 X(Smpte4320p50, Raster_UHD8K, FPS_50, Progressive, FormatFlag_Smpte | FormatFlag_Pal | FormatFlag_Uhd8k) \
111 X(Smpte4320p59_94, Raster_UHD8K, FPS_59_94, Progressive, \
112 FormatFlag_Smpte | FormatFlag_Ntsc | FormatFlag_Uhd8k) \
113 X(Smpte4320p60, Raster_UHD8K, FPS_60, Progressive, FormatFlag_Smpte | FormatFlag_Uhd8k) \
114 X(Dci2Kp24, Raster_2K, FPS_24, Progressive, FormatFlag_Dci) \
115 X(Dci2Kp25, Raster_2K, FPS_25, Progressive, FormatFlag_Dci) \
116 X(Dci2Kp30, Raster_2K, FPS_30, Progressive, FormatFlag_Dci) \
117 X(Dci2Kp48, Raster_2K, FPS_48, Progressive, FormatFlag_Dci) \
118 X(Dci2Kp50, Raster_2K, FPS_50, Progressive, FormatFlag_Dci) \
119 X(Dci2Kp60, Raster_2K, FPS_60, Progressive, FormatFlag_Dci) \
120 X(Dci4Kp24, Raster_4K, FPS_24, Progressive, FormatFlag_Dci) \
121 X(Dci4Kp25, Raster_4K, FPS_25, Progressive, FormatFlag_Dci) \
122 X(Dci4Kp30, Raster_4K, FPS_30, Progressive, FormatFlag_Dci) \
123 X(Dci4Kp48, Raster_4K, FPS_48, Progressive, FormatFlag_Dci) \
124 X(Dci4Kp50, Raster_4K, FPS_50, Progressive, FormatFlag_Dci) \
125 X(Dci4Kp60, Raster_4K, FPS_60, Progressive, FormatFlag_Dci)
200 PROMEKI_DATATYPE(VideoFormat, DataTypeVideoFormat, 1)
203 Error writeToStream(DataStream &s) const;
205 template <uint32_t V> static Result<VideoFormat> readFromStream(DataStream &s);
208 enum WellKnownRaster {
209 Raster_NotWellKnown = 0,
210#define X(id, name, w, h) id,
211 PROMEKI_WELL_KNOWN_RASTERS
223 enum WellKnownFormatFlag : uint32_t {
224 FormatFlag_Smpte = 1u << 0,
225 FormatFlag_Dci = 1u << 1,
226 FormatFlag_Ntsc = 1u << 2,
227 FormatFlag_Pal = 1u << 3,
228 FormatFlag_Sd = 1u << 4,
229 FormatFlag_Hd = 1u << 5,
230 FormatFlag_Uhd = 1u << 6,
231 FormatFlag_Uhd8k = 1u << 7,
249 enum WellKnownFormat {
252#define X(id, raster, rate, scan, flags) id,
253 PROMEKI_WELL_KNOWN_VIDEO_FORMATS
258 using WellKnownFormatList = ::promeki::List<WellKnownFormat>;
261 struct StringOptions {
272 bool useNamedRaster =
false;
276 struct ParseOptions {
295 bool strictInterlacedFieldRate =
true;
299 VideoFormat() =
default;
307 VideoFormat(
const Size2Du32 &raster,
const FrameRate &rate,
308 VideoScanMode scanMode = VideoScanMode::Progressive);
319 VideoFormat(WellKnownRaster raster,
const FrameRate &rate,
320 VideoScanMode scanMode = VideoScanMode::Progressive);
332 VideoFormat(WellKnownFormat fmt);
335 bool isValid()
const {
return _raster.isValid() && _rate.isValid(); }
338 const Size2Du32 &raster()
const {
return _raster; }
341 const FrameRate &frameRate()
const {
return _rate; }
344 VideoScanMode videoScanMode()
const {
return _scanMode; }
350 WellKnownRaster wellKnownRaster()
const;
353 bool isWellKnownRaster()
const {
return wellKnownRaster() != Raster_NotWellKnown; }
364 WellKnownFormat wellKnownFormat()
const;
367 bool isWellKnownFormat()
const {
368 const WellKnownFormat
id = wellKnownFormat();
369 return id != Invalid &&
id != NotWellKnown;
378 uint32_t wellKnownFormatFlags()
const;
381 bool isSmpteFormat()
const {
return (wellKnownFormatFlags() & FormatFlag_Smpte) != 0; }
384 bool isDciFormat()
const {
return (wellKnownFormatFlags() & FormatFlag_Dci) != 0; }
387 bool isNtscFormat()
const {
return (wellKnownFormatFlags() & FormatFlag_Ntsc) != 0; }
390 bool isPalFormat()
const {
return (wellKnownFormatFlags() & FormatFlag_Pal) != 0; }
393 bool isSdFormat()
const {
return (wellKnownFormatFlags() & FormatFlag_Sd) != 0; }
396 bool isHdFormat()
const {
return (wellKnownFormatFlags() & FormatFlag_Hd) != 0; }
399 bool isUhdFormat()
const {
return (wellKnownFormatFlags() & FormatFlag_Uhd) != 0; }
402 bool isUhd8kFormat()
const {
return (wellKnownFormatFlags() & FormatFlag_Uhd8k) != 0; }
412 bool isBroadcastFormat()
const {
413 const uint32_t f = wellKnownFormatFlags();
414 return (f & FormatFlag_Smpte) != 0 && (f & FormatFlag_Dci) == 0;
425 bool isCinemaFormat()
const {
return isDciFormat(); }
436 bool isIntegerCadence()
const {
return _rate.isValid() && _rate.denominator() == 1; }
445 static uint32_t formatFlags(WellKnownFormat fmt);
463 static WellKnownFormatList allWellKnownFormats(uint32_t requiredFlags = 0);
473 String rasterString()
const {
return rasterString(StringOptions()); }
478 String rasterString(
const StringOptions &opts)
const;
493 String frameRateString()
const;
500 String toString()
const {
return toString(StringOptions()); }
505 String toString(
const StringOptions &opts)
const;
513 static Result<VideoFormat> fromString(
const String &str) {
return fromString(str, ParseOptions()); }
521 static Result<VideoFormat> fromString(
const String &str,
const ParseOptions &opts);
524 bool operator==(
const VideoFormat &o)
const {
525 return _raster == o._raster && _rate == o._rate && _scanMode == o._scanMode;
529 bool operator!=(
const VideoFormat &o)
const {
return !(*
this == o); }
540 bool operator==(WellKnownFormat fmt)
const {
return wellKnownFormat() == fmt; }
543 bool operator!=(WellKnownFormat fmt)
const {
return wellKnownFormat() != fmt; }
546 friend bool operator==(WellKnownFormat fmt,
const VideoFormat &vf) {
return vf == fmt; }
549 friend bool operator!=(WellKnownFormat fmt,
const VideoFormat &vf) {
return vf != fmt; }
554 VideoScanMode _scanMode{VideoScanMode::Progressive};
581template <>
struct std::formatter<promeki::VideoFormat> {
587 Style _style = Style::Smpte;
588 std::formatter<std::string_view> _base;
590 constexpr auto parse(std::format_parse_context &ctx) {
591 auto it = ctx.begin();
592 auto end = ctx.end();
597 auto tryKeyword = [&](
const char *kw, Style s) {
599 while (*kw && p != end && *p == *kw) {
603 if (*kw == 0 && (p == end || *p ==
'}' || *p ==
':')) {
611 if (!tryKeyword(
"smpte", Style::Smpte) && !tryKeyword(
"named", Style::Named)) {
619 if (it != end && *it ==
':') ++it;
622 return _base.parse(ctx);
625 template <
typename FormatContext>
626 auto format(
const promeki::VideoFormat &vf, FormatContext &ctx)
const {
627 promeki::VideoFormat::StringOptions opts;
628 opts.useNamedRaster = (_style == Style::Named);
629 const promeki::String s = vf.toString(opts);
630 return _base.format(std::string_view(s.cstr(), s.byteCount()), ctx);