5#include <QtCore/qcoreapplication.h>
10#include <QtCore/qdebug.h>
13#if defined(QT_PLATFORM_UIKIT)
14#import <QuartzCore/CADisplayLink.h>
15#import <Foundation/NSRunLoop.h>
16#define _m_displayLink static_cast<DisplayLinkObserver*>(m_displayLink)
22#if defined(QT_PLATFORM_UIKIT)
23@interface DisplayLinkObserver : NSObject
27- (
void)displayLinkNotification:(CADisplayLink *)sender;
31@implementation DisplayLinkObserver
33 AVFDisplayLink *m_avfDisplayLink;
34 CADisplayLink *m_displayLink;
37- (id)initWithAVFDisplayLink:(AVFDisplayLink *)link
42 m_avfDisplayLink = link;
43 m_displayLink = [[CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkNotification:)] retain];
52 [m_displayLink release];
53 m_displayLink =
nullptr;
61 [m_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
66 [m_displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
69- (
void)displayLinkNotification:(CADisplayLink *)sender
72 m_avfDisplayLink->displayLinkEvent(
nullptr);
77static CVReturn CVDisplayLinkCallback([[maybe_unused]] CVDisplayLinkRef displayLink,
78 [[maybe_unused]]
const CVTimeStamp *inNow,
79 const CVTimeStamp *inOutputTime,
80 [[maybe_unused]] CVOptionFlags flagsIn,
81 [[maybe_unused]] CVOptionFlags *flagsOut,
82 void *displayLinkContext)
84 AVFDisplayLink *link = (AVFDisplayLink *)displayLinkContext;
86 link->displayLinkEvent(inOutputTime);
87 return kCVReturnSuccess;
91AVFDisplayLink::AVFDisplayLink(QObject *parent)
94#if defined(QT_PLATFORM_UIKIT)
95 m_displayLink = [[DisplayLinkObserver alloc] initWithAVFDisplayLink:
this];
98 CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink);
101 CVDisplayLinkSetCurrentCGDisplay(m_displayLink, kCGDirectMainDisplay);
104 CVDisplayLinkSetOutputCallback(m_displayLink, &CVDisplayLinkCallback,
this);
109AVFDisplayLink::~AVFDisplayLink()
112 qDebug() << Q_FUNC_INFO;
117#if defined(QT_PLATFORM_UIKIT)
118 [_m_displayLink release];
120 CVDisplayLinkRelease(m_displayLink);
122 m_displayLink =
nullptr;
126bool AVFDisplayLink::isValid()
const
128 return m_displayLink !=
nullptr;
131bool AVFDisplayLink::isActive()
const
136void AVFDisplayLink::start()
138 if (m_displayLink && !m_isActive) {
139#if defined(QT_PLATFORM_UIKIT)
140 [_m_displayLink start];
142 CVDisplayLinkStart(m_displayLink);
148void AVFDisplayLink::stop()
150 if (m_displayLink && m_isActive) {
151#if defined(QT_PLATFORM_UIKIT)
152 [_m_displayLink stop];
154 CVDisplayLinkStop(m_displayLink);
159 std::lock_guard guard{ m_displayLinkMutex };
160 m_frameTimeStamp = std::nullopt;
164void AVFDisplayLink::displayLinkEvent(
const CVTimeStamp *ts)
170 std::unique_lock guard{ m_displayLinkMutex };
172 bool pending = m_frameTimeStamp.has_value();
173#if defined(QT_PLATFORM_UIKIT)
175 m_frameTimeStamp = CVTimeStamp{};
177 m_frameTimeStamp = *ts;
182 qApp->postEvent(
this,
new QEvent(QEvent::User), Qt::HighEventPriority);
185bool AVFDisplayLink::event(QEvent *event)
187 switch (event->type()){
189 std::unique_lock guard{ m_displayLinkMutex };
190 if (!m_frameTimeStamp)
193 CVTimeStamp ts = *m_frameTimeStamp;
194 m_frameTimeStamp = std::nullopt;
204 return QObject::event(event);
207#include "moc_avfdisplaylink_p.cpp"