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
qwindowsformatinfo.cpp
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 <mfapi.h>
7#include <mftransform.h>
8#include <QtCore/private/qcomptr_p.h>
9#include <private/qwindowsmultimediautils_p.h>
10#include <private/qcomtaskresource_p.h>
11
12#include <QtCore/qlist.h>
13#include <QtCore/qset.h>
14#include <QtCore/qhash.h>
15#include <QtGui/qimagewriter.h>
16
18
19namespace {
20
21template<typename T>
22using CheckedCodecs = QHash<std::pair<T, QMediaFormat::ConversionMode>, bool>;
23
24bool isSupportedMFT(const GUID &category, const MFT_REGISTER_TYPE_INFO &type, QMediaFormat::ConversionMode mode)
25{
26 UINT32 count = 0;
27 QComTaskResource<IMFActivate *> activate;
28 HRESULT hr = MFTEnumEx(
29 category,
30 MFT_ENUM_FLAG_ALL,
31 (mode == QMediaFormat::Encode) ? nullptr : &type, // Input type
32 (mode == QMediaFormat::Encode) ? &type : nullptr, // Output type
33 activate.address(),
34 &count
35 );
36
37 return SUCCEEDED(hr) && count > 0;
38}
39
40bool isSupportedCodec(QMediaFormat::AudioCodec codec, QMediaFormat::ConversionMode mode)
41{
42 return isSupportedMFT((mode == QMediaFormat::Encode) ? MFT_CATEGORY_AUDIO_ENCODER : MFT_CATEGORY_AUDIO_DECODER,
43 { MFMediaType_Audio, QWindowsMultimediaUtils::audioFormatForCodec(codec) },
44 mode);
45}
46
47bool isSupportedCodec(QMediaFormat::VideoCodec codec, QMediaFormat::ConversionMode mode)
48{
49 return isSupportedMFT((mode == QMediaFormat::Encode) ? MFT_CATEGORY_VIDEO_ENCODER : MFT_CATEGORY_VIDEO_DECODER,
50 { MFMediaType_Video, QWindowsMultimediaUtils::videoFormatForCodec(codec) },
51 mode);
52}
53
54template <typename T>
55bool isSupportedCodec(T codec, QMediaFormat::ConversionMode m, CheckedCodecs<T> &checkedCodecs)
56{
57 if (auto it = checkedCodecs.constFind(std::pair{codec, m}); it != checkedCodecs.constEnd())
58 return it.value();
59
60 const bool supported = isSupportedCodec(codec, m);
61
62 checkedCodecs.insert(std::pair{codec, m}, supported);
63 return supported;
64}
65
66}
67
69{
70 QList<QImageCapture::FileFormat> list;
71 const auto formats = QImageWriter::supportedImageFormats();
72
73 for (const auto &f : formats) {
74 auto format = QString::fromUtf8(f);
75 if (format.compare(QLatin1String("jpg"), Qt::CaseInsensitive) == 0)
76 list.append(QImageCapture::FileFormat::JPEG);
77 else if (format.compare(QLatin1String("png"), Qt::CaseInsensitive) == 0)
78 list.append(QImageCapture::FileFormat::PNG);
79 else if (format.compare(QLatin1String("webp"), Qt::CaseInsensitive) == 0)
80 list.append(QImageCapture::FileFormat::WebP);
81 else if (format.compare(QLatin1String("tiff"), Qt::CaseInsensitive) == 0)
82 list.append(QImageCapture::FileFormat::Tiff);
83 }
84
85 return list;
86}
87
88QWindowsFormatInfo::QWindowsFormatInfo()
89{
90 const QList<CodecMap> containerTable = {
91 { QMediaFormat::MPEG4,
92 { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::MP3, QMediaFormat::AudioCodec::ALAC, QMediaFormat::AudioCodec::AC3, QMediaFormat::AudioCodec::EAC3 },
93 { QMediaFormat::VideoCodec::H264, QMediaFormat::VideoCodec::H265, QMediaFormat::VideoCodec::MotionJPEG } },
94 { QMediaFormat::Matroska,
95 { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::MP3, QMediaFormat::AudioCodec::ALAC, QMediaFormat::AudioCodec::AC3, QMediaFormat::AudioCodec::EAC3, QMediaFormat::AudioCodec::FLAC, QMediaFormat::AudioCodec::Vorbis, QMediaFormat::AudioCodec::Opus },
96 { QMediaFormat::VideoCodec::H264, QMediaFormat::VideoCodec::H265, QMediaFormat::VideoCodec::VP8, QMediaFormat::VideoCodec::VP9, QMediaFormat::VideoCodec::MotionJPEG } },
97 { QMediaFormat::WebM,
98 { QMediaFormat::AudioCodec::Vorbis, QMediaFormat::AudioCodec::Opus },
99 { QMediaFormat::VideoCodec::VP8, QMediaFormat::VideoCodec::VP9 } },
100 { QMediaFormat::QuickTime,
101 { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::MP3, QMediaFormat::AudioCodec::ALAC, QMediaFormat::AudioCodec::AC3, QMediaFormat::AudioCodec::EAC3 },
102 { QMediaFormat::VideoCodec::H264, QMediaFormat::VideoCodec::H265, QMediaFormat::VideoCodec::MotionJPEG } },
103 { QMediaFormat::AAC,
104 { QMediaFormat::AudioCodec::AAC },
105 {} },
106 { QMediaFormat::MP3,
107 { QMediaFormat::AudioCodec::MP3 },
108 {} },
109 { QMediaFormat::FLAC,
110 { QMediaFormat::AudioCodec::FLAC },
111 {} },
112 { QMediaFormat::Mpeg4Audio,
113 { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::MP3, QMediaFormat::AudioCodec::ALAC, QMediaFormat::AudioCodec::AC3, QMediaFormat::AudioCodec::EAC3 },
114 {} },
115 { QMediaFormat::WMA,
116 { QMediaFormat::AudioCodec::WMA },
117 {} },
118 { QMediaFormat::WMV,
119 { QMediaFormat::AudioCodec::WMA },
120 { QMediaFormat::VideoCodec::WMV } }
121 };
122
123 const QSet<QMediaFormat::FileFormat> decoderFormats = {
124 QMediaFormat::MPEG4,
125 QMediaFormat::Matroska,
126 QMediaFormat::WebM,
127 QMediaFormat::QuickTime,
128 QMediaFormat::AAC,
129 QMediaFormat::MP3,
130 QMediaFormat::FLAC,
131 QMediaFormat::Mpeg4Audio,
132 QMediaFormat::WMA,
133 QMediaFormat::WMV,
134 };
135
136 const QSet<QMediaFormat::FileFormat> encoderFormats = {
137 QMediaFormat::MPEG4,
138 QMediaFormat::AAC,
139 QMediaFormat::MP3,
140 QMediaFormat::FLAC,
141 QMediaFormat::Mpeg4Audio,
142 QMediaFormat::WMA,
143 QMediaFormat::WMV,
144 };
145
146 CheckedCodecs<QMediaFormat::AudioCodec> checkedAudioCodecs;
147 CheckedCodecs<QMediaFormat::VideoCodec> checkedVideoCodecs;
148
149 auto ensureCodecs = [&] (CodecMap &codecs, QMediaFormat::ConversionMode mode) {
150 codecs.audio.removeIf([&] (auto codec) { return !isSupportedCodec(codec, mode, checkedAudioCodecs); });
151 codecs.video.removeIf([&] (auto codec) { return !isSupportedCodec(codec, mode, checkedVideoCodecs); });
152 return !codecs.video.empty() || !codecs.audio.empty();
153 };
154
155 for (const auto &codecMap : containerTable) {
156 if (decoderFormats.contains(codecMap.format)) {
157 auto m = codecMap;
158 if (ensureCodecs(m, QMediaFormat::Decode))
159 decoders.append(m);
160 }
161
162 if (encoderFormats.contains(codecMap.format)) {
163 auto m = codecMap;
164 if (ensureCodecs(m, QMediaFormat::Encode))
165 encoders.append(m);
166 }
167 }
168
169 imageFormats = getImageFormatList();
170}
171
172QWindowsFormatInfo::~QWindowsFormatInfo()
173{
174}
175
176QT_END_NAMESPACE
bool isSupportedCodec(T codec, QMediaFormat::ConversionMode m, CheckedCodecs< T > &checkedCodecs)
bool isSupportedMFT(const GUID &category, const MFT_REGISTER_TYPE_INFO &type, QMediaFormat::ConversionMode mode)
bool isSupportedCodec(QMediaFormat::AudioCodec codec, QMediaFormat::ConversionMode mode)
static QList< QImageCapture::FileFormat > getImageFormatList()