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 | |
4 | #include "qmediaformat.h" |
5 | #include "private/qplatformmediaintegration_p.h" |
6 | #include "private/qplatformmediaformatinfo_p.h" |
7 | #include <QtCore/qmimedatabase.h> |
8 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | /*! |
12 | \class QMediaFormat |
13 | \ingroup multimedia |
14 | \inmodule QtMultimedia |
15 | \brief Describes an encoding format for a multimedia file or stream. |
16 | \since 6.2 |
17 | |
18 | QMediaFormat describes an encoding format for a multimedia file or stream. |
19 | |
20 | You can check whether a certain media format can be used for encoding |
21 | or decoding using QMediaFormat. |
22 | */ |
23 | |
24 | /*! |
25 | \qmlvaluetype mediaFormat |
26 | \ingroup qmlvaluetypes |
27 | \since 6.2 |
28 | //! \instantiates QMediaFormat |
29 | \brief MediaFormat describes the format of a media file. |
30 | \inqmlmodule QtMultimedia |
31 | \ingroup multimedia_qml |
32 | |
33 | The MediaFormat type describes the format of a media file. It contains |
34 | three properties that describe the file type and the audio and video codecs |
35 | that are being used. |
36 | |
37 | MediaFormat can be used to specify the type of file that should be created |
38 | by a MediaRecorder. The snippet below shows an example that sets up the |
39 | recorder to create an mpeg4 video with AAC encoded audio and H265 video: |
40 | |
41 | \qml |
42 | CaptureSession { |
43 | ... // setup inputs |
44 | MediaRecorder { |
45 | mediaFormat { |
46 | fileFormat: MediaFormat.MPEG4 |
47 | audioCodec: MediaFormat.AudioCodec.AAC |
48 | videoCodec: MediaFormat.VideoCodec.H265 |
49 | } |
50 | } |
51 | } |
52 | \endqml |
53 | |
54 | If the specified mediaFormat is not supported, the MediaRecorder will automatically try |
55 | to find the best possible replacement format and use that instead. |
56 | |
57 | \sa MediaRecorder, CaptureSession |
58 | */ |
59 | |
60 | namespace { |
61 | |
62 | const char *mimeTypeForFormat[QMediaFormat::LastFileFormat + 2] = |
63 | { |
64 | "" , |
65 | "video/x-ms-wmv" , |
66 | "video/x-msvideo" , |
67 | "video/x-matroska" , |
68 | "video/mp4" , |
69 | "video/ogg" , |
70 | "video/quicktime" , |
71 | "video/webm" , |
72 | // Audio Formats |
73 | "audio/mp4" , |
74 | "audio/aac" , |
75 | "audio/x-ms-wma" , |
76 | "audio/mpeg" , |
77 | "audio/flac" , |
78 | "audio/wav" |
79 | }; |
80 | |
81 | constexpr QMediaFormat::FileFormat videoFormatPriorityList[] = |
82 | { |
83 | QMediaFormat::MPEG4, |
84 | QMediaFormat::QuickTime, |
85 | QMediaFormat::AVI, |
86 | QMediaFormat::WebM, |
87 | QMediaFormat::WMV, |
88 | QMediaFormat::Matroska, |
89 | QMediaFormat::Ogg, |
90 | QMediaFormat::UnspecifiedFormat |
91 | }; |
92 | |
93 | constexpr QMediaFormat::FileFormat audioFormatPriorityList[] = |
94 | { |
95 | QMediaFormat::Mpeg4Audio, |
96 | QMediaFormat::MP3, |
97 | QMediaFormat::WMA, |
98 | QMediaFormat::FLAC, |
99 | QMediaFormat::Wave, |
100 | QMediaFormat::UnspecifiedFormat |
101 | }; |
102 | |
103 | constexpr QMediaFormat::AudioCodec audioPriorityList[] = |
104 | { |
105 | QMediaFormat::AudioCodec::AAC, |
106 | QMediaFormat::AudioCodec::MP3, |
107 | QMediaFormat::AudioCodec::AC3, |
108 | QMediaFormat::AudioCodec::Opus, |
109 | QMediaFormat::AudioCodec::EAC3, |
110 | QMediaFormat::AudioCodec::DolbyTrueHD, |
111 | QMediaFormat::AudioCodec::WMA, |
112 | QMediaFormat::AudioCodec::FLAC, |
113 | QMediaFormat::AudioCodec::Vorbis, |
114 | QMediaFormat::AudioCodec::Wave, |
115 | QMediaFormat::AudioCodec::Unspecified |
116 | }; |
117 | |
118 | constexpr QMediaFormat::VideoCodec videoPriorityList[] = |
119 | { |
120 | QMediaFormat::VideoCodec::H265, |
121 | QMediaFormat::VideoCodec::VP9, |
122 | QMediaFormat::VideoCodec::H264, |
123 | QMediaFormat::VideoCodec::AV1, |
124 | QMediaFormat::VideoCodec::VP8, |
125 | QMediaFormat::VideoCodec::WMV, |
126 | QMediaFormat::VideoCodec::Theora, |
127 | QMediaFormat::VideoCodec::MPEG4, |
128 | QMediaFormat::VideoCodec::MPEG2, |
129 | QMediaFormat::VideoCodec::MPEG1, |
130 | QMediaFormat::VideoCodec::MotionJPEG, |
131 | }; |
132 | |
133 | } |
134 | |
135 | class QMediaFormatPrivate : public QSharedData |
136 | {}; |
137 | |
138 | QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QMediaFormatPrivate); |
139 | |
140 | /*! \enum QMediaFormat::FileFormat |
141 | |
142 | Describes the container format used in a multimedia file or stream. |
143 | |
144 | \value WMA |
145 | \l {Windows Media Audio} |
146 | \value AAC |
147 | \l{Advanced Audio Coding} |
148 | \value Matroska |
149 | \l{Matroska (MKV)} |
150 | \value WMV |
151 | \l{Windows Media Video} |
152 | \value MP3 |
153 | \l{MPEG-1 Audio Layer III or MPEG-2 Audio Layer III} |
154 | \value Wave |
155 | \l{Waveform Audio File Format} |
156 | \value Ogg |
157 | \l{Ogg} |
158 | \value MPEG4 |
159 | \l{MPEG-4} |
160 | \value AVI |
161 | \l{Audio Video Interleave} |
162 | \value QuickTime |
163 | \l{QuickTime} |
164 | \value WebM |
165 | \l{WebM} |
166 | \value Mpeg4Audio |
167 | \l{MPEG-4 Part 3 or MPEG-4 Audio (formally ISO/IEC 14496-3)} |
168 | \value FLAC |
169 | \l{Free Lossless Audio Codec} |
170 | \value UnspecifiedFormat |
171 | The format is unspecified. |
172 | |
173 | \omitvalue LastFileFormat |
174 | */ |
175 | |
176 | /*! \qmlproperty enumeration QtMultimedia::mediaFormat::fileFormat |
177 | |
178 | Describes the container format used in a multimedia file or stream. |
179 | It can take one of the following values: |
180 | |
181 | \table |
182 | \header \li Property value |
183 | \li Description |
184 | \row \li MediaFormat.WMA |
185 | \li \l{Windows Media Audio} |
186 | \row \li MediaFormat.AAC |
187 | \li \l{Advanced Audio Coding} |
188 | \row \li MediaFormat.Matroska |
189 | \li \l{Matroska (MKV)} |
190 | \row \li MediaFormat.WMV |
191 | \li \l{Windows Media Video} |
192 | \row \li MediaFormat.MP3 |
193 | \li \l{MPEG-1 Audio Layer III or MPEG-2 Audio Layer III} |
194 | \row \li MediaFormat.Wave |
195 | \li \l{Waveform Audio File Format} |
196 | \row \li MediaFormat.Ogg |
197 | \li \l{Ogg} |
198 | \row \li MediaFormat.MPEG4 |
199 | \li \l{MPEG-4} |
200 | \row \li MediaFormat.AVI |
201 | \li \l{Audio Video Interleave} |
202 | \row \li MediaFormat.QuickTime |
203 | \li \l{QuickTime} |
204 | \row \li MediaFormat.WebM |
205 | \li \l{WebM} |
206 | \row \li MediaFormat.Mpeg4Audio |
207 | \li \l{MPEG-4 Part 3 or MPEG-4 Audio (formally ISO/IEC 14496-3)} |
208 | \row \li MediaFormat.FLAC |
209 | \li \l{Free Lossless Audio Codec} |
210 | \row \li MediaFormat.UnspecifiedFormat |
211 | \li The format is unspecified. |
212 | \endtable |
213 | */ |
214 | |
215 | /*! \enum QMediaFormat::AudioCodec |
216 | |
217 | Describes the audio codec used in multimedia file or stream. |
218 | |
219 | \value WMA |
220 | \l {Windows Media Audio} |
221 | \value AC3 |
222 | \l {Dolby Digital} |
223 | \value AAC |
224 | \l{Advanced Audio Coding} |
225 | \value ALAC |
226 | \l{Apple Lossless Audio Codec} |
227 | \value DolbyTrueHD |
228 | \l{Dolby TrueHD} |
229 | \value EAC3 |
230 | \l {Dolby Digital Plus (EAC3)} |
231 | \value MP3 |
232 | \l{MPEG-1 Audio Layer III or MPEG-2 Audio Layer III} |
233 | \value Wave |
234 | \l{Waveform Audio File Format} |
235 | \value Vorbis |
236 | \l{Ogg Vorbis} |
237 | \value FLAC |
238 | \l{Free Lossless Audio Codec} |
239 | \value Opus |
240 | \l{Opus Audio Format} |
241 | \value Unspecified |
242 | Unspecified codec |
243 | |
244 | \omitvalue LastAudioCodec |
245 | */ |
246 | |
247 | /*! \qmlproperty enumeration QtMultimedia::mediaFormat::audioCodec |
248 | |
249 | Describes the audio codec used in multimedia file or stream. |
250 | It can take one of the following values: |
251 | |
252 | \table |
253 | \header \li Property value |
254 | \li Description |
255 | \row \li MediaFormat.WMA |
256 | \li \l {Windows Media Audio} |
257 | \row \li MediaFormat.AC3 |
258 | \li \l {Dolby Digital} |
259 | \row \li MediaFormat.AAC |
260 | \li \l{Advanced Audio Coding} |
261 | \row \li MediaFormat.ALAC |
262 | \li \l{Apple Lossless Audio Codec} |
263 | \row \li MediaFormat.DolbyTrueHD |
264 | \li \l{Dolby TrueHD} |
265 | \row \li MediaFormat.EAC3 |
266 | \li \l {Dolby Digital Plus (EAC3)} |
267 | \row \li MediaFormat.MP3 |
268 | \li \l{MPEG-1 Audio Layer III or MPEG-2 Audio Layer III} |
269 | \row \li MediaFormat.Wave |
270 | \li \l{Waveform Audio File Format} |
271 | \row \li MediaFormat.Vorbis |
272 | \li \l{Ogg Vorbis} |
273 | \row \li MediaFormat.FLAC |
274 | \li \l{Free Lossless Audio Codec} |
275 | \row \li MediaFormat.Opus |
276 | \li \l{Opus Audio Format} |
277 | \row \li MediaFormat.Unspecified |
278 | \li Unspecified codec |
279 | \endtable |
280 | */ |
281 | |
282 | /*! \enum QMediaFormat::VideoCodec |
283 | |
284 | Describes the video coded used in multimedia file or stream. |
285 | |
286 | \value VP8 |
287 | \l{VP8} |
288 | \value MPEG2 |
289 | \l{MPEG-2} |
290 | \value MPEG1 |
291 | \l{MPEG-1} |
292 | \value WMV |
293 | \l{Windows Media Video} |
294 | \value H265 |
295 | \l{High Efficiency Video Coding (HEVC)} |
296 | \value H264 |
297 | \l{Advanced Video Coding} |
298 | \value MPEG4 |
299 | \l{MPEG-4} |
300 | \value AV1 |
301 | \l{AOMedia Video 1} |
302 | \value MotionJPEG |
303 | \l{MotionJPEG} |
304 | \value VP9 |
305 | \l{VP9} |
306 | \value Theora |
307 | \l{Theora} |
308 | \value Unspecified |
309 | Video codec not specified |
310 | |
311 | \omitvalue LastVideoCodec |
312 | */ |
313 | |
314 | /*! \qmlproperty enumeration QtMultimedia::mediaFormat::videoCodec |
315 | |
316 | Describes the video codec used in multimedia file or stream. |
317 | It can take one of the following values: |
318 | |
319 | \table |
320 | \header \li Property value |
321 | \li Description |
322 | \row \li MediaFormat.VP8 |
323 | \li \l{VP8} |
324 | \row \li MediaFormat.MPEG2 |
325 | \li \l{MPEG-2} |
326 | \row \li MediaFormat.MPEG1 |
327 | \li \l{MPEG-1} |
328 | \row \li MediaFormat.WMV |
329 | \li \l{Windows Media Video} |
330 | \row \li MediaFormat.H265 |
331 | \li \l{High Efficiency Video Coding (HEVC)} |
332 | \row \li MediaFormat.H264 |
333 | \li \l{Advanced Video Coding} |
334 | \row \li MediaFormat.MPEG4 |
335 | \li \l{MPEG-4} |
336 | \row \li MediaFormat.AV1 |
337 | \li \l{AOMedia Video 1} |
338 | \row \li MediaFormat.MotionJPEG |
339 | \li \l{MotionJPEG} |
340 | \row \li MediaFormat.VP9 |
341 | \li \l{VP9} |
342 | \row \li MediaFormat.Theora |
343 | \li \l{Theora} |
344 | \row \li MediaFormat.Unspecified |
345 | \li Video codec not specified |
346 | \endtable |
347 | */ |
348 | |
349 | // these are non inline to make a possible future addition of a d pointer binary compatible |
350 | |
351 | /*! |
352 | Constructs a QMediaFormat object for \a format. |
353 | */ |
354 | QMediaFormat::QMediaFormat(FileFormat format) |
355 | : fmt(format) |
356 | { |
357 | } |
358 | |
359 | /*! |
360 | Destroys the QMediaFormat object. |
361 | */ |
362 | QMediaFormat::~QMediaFormat() = default; |
363 | |
364 | /*! |
365 | Constructs a QMediaFormat object by copying from \a other. |
366 | */ |
367 | QMediaFormat::QMediaFormat(const QMediaFormat &other) noexcept = default; |
368 | |
369 | /*! |
370 | \fn void QMediaFormat::swap(QMediaFormat &other) noexcept |
371 | |
372 | Swaps the media format with \a other. |
373 | */ |
374 | /*! |
375 | Copies \a other into this QMediaFormat object. |
376 | */ |
377 | QMediaFormat &QMediaFormat::operator=(const QMediaFormat &other) noexcept = default; |
378 | |
379 | /*! \fn QMediaFormat::QMediaFormat(QMediaFormat &&other) |
380 | |
381 | Constructs a QMediaFormat objects by moving from \a other. |
382 | */ |
383 | |
384 | /*! \fn QMediaFormat &QMediaFormat::operator=(QMediaFormat &&other) |
385 | |
386 | Moves \a other into this QMediaFormat objects. |
387 | */ |
388 | |
389 | // Properties |
390 | /*! \property QMediaFormat::fileFormat |
391 | |
392 | \brief The file (container) format of the media. |
393 | |
394 | \sa QMediaFormat::FileFormat |
395 | */ |
396 | |
397 | /*! \property QMediaFormat::audioCodec |
398 | |
399 | \brief The audio codec of the media. |
400 | |
401 | \sa QMediaFormat::AudioCodec |
402 | */ |
403 | |
404 | /*! \property QMediaFormat::videoCodec |
405 | |
406 | \brief The video codec of the media. |
407 | |
408 | \sa QMediaFormat::VideoCodec |
409 | */ |
410 | |
411 | /*! \fn void QMediaFormat::setVideoCodec(VideoCodec codec) |
412 | |
413 | Sets the video codec to \a codec. |
414 | |
415 | \sa videoCodec(), QMediaFormat::VideoCodec |
416 | */ |
417 | |
418 | /*! \fn QMediaFormat::VideoCodec QMediaFormat::videoCodec() const |
419 | |
420 | Returns the video codec used in this format. |
421 | |
422 | \sa setVideoCodec(), QMediaFormat::VideoCodec |
423 | */ |
424 | |
425 | /*! \fn void QMediaFormat::setAudioCodec(AudioCodec codec) |
426 | |
427 | Sets the audio codec to \a codec. |
428 | |
429 | \sa audioCodec(), QMediaFormat::AudioCodec |
430 | */ |
431 | |
432 | /*! \fn QMediaFormat::AudioCodec QMediaFormat::audioCodec() const |
433 | |
434 | Returns the audio codec used in this format. |
435 | |
436 | \sa setAudioCodec(), QMediaFormat::AudioCodec |
437 | */ |
438 | |
439 | /*! |
440 | Returns \c true if Qt Multimedia can encode or decode this format, |
441 | depending on \a mode. |
442 | */ |
443 | |
444 | bool QMediaFormat::isSupported(ConversionMode mode) const |
445 | { |
446 | return QPlatformMediaIntegration::instance()->formatInfo()->isSupported(format: *this, m: mode); |
447 | } |
448 | |
449 | /*! |
450 | Returns the \l{MIME type} for the file format used in this media format. |
451 | */ |
452 | |
453 | QMimeType QMediaFormat::mimeType() const |
454 | { |
455 | return QMimeDatabase().mimeTypeForName(nameOrAlias: QString::fromLatin1(ba: mimeTypeForFormat[fmt + 1])); |
456 | } |
457 | |
458 | /*! |
459 | \enum QMediaFormat::ConversionMode |
460 | |
461 | In many cases, systems have asymmetric capabilities and can often decode more formats |
462 | or codecs than can be encoded. This enum describes the requested conversion mode to |
463 | be used when checking whether a certain file format or codec is supported. |
464 | |
465 | \value Encode |
466 | Used to check whether a certain file format or codec can be encoded. |
467 | \value Decode |
468 | Used to check whether a certain file format or codec can be decoded. |
469 | |
470 | \sa supportedFileFormats, supportedAudioCodecs, supportedVideoCodecs |
471 | */ |
472 | |
473 | /*! |
474 | \qmlmethod list<FileFormat> QtMultimedia::mediaFormat::supportedFileFormats(conversionMode) |
475 | Returns a list of file formats for the audio and video |
476 | codec indicated by \a{conversionMode}. |
477 | |
478 | To get all supported file formats, run this query on a default constructed MediaFormat. To |
479 | get a list of file formats supporting a specific combination of an audio and video codec, |
480 | you can set the audioCodec and videoCodec properties before running this query. |
481 | |
482 | \sa QMediaFormat::ConversionMode |
483 | */ |
484 | |
485 | /*! |
486 | Returns a list of file formats for the audio and video |
487 | codec indicated by \a{m}. |
488 | |
489 | To get all supported file formats, run this query on a default constructed |
490 | QMediaFormat. |
491 | |
492 | \sa QMediaFormat::ConversionMode |
493 | */ |
494 | QList<QMediaFormat::FileFormat> QMediaFormat::supportedFileFormats(QMediaFormat::ConversionMode m) |
495 | { |
496 | return QPlatformMediaIntegration::instance()->formatInfo()->supportedFileFormats(constraints: *this, m); |
497 | } |
498 | |
499 | /*! |
500 | \qmlmethod list<VideoCodec> QtMultimedia::mediaFormat::supportedVideoCodecs(conversionMode) |
501 | Returns a list of video codecs for the chosen file format and |
502 | audio codec (\a conversionMode). |
503 | |
504 | To get all supported video codecs, run this query on a default constructed MediaFormat. To |
505 | get a list of supported video codecs for a specific combination of a file format and an audio |
506 | codec, you can set the fileFormat and audioCodec properties before running this query. |
507 | |
508 | \sa QMediaFormat::ConversionMode |
509 | */ |
510 | |
511 | /*! |
512 | Returns a list of video codecs for the chosen file format and |
513 | audio codec (\a m). |
514 | |
515 | To get all supported video codecs, run this query on a default constructed |
516 | MediaFormat. |
517 | |
518 | \sa QMediaFormat::ConversionMode |
519 | */ |
520 | QList<QMediaFormat::VideoCodec> QMediaFormat::supportedVideoCodecs(QMediaFormat::ConversionMode m) |
521 | { |
522 | return QPlatformMediaIntegration::instance()->formatInfo()->supportedVideoCodecs(constraints: *this, m); |
523 | } |
524 | |
525 | /*! |
526 | \qmlmethod list<AudioCodec> QtMultimedia::mediaFormat::supportedAudioFormats(conversionMode) |
527 | Returns a list of audio codecs for the chosen file format and |
528 | video codec (\a conversionMode). |
529 | |
530 | To get all supported audio codecs, run this query on a default constructed MediaFormat. To get |
531 | a list of supported audio codecs for a specific combination of a file format and a video codec, |
532 | you can set the fileFormat and videoCodec properties before running this query. |
533 | |
534 | \sa QMediaFormat::ConversionMode |
535 | */ |
536 | |
537 | /*! |
538 | Returns a list of audio codecs for the chosen file format and |
539 | video codec (\a m). |
540 | |
541 | To get all supported audio codecs, run this query on a default constructed |
542 | QMediaFormat. |
543 | |
544 | \sa QMediaFormat::ConversionMode |
545 | */ |
546 | QList<QMediaFormat::AudioCodec> QMediaFormat::supportedAudioCodecs(QMediaFormat::ConversionMode m) |
547 | { |
548 | return QPlatformMediaIntegration::instance()->formatInfo()->supportedAudioCodecs(constraints: *this, m); |
549 | } |
550 | |
551 | /*! |
552 | \qmlmethod string QtMultimedia::mediaFormat::fileFormatName(fileFormat) |
553 | Returns a string based name for \a fileFormat. |
554 | */ |
555 | |
556 | /*! |
557 | Returns a string based name for \a fileFormat. |
558 | */ |
559 | QString QMediaFormat::fileFormatName(QMediaFormat::FileFormat fileFormat) |
560 | { |
561 | constexpr const char *descriptions[QMediaFormat::LastFileFormat + 2] = { |
562 | "Unspecified" , |
563 | "WMV" , |
564 | "AVI" , |
565 | "Matroska" , |
566 | "MPEG-4" , |
567 | "Ogg" , |
568 | "QuickTime" , |
569 | "WebM" , |
570 | // Audio Formats |
571 | "MPEG-4 Audio" , |
572 | "AAC" , |
573 | "WMA" , |
574 | "MP3" , |
575 | "FLAC" , |
576 | "Wave" |
577 | }; |
578 | return QString::fromUtf8(utf8: descriptions[int(fileFormat) + 1]); |
579 | } |
580 | |
581 | /*! |
582 | \qmlmethod string QtMultimedia::mediaFormat::audioCodecName(codec) |
583 | Returns a string based name for \a codec. |
584 | */ |
585 | |
586 | /*! |
587 | Returns a string based name for \a codec. |
588 | */ |
589 | QString QMediaFormat::audioCodecName(QMediaFormat::AudioCodec codec) |
590 | { |
591 | constexpr const char *descriptions[] = { |
592 | "Invalid" , |
593 | "MP3" , |
594 | "AAC" , |
595 | "AC3" , |
596 | "EAC3" , |
597 | "FLAC" , |
598 | "DolbyTrueHD" , |
599 | "Opus" , |
600 | "Vorbis" , |
601 | "Wave" , |
602 | "WMA" , |
603 | "ALAC" , |
604 | }; |
605 | return QString::fromUtf8(utf8: descriptions[int(codec) + 1]); |
606 | } |
607 | |
608 | /*! |
609 | \qmlmethod string QtMultimedia::mediaFormat::videoCodecName(codec) |
610 | Returns a string based name for \a codec. |
611 | */ |
612 | |
613 | /*! |
614 | Returns a string based name for \a codec. |
615 | */ |
616 | QString QMediaFormat::videoCodecName(QMediaFormat::VideoCodec codec) |
617 | { |
618 | constexpr const char *descriptions[] = { |
619 | "Invalid" , |
620 | "MPEG1" , |
621 | "MPEG2" , |
622 | "MPEG4" , |
623 | "H264" , |
624 | "H265" , |
625 | "VP8" , |
626 | "VP9" , |
627 | "AV1" , |
628 | "Theora" , |
629 | "WMV" , |
630 | "MotionJPEG" |
631 | }; |
632 | return QString::fromUtf8(utf8: descriptions[int(codec) + 1]); |
633 | } |
634 | |
635 | /*! |
636 | \qmlmethod string QtMultimedia::mediaFormat::fileFormatDescription(fileFormat) |
637 | Returns a description for \a fileFormat. |
638 | */ |
639 | |
640 | /*! |
641 | Returns a description for \a fileFormat. |
642 | */ |
643 | QString QMediaFormat::fileFormatDescription(QMediaFormat::FileFormat fileFormat) |
644 | { |
645 | constexpr const char *descriptions[QMediaFormat::LastFileFormat + 2] = { |
646 | "Unspecified File Format" , |
647 | "Windows Media Video" , |
648 | "Audio Video Interleave" , |
649 | "Matroska Multimedia Container" , |
650 | "MPEG-4 Video Container" , |
651 | "Ogg" , |
652 | "QuickTime Container" , |
653 | "WebM" , |
654 | // Audio Formats |
655 | "MPEG-4 Audio" , |
656 | "AAC" , |
657 | "Windows Media Audio" , |
658 | "MP3" , |
659 | "Free Lossless Audio Codec (FLAC)" , |
660 | "Wave File" |
661 | }; |
662 | return QString::fromUtf8(utf8: descriptions[int(fileFormat) + 1]); |
663 | } |
664 | |
665 | /*! |
666 | \qmlmethod string QtMultimedia::mediaFormat::audioCodecDescription(codec) |
667 | Returns a description for \a codec. |
668 | */ |
669 | |
670 | /*! |
671 | Returns a description for \a codec. |
672 | */ |
673 | QString QMediaFormat::audioCodecDescription(QMediaFormat::AudioCodec codec) |
674 | { |
675 | constexpr const char *descriptions[] = { |
676 | "Unspecified Audio Codec" , |
677 | "MP3" , |
678 | "Advanced Audio Codec (AAC)" , |
679 | "Dolby Digital (AC3)" , |
680 | "Dolby Digital Plus (E-AC3)" , |
681 | "Free Lossless Audio Codec (FLAC)" , |
682 | "Dolby True HD" , |
683 | "Opus" , |
684 | "Vorbis" , |
685 | "Wave" , |
686 | "Windows Media Audio" , |
687 | "Apple Lossless Audio Codec (ALAC)" , |
688 | }; |
689 | return QString::fromUtf8(utf8: descriptions[int(codec) + 1]); |
690 | } |
691 | |
692 | /*! |
693 | \qmlmethod string QtMultimedia::mediaFormat::videoCodecDescription(codec) |
694 | Returns a description for \a codec. |
695 | */ |
696 | |
697 | /*! |
698 | Returns a description for \a codec. |
699 | */ |
700 | QString QMediaFormat::videoCodecDescription(QMediaFormat::VideoCodec codec) |
701 | { |
702 | constexpr const char *descriptions[] = { |
703 | "Unspecified Video Codec" , |
704 | "MPEG-1 Video" , |
705 | "MPEG-2 Video" , |
706 | "MPEG-4 Video" , |
707 | "H.264" , |
708 | "H.265" , |
709 | "VP8" , |
710 | "VP9" , |
711 | "AV1" , |
712 | "Theora" , |
713 | "Windows Media Video" , |
714 | "MotionJPEG" |
715 | }; |
716 | return QString::fromUtf8(utf8: descriptions[int(codec) + 1]); |
717 | } |
718 | |
719 | /*! |
720 | \fn bool QMediaFormat::operator!=(const QMediaFormat &other) const |
721 | |
722 | Returns \c true if \a other is not equal to the current media format, |
723 | otherwise returns \c false. |
724 | */ |
725 | |
726 | /*! |
727 | Returns \c true if \a other is equal to the current media format, otherwise |
728 | returns \c false. |
729 | */ |
730 | bool QMediaFormat::operator==(const QMediaFormat &other) const |
731 | { |
732 | Q_ASSERT(!d); |
733 | return fmt == other.fmt && |
734 | audio == other.audio && |
735 | video == other.video; |
736 | } |
737 | |
738 | /*! |
739 | \enum QMediaFormat::ResolveFlags |
740 | |
741 | Describes the requirements for resolving a suitable format for |
742 | QMediaRecorder. |
743 | |
744 | \value NoFlags |
745 | No requirements |
746 | \value RequiresVideo |
747 | A video codec is required |
748 | |
749 | \sa resolveForEncoding() |
750 | */ |
751 | |
752 | /*! |
753 | Resolves the format, based on \a flags, to a format that is supported by |
754 | QMediaRecorder. |
755 | |
756 | This method tries to find the best possible match for unspecified settings. |
757 | Settings that are not supported by the recorder will be modified to the closest |
758 | match that is supported. |
759 | |
760 | When resolving, priority is given in the following order: |
761 | \list 1 |
762 | \li File format |
763 | \li Video codec |
764 | \li Audio codec |
765 | \endlist |
766 | */ |
767 | void QMediaFormat::resolveForEncoding(ResolveFlags flags) |
768 | { |
769 | const bool requiresVideo = (flags & ResolveFlags::RequiresVideo) != 0; |
770 | |
771 | if (!requiresVideo) |
772 | video = VideoCodec::Unspecified; |
773 | |
774 | // need to adjust the format. Priority is given first to file format, then video codec, then audio codec |
775 | |
776 | QMediaFormat nullFormat; |
777 | auto supportedFormats = nullFormat.supportedFileFormats(m: QMediaFormat::Encode); |
778 | auto supportedAudioCodecs = nullFormat.supportedAudioCodecs(m: QMediaFormat::Encode); |
779 | auto supportedVideoCodecs = nullFormat.supportedVideoCodecs(m: QMediaFormat::Encode); |
780 | |
781 | auto bestSupportedFileFormat = [&](QMediaFormat::AudioCodec audio = QMediaFormat::AudioCodec::Unspecified, |
782 | QMediaFormat::VideoCodec video = QMediaFormat::VideoCodec::Unspecified) |
783 | { |
784 | QMediaFormat f; |
785 | f.setAudioCodec(audio); |
786 | f.setVideoCodec(video); |
787 | auto supportedFormats = f.supportedFileFormats(m: QMediaFormat::Encode); |
788 | auto *list = (flags == NoFlags) ? audioFormatPriorityList : videoFormatPriorityList; |
789 | while (*list != QMediaFormat::UnspecifiedFormat) { |
790 | if (supportedFormats.contains(t: *list)) |
791 | break; |
792 | ++list; |
793 | } |
794 | return *list; |
795 | }; |
796 | |
797 | // reset format if it does not support video when video is required |
798 | if (requiresVideo && this->supportedVideoCodecs(m: QMediaFormat::Encode).isEmpty()) |
799 | fmt = QMediaFormat::UnspecifiedFormat; |
800 | |
801 | // reset non supported formats and codecs |
802 | if (!supportedFormats.contains(t: fmt)) |
803 | fmt = QMediaFormat::UnspecifiedFormat; |
804 | if (!supportedAudioCodecs.contains(t: audio)) |
805 | audio = QMediaFormat::AudioCodec::Unspecified; |
806 | if (!requiresVideo || !supportedVideoCodecs.contains(t: video)) |
807 | video = QMediaFormat::VideoCodec::Unspecified; |
808 | |
809 | if (requiresVideo) { |
810 | // try finding a file format that is supported |
811 | if (fmt == QMediaFormat::UnspecifiedFormat) |
812 | fmt = bestSupportedFileFormat(audio, video); |
813 | // try without the audio codec |
814 | if (fmt == QMediaFormat::UnspecifiedFormat) |
815 | fmt = bestSupportedFileFormat(QMediaFormat::AudioCodec::Unspecified, video); |
816 | } |
817 | // try without the video codec |
818 | if (fmt == QMediaFormat::UnspecifiedFormat) |
819 | fmt = bestSupportedFileFormat(audio); |
820 | // give me a format that's supported |
821 | if (fmt == QMediaFormat::UnspecifiedFormat) |
822 | fmt = bestSupportedFileFormat(); |
823 | // still nothing? Give up |
824 | if (fmt == QMediaFormat::UnspecifiedFormat) { |
825 | *this = {}; |
826 | return; |
827 | } |
828 | |
829 | // find a working video codec |
830 | if (requiresVideo) { |
831 | // reset the audio codec, so that we won't throw away the video codec |
832 | // if it is supported (choosing the specified video codec has higher |
833 | // priority than the specified audio codec) |
834 | auto a = audio; |
835 | audio = QMediaFormat::AudioCodec::Unspecified; |
836 | auto videoCodecs = this->supportedVideoCodecs(m: QMediaFormat::Encode); |
837 | if (!videoCodecs.contains(t: video)) { |
838 | // not supported, try to find a replacement |
839 | auto *list = videoPriorityList; |
840 | while (*list != QMediaFormat::VideoCodec::Unspecified) { |
841 | if (videoCodecs.contains(t: *list)) |
842 | break; |
843 | ++list; |
844 | } |
845 | video = *list; |
846 | } |
847 | audio = a; |
848 | } else { |
849 | video = QMediaFormat::VideoCodec::Unspecified; |
850 | } |
851 | |
852 | // and a working audio codec |
853 | auto audioCodecs = this->supportedAudioCodecs(m: QMediaFormat::Encode); |
854 | if (!audioCodecs.contains(t: audio)) { |
855 | auto *list = audioPriorityList; |
856 | while (*list != QMediaFormat::AudioCodec::Unspecified) { |
857 | if (audioCodecs.contains(t: *list)) |
858 | break; |
859 | ++list; |
860 | } |
861 | audio = *list; |
862 | } |
863 | } |
864 | |
865 | /*! |
866 | \variable QMediaFormat::audio |
867 | \internal |
868 | */ |
869 | /*! |
870 | \variable QMediaFormat::d |
871 | \internal |
872 | */ |
873 | /*! |
874 | \variable QMediaFormat::video |
875 | \internal |
876 | */ |
877 | /*! |
878 | \variable QMediaFormat::fmt |
879 | \internal |
880 | */ |
881 | QT_END_NAMESPACE |
882 | |
883 | #include "moc_qmediaformat.cpp" |
884 | |