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
qdarwinformatsinfo.mm
Go to the documentation of this file.
1// Copyright (C) 2021 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
5
6#include <QtCore/qdebug.h>
7
8#include <AVFoundation/AVFoundation.h>
9
11
12static struct {
13 const char *name;
15} mediaContainerMap[] = {
16 { "video/x-ms-asf", QMediaFormat::WMV },
17 { "video/avi", QMediaFormat::AVI },
18 { "video/x-matroska", QMediaFormat::Matroska },
19 { "video/mp4", QMediaFormat::MPEG4 },
20 { "video/quicktime", QMediaFormat::QuickTime },
21 { "video/ogg", QMediaFormat::Ogg },
22 { "audio/mp3", QMediaFormat::MP3 },
23 { "audio/flac", QMediaFormat::FLAC },
24 { nullptr, QMediaFormat::UnspecifiedFormat }
25};
26
27static struct {
28 const char *name;
29 QMediaFormat::VideoCodec value;
30} videoCodecMap[] = {
31 // See CMVideoCodecType for the four character code names of codecs
32 { "; codecs=\"mp1v\"", QMediaFormat::VideoCodec::MPEG1 },
33 { "; codecs=\"mp2v\"", QMediaFormat::VideoCodec::MPEG2 },
34 { "; codecs=\"mp4v\"", QMediaFormat::VideoCodec::MPEG4 },
35 { "; codecs=\"avc1\"", QMediaFormat::VideoCodec::H264 },
36 { "; codecs=\"hvc1\"", QMediaFormat::VideoCodec::H265 },
37 { "; codecs=\"vp09\"", QMediaFormat::VideoCodec::VP9 },
38 { "; codecs=\"av01\"", QMediaFormat::VideoCodec::AV1 }, // ### ????
39 { "; codecs=\"jpeg\"", QMediaFormat::VideoCodec::MotionJPEG },
40 { nullptr, QMediaFormat::VideoCodec::Unspecified }
41};
42
43static struct {
44 const char *name;
45 QMediaFormat::AudioCodec value;
46} audioCodecMap[] = {
47 // AudioFile.h
48 // ### The next two entries do not work, probably because they contain non a space and period and AVFoundation doesn't like that
49 // We know they are supported on all Apple platforms, so we'll add them manually below
50// { "; codecs=\".mp3\"", QMediaFormat::AudioCodec::MP3 },
51// { "; codecs=\"aac \"", QMediaFormat::AudioCodec::AAC },
52 { "; codecs=\"ac-3\"", QMediaFormat::AudioCodec::AC3 },
53 { "; codecs=\"ec-3\"", QMediaFormat::AudioCodec::EAC3 },
54 { "; codecs=\"flac\"", QMediaFormat::AudioCodec::FLAC },
55 { "; codecs=\"alac\"", QMediaFormat::AudioCodec::ALAC },
56 { "; codecs=\"opus\"", QMediaFormat::AudioCodec::Opus },
57 { nullptr, QMediaFormat::AudioCodec::Unspecified },
58};
59
61{
62 auto avtypes = [AVURLAsset audiovisualMIMETypes];
63 for (AVFileType filetype in avtypes) {
64 auto *m = mediaContainerMap;
65 while (m->name) {
66 if (strcmp(filetype.UTF8String, m->name)) {
67 ++m;
68 continue;
69 }
70
71 QList<QMediaFormat::VideoCodec> video;
72 QList<QMediaFormat::AudioCodec> audio;
73
74 auto *v = videoCodecMap;
75 while (v->name) {
76 QByteArray extendedMimetype = m->name;
77 extendedMimetype += v->name;
78 if ([AVURLAsset isPlayableExtendedMIMEType:[NSString stringWithUTF8String:extendedMimetype.constData()]])
79 video << v->value;
80 ++v;
81 }
82
83 auto *a = audioCodecMap;
84 while (a->name) {
85 QByteArray extendedMimetype = m->name;
86 extendedMimetype += a->name;
87 if ([AVURLAsset isPlayableExtendedMIMEType:[NSString stringWithUTF8String:extendedMimetype.constData()]])
88 audio << a->value;
89 ++a;
90 }
91 // Added manually, see comment in the list above
92 if (m->value <= QMediaFormat::AAC)
93 audio << QMediaFormat::AudioCodec::AAC;
94 if (m->value < QMediaFormat::AAC || m->value == QMediaFormat::MP3)
95 audio << QMediaFormat::AudioCodec::MP3;
96
97 decoders << CodecMap{ m->value, audio, video };
98 ++m;
99 }
100 }
101
102 // seems AVFoundation only supports those for encoding
103 encoders = {
104 { QMediaFormat::MPEG4,
105 { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::ALAC },
106 { QMediaFormat::VideoCodec::H264, QMediaFormat::VideoCodec::H265, QMediaFormat::VideoCodec::MotionJPEG } },
107 { QMediaFormat::QuickTime,
108 { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::ALAC },
109 { QMediaFormat::VideoCodec::H264, QMediaFormat::VideoCodec::H265, QMediaFormat::VideoCodec::MotionJPEG } },
110 { QMediaFormat::Mpeg4Audio,
111 { QMediaFormat::AudioCodec::AAC },
112 {} },
113 { QMediaFormat::Wave,
114 { QMediaFormat::AudioCodec::Wave },
115 {} },
116 };
117
118 // ###
119 imageFormats << QImageCapture::JPEG;
120}
121
123
124int QDarwinFormatInfo::audioFormatForCodec(QMediaFormat::AudioCodec codec)
125{
126 int codecId = kAudioFormatMPEG4AAC;
127 switch (codec) {
128 case QMediaFormat::AudioCodec::Unspecified:
129 case QMediaFormat::AudioCodec::DolbyTrueHD:
130 case QMediaFormat::AudioCodec::Vorbis:
131 case QMediaFormat::AudioCodec::WMA:
132 // Unsupported, shouldn't happen. Fall back to AAC
133 case QMediaFormat::AudioCodec::AAC:
134 codecId = kAudioFormatMPEG4AAC;
135 break;
136 case QMediaFormat::AudioCodec::MP3:
137 codecId = kAudioFormatMPEGLayer3;
138 break;
139 case QMediaFormat::AudioCodec::AC3:
140 codecId = kAudioFormatAC3;
141 break;
142 case QMediaFormat::AudioCodec::EAC3:
143 codecId = kAudioFormatEnhancedAC3;
144 break;
145 case QMediaFormat::AudioCodec::FLAC:
146 codecId = kAudioFormatFLAC;
147 break;
148 case QMediaFormat::AudioCodec::ALAC:
149 codecId = kAudioFormatAppleLossless;
150 break;
151 case QMediaFormat::AudioCodec::Opus:
152 codecId = kAudioFormatOpus;
153 break;
154 case QMediaFormat::AudioCodec::Wave:
155 codecId = kAudioFormatLinearPCM;
156 }
157 return codecId;
158}
159
160NSString *QDarwinFormatInfo::videoFormatForCodec(QMediaFormat::VideoCodec codec)
161{
162 const char *c = "hvc1"; // fallback is H265
163 switch (codec) {
164 case QMediaFormat::VideoCodec::Unspecified:
165 case QMediaFormat::VideoCodec::VP8:
166 case QMediaFormat::VideoCodec::H265:
167 case QMediaFormat::VideoCodec::AV1:
168 case QMediaFormat::VideoCodec::Theora:
169 case QMediaFormat::VideoCodec::WMV:
170 break;
171
172 case QMediaFormat::VideoCodec::MPEG1:
173 c = "mp1v";
174 break;
175 case QMediaFormat::VideoCodec::MPEG2:
176 c = "mp2v";
177 break;
178 case QMediaFormat::VideoCodec::MPEG4:
179 c = "mp4v";
180 break;
181 case QMediaFormat::VideoCodec::H264:
182 c = "avc1";
183 break;
184 case QMediaFormat::VideoCodec::VP9:
185 c = "vp09";
186 break;
187 case QMediaFormat::VideoCodec::MotionJPEG:
188 c = "jpeg";
189 }
190 return [NSString stringWithUTF8String:c];
191}
192
193NSString *QDarwinFormatInfo::avFileTypeForContainerFormat(QMediaFormat::FileFormat container)
194{
195 switch (container) {
196 case QMediaFormat::MPEG4:
197 return AVFileTypeMPEG4;
198 case QMediaFormat::QuickTime:
199 return AVFileTypeQuickTimeMovie;
200 case QMediaFormat::MP3:
201 return AVFileTypeMPEGLayer3;
202 case QMediaFormat::Mpeg4Audio:
203 return AVFileTypeAppleM4A;
204 case QMediaFormat::Wave:
205 return AVFileTypeWAVE;
206 default:
207 return AVFileTypeQuickTimeMovie;
208 }
209}
210
211QT_END_NAMESPACE
~QDarwinFormatInfo() override
Combined button and popup list for selecting options.
QMediaFormat::FileFormat value
const char * name