Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
avfvideosink.mm
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "avfvideosink_p.h"
5
6#include <rhi/qrhi.h>
7#include <QtGui/qopenglcontext.h>
8
9#include <AVFoundation/AVFoundation.h>
10#import <QuartzCore/CATransaction.h>
11
12#if __has_include(<AppKit/AppKit.h>)
13#include <AppKit/AppKit.h>
14#endif
15
16#if __has_include(<UIKit/UIKit.h>)
17#include <UIKit/UIKit.h>
18#endif
19
21
26
30
32{
33 if (m_rhi == rhi)
34 return;
35 m_rhi = rhi;
36 if (m_interface)
37 m_interface->setRhi(rhi);
38}
39
41{
42 if (size == nativeSize())
43 return;
45 if (m_interface)
46 m_interface->nativeSizeChanged();
47}
48
50{
51 m_interface = interface;
52 if (m_interface)
53 m_interface->setRhi(m_rhi);
54}
55
64
65void AVFVideoSinkInterface::freeTextureCaches()
66{
68 CFRelease(cvMetalTextureCache);
69 cvMetalTextureCache = nullptr;
70#if defined(Q_OS_MACOS)
71 if (cvOpenGLTextureCache)
72 CFRelease(cvOpenGLTextureCache);
73 cvOpenGLTextureCache = nullptr;
74#elif defined(Q_OS_IOS)
75 if (cvOpenGLESTextureCache)
76 CFRelease(cvOpenGLESTextureCache);
77 cvOpenGLESTextureCache = nullptr;
78#endif
79}
80
82{
83 if (sink == m_sink)
84 return;
85
86 if (m_sink)
88
89 m_sink = sink;
90
91 if (m_sink) {
94 }
95}
96
98{
100 if (m_rhi == rhi)
101 return;
102 freeTextureCaches();
103 m_rhi = rhi;
104
105 if (!rhi)
106 return;
107 if (rhi->backend() == QRhi::Metal) {
108 const auto *metal = static_cast<const QRhiMetalNativeHandles *>(rhi->nativeHandles());
109
110 // Create a Metal Core Video texture cache from the pixel buffer.
112 if (CVMetalTextureCacheCreate(
113 kCFAllocatorDefault,
114 nil,
115 (id<MTLDevice>)metal->dev,
116 nil,
117 &cvMetalTextureCache) != kCVReturnSuccess) {
118 qWarning() << "Metal texture cache creation failed";
119 m_rhi = nullptr;
120 }
121 } else if (rhi->backend() == QRhi::OpenGLES2) {
122#if QT_CONFIG(opengl)
123#ifdef Q_OS_MACOS
124 const auto *gl = static_cast<const QRhiGles2NativeHandles *>(rhi->nativeHandles());
125
126 auto nsGLContext = gl->context->nativeInterface<QNativeInterface::QCocoaGLContext>()->nativeContext();
127 auto nsGLPixelFormat = nsGLContext.pixelFormat.CGLPixelFormatObj;
128
129 // Create an OpenGL CoreVideo texture cache from the pixel buffer.
130 if (CVOpenGLTextureCacheCreate(
131 kCFAllocatorDefault,
132 nullptr,
133 reinterpret_cast<CGLContextObj>(nsGLContext.CGLContextObj),
134 nsGLPixelFormat,
135 nil,
136 &cvOpenGLTextureCache)) {
137 qWarning() << "OpenGL texture cache creation failed";
138 m_rhi = nullptr;
139 }
140#endif
141#ifdef Q_OS_IOS
142 // Create an OpenGL CoreVideo texture cache from the pixel buffer.
143 if (CVOpenGLESTextureCacheCreate(
144 kCFAllocatorDefault,
145 nullptr,
146 [EAGLContext currentContext],
147 nullptr,
148 &cvOpenGLESTextureCache)) {
149 qWarning() << "OpenGL texture cache creation failed";
150 m_rhi = nullptr;
151 }
152#endif
153#else
154 m_rhi = nullptr;
155#endif // QT_CONFIG(opengl)
156 }
158}
159
161{
162 if (layer == m_layer)
163 return;
164
165 if (m_layer)
167
168 m_layer = layer;
169 if (m_layer)
170 [m_layer retain];
171
172 reconfigure();
173}
174
176{
179 m_outputSettings = nil;
180
181 // Set pixel format
182 NSDictionary *dictionary = nil;
183 if (m_rhi && m_rhi->backend() == QRhi::OpenGLES2) {
184#if QT_CONFIG(opengl)
185 dictionary = @{(NSString *)kCVPixelBufferPixelFormatTypeKey:
186 @(kCVPixelFormatType_32BGRA)
187#ifndef Q_OS_IOS // On iOS this key generates a warning about unsupported key.
188 , (NSString *)kCVPixelBufferOpenGLCompatibilityKey: @true
189#endif // Q_OS_IOS
190 };
191#endif
192 } else {
193 dictionary = @{(NSString *)kCVPixelBufferPixelFormatTypeKey:
194 @[
195 @(kCVPixelFormatType_32BGRA),
196 @(kCVPixelFormatType_32RGBA),
197 @(kCVPixelFormatType_422YpCbCr8),
198 @(kCVPixelFormatType_422YpCbCr8_yuvs),
199 @(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange),
200 @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange),
201 @(kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange),
202 @(kCVPixelFormatType_420YpCbCr10BiPlanarFullRange),
203 @(kCVPixelFormatType_OneComponent8),
204 @(kCVPixelFormatType_OneComponent16),
205 @(kCVPixelFormatType_420YpCbCr8Planar),
206 @(kCVPixelFormatType_420YpCbCr8PlanarFullRange)
207 ]
208#ifndef Q_OS_IOS // This key is not supported and generates a warning.
209 , (NSString *)kCVPixelBufferMetalCompatibilityKey: @true
210#endif // Q_OS_IOS
211 };
212 }
213
214 m_outputSettings = [[NSDictionary alloc] initWithDictionary:dictionary];
215}
216
218{
219 if (!m_layer)
220 return;
221 [CATransaction begin];
222 [CATransaction setDisableActions: YES]; // disable animation/flicks
223 m_layer.frame = QRectF(0, 0, nativeSize().width(), nativeSize().height()).toCGRect();
224 m_layer.bounds = m_layer.frame;
225 [CATransaction commit];
226}
227
228#include "moc_avfvideosink_p.cpp"
virtual void setLayer(CALayer *layer)
NSDictionary * m_outputSettings
virtual void setOutputSettings()
virtual void setRhi(QRhi *)
virtual void reconfigure()=0
AVFVideoSink * m_sink
void setVideoSink(AVFVideoSink *sink)
QSize nativeSize() const
CVMetalTextureCacheRef cvMetalTextureCache
AVFVideoSink(QVideoSink *parent=nullptr)
virtual ~AVFVideoSink()
void setRhi(QRhi *rhi) override
void setVideoSinkInterface(AVFVideoSinkInterface *interface)
void setNativeSize(QSize size)
\inmodule QtCore
Definition qmutex.h:313
Native interface to an NSOpenGLContext on \macos.
\inmodule QtCore\reentrant
Definition qrect.h:484
\variable QRhiGles2InitParams::format
\inmodule QtRhi
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
Definition qrhi.h:1804
Implementation backend() const
Definition qrhi.cpp:8651
@ Metal
Definition qrhi.h:1811
@ OpenGLES2
Definition qrhi.h:1809
const QRhiNativeHandles * nativeHandles()
Definition qrhi.cpp:10137
\inmodule QtCore
Definition qsize.h:25
The QVideoSink class represents a generic sink for video data.
Definition qvideosink.h:22
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char * interface
EGLOutputLayerEXT layer
#define qWarning
Definition qlogging.h:166
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLint GLint GLint GLsizei GLsizei GLsizei GLboolean commit
GLint GLsizei width
GLsizei GLenum GLboolean sink
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QFuture< QSet< QString > > dictionary
sem release()