summaryrefslogtreecommitdiffstats
path: root/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm
diff options
context:
space:
mode:
authorJames Turner <james.turner@kdab.com>2015-01-12 13:51:25 +0000
committerYoann Lopes <yoann.lopes@theqtcompany.com>2015-02-04 11:28:02 +0000
commit9444c8ec6161bee3e399f9d385974dbaa6216283 (patch)
tree8baa73fe66c90b9d0267fb7e6bd2f0ee436439af /src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm
parent3e94b7ce2d8166767ec47425d2cefbc77cb5fde2 (diff)
iOS video frame render implementation.
Uses CVTextureCache, iOS only for now, OS-X code could be ported but will need further work to support TEXTURE_RECTANGLE in the QVideoNode classes. When we can’t share a context, falls back to an offscreen window, FBO rendering and grabbing a QImage. Change-Id: I23b831fdcc63aeb1b67b7741d8d56779470240d3 Reviewed-by: Yoann Lopes <yoann.lopes@theqtcompany.com>
Diffstat (limited to 'src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm')
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm92
1 files changed, 88 insertions, 4 deletions
diff --git a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm b/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm
index b3f9b690d..d52a4a7fe 100644
--- a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm
@@ -46,8 +46,70 @@
#include <QtCore/qdebug.h>
#endif
+#if defined(Q_OS_IOS)
+#import <QuartzCore/CADisplayLink.h>
+#import <Foundation/NSRunLoop.h>
+#define _m_displayLink static_cast<DisplayLinkObserver*>(m_displayLink)
+#else
+#endif
+
QT_USE_NAMESPACE
+#if defined(Q_OS_IOS)
+@interface DisplayLinkObserver : NSObject
+{
+ AVFDisplayLink *m_avfDisplayLink;
+ CADisplayLink *m_displayLink;
+}
+
+- (void)start;
+- (void)stop;
+- (void)displayLinkNotification:(CADisplayLink *)sender;
+
+@end
+
+@implementation DisplayLinkObserver
+
+- (id)initWithAVFDisplayLink:(AVFDisplayLink *)link
+{
+ self = [super init];
+
+ if (self) {
+ m_avfDisplayLink = link;
+ m_displayLink = [[CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkNotification:)] retain];
+ }
+
+ return self;
+}
+
+- (void) dealloc
+{
+ if (m_displayLink) {
+ [m_displayLink release];
+ m_displayLink = NULL;
+ }
+
+ [super dealloc];
+}
+
+- (void)start
+{
+ [m_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+}
+
+- (void)stop
+{
+ [m_displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+}
+
+- (void)displayLinkNotification:(CADisplayLink *)sender
+{
+ Q_UNUSED(sender);
+ m_avfDisplayLink->displayLinkEvent(nullptr);
+}
+
+@end
+#else
static CVReturn CVDisplayLinkCallback(CVDisplayLinkRef displayLink,
const CVTimeStamp *inNow,
const CVTimeStamp *inOutputTime,
@@ -65,12 +127,17 @@ static CVReturn CVDisplayLinkCallback(CVDisplayLinkRef displayLink,
link->displayLinkEvent(inOutputTime);
return kCVReturnSuccess;
}
+#endif
AVFDisplayLink::AVFDisplayLink(QObject *parent)
: QObject(parent)
+ , m_displayLink(0)
, m_pendingDisplayLinkEvent(false)
, m_isActive(false)
{
+#if defined(Q_OS_IOS)
+ m_displayLink = [[DisplayLinkObserver alloc] initWithAVFDisplayLink:this];
+#else
// create display link for the main display
CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink);
if (m_displayLink) {
@@ -80,6 +147,7 @@ AVFDisplayLink::AVFDisplayLink(QObject *parent)
// set the renderer output callback function
CVDisplayLinkSetOutputCallback(m_displayLink, &CVDisplayLinkCallback, this);
}
+#endif
}
AVFDisplayLink::~AVFDisplayLink()
@@ -89,8 +157,12 @@ AVFDisplayLink::~AVFDisplayLink()
#endif
if (m_displayLink) {
- CVDisplayLinkStop(m_displayLink);
+ stop();
+#if defined(Q_OS_IOS)
+ [_m_displayLink release];
+#else
CVDisplayLinkRelease(m_displayLink);
+#endif
m_displayLink = NULL;
}
}
@@ -108,20 +180,27 @@ bool AVFDisplayLink::isActive() const
void AVFDisplayLink::start()
{
if (m_displayLink && !m_isActive) {
- CVDisplayLinkStart(m_displayLink);
- m_isActive = true;
+#if defined(Q_OS_IOS)
+ [_m_displayLink start];
+#else
+ CVDisplayLinkStart(m_displayLink);
+#endif
+ m_isActive = true;
}
}
void AVFDisplayLink::stop()
{
if (m_displayLink && m_isActive) {
+#if defined(Q_OS_IOS)
+ [_m_displayLink stop];
+#else
CVDisplayLinkStop(m_displayLink);
+#endif
m_isActive = false;
}
}
-
void AVFDisplayLink::displayLinkEvent(const CVTimeStamp *ts)
{
// This function is called from a
@@ -131,7 +210,12 @@ void AVFDisplayLink::displayLinkEvent(const CVTimeStamp *ts)
m_displayLinkMutex.lock();
bool pending = m_pendingDisplayLinkEvent;
m_pendingDisplayLinkEvent = true;
+#if defined(Q_OS_IOS)
+ Q_UNUSED(ts);
+ memset(&m_frameTimeStamp, 0, sizeof(CVTimeStamp));
+#else
m_frameTimeStamp = *ts;
+#endif
m_displayLinkMutex.unlock();
if (!pending)