Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qavfcamerarotationtracker.mm
Go to the documentation of this file.
1
// Copyright (C) 2025 The Qt Company Ltd.
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
<
QtFFmpegMediaPluginImpl
/
private
/
qavfcamerarotationtracker_p
.
h
>
5
6
#
include
<
QtCore
/
qassert
.
h
>
7
8
#
include
<
AVFoundation
/
AVFoundation
.
h
>
9
10
#
ifdef
Q_OS_IOS
11
#
include
<
UIKit
/
UIKit
.
h
>
12
#
endif
// Q_OS_IOS
13
14
#
include
<
cmath
>
15
16
QT_BEGIN_NAMESPACE
17
18
namespace
{
19
20
#
ifdef
Q_OS_IOS
21
[[nodiscard]]
int
uiDeviceOrientationToRotationDegrees(UIDeviceOrientation orientation)
22
{
23
switch
(orientation) {
24
case
UIDeviceOrientationLandscapeLeft:
return
0;
25
case
UIDeviceOrientationPortrait:
return
90;
26
case
UIDeviceOrientationLandscapeRight:
return
180;
27
case
UIDeviceOrientationPortraitUpsideDown:
return
270;
28
default
:
29
Q_ASSERT(
false
);
30
Q_UNREACHABLE_RETURN(0);
31
}
32
}
33
#
endif
34
35
}
36
37
namespace
QFFmpeg
{
// namespace QFFmpeg start
38
39
AvfCameraRotationTracker
::
AvfCameraRotationTracker
(
AVCaptureDevice
*
avCaptureDevice
)
40
{
41
Q_ASSERT
(
avCaptureDevice
!=
nullptr
);
42
43
m_avCaptureDevice
= [
avCaptureDevice
retain
];
44
45
// Use RotationCoordinator if we can.
46
if
(@
available
(
macOS
14.0,
iOS
17.0, *)) {
47
m_avRotationCoordinator
= [[
AVCaptureDeviceRotationCoordinator
alloc
]
48
initWithDevice
:
m_avCaptureDevice
49
previewLayer
:
nil
];
50
}
51
#
ifdef
Q_OS_IOS
52
else
{
53
// If we're running iOS 16 or older, we need to register for UIDeviceOrientation changes.
54
[[
UIDevice
currentDevice
]
beginGeneratingDeviceOrientationNotifications
];
55
m_receivingUiDeviceOrientationNotifications
=
true
;
56
}
57
#
endif
58
}
59
60
AvfCameraRotationTracker
::
AvfCameraRotationTracker
(
AvfCameraRotationTracker
&&
other
)
noexcept
:
61
m_avCaptureDevice
(
std
::
exchange
(
other
.
m_avCaptureDevice
,
nullptr
))
62
#
ifdef
Q_OS_IOS
63
,
m_receivingUiDeviceOrientationNotifications
(
64
std
::
exchange
(
other
.
m_receivingUiDeviceOrientationNotifications
,
false
))
65
#
endif
66
{
67
if
(@
available
(
macOS
14.0,
iOS
17.0, *)) {
68
m_avRotationCoordinator
=
std
::
exchange
(
other
.
m_avRotationCoordinator
,
nullptr
);
69
}
70
}
71
72
AvfCameraRotationTracker
::~
AvfCameraRotationTracker
()
73
{
74
clear
();
75
}
76
77
void
AvfCameraRotationTracker
::
swap
(
AvfCameraRotationTracker
&
other
)
78
{
79
std
::
swap
(
m_avCaptureDevice
,
other
.
m_avCaptureDevice
);
80
if
(@
available
(
macOS
14.0,
iOS
17.0, *)) {
81
std
::
swap
(
m_avRotationCoordinator
,
other
.
m_avRotationCoordinator
);
82
}
83
84
#
ifdef
Q_OS_IOS
85
std
::
swap
(
86
m_receivingUiDeviceOrientationNotifications
,
87
other
.
m_receivingUiDeviceOrientationNotifications
);
88
#
endif
89
}
90
91
void
AvfCameraRotationTracker
::
clear
()
92
{
93
if
(
m_avCaptureDevice
!=
nullptr
) {
94
[
m_avCaptureDevice
release
];
95
m_avCaptureDevice
=
nullptr
;
96
}
97
98
if
(@
available
(
macOS
14.0,
iOS
17.0, *)) {
99
if
(
m_avRotationCoordinator
!=
nullptr
) {
100
[
m_avRotationCoordinator
release
];
101
m_avRotationCoordinator
=
nullptr
;
102
}
103
}
104
105
#
ifdef
Q_OS_IOS
106
if
(
m_receivingUiDeviceOrientationNotifications
)
107
[[
UIDevice
currentDevice
]
endGeneratingDeviceOrientationNotifications
];
108
m_receivingUiDeviceOrientationNotifications
=
false
;
109
#
endif
110
}
111
112
int
AvfCameraRotationTracker
::
rotationDegrees
()
const
113
{
114
if
(
m_avCaptureDevice
==
nullptr
)
115
return
0;
116
117
if
(@
available
(
macOS
14.0,
iOS
17.0, *)) {
118
// This code assumes that AVCaptureDeviceRotationCoordinator
119
// .videoRotationAngleForHorizonLevelCapture returns degrees that are divisible by 90.
120
// This has been the case during testing.
121
//
122
// TODO: Some rotations are not valid for preview on some devices (such as
123
// iPhones not being allowed to have an upside-down window). This usage of the
124
// rotation coordinator will still return it as a valid preview rotation, and
125
// might cause bugs on iPhone previews.
126
if
(
m_avRotationCoordinator
!=
nullptr
)
127
return
std
::
lround
(
m_avRotationCoordinator
.
videoRotationAngleForHorizonLevelCapture
);
128
}
129
#
ifdef
Q_OS_IOS
130
if
(
m_receivingUiDeviceOrientationNotifications
) {
131
// TODO: The new orientation can be FlatFaceDown or FlatFaceUp, neither of
132
// which should trigger a camera re-orientation. We can't store the previously
133
// valid orientation because this method has to be const. Currently
134
// this means orientation of the camera might be incorrect when laying the device
135
// down flat.
136
const
UIDeviceOrientation
orientation
= [[
UIDevice
currentDevice
]
orientation
];
137
138
const
AVCaptureDevicePosition
captureDevicePosition
=
m_avCaptureDevice
.
position
;
139
140
// If the position is set to PositionUnspecified, it's a good indication that
141
// this is an external webcam. In which case, don't apply any rotation.
142
if
(
captureDevicePosition
==
AVCaptureDevicePositionBack
)
143
return
uiDeviceOrientationToRotationDegrees
(
orientation
);
144
else
if
(
captureDevicePosition
==
AVCaptureDevicePositionFront
)
145
return
360 -
uiDeviceOrientationToRotationDegrees
(
orientation
);
146
}
147
#
endif
148
149
return
0;
150
}
151
152
}
// namespace QFFmpeg end
153
154
QT_END_NAMESPACE
QFFmpeg::AvioWriteBufferType
std::conditional_t< QT_FFMPEG_AVIO_WRITE_CONST, const uint8_t *, uint8_t * > AvioWriteBufferType
Definition
qffmpegioutils_p.h:29
qtmultimedia
src
plugins
multimedia
ffmpeg
darwin
qavfcamerarotationtracker.mm
Generated on
for Qt by
1.14.0