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