source: trunk/src/3rdparty/phonon/qt7/backendinfo.mm

Last change on this file was 846, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 12.0 KB
Line 
1/* This file is part of the KDE project.
2
3 Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
5 This library is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 2.1 or 3 of the License.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this library. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#import <QTKit/QTMovie.h>
19#ifdef QUICKTIME_C_API_AVAILABLE
20 #include <QuickTime/QuickTime.h>
21 #undef check // avoid name clash;
22#endif
23
24#include "backendinfo.h"
25#include "backendheader.h"
26
27#include <AudioToolbox/AudioToolbox.h>
28#include <AudioUnit/AudioUnit.h>
29#include <CoreServices/CoreServices.h>
30
31
32QT_BEGIN_NAMESPACE
33
34namespace Phonon
35{
36namespace QT7
37{
38
39QString BackendInfo::quickTimeVersionString()
40{
41 SInt32 version;
42 OSStatus err = Gestalt(gestaltQuickTimeVersion, &version);
43 if (err != noErr)
44 return QString("00.0.0.0000");
45 QString versionString = QString("%1%2.%3.%4.%5%6%7%8")
46 .arg((version >> (7*4)) & 0xF)
47 .arg((version >> (6*4)) & 0xF)
48 .arg((version >> (5*4)) & 0xF)
49 .arg((version >> (4*4)) & 0xF)
50 .arg((version >> (3*4)) & 0xF)
51 .arg((version >> (2*4)) & 0xF)
52 .arg((version >> (1*4)) & 0xF)
53 .arg((version >> (0*4)) & 0xF);
54 return versionString;
55}
56
57bool BackendInfo::isQuickTimeVersionAvailable(int minHexVersion)
58{
59 // minHexVersion == 0x0741 means version 7.4.1
60 SInt32 qtHexVersion;
61 OSStatus err = Gestalt(gestaltQuickTimeVersion, &qtHexVersion);
62 return (err == noErr) ? ((qtHexVersion >> 16) >= minHexVersion) : 0;
63}
64
65#ifdef QUICKTIME_C_API_AVAILABLE
66static QString getMimeTypeTag(QTAtomContainer mimeList, int index, OSType type)
67{
68 QTAtom mimeAtom = QTFindChildByIndex(mimeList, kParentAtomIsContainer, type, index, 0);
69 char mimeCharArray[256];
70 long length;
71 OSStatus err = QTCopyAtomDataToPtr(mimeList, mimeAtom, true, sizeof(mimeCharArray)-1, mimeCharArray, &length);
72 if (err == noErr)
73 return QString::fromAscii(mimeCharArray, length);
74 return QString();
75}
76#endif // QUICKTIME_C_API_AVAILABLE
77
78#ifdef QUICKTIME_C_API_AVAILABLE
79QStringList BackendInfo::quickTimeMimeTypes(Scope scope)
80{
81 QStringList mimeTypes;
82 ARGUMENT_UNSUPPORTED(scope, Out, NORMAL_ERROR, mimeTypes)
83
84 ComponentDescription description;
85 description.componentType = MovieImportType;
86 description.componentSubType = 0;
87 description.componentManufacturer = 0;
88 description.componentFlags = hasMovieImportMIMEList | canMovieImportFiles;
89 description.componentFlagsMask = canMovieImportFiles | movieImportSubTypeIsFileExtension | hasMovieImportMIMEList;
90 Component component = FindNextComponent(0, &description);
91
92 while (component) {
93 QTAtomContainer mimeList = 0;
94 OSStatus err = MovieImportGetMIMETypeList((MovieImportComponent)component, &mimeList);
95 if (err == noErr){
96 int count = QTCountChildrenOfType(mimeList, kParentAtomIsContainer, 0);
97 for (int i=1; i<=count; ++i){
98 QString mimeType = getMimeTypeTag(mimeList, i, kMimeInfoMimeTypeTag);
99 if (mimeType.startsWith(QLatin1String("audio")) || mimeType.startsWith(QLatin1String("video"))){
100 if (err == noErr && !mimeType.isEmpty())
101 mimeTypes << mimeType;
102 }
103 }
104 }
105 QTDisposeAtomContainer(mimeList);
106 component = FindNextComponent(component, &description);
107 }
108 mimeTypes.sort();
109 return mimeTypes;
110}
111
112#else // QUICKTIME_C_API_AVAILABLE == false
113
114QString mimeForExtensionAudio(const QString &ext)
115{
116 if (ext == "3g2") return QLatin1String("audio/3g2");
117 if (ext == "3gp") return QLatin1String("audio/3gp");
118 if (ext == "aac") return QLatin1String("audio/aac");
119 if (ext == "ac3") return QLatin1String("audio/ac3");
120 if (ext == "aif") return QLatin1String("audio/aif");
121 if (ext == "aifc") return QLatin1String("audio/aifc");
122 if (ext == "aiff") return QLatin1String("audio/aiff");
123 if (ext == "amr") return QLatin1String("audio/amr");
124 if (ext == "au") return QLatin1String("audio/au");
125 if (ext == "bwf") return QLatin1String("audio/bwf");
126 if (ext == "caf") return QLatin1String("audio/caf");
127 if (ext == "cdda") return QLatin1String("audio/cdda");
128 if (ext == "gsm") return QLatin1String("audio/gsm");
129 if (ext == "kar") return QLatin1String("audio/kar");
130 if (ext == "m1a") return QLatin1String("audio/m1a");
131 if (ext == "m1s") return QLatin1String("audio/m1s");
132 if (ext == "m3u") return QLatin1String("audio/m3u");
133 if (ext == "m3url") return QLatin1String("audio/m3url");
134 if (ext == "mid") return QLatin1String("audio/mid");
135 if (ext == "midi") return QLatin1String("audio/midi");
136 if (ext == "mka") return QLatin1String("audio/mka");
137 if (ext == "mp3") return QLatin1String("audio/mp3");
138 if (ext == "mp4") return QLatin1String("audio/mp4");
139 if (ext == "mpa") return QLatin1String("audio/mpa");
140 if (ext == "mpeg") return QLatin1String("audio/mpeg");
141 if (ext == "mpg") return QLatin1String("audio/mpg");
142 if (ext == "mpg4") return QLatin1String("audio/mpg4");
143 if (ext == "mpm") return QLatin1String("audio/mpm");
144 if (ext == "qcp") return QLatin1String("audio/qcp");
145 if (ext == "sd2") return QLatin1String("audio/sd2");
146 if (ext == "smf") return QLatin1String("audio/smf");
147 if (ext == "snd") return QLatin1String("audio/snd");
148 if (ext == "ulw") return QLatin1String("audio/ulw");
149 if (ext == "wav") return QLatin1String("audio/wav");
150 if (ext == "wax") return QLatin1String("audio/wax");
151 if (ext == "wma") return QLatin1String("audio/wma");
152 return QString();
153}
154
155QString mimeForExtensionVideo(const QString &ext)
156{
157 if (ext == "3g2") return QLatin1String("video/3g2");
158 if (ext == "3gp") return QLatin1String("video/3gp");
159 if (ext == "asf") return QLatin1String("video/asf");
160 if (ext == "asx") return QLatin1String("video/asx");
161 if (ext == "avi") return QLatin1String("video/avi");
162 if (ext == "dif") return QLatin1String("video/dif");
163 if (ext == "dv") return QLatin1String("video/dv");
164 if (ext == "flc") return QLatin1String("video/flc");
165 if (ext == "fli") return QLatin1String("video/fli");
166 if (ext == "m15") return QLatin1String("video/m15");
167 if (ext == "m1a") return QLatin1String("video/m1a");
168 if (ext == "m1s") return QLatin1String("video/m1s");
169 if (ext == "m1v") return QLatin1String("video/m1v");
170 if (ext == "m75") return QLatin1String("video/m75");
171 if (ext == "mkv") return QLatin1String("video/mkv");
172 if (ext == "mp4") return QLatin1String("video/mp4");
173 if (ext == "mpa") return QLatin1String("video/mpa");
174 if (ext == "mpeg") return QLatin1String("video/mpeg");
175 if (ext == "mpg") return QLatin1String("video/mpg");
176 if (ext == "mpg4") return QLatin1String("video/mpg4");
177 if (ext == "mpm") return QLatin1String("video/mpm");
178 if (ext == "mpv") return QLatin1String("video/mpv");
179 if (ext == "vfw") return QLatin1String("video/vfw");
180 if (ext == "wm") return QLatin1String("video/wm");
181 if (ext == "wmv") return QLatin1String("video/wmv");
182 if (ext == "wmx") return QLatin1String("video/wmx");
183 if (ext == "wvx") return QLatin1String("video/wvx");
184 return QString();
185}
186
187QStringList BackendInfo::quickTimeMimeTypes(Scope scope)
188{
189 QStringList mimeTypes;
190 QStringList fileExtensions;
191 ARGUMENT_UNSUPPORTED(scope, Out, NORMAL_ERROR, mimeTypes)
192
193 PhononAutoReleasePool pool;
194 NSArray *fileTypes = [QTMovie movieFileTypes:QTIncludeAllTypes];
195 for (NSString *type in fileTypes){
196 QString formattedType = QString::fromUtf8([type UTF8String]);
197 formattedType = formattedType.remove('\'').remove('.').toLower();
198 QString audioMime = mimeForExtensionAudio(formattedType);
199 QString videoMime = mimeForExtensionVideo(formattedType);
200 if (!audioMime.isEmpty())
201 mimeTypes << audioMime;
202 if (!videoMime.isEmpty())
203 mimeTypes << videoMime;
204 if (audioMime.isEmpty() && videoMime.isEmpty())
205 fileExtensions << QLatin1String("application/x-qt-") + formattedType;
206 }
207 mimeTypes.sort();
208 fileExtensions.sort();
209 return mimeTypes + fileExtensions;
210}
211#endif // QUICKTIME_C_API_AVAILABLE
212
213QStringList BackendInfo::quickTimeCompressionFormats()
214{
215 QStringList result;
216
217#ifdef QUICKTIME_C_API_AVAILABLE
218
219 ComponentInstance component = 0;
220 OSStatus err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &component);
221 BACKEND_ASSERT3(err == noErr, "Could not open component for retrieving awailable compression formats", NORMAL_ERROR, result)
222
223 UInt32 size;
224 err = QTGetComponentPropertyInfo(component, kQTPropertyClass_SCAudio, kQTSCAudioPropertyID_AvailableCompressionFormatNamesList, 0, &size,0);
225 BACKEND_ASSERT3(err == noErr, "Could not get awailable compression formats", NORMAL_ERROR, result)
226
227 CFArrayRef formats[size];
228 err = QTGetComponentProperty(component, kQTPropertyClass_SCAudio, kQTSCAudioPropertyID_AvailableCompressionFormatNamesList, size, &formats, &size);
229 BACKEND_ASSERT3(err == noErr, "Could not get awailable compression formats", NORMAL_ERROR, result)
230
231 CFIndex count = CFArrayGetCount(*formats);
232 for (CFIndex i=0; i<count; ++i){
233 const CFStringRef name = (const struct __CFString *) CFArrayGetValueAtIndex(*formats, i);
234 result << PhononCFString::toQString(name);
235 }
236
237#endif // QUICKTIME_C_API_AVAILABLE
238 return result;
239}
240
241
242QStringList BackendInfo::coreAudioCodecs(Scope scope)
243{
244 QStringList result;
245 UInt32 size;
246 OSStatus err;
247 OSType *formatIDs;
248
249 OSType encodersOrDecoders = (scope == In)
250 ? kAudioFormatProperty_EncodeFormatIDs : kAudioFormatProperty_DecodeFormatIDs;
251
252 err = AudioFormatGetPropertyInfo(encodersOrDecoders, 0, NULL, &size);
253 BACKEND_ASSERT3(err == noErr, "Could not get awailable decoders/encoders", NORMAL_ERROR, result)
254
255 formatIDs = (OSType*)malloc(size);
256 UInt32 numFormats = size / sizeof(OSType);
257 err = AudioFormatGetProperty(encodersOrDecoders, 0, NULL, &size, formatIDs);
258 BACKEND_ASSERT(err == noErr, "Could not get awailable decoders/encoders", NORMAL_ERROR){
259 free(formatIDs);
260 return result;
261 }
262
263 for (UInt32 i=0; i<numFormats; ++i){
264 AudioStreamBasicDescription absd;
265 memset(&absd, 0, sizeof(absd));
266 absd.mFormatID = formatIDs[i];
267
268 CFStringRef name;
269 size = sizeof(CFStringRef);
270 err = AudioFormatGetProperty(kAudioFormatProperty_FormatName, sizeof(absd), &absd, &size, &name);
271 BACKEND_ASSERT(err == noErr, "Could not get awailable decoder/encoder names", NORMAL_ERROR){
272 free(formatIDs);
273 return result;
274 }
275 result << PhononCFString::toQString(name);
276 }
277 free(formatIDs);
278 return result;
279}
280
281QStringList BackendInfo::coreAudioFileTypes(Scope scope)
282{
283 QStringList result;
284 OSStatus err;
285 UInt32 propertySize;
286
287 OSType readOrwrite = (scope == In)
288 ? kAudioFileGlobalInfo_ReadableTypes : kAudioFileGlobalInfo_WritableTypes;
289
290 err = AudioFileGetGlobalInfoSize(readOrwrite, 0, NULL, &propertySize);
291 BACKEND_ASSERT3(err == noErr, "Could not get core audio file types", NORMAL_ERROR, result)
292
293 OSType *types = (OSType*)malloc(propertySize);
294 err = AudioFileGetGlobalInfo(readOrwrite, 0, NULL, &propertySize, types);
295 BACKEND_ASSERT3(err == noErr, "Could not get core audio file types", NORMAL_ERROR, result)
296
297 UInt32 numTypes = propertySize / sizeof(OSType);
298 for (UInt32 i=0; i<numTypes; ++i){
299 CFStringRef name;
300 UInt32 outSize = sizeof(name);
301 err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_FileTypeName, sizeof(OSType), types+i, &outSize, &name);
302 BACKEND_ASSERT3(err == noErr, "Could not get core audio file type names", NORMAL_ERROR, result)
303 result << PhononCFString::toQString(name);
304 }
305 return result;
306}
307
308}}
309
310QT_END_NAMESPACE
311
Note: See TracBrowser for help on using the repository browser.