11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
26PROMEKI_NAMESPACE_BEGIN
28class UncompressedVideoPayload;
95class VideoTestPattern {
98 using Pattern = VideoPattern;
106 VideoTestPattern(
const VideoTestPattern &) =
delete;
107 VideoTestPattern &operator=(
const VideoTestPattern &) =
delete;
110 Pattern pattern()
const {
return _pattern; }
121 void setPattern(Pattern pattern);
124 const Color &solidColor()
const {
return _solidColor; }
131 void setSolidColor(
const Color &color);
136 bool burnEnabled()
const {
return _burnEnabled; }
147 void setBurnEnabled(
bool val) { _burnEnabled = val; }
150 const String &burnFontFilename()
const {
return _burnFontFilename; }
156 void setBurnFontFilename(
const String &path);
165 int burnFontSize()
const {
return _burnFontSize; }
173 void setBurnFontSize(
int px);
176 const Color &burnTextColor()
const {
return _burnTextColor; }
179 void setBurnTextColor(
const Color &c);
182 const Color &burnBackgroundColor()
const {
return _burnBackgroundColor; }
185 void setBurnBackgroundColor(
const Color &c);
188 bool burnDrawBackground()
const {
return _burnDrawBackground; }
200 void setBurnDrawBackground(
bool val) { _burnDrawBackground = val; }
203 BurnPosition burnPosition()
const {
return _burnPosition; }
206 void setBurnPosition(BurnPosition pos) { _burnPosition = pos; }
213 int burnTopReserved()
const {
return _burnTopReserved; }
230 void setBurnTopReserved(
int lines) { _burnTopReserved = (lines > 0) ? lines : 0; }
251 SharedPtr<UncompressedVideoPayload, true, UncompressedVideoPayload>
252 createPayload(
const ImageDesc &desc,
double motionOffset = 0.0,
253 const Timecode ¤tTimecode = Timecode())
const;
265 Error applyBurn(UncompressedVideoPayload &inout,
const String &burnText)
const;
272 void render(UncompressedVideoPayload &img,
double motionOffset = 0.0)
const;
292 void setAllocator(MediaIOAllocator::Ptr allocator);
297 MediaIOAllocator::Ptr allocator()
const {
return _allocator; }
314 MotionBand &motionBand() {
return _motionBand; }
317 const MotionBand &motionBand()
const {
return _motionBand; }
328 Error applyMotionBand(UncompressedVideoPayload &inout, uint64_t frameCount)
const {
329 return _motionBand.apply(inout, frameCount);
334 VideoPattern _pattern = VideoPattern::ColorBars;
338 bool _burnEnabled =
false;
339 String _burnFontFilename;
340 int _burnFontSize = 36;
347 mutable int _burnEffectiveFontSize = 36;
348 Color _burnTextColor = Color::White;
349 Color _burnBackgroundColor = Color::Black;
350 bool _burnDrawBackground =
true;
351 BurnPosition _burnPosition = BurnPosition::BottomCenter;
352 int _burnTopReserved = 0;
370 static constexpr int CacheSlotCount = 2;
371 mutable SharedPtr<UncompressedVideoPayload, true, UncompressedVideoPayload>
372 _cachedPayloads[CacheSlotCount];
373 mutable size_t _cacheW = 0;
374 mutable size_t _cacheH = 0;
375 mutable int _cachePixelFormatId = 0;
381 MediaIOAllocator::Ptr _allocator;
387 MotionBand _motionBand;
392 mutable FastFont::UPtr _burnFont;
393 mutable bool _burnFontConfigDirty =
true;
404 mutable PaintEngine::Pixel _cachedBgPixel;
405 mutable PixelFormat _cachedBgPixelFormat;
407 bool isStaticPattern()
const;
425 template <
typename Builder>
426 SharedPtr<UncompressedVideoPayload, true, UncompressedVideoPayload>
427 cachedPayload(
int slotIndex,
const ImageDesc &desc, Builder &&build)
const {
428 if (_cacheW != desc.width() || _cacheH != desc.height() ||
429 _cachePixelFormatId !=
static_cast<int>(desc.pixelFormat().id())) {
430 invalidatePayloadCache();
431 _cacheW = desc.width();
432 _cacheH = desc.height();
433 _cachePixelFormatId =
static_cast<int>(desc.pixelFormat().id());
435 auto &slot = _cachedPayloads[slotIndex];
436 if (!slot.isValid()) {
444 slot = _allocator.isValid() ? _allocator->allocateVideoPayload(desc)
445 : UncompressedVideoPayload::allocate(desc);
446 if (slot.isValid()) {
454 (void)slot->data().seal();
461 void invalidatePayloadCache()
const;
463 void applyBurnFontConfig()
const;
464 void computeBurnPosition(
int frameW,
int frameH,
int textW,
int totalH,
int ascender,
int &x,
479 ImageDesc rgbScratchDesc(
const ImageDesc &target)
const;
481 void renderColorBars(UncompressedVideoPayload &img,
double offset,
bool full)
const;
482 void renderRamp(UncompressedVideoPayload &img,
double offset)
const;
483 void renderGrid(UncompressedVideoPayload &img,
double offset)
const;
484 void renderCrosshatch(UncompressedVideoPayload &img,
double offset)
const;
485 void renderCheckerboard(UncompressedVideoPayload &img,
double offset)
const;
486 void renderZonePlate(UncompressedVideoPayload &img,
double phase)
const;
487 void renderNoise(UncompressedVideoPayload &img)
const;
488 void renderSolid(UncompressedVideoPayload &img,
const Color &color)
const;
489 void renderColorChecker(UncompressedVideoPayload &img)
const;
490 void renderSMPTE219(UncompressedVideoPayload &img)
const;
491 void renderMultiBurst(UncompressedVideoPayload &img)
const;
492 void renderLimitRange(UncompressedVideoPayload &img)
const;
493 void renderCircularZone(UncompressedVideoPayload &img,
double phase)
const;
494 void renderAlignment(UncompressedVideoPayload &img)
const;
495 void renderSDIPathological(UncompressedVideoPayload &img,
bool isEQ)
const;