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);
73template <
typename Float>
76 return r.den != 0 ? Float(r.num) / Float(r.den) :
std::optional<Float>{};
81 return toFloat<qreal>(r);
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);
91inline void setAVFrameTime(AVFrame &frame, int64_t pts,
const AVRational &timeBase)
94#if QT_FFMPEG_HAS_FRAME_TIME_BASE
95 frame.time_base = timeBase;
101inline void getAVFrameTime(
const AVFrame &frame, int64_t &pts, AVRational &timeBase)
104#if QT_FFMPEG_HAS_FRAME_TIME_BASE
105 timeBase = frame.time_base;
113#if QT_FFMPEG_HAS_FRAME_DURATION
114 return frame.duration;
116 return frame.pkt_duration;
144 template <
typename T>
155 template <
typename T>
158 using FunctionType =
decltype(F);
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**");
164 if constexpr (
std::is_invocable_v<FunctionType, T **>) {
176 return AVFrameUPtr(av_frame_alloc());
196 if (ctx->flags & AVFMT_FLAG_CUSTOM_IO)
197 freeAVIOContext(ctx->pb);
199 avformat_close_input(&ctx);
212template <
typename Value,
typename Predicate>
213std::optional<Value>
findIf(QSpan<
const Value> range,
const Predicate &predicate)
215 const auto value = ranges::find_if(range, predicate);
216 if (value == range.end())
226template <
typename Predicate>
229 if (codec.type() != AVMEDIA_TYPE_VIDEO)
232 const auto pixelFormats = codec.pixelFormats();
234 if (
const auto format = findIf(pixelFormats, predicate))
239 for (
const AVCodecHWConfig *
const config : codec.hwConfigs()) {
240 const AVPixelFormat format = config->pix_fmt;
242 if (format == AV_PIX_FMT_NONE)
245 if (predicate(format))
253template <
typename Function>
256 findAVPixelFormat(codec, [&function](AVPixelFormat format) {
262template <
typename ValueT,
typename ScoreT =
AVScore>
269template <
typename ValueRange,
typename CalculateScore,
275 static_assert(
std::is_invocable_v<CalculateScore, Value>);
278 for (
const Value &val : values) {
279 const ScoreType score = calculateScore(val);
280 if (score == std::numeric_limits<ScoreType>::min())
283 if (!result || score > result->score)
284 result = { val, score };
286 if (result->score == std::numeric_limits<ScoreType>::max())
293template <
typename ValueRange,
typename CalculateScore,
297 auto optionalValueAndScore = findBestAVValueWithScore(values, calculateScore);
298 if (optionalValueAndScore)
299 return optionalValueAndScore->value;
308 return !isHwPixelFormat(format);
320 const AVAudioFormat &outputFormat);
337 AVPixelFormat dstPixFmt, SwsFlags conversionType =
SWS_BICUBIC);
378#if QT_FFMPEG_HAS_AV_CHANNEL_LAYOUT
379QDebug operator<<(QDebug,
const AVChannelLayout &);
AVFrameUPtr makeAVFrame()
void getAVFrameTime(const AVFrame &frame, int64_t &pts, AVRational &timeBase)
QSize frameSize(const AVFrame &frame)
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)
std::optional< qreal > toReal(AVRational r)
bool isHwPixelFormat(AVPixelFormat format)
AVPacketSideData * addStreamSideData(AVStream *stream, AVPacketSideData sideData)
QString err2str(int errnum)
QSize frameSize(const AVFrame *frame)
std::optional< Float > toFloat(AVRational r)
AVHWDeviceContext * avFrameDeviceContext(const AVFrame *frame)
void setAVFrameTime(AVFrame &frame, int64_t pts, const AVRational &timeBase)
bool isSwPixelFormat(AVPixelFormat format)
AVColorTransferCharacteristic toAvColorTransfer(QVideoFrameFormat::ColorTransfer colorTrc)
std::optional< Value > findIf(QSpan< const Value > range, const Predicate &predicate)
QString toString(AVPixelFormatFlags flags)
std::optional< ValueAndScore< Value, ScoreType > > findBestAVValueWithScore(ValueRange &&values, const CalculateScore &calculateScore)
void forEachAVPixelFormat(const Codec &codec, const Function &function)
QVideoFrameFormat::ColorSpace fromAvColorSpace(AVColorSpace colorSpace)
std::optional< AVPixelFormat > findAVPixelFormat(const Codec &codec, const Predicate &predicate)
QVideoFrameFormat::ColorTransfer fromAvColorTransfer(AVColorTransferCharacteristic colorTrc)
void freeAVIOContext(AVIOContext *&ctx)
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)
QString toString(AVCodecCapabilities capabilities)
bool isAVFormatSupported(const Codec &codec, const PixelOrSampleFormat &format)
const AVPacketSideData * streamSideData(const AVStream *stream, AVPacketSideDataType type)
AVColorRange toAvColorRange(QVideoFrameFormat::ColorRange colorRange)
std::optional< Value > findBestAVValue(ValueRange &&values, const CalculateScore &calculateScore)
QString toString(AVHwConfigMethods methods)
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::AVCodecCapabilities caps)
QDebug operator<<(QDebug dbg, QFFmpeg::AVPixelFormatFlags flags)
QDebug operator<<(QDebug dbg, QFFmpeg::AVHwConfigMethods methods)
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
void operator()(AVFormatContext *ctx) const
void operator()(T *object) const