6#include <QtCore/qcoreapplication.h>
9#include <QtCore/qdebug.h>
14#if defined(QT_PLATFORM_UIKIT)
15#import <QuartzCore/CADisplayLink.h>
16#import <Foundation/NSRunLoop.h>
21#if defined(QT_PLATFORM_UIKIT)
23@implementation DisplayLinkObserver
25 AVFDisplayLink *m_avfDisplayLink;
26 CADisplayLink *m_displayLink;
29- (id)initWithAVFDisplayLink:(AVFDisplayLink *)link
34 m_avfDisplayLink = link;
35 m_displayLink = [[CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkNotification:)] retain];
44 [m_displayLink release];
45 m_displayLink =
nullptr;
53 [m_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
58 [m_displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
61- (
void)displayLinkNotification:(CADisplayLink *)sender
64 m_avfDisplayLink->displayLinkEvent(
nullptr);
69static CVReturn CVDisplayLinkCallback([[maybe_unused]] CVDisplayLinkRef displayLink,
70 [[maybe_unused]]
const CVTimeStamp *inNow,
71 const CVTimeStamp *inOutputTime,
72 [[maybe_unused]] CVOptionFlags flagsIn,
73 [[maybe_unused]] CVOptionFlags *flagsOut,
74 void *displayLinkContext)
76 AVFDisplayLink *link = (AVFDisplayLink *)displayLinkContext;
78 link->displayLinkEvent(inOutputTime);
79 return kCVReturnSuccess;
83AVFDisplayLink::AVFDisplayLink(QObject *parent)
86#if defined(QT_PLATFORM_UIKIT)
87 m_displayLink = [[DisplayLinkObserver alloc] initWithAVFDisplayLink:
this];
90 CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink);
93 CVDisplayLinkSetCurrentCGDisplay(m_displayLink, kCGDirectMainDisplay);
96 CVDisplayLinkSetOutputCallback(m_displayLink, &CVDisplayLinkCallback,
this);
101AVFDisplayLink::~AVFDisplayLink()
104 qDebug() << Q_FUNC_INFO;
109#if defined(QT_PLATFORM_UIKIT)
110 [m_displayLink release];
112 CVDisplayLinkRelease(m_displayLink);
114 m_displayLink =
nullptr;
118bool AVFDisplayLink::isValid()
const
120 return m_displayLink !=
nullptr;
123bool AVFDisplayLink::isActive()
const
128void AVFDisplayLink::start()
130 if (m_displayLink && !m_isActive) {
131#if defined(QT_PLATFORM_UIKIT)
132 [m_displayLink start];
134 CVDisplayLinkStart(m_displayLink);
140void AVFDisplayLink::stop()
142 if (m_displayLink && m_isActive) {
143#if defined(QT_PLATFORM_UIKIT)
144 [m_displayLink stop];
146 CVDisplayLinkStop(m_displayLink);
151 std::lock_guard guard{ m_displayLinkMutex };
152 m_frameTimeStamp = std::nullopt;
156void AVFDisplayLink::displayLinkEvent(
const CVTimeStamp *ts)
162 std::unique_lock guard{ m_displayLinkMutex };
164 bool pending = m_frameTimeStamp.has_value();
165#if defined(QT_PLATFORM_UIKIT)
167 m_frameTimeStamp = CVTimeStamp{};
169 m_frameTimeStamp = *ts;
174 qApp->postEvent(
this,
new QEvent(QEvent::User), Qt::HighEventPriority);
177bool AVFDisplayLink::event(QEvent *event)
179 switch (event->type()){
181 std::unique_lock guard{ m_displayLinkMutex };
182 if (!m_frameTimeStamp)
185 CVTimeStamp ts = *m_frameTimeStamp;
186 m_frameTimeStamp = std::nullopt;
196 return QObject::event(event);
199#include "moc_avfdisplaylink_p.cpp"