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
qffmpeg_p.h
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#ifndef QFFMPEG_P_H
4#define QFFMPEG_P_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include <QtFFmpegMediaPluginImpl/private/qffmpegdefs_p.h>
18#include <QtFFmpegMediaPluginImpl/private/qffmpegcodec_p.h>
19#include <QtFFmpegMediaPluginImpl/private/qffmpegavaudioformat_p.h>
20#include <QtMultimedia/qvideoframeformat.h>
21#include <QtMultimedia/private/qmultimedia_ranges_p.h>
22
23#include <qstring.h>
24#include <optional>
25
26[[maybe_unused]] static inline bool operator==(const AVRational &lhs, const AVRational &rhs)
27{
28 return lhs.num == rhs.num && lhs.den == rhs.den;
29}
30
31[[maybe_unused]] static inline bool operator!=(const AVRational &lhs, const AVRational &rhs)
32{
33 return !(lhs == rhs);
34}
35
36QT_BEGIN_NAMESPACE
37
38namespace QFFmpeg
39{
40
42
43inline std::optional<qint64> mul(qint64 a, AVRational b)
44{
45 if (b.den == 0)
46 return {};
47
48 auto multiplyAndRound = [](qint64 a, AVRational b) { //
49 return (a * b.num + b.den / 2) / b.den;
50 };
51
52 if (a < 0)
53 return -multiplyAndRound(-a, b);
54 else
55 return multiplyAndRound(a, b);
56}
57
58inline std::optional<qreal> mul(qreal a, AVRational b)
59{
60 return b.den != 0 ? a * qreal(b.num) / qreal(b.den) : std::optional<qreal>{};
61}
62
63inline std::optional<qint64> timeStampMs(qint64 ts, AVRational base)
64{
65 return mul(1'000 * ts, base);
66}
67
68inline std::optional<qint64> timeStampUs(qint64 ts, AVRational base)
69{
70 return mul(1'000'000 * ts, base);
71}
72
73template <typename Float>
74inline std::optional<Float> toFloat(AVRational r)
75{
76 return r.den != 0 ? Float(r.num) / Float(r.den) : std::optional<Float>{};
77}
78
79inline std::optional<qreal> toReal(AVRational r)
80{
81 return toFloat<qreal>(r);
82}
83
84inline QString err2str(int errnum)
85{
86 char buffer[AV_ERROR_MAX_STRING_SIZE + 1] = {};
87 av_make_error_string(buffer, AV_ERROR_MAX_STRING_SIZE, errnum);
88 return QString::fromLocal8Bit(buffer);
89}
90
91inline void setAVFrameTime(AVFrame &frame, int64_t pts, const AVRational &timeBase)
92{
93 frame.pts = pts;
94#if QT_FFMPEG_HAS_FRAME_TIME_BASE
95 frame.time_base = timeBase;
96#else
97 Q_UNUSED(timeBase);
98#endif
99}
100
101inline void getAVFrameTime(const AVFrame &frame, int64_t &pts, AVRational &timeBase)
102{
103 pts = frame.pts;
104#if QT_FFMPEG_HAS_FRAME_TIME_BASE
105 timeBase = frame.time_base;
106#else
107 timeBase = { 0, 1 };
108#endif
109}
110
111inline int64_t getAVFrameDuration(const AVFrame &frame)
112{
113#if QT_FFMPEG_HAS_FRAME_DURATION
114 return frame.duration;
115#else
116 return frame.pkt_duration;
117#endif
118}
119
121{
122 AVDictionary *opts = nullptr;
123
124 operator AVDictionary **() { return &opts; }
125
127
129
131 : opts(std::exchange(other.opts, nullptr))
132 {
133 }
134
136 {
137 if (opts)
139 }
140};
141
143{
144 template <typename T>
145 void operator()(T *object) const
146 {
147 if (object)
148 av_free(object);
149 }
150};
151
152template <auto F>
154{
155 template <typename T>
156 void operator()(T *object) const
157 {
158 using FunctionType = decltype(F);
159
160 static_assert(std::is_invocable_v<FunctionType, T *>
161 || std::is_invocable_v<FunctionType, T **>,
162 "F must be invocable with either T* or T**");
163
164 if constexpr (std::is_invocable_v<FunctionType, T **>) {
165 if (object)
166 F(&object);
167 } else
168 F(object);
169 }
170};
171
173
175{
176 return AVFrameUPtr(av_frame_alloc());
177}
178
186
187void freeAVIOContext(AVIOContext *&);
188
190{
191 void operator()(AVFormatContext *ctx) const
192 {
193 if (!ctx)
194 return;
195
196 if (ctx->flags & AVFMT_FLAG_CUSTOM_IO)
197 freeAVIOContext(ctx->pb);
198
199 avformat_close_input(&ctx);
200 }
201};
202
205
206bool isAVFormatSupported(const Codec &, const PixelOrSampleFormat &);
207
208// Search for the first element in the range that satisfies the predicate
209// The predicate is evaluated for each value in the range until it returns
210// true, and the corresponding value is returned. If no match is found,
211// std::nullopt is returned.
212template <typename Value, typename Predicate>
213std::optional<Value> findIf(QSpan<const Value> range, const Predicate &predicate)
214{
215 const auto value = ranges::find_if(range, predicate);
216 if (value == range.end())
217 return {};
218 return *value;
219}
220
221// Search the codec's pixel formats for a format that matches the predicate.
222// If no pixel format is found, repeat the search through the pixel formats
223// of all the codec's hardware configs. If no matching pixel format is found,
224// std::nullopt is returned. The predicate is evaluated once for each pixel
225// format until the predicate returns true.
226template <typename Predicate>
227std::optional<AVPixelFormat> findAVPixelFormat(const Codec &codec, const Predicate &predicate)
228{
229 if (codec.type() != AVMEDIA_TYPE_VIDEO)
230 return {};
231
232 const auto pixelFormats = codec.pixelFormats();
233
234 if (const auto format = findIf(pixelFormats, predicate))
235 return format;
236
237 // No matching pixel format was found. Check the pixel format
238 // of the codec's hardware config.
239 for (const AVCodecHWConfig *const config : codec.hwConfigs()) {
240 const AVPixelFormat format = config->pix_fmt;
241
242 if (format == AV_PIX_FMT_NONE)
243 continue;
244
245 if (predicate(format))
246 return format;
247 }
248 return {};
249}
250
251// Evaluate the function for each of the codec's pixel formats and each of
252// the pixel formats supported by the codec's hardware configs.
253template <typename Function>
254void forEachAVPixelFormat(const Codec &codec, const Function &function)
255{
256 findAVPixelFormat(codec, [&function](AVPixelFormat format) {
257 function(format);
258 return false; // Evaluate the function for all pixel formats
259 });
260}
261
262template <typename ValueT, typename ScoreT = AVScore>
264{
265 ValueT value;
267};
268
269template <typename ValueRange, typename CalculateScore,
271 typename ScoreType = std::invoke_result_t<CalculateScore, Value>>
272std::optional<ValueAndScore<Value, ScoreType>>
273findBestAVValueWithScore(ValueRange &&values, const CalculateScore &calculateScore)
274{
275 static_assert(std::is_invocable_v<CalculateScore, Value>);
276
277 std::optional<ValueAndScore<Value, ScoreType>> result;
278 for (const Value &val : values) {
279 const ScoreType score = calculateScore(val);
280 if (score == std::numeric_limits<ScoreType>::min())
281 continue;
282
283 if (!result || score > result->score)
284 result = { val, score };
285
286 if (result->score == std::numeric_limits<ScoreType>::max())
287 return result;
288 }
289
290 return result;
291}
292
293template <typename ValueRange, typename CalculateScore,
295std::optional<Value> findBestAVValue(ValueRange &&values, const CalculateScore &calculateScore)
296{
297 auto optionalValueAndScore = findBestAVValueWithScore(values, calculateScore);
298 if (optionalValueAndScore)
299 return optionalValueAndScore->value;
300 else
301 return std::nullopt;
302}
303
304bool isHwPixelFormat(AVPixelFormat format);
305
306inline bool isSwPixelFormat(AVPixelFormat format)
307{
308 return !isHwPixelFormat(format);
309}
310
311void applyExperimentalCodecOptions(const Codec &codec, AVDictionary **opts);
312
313AVPixelFormat pixelFormatForHwDevice(AVHWDeviceType deviceType);
314
315AVPacketSideData *addStreamSideData(AVStream *stream, AVPacketSideData sideData);
316
317const AVPacketSideData *streamSideData(const AVStream *stream, AVPacketSideDataType type);
318
319SwrContextUPtr createResampleContext(const AVAudioFormat &inputFormat,
320 const AVAudioFormat &outputFormat);
321
322QVideoFrameFormat::ColorTransfer fromAvColorTransfer(AVColorTransferCharacteristic colorTrc);
323
324AVColorTransferCharacteristic toAvColorTransfer(QVideoFrameFormat::ColorTransfer colorTrc);
325
326QVideoFrameFormat::ColorSpace fromAvColorSpace(AVColorSpace colorSpace);
327
328AVColorSpace toAvColorSpace(QVideoFrameFormat::ColorSpace colorSpace);
329
330QVideoFrameFormat::ColorRange fromAvColorRange(AVColorRange colorRange);
331
332AVColorRange toAvColorRange(QVideoFrameFormat::ColorRange colorRange);
333
334AVHWDeviceContext *avFrameDeviceContext(const AVFrame *frame);
335
336SwsContextUPtr createSwsContext(const QSize &srcSize, AVPixelFormat srcPixFmt, const QSize &dstSize,
337 AVPixelFormat dstPixFmt, SwsFlags conversionType = SWS_BICUBIC);
338
339QSize frameSize(const AVFrame &);
340QSize frameSize(const AVFrame *);
341QSize frameSize(const AVFrameUPtr &);
342
343#ifdef Q_OS_DARWIN
345
347
348#endif
349
350enum class AVError : int {
352};
353
357
358QString toString(AVCodecCapabilities capabilities);
359QString toString(AVPixelFormatFlags flags);
360QString toString(AVHwConfigMethods methods);
361
362} // namespace QFFmpeg
363
364QDebug operator<<(QDebug, const AVRational &);
365QDebug operator<<(QDebug, const AVDictionary &);
372QDebug operator<<(QDebug, const AVOutputFormat *);
373QDebug operator<<(QDebug, const AVInputFormat *);
377
378#if QT_FFMPEG_HAS_AV_CHANNEL_LAYOUT
379QDebug operator<<(QDebug, const AVChannelLayout &);
380#endif
381
382QT_END_NAMESPACE
383
384#endif
AVFrameUPtr makeAVFrame()
Definition qffmpeg_p.h:174
void getAVFrameTime(const AVFrame &frame, int64_t &pts, AVRational &timeBase)
Definition qffmpeg_p.h:101
QSize frameSize(const AVFrame &frame)
Definition qffmpeg.cpp:352
AVColorSpace toAvColorSpace(QVideoFrameFormat::ColorSpace colorSpace)
Definition qffmpeg.cpp:271
int64_t getAVFrameDuration(const AVFrame &frame)
Definition qffmpeg_p.h:111
SwsContextUPtr createSwsContext(const QSize &srcSize, AVPixelFormat srcPixFmt, const QSize &dstSize, AVPixelFormat dstPixFmt, SwsFlags conversionType)
Definition qffmpeg.cpp:324
void applyExperimentalCodecOptions(const Codec &codec, AVDictionary **opts)
Definition qffmpeg.cpp:61
std::optional< qreal > toReal(AVRational r)
Definition qffmpeg_p.h:79
bool isHwPixelFormat(AVPixelFormat format)
Definition qffmpeg.cpp:55
AVPacketSideData * addStreamSideData(AVStream *stream, AVPacketSideData sideData)
Definition qffmpeg.cpp:104
QString err2str(int errnum)
Definition qffmpeg_p.h:84
QSize frameSize(const AVFrame *frame)
Definition qffmpeg.cpp:357
std::optional< Float > toFloat(AVRational r)
Definition qffmpeg_p.h:74
AVHWDeviceContext * avFrameDeviceContext(const AVFrame *frame)
Definition qffmpeg.cpp:311
void setAVFrameTime(AVFrame &frame, int64_t pts, const AVRational &timeBase)
Definition qffmpeg_p.h:91
bool isSwPixelFormat(AVPixelFormat format)
Definition qffmpeg_p.h:306
AVColorTransferCharacteristic toAvColorTransfer(QVideoFrameFormat::ColorTransfer colorTrc)
Definition qffmpeg.cpp:222
AVCodecCapabilities
Definition qffmpeg_p.h:354
std::optional< Value > findIf(QSpan< const Value > range, const Predicate &predicate)
Definition qffmpeg_p.h:213
QString toString(AVPixelFormatFlags flags)
Definition qffmpeg.cpp:602
std::optional< ValueAndScore< Value, ScoreType > > findBestAVValueWithScore(ValueRange &&values, const CalculateScore &calculateScore)
Definition qffmpeg_p.h:273
void forEachAVPixelFormat(const Codec &codec, const Function &function)
Definition qffmpeg_p.h:254
QVideoFrameFormat::ColorSpace fromAvColorSpace(AVColorSpace colorSpace)
Definition qffmpeg.cpp:244
std::optional< AVPixelFormat > findAVPixelFormat(const Codec &codec, const Predicate &predicate)
Definition qffmpeg_p.h:227
QVideoFrameFormat::ColorTransfer fromAvColorTransfer(AVColorTransferCharacteristic colorTrc)
Definition qffmpeg.cpp:192
AVPixelFormatFlags
Definition qffmpeg_p.h:355
void freeAVIOContext(AVIOContext *&ctx)
Definition qffmpeg.cpp:343
QVideoFrameFormat::ColorRange fromAvColorRange(AVColorRange colorRange)
Definition qffmpeg.cpp:287
std::optional< qint64 > timeStampMs(qint64 ts, AVRational base)
Definition qffmpeg_p.h:63
SwrContextUPtr createResampleContext(const AVAudioFormat &inputFormat, const AVAudioFormat &outputFormat)
Definition qffmpeg.cpp:146
AVPixelFormat pixelFormatForHwDevice(AVHWDeviceType deviceType)
Definition qffmpeg.cpp:70
AVHwConfigMethods
Definition qffmpeg_p.h:356
std::optional< qint64 > timeStampUs(qint64 ts, AVRational base)
Definition qffmpeg_p.h:68
QString toString(AVCodecCapabilities capabilities)
Definition qffmpeg.cpp:576
bool isAVFormatSupported(const Codec &codec, const PixelOrSampleFormat &format)
Definition qffmpeg.cpp:48
const AVPacketSideData * streamSideData(const AVStream *stream, AVPacketSideDataType type)
Definition qffmpeg.cpp:130
AVColorRange toAvColorRange(QVideoFrameFormat::ColorRange colorRange)
Definition qffmpeg.cpp:299
std::optional< Value > findBestAVValue(ValueRange &&values, const CalculateScore &calculateScore)
Definition qffmpeg_p.h:295
QString toString(AVHwConfigMethods methods)
Definition qffmpeg.cpp:618
std::optional< qint64 > mul(qint64 a, AVRational b)
Definition qffmpeg_p.h:43
QDebug operator<<(QDebug dbg, const NSObject *nsObject)
Definition qcore_mac.mm:209
QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2620
QDebug operator<<(QDebug dbg, const QFFmpeg::AVDictionaryHolder &dict)
Definition qffmpeg.cpp:404
QDebug operator<<(QDebug dbg, QFFmpeg::AVCodecCapabilities caps)
Definition qffmpeg.cpp:629
QDebug operator<<(QDebug dbg, QFFmpeg::AVPixelFormatFlags flags)
Definition qffmpeg.cpp:634
QDebug operator<<(QDebug dbg, QFFmpeg::AVHwConfigMethods methods)
Definition qffmpeg.cpp:639
QDebug operator<<(QDebug dbg, QFFmpeg::AVError error)
Definition qffmpeg.cpp:413
static bool operator==(const AVRational &lhs, const AVRational &rhs)
Definition qffmpeg_p.h:26
static bool operator!=(const AVRational &lhs, const AVRational &rhs)
Definition qffmpeg_p.h:31
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)
void operator()(T *object) const
Definition qffmpeg_p.h:156
void operator()(AVFormatContext *ctx) const
Definition qffmpeg_p.h:191
void operator()(T *object) const
Definition qffmpeg_p.h:145