1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#ifndef QFFMPEGHWACCEL_P_H
4#define QFFMPEGHWACCEL_P_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include "qffmpeg_p.h"
18#include "qvideoframeformat.h"
19#include "qabstractvideobuffer.h"
20
21#include <qshareddata.h>
22#include <memory>
23#include <functional>
24#include <mutex>
25
26QT_BEGIN_NAMESPACE
27
28class QRhi;
29class QRhiTexture;
30class QFFmpegVideoBuffer;
31
32namespace QFFmpeg {
33
34// used for the get_format callback for the decoder
35enum AVPixelFormat getFormat(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
36
37class HWAccel;
38
39class TextureSet {
40public:
41 // ### Should add QVideoFrameFormat::PixelFormat here
42 virtual ~TextureSet() {}
43 virtual qint64 textureHandle(QRhi *, int /*plane*/) { return 0; }
44};
45
46class TextureConverterBackend
47{
48public:
49 TextureConverterBackend(QRhi *rhi)
50 : rhi(rhi)
51 {}
52 virtual ~TextureConverterBackend() {}
53 virtual TextureSet *getTextures(AVFrame * /*frame*/) { return nullptr; }
54
55 QRhi *rhi = nullptr;
56};
57
58class TextureConverter
59{
60 class Data final
61 {
62 public:
63 QAtomicInt ref = 0;
64 QRhi *rhi = nullptr;
65 AVPixelFormat format = AV_PIX_FMT_NONE;
66 std::unique_ptr<TextureConverterBackend> backend;
67 };
68public:
69 TextureConverter(QRhi *rhi = nullptr);
70
71 void init(AVFrame *frame) {
72 AVPixelFormat fmt = frame ? AVPixelFormat(frame->format) : AV_PIX_FMT_NONE;
73 if (fmt != d->format)
74 updateBackend(format: fmt);
75 }
76 TextureSet *getTextures(AVFrame *frame);
77 bool isNull() const { return !d->backend || !d->backend->rhi; }
78
79private:
80 void updateBackend(AVPixelFormat format);
81
82 QExplicitlySharedDataPointer<Data> d;
83};
84
85class HWAccel;
86using HWAccelUPtr = std::unique_ptr<HWAccel>;
87
88class HWAccel
89{
90 AVBufferUPtr m_hwDeviceContext;
91 AVBufferUPtr m_hwFramesContext;
92
93 mutable std::once_flag m_constraintsOnceFlag;
94 mutable AVHWFramesConstraintsUPtr m_constraints;
95
96public:
97 ~HWAccel();
98
99 static HWAccelUPtr create(AVHWDeviceType deviceType);
100
101 static std::pair<const AVCodec *, HWAccelUPtr>
102 findEncoderWithHwAccel(AVCodecID id,
103 const std::function<bool(const HWAccel &)> &hwAccelPredicate = nullptr);
104
105 static std::pair<const AVCodec *, HWAccelUPtr>
106 findDecoderWithHwAccel(AVCodecID id,
107 const std::function<bool(const HWAccel &)> &hwAccelPredicate = nullptr);
108
109 AVHWDeviceType deviceType() const;
110
111 AVBufferRef *hwDeviceContextAsBuffer() const { return m_hwDeviceContext.get(); }
112 AVHWDeviceContext *hwDeviceContext() const;
113 AVPixelFormat hwFormat() const;
114 const AVHWFramesConstraints *constraints() const;
115
116 bool matchesSizeContraints(QSize size) const;
117
118 void createFramesContext(AVPixelFormat swFormat, const QSize &size);
119 AVBufferRef *hwFramesContextAsBuffer() const { return m_hwFramesContext.get(); }
120 AVHWFramesContext *hwFramesContext() const;
121
122 static AVPixelFormat format(AVFrame *frame);
123 static const std::vector<AVHWDeviceType> &encodingDeviceTypes();
124
125 static const std::vector<AVHWDeviceType> &decodingDeviceTypes();
126
127private:
128 HWAccel(AVBufferUPtr hwDeviceContext) : m_hwDeviceContext(std::move(hwDeviceContext)) { }
129};
130
131AVFrameUPtr copyFromHwPool(AVFrameUPtr frame);
132
133}
134
135QT_END_NAMESPACE
136
137#endif
138

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtmultimedia/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_p.h