// Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QFFMPEG_P_H #define QFFMPEG_P_H #include #include extern "C" { #include #include #include #include #include } #define QT_FFMPEG_OLD_CHANNEL_LAYOUT (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,24,100)) QT_BEGIN_NAMESPACE namespace QFFmpeg { inline std::optional mul(qint64 a, AVRational b) { return b.den != 0 ? (a * b.num + b.den / 2) / b.den : std::optional{}; } inline std::optional mul(qreal a, AVRational b) { return b.den != 0 ? a * qreal(b.num) / qreal(b.den) : std::optional{}; } inline std::optional timeStampMs(qint64 ts, AVRational base) { return mul(1'000 * ts, base); } inline std::optional timeStampUs(qint64 ts, AVRational base) { return mul(1'000'000 * ts, base); } inline std::optional toFloat(AVRational r) { return r.den != 0 ? float(r.num) / float(r.den) : std::optional{}; } inline QString err2str(int errnum) { char buffer[AV_ERROR_MAX_STRING_SIZE + 1] = {}; av_make_error_string(buffer, AV_ERROR_MAX_STRING_SIZE, errnum); return QString::fromLocal8Bit(buffer); } struct AVFrameDeleter { void operator()(AVFrame *frame) const { if (frame) av_frame_free(&frame); } }; using AVFrameUPtr = std::unique_ptr; inline AVFrameUPtr makeAVFrame() { return AVFrameUPtr(av_frame_alloc()); } struct AVPacketDeleter { void operator()(AVPacket *packet) const { if (packet) av_packet_free(&packet); } }; using AVPacketUPtr = std::unique_ptr; struct AVCodecContextDeleter { void operator()(AVCodecContext *context) const { if (context) avcodec_free_context(&context); } }; using AVCodecContextUPtr = std::unique_ptr; QT_END_NAMESPACE } #endif