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>
25[[maybe_unused]]
static inline bool operator==(
const AVRational &lhs,
const AVRational &rhs)
27 return lhs.num == rhs.num && lhs.den == rhs.den;
30[[maybe_unused]]
static inline bool operator!=(
const AVRational &lhs,
const AVRational &rhs)
45 auto multiplyAndRound = [](qint64 a, AVRational b) {
46 return (a * b.num + b.den / 2) / b.den;
50 return -multiplyAndRound(-a, b);
52 return multiplyAndRound(a, b);
57 return b.den != 0 ? a * qreal(b.num) / qreal(b.den) : std::optional<qreal>{};
62 return mul(1'000 * ts, base);
67 return mul(1'000'000 * ts, base);
72 return r.den != 0 ?
float(r.num) /
float(r.den) : std::optional<
float>{};
77 char buffer[AV_ERROR_MAX_STRING_SIZE + 1] = {};
78 av_make_error_string(buffer, AV_ERROR_MAX_STRING_SIZE, errnum);
79 return QString::fromLocal8Bit(buffer);
82inline void setAVFrameTime(AVFrame &frame, int64_t pts,
const AVRational &timeBase)
85#if QT_FFMPEG_HAS_FRAME_TIME_BASE
86 frame.time_base = timeBase;
92inline void getAVFrameTime(
const AVFrame &frame, int64_t &pts, AVRational &timeBase)
95#if QT_FFMPEG_HAS_FRAME_TIME_BASE
96 timeBase = frame.time_base;
104#if QT_FFMPEG_HAS_FRAME_DURATION
105 return frame.duration;
107 return frame.pkt_duration;
133template<
typename FunctionType, FunctionType F>
136 template <
typename T, std::invoke_result_t<FunctionType, T **> * =
nullptr>
143 template <
typename T, std::invoke_result_t<FunctionType, T *> * =
nullptr>
154 return AVFrameUPtr(av_frame_alloc());
179template <
typename Value>
180bool hasValue(QSpan<
const Value> range, Value value)
182 return std::find(range.begin(), range.end(), value) != range.end();
189template <
typename Value,
typename Predicate>
190std::optional<Value>
findIf(QSpan<
const Value> range,
const Predicate &predicate)
192 const auto value = std::find_if(range.begin(), range.end(), predicate);
193 if (value == range.end())
203template <
typename Predicate>
206 if (codec.type() != AVMEDIA_TYPE_VIDEO)
209 const auto pixelFormats = codec.pixelFormats();
211 if (
const auto format = findIf(pixelFormats, predicate))
216 for (
const AVCodecHWConfig *
const config : codec.hwConfigs()) {
217 const AVPixelFormat format = config->pix_fmt;
219 if (format == AV_PIX_FMT_NONE)
222 if (predicate(format))
230template <
typename Function>
233 findAVPixelFormat(codec, [&function](AVPixelFormat format) {
239template <
typename ValueT,
typename ScoreT =
AVScore>
246template <
typename Value,
typename CalculateScore,
249 const CalculateScore &calculateScore)
251 static_assert(
std::is_invocable_v<CalculateScore, Value>);
254 for (
const Value &val : values) {
255 const ScoreType score = calculateScore(val);
256 if (score > result.score)
257 result = { val, score };
259 if (result.score == std::numeric_limits<ScoreType>::max())
266template <
typename Value,
typename CalculateScore>
268 const CalculateScore &calculateScore)
270 return findBestAVValueWithScore(values, calculateScore).value;
277 return !isHwPixelFormat(format);
289 const AVAudioFormat &outputFormat);
306 AVPixelFormat dstPixFmt, SwsFlags conversionType =
SWS_BICUBIC);
326#if QT_FFMPEG_HAS_AV_CHANNEL_LAYOUT
327QDebug 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)
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)
std::conditional_t< QT_FFMPEG_AVIO_WRITE_CONST, const uint8_t *, uint8_t * > AvioWriteBufferType
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)
Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core")
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)
void operator()(T *object) const
std::optional< ValueT > value