11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
27#if PROMEKI_ENABLE_FREETYPE
32PROMEKI_NAMESPACE_BEGIN
34class UncompressedVideoPayload;
101class VideoTestPattern {
104 using Pattern = VideoPattern;
112 VideoTestPattern(
const VideoTestPattern &) =
delete;
113 VideoTestPattern &operator=(
const VideoTestPattern &) =
delete;
116 Pattern pattern()
const {
return _pattern; }
127 void setPattern(Pattern pattern);
130 const Color &solidColor()
const {
return _solidColor; }
137 void setSolidColor(
const Color &color);
142 bool burnEnabled()
const {
return _burnEnabled; }
153 void setBurnEnabled(
bool val) { _burnEnabled = val; }
156 const String &burnFontFilename()
const {
return _burnFontFilename; }
162 void setBurnFontFilename(
const String &path);
171 int burnFontSize()
const {
return _burnFontSize; }
179 void setBurnFontSize(
int px);
182 const Color &burnTextColor()
const {
return _burnTextColor; }
185 void setBurnTextColor(
const Color &c);
188 const Color &burnBackgroundColor()
const {
return _burnBackgroundColor; }
191 void setBurnBackgroundColor(
const Color &c);
194 bool burnDrawBackground()
const {
return _burnDrawBackground; }
206 void setBurnDrawBackground(
bool val) { _burnDrawBackground = val; }
209 BurnPosition burnPosition()
const {
return _burnPosition; }
212 void setBurnPosition(BurnPosition pos) { _burnPosition = pos; }
219 int burnTopReserved()
const {
return _burnTopReserved; }
236 void setBurnTopReserved(
int lines) { _burnTopReserved = (lines > 0) ? lines : 0; }
257 SharedPtr<UncompressedVideoPayload, true, UncompressedVideoPayload>
258 createPayload(
const ImageDesc &desc,
double motionOffset = 0.0,
259 const Timecode ¤tTimecode = Timecode())
const;
271 Error applyBurn(UncompressedVideoPayload &inout,
const String &burnText)
const;
278 void render(UncompressedVideoPayload &img,
double motionOffset = 0.0)
const;
298 void setAllocator(MediaIOAllocator::Ptr allocator);
303 MediaIOAllocator::Ptr allocator()
const {
return _allocator; }
320 MotionBand &motionBand() {
return _motionBand; }
323 const MotionBand &motionBand()
const {
return _motionBand; }
334 Error applyMotionBand(UncompressedVideoPayload &inout, uint64_t frameCount)
const {
335 return _motionBand.apply(inout, frameCount);
340 VideoPattern _pattern = VideoPattern::ColorBars;
344 bool _burnEnabled =
false;
345 String _burnFontFilename;
346 int _burnFontSize = 36;
353 mutable int _burnEffectiveFontSize = 36;
354 Color _burnTextColor = Color::White;
355 Color _burnBackgroundColor = Color::Black;
356 bool _burnDrawBackground =
true;
357 BurnPosition _burnPosition = BurnPosition::BottomCenter;
358 int _burnTopReserved = 0;
376 static constexpr int CacheSlotCount = 2;
377 mutable SharedPtr<UncompressedVideoPayload, true, UncompressedVideoPayload>
378 _cachedPayloads[CacheSlotCount];
379 mutable size_t _cacheW = 0;
380 mutable size_t _cacheH = 0;
381 mutable int _cachePixelFormatId = 0;
387 MediaIOAllocator::Ptr _allocator;
393 MotionBand _motionBand;
400#if PROMEKI_ENABLE_FREETYPE
401 mutable FastFont::UPtr _burnFont;
403 mutable bool _burnFontConfigDirty =
true;
414 mutable PaintEngine::Pixel _cachedBgPixel;
415 mutable PixelFormat _cachedBgPixelFormat;
417 bool isStaticPattern()
const;
435 template <
typename Builder>
436 SharedPtr<UncompressedVideoPayload, true, UncompressedVideoPayload>
437 cachedPayload(
int slotIndex,
const ImageDesc &desc, Builder &&build)
const {
438 if (_cacheW != desc.width() || _cacheH != desc.height() ||
439 _cachePixelFormatId !=
static_cast<int>(desc.pixelFormat().id())) {
440 invalidatePayloadCache();
441 _cacheW = desc.width();
442 _cacheH = desc.height();
443 _cachePixelFormatId =
static_cast<int>(desc.pixelFormat().id());
445 auto &slot = _cachedPayloads[slotIndex];
446 if (!slot.isValid()) {
454 slot = _allocator.isValid() ? _allocator->allocateVideoPayload(desc)
455 : UncompressedVideoPayload::allocate(desc);
456 if (slot.isValid()) {
464 (void)slot->data().seal();
471 void invalidatePayloadCache()
const;
473 void applyBurnFontConfig()
const;
474 void computeBurnPosition(
int frameW,
int frameH,
int textW,
int totalH,
int ascender,
int &x,
489 ImageDesc rgbScratchDesc(
const ImageDesc &target)
const;
491 void renderColorBars(UncompressedVideoPayload &img,
double offset,
bool full)
const;
492 void renderRamp(UncompressedVideoPayload &img,
double offset)
const;
493 void renderGrid(UncompressedVideoPayload &img,
double offset)
const;
494 void renderCrosshatch(UncompressedVideoPayload &img,
double offset)
const;
495 void renderCheckerboard(UncompressedVideoPayload &img,
double offset)
const;
496 void renderZonePlate(UncompressedVideoPayload &img,
double phase)
const;
497 void renderNoise(UncompressedVideoPayload &img)
const;
498 void renderSolid(UncompressedVideoPayload &img,
const Color &color)
const;
499 void renderColorChecker(UncompressedVideoPayload &img)
const;
500 void renderSMPTE219(UncompressedVideoPayload &img)
const;
501 void renderMultiBurst(UncompressedVideoPayload &img)
const;
502 void renderLimitRange(UncompressedVideoPayload &img)
const;
503 void renderCircularZone(UncompressedVideoPayload &img,
double phase)
const;
504 void renderAlignment(UncompressedVideoPayload &img)
const;
505 void renderSDIPathological(UncompressedVideoPayload &img,
bool isEQ)
const;