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>
26[[maybe_unused]]
static inline bool operator==(
const AVRational &lhs,
const AVRational &rhs)
28 return lhs.num == rhs.num && lhs.den == rhs.den;
31[[maybe_unused]]
static inline bool operator!=(
const AVRational &lhs,
const AVRational &rhs)
48 auto multiplyAndRound = [](qint64 a, AVRational b) {
49 return (a * b.num + b.den / 2) / b.den;
53 return -multiplyAndRound(-a, b);
55 return multiplyAndRound(a, b);
60 return b.den != 0 ? a * qreal(b.num) / qreal(b.den) : std::optional<qreal>{};
65 return mul(1'000 * ts, base);
70 return mul(1'000'000 * ts, base);
75 return r.den != 0 ?
float(r.num) /
float(r.den) : std::optional<
float>{};
80 char buffer[AV_ERROR_MAX_STRING_SIZE + 1] = {};
81 av_make_error_string(buffer, AV_ERROR_MAX_STRING_SIZE, errnum);
82 return QString::fromLocal8Bit(buffer);
85inline void setAVFrameTime(AVFrame &frame, int64_t pts,
const AVRational &timeBase)
88#if QT_FFMPEG_HAS_FRAME_TIME_BASE
89 frame.time_base = timeBase;
95inline void getAVFrameTime(
const AVFrame &frame, int64_t &pts, AVRational &timeBase)
98#if QT_FFMPEG_HAS_FRAME_TIME_BASE
99 timeBase = frame.time_base;
107#if QT_FFMPEG_HAS_FRAME_DURATION
108 return frame.duration;
110 return frame.pkt_duration;
139 template <
typename T>
142 using FunctionType =
decltype(F);
144 static_assert(
std::is_invocable_v<FunctionType, T *>
145 ||
std::is_invocable_v<FunctionType, T **>,
146 "F must be invocable with either T* or T**");
148 if constexpr (
std::is_invocable_v<FunctionType, T **>) {
160 return AVFrameUPtr(av_frame_alloc());
177template <
typename Value,
typename Predicate>
178std::optional<Value>
findIf(QSpan<
const Value> range,
const Predicate &predicate)
180 const auto value = ranges::find_if(range, predicate);
181 if (value == range.end())
191template <
typename Predicate>
194 if (codec.type() != AVMEDIA_TYPE_VIDEO)
197 const auto pixelFormats = codec.pixelFormats();
199 if (
const auto format = findIf(pixelFormats, predicate))
204 for (
const AVCodecHWConfig *
const config : codec.hwConfigs()) {
205 const AVPixelFormat format = config->pix_fmt;
207 if (format == AV_PIX_FMT_NONE)
210 if (predicate(format))
218template <
typename Function>
221 findAVPixelFormat(codec, [&function](AVPixelFormat format) {
227template <
typename ValueT,
typename ScoreT =
AVScore>
234template <
typename Value,
typename CalculateScore,
237 const CalculateScore &calculateScore)
239 static_assert(
std::is_invocable_v<CalculateScore, Value>);
242 for (
const Value &val : values) {
243 const ScoreType score = calculateScore(val);
244 if (score > result.score)
245 result = { val, score };
247 if (result.score == std::numeric_limits<ScoreType>::max())
254template <
typename Value,
typename CalculateScore>
256 const CalculateScore &calculateScore)
258 return findBestAVValueWithScore(values, calculateScore).value;
265 return !isHwPixelFormat(format);
277 const AVAudioFormat &outputFormat);
294 AVPixelFormat dstPixFmt, SwsFlags conversionType =
SWS_BICUBIC);
319#if QT_FFMPEG_HAS_AV_CHANNEL_LAYOUT
320QDebug operator<<(QDebug,
const AVChannelLayout &);
ValueAndScore< Value, ScoreType > findBestAVValueWithScore(QSpan< const Value > values, const CalculateScore &calculateScore)
AVFrameUPtr makeAVFrame()
void getAVFrameTime(const AVFrame &frame, int64_t &pts, AVRational &timeBase)
AVColorSpace toAvColorSpace(QVideoFrameFormat::ColorSpace colorSpace)
int64_t getAVFrameDuration(const AVFrame &frame)
SwsContextUPtr createSwsContext(const QSize &srcSize, AVPixelFormat srcPixFmt, const QSize &dstSize, AVPixelFormat dstPixFmt, SwsFlags conversionType)
void applyExperimentalCodecOptions(const Codec &codec, AVDictionary **opts)
bool isHwPixelFormat(AVPixelFormat format)
AVPacketSideData * addStreamSideData(AVStream *stream, AVPacketSideData sideData)
QString err2str(int errnum)
AVHWDeviceContext * avFrameDeviceContext(const AVFrame *frame)
void setAVFrameTime(AVFrame &frame, int64_t pts, const AVRational &timeBase)
bool isSwPixelFormat(AVPixelFormat format)
AVColorTransferCharacteristic toAvColorTransfer(QVideoFrameFormat::ColorTransfer colorTrc)
QT_MANGLE_NAMESPACE(QMacScreenCaptureStreamDelegate) QMacScreenCaptureStreamDelegate
std::optional< Value > findIf(QSpan< const Value > range, const Predicate &predicate)
void forEachAVPixelFormat(const Codec &codec, const Function &function)
QVideoFrameFormat::ColorSpace fromAvColorSpace(AVColorSpace colorSpace)
bool isAVFormatSupported(const Codec &codec, PixelOrSampleFormat format)
std::optional< AVPixelFormat > findAVPixelFormat(const Codec &codec, const Predicate &predicate)
QVideoFrameFormat::ColorTransfer fromAvColorTransfer(AVColorTransferCharacteristic colorTrc)
QVideoFrameFormat::ColorRange fromAvColorRange(AVColorRange colorRange)
std::optional< qint64 > timeStampMs(qint64 ts, AVRational base)
SwrContextUPtr createResampleContext(const AVAudioFormat &inputFormat, const AVAudioFormat &outputFormat)
AVPixelFormat pixelFormatForHwDevice(AVHWDeviceType deviceType)
std::optional< qint64 > timeStampUs(qint64 ts, AVRational base)
const AVPacketSideData * streamSideData(const AVStream *stream, AVPacketSideDataType type)
AVColorRange toAvColorRange(QVideoFrameFormat::ColorRange colorRange)
std::optional< Value > findBestAVValue(QSpan< const Value > values, const CalculateScore &calculateScore)
std::optional< float > toFloat(AVRational r)
std::optional< qint64 > mul(qint64 a, AVRational b)
QDebug operator<<(QDebug dbg, const NSObject *nsObject)
QDebug operator<<(QDebug debug, QDir::Filters filters)
QDebug operator<<(QDebug dbg, const QFFmpeg::AVDictionaryHolder &dict)
QDebug operator<<(QDebug dbg, QFFmpeg::AVError error)
static bool operator==(const AVRational &lhs, const AVRational &rhs)
static bool operator!=(const AVRational &lhs, const AVRational &rhs)
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)
void operator()(T *object) const
std::optional< ValueT > value