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());
174template <
typename Value>
175bool hasValue(QSpan<
const Value> range, Value value)
177 return ranges::contains(range, value);
184template <
typename Value,
typename Predicate>
185std::optional<Value>
findIf(QSpan<
const Value> range,
const Predicate &predicate)
187 const auto value = ranges::find_if(range, predicate);
188 if (value == range.end())
198template <
typename Predicate>
201 if (codec.type() != AVMEDIA_TYPE_VIDEO)
204 const auto pixelFormats = codec.pixelFormats();
206 if (
const auto format = findIf(pixelFormats, predicate))
211 for (
const AVCodecHWConfig *
const config : codec.hwConfigs()) {
212 const AVPixelFormat format = config->pix_fmt;
214 if (format == AV_PIX_FMT_NONE)
217 if (predicate(format))
225template <
typename Function>
228 findAVPixelFormat(codec, [&function](AVPixelFormat format) {
234template <
typename ValueT,
typename ScoreT =
AVScore>
241template <
typename Value,
typename CalculateScore,
244 const CalculateScore &calculateScore)
246 static_assert(
std::is_invocable_v<CalculateScore, Value>);
249 for (
const Value &val : values) {
250 const ScoreType score = calculateScore(val);
251 if (score > result.score)
252 result = { val, score };
254 if (result.score == std::numeric_limits<ScoreType>::max())
261template <
typename Value,
typename CalculateScore>
263 const CalculateScore &calculateScore)
265 return findBestAVValueWithScore(values, calculateScore).value;
272 return !isHwPixelFormat(format);
284 const AVAudioFormat &outputFormat);
301 AVPixelFormat dstPixFmt, SwsFlags conversionType =
SWS_BICUBIC);
321#if QT_FFMPEG_HAS_AV_CHANNEL_LAYOUT
322QDebug 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)
std::optional< Value > findIf(QSpan< const Value > range, const Predicate &predicate)
std::conditional_t< QT_FFMPEG_AVIO_WRITE_CONST, const uint8_t *, uint8_t * > AvioWriteBufferType
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)
bool hasValue(QSpan< const Value > range, Value value)
std::optional< qint64 > mul(qint64 a, AVRational b)
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