Revision control

Copy as Markdown

// 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 QFFMPEGHWACCEL_P_H
#define QFFMPEGHWACCEL_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtFFmpegMediaPluginImpl/private/qffmpeg_p.h>
#include <QtFFmpegMediaPluginImpl/private/qffmpegtextureconverter_p.h>
#include <QtMultimedia/qvideoframeformat.h>
#include <QtMultimedia/private/qhwvideobuffer_p.h>
#include <QtMultimedia/private/qrhivaluemapper_p.h>
#include <QtCore/qspan.h>
#include <memory>
#include <mutex>
QT_BEGIN_NAMESPACE
class QRhi;
class QRhiTexture;
class QFFmpegVideoBuffer;
namespace QFFmpeg {
// used for the get_format callback for the decoder
AVPixelFormat getFormat(AVCodecContext *s, const AVPixelFormat *fmt);
class HWAccel;
class HWAccel;
using HWAccelUPtr = std::unique_ptr<HWAccel>;
/**
* @brief The HwFrameContextData class contains custom belongings
* of hw frames context.
*/
struct HwFrameContextData
{
using AVHWFramesContextDeleter = void (*)(struct AVHWFramesContext *ctx);
AVHWFramesContextDeleter avDeleter = nullptr;
void *avUserOpaque = nullptr;
QRhiValueMapper<TextureConverter> textureConverterMapper = {};
/**
* @brief gets or creates an instance of the class, associated with
* the frames context of the specified frame. Note, AVFrame
* holds shared ownership of the frames context, so consider this
* when designing HwFrameContextData's lifetime.
*/
static HwFrameContextData &ensure(AVFrame &hwFrame);
};
class HWAccel
{
const AVBufferUPtr m_hwDeviceContext;
AVBufferUPtr m_hwFramesContext;
mutable std::once_flag m_constraintsOnceFlag;
mutable AVHWFramesConstraintsUPtr m_constraints;
public:
~HWAccel();
static HWAccelUPtr create(AVHWDeviceType deviceType);
static std::pair<std::optional<Codec>, HWAccelUPtr> findDecoderWithHwAccel(AVCodecID id);
AVHWDeviceType deviceType() const;
AVBufferRef *hwDeviceContextAsBuffer() const { return m_hwDeviceContext.get(); }
AVHWDeviceContext *hwDeviceContext() const;
AVPixelFormat hwFormat() const;
const AVHWFramesConstraints *constraints() const;
bool matchesSizeContraints(QSize size) const;
void createFramesContext(AVPixelFormat swFormat, const QSize &size);
void destroyFramesContext();
void updateFramesContext(AVPixelFormat swFormat, const QSize &size);
AVBufferRef *hwFramesContextAsBuffer() const { return m_hwFramesContext.get(); }
AVHWFramesContext *hwFramesContext() const;
static AVPixelFormat format(AVFrame *frame);
static QSpan<const AVHWDeviceType> encodingDeviceTypes();
static QSpan<const AVHWDeviceType> decodingDeviceTypes();
private:
HWAccel(AVBufferUPtr hwDeviceContext) : m_hwDeviceContext(std::move(hwDeviceContext)) { }
};
AVFrameUPtr copyFromHwPool(AVFrameUPtr frame);
} // namespace QFFmpeg
QT_END_NAMESPACE
#endif