1// Copyright (C) 2022 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 QFFMPEGVIDEOFRAMEENCODER_P_H
4#define QFFMPEGVIDEOFRAMEENCODER_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 "qffmpeghwaccel_p.h"
18#include "private/qplatformmediarecorder_p.h"
19#include "private/qmultimediautils_p.h"
20
21#include <unordered_set>
22
23QT_BEGIN_NAMESPACE
24
25class QMediaEncoderSettings;
26
27namespace QFFmpeg {
28
29class VideoFrameEncoder;
30using VideoFrameEncoderUPtr = std::unique_ptr<VideoFrameEncoder>;
31
32class VideoFrameEncoder
33{
34public:
35 struct SourceParams
36 {
37 QSize size;
38 AVPixelFormat format = AV_PIX_FMT_NONE;
39 AVPixelFormat swFormat = AV_PIX_FMT_NONE;
40 VideoTransformation transform;
41 qreal frameRate = 0.;
42 AVColorTransferCharacteristic colorTransfer = AVCOL_TRC_UNSPECIFIED;
43 AVColorSpace colorSpace = AVCOL_SPC_UNSPECIFIED;
44 AVColorRange colorRange = AVCOL_RANGE_UNSPECIFIED;
45 };
46 static VideoFrameEncoderUPtr create(const QMediaEncoderSettings &encoderSettings,
47 const SourceParams &sourceParams,
48 AVFormatContext *formatContext);
49
50 ~VideoFrameEncoder();
51
52 AVPixelFormat sourceFormat() const { return m_sourceFormat; }
53 AVPixelFormat targetFormat() const { return m_targetFormat; }
54
55 qreal codecFrameRate() const;
56
57 qint64 getPts(qint64 ms) const;
58
59 const AVRational &getTimeBase() const;
60
61 int sendFrame(AVFrameUPtr inputFrame);
62 AVPacketUPtr retrievePacket();
63
64private:
65 VideoFrameEncoder(AVStream *stream, const AVCodec *codec, HWAccelUPtr hwAccel,
66 const SourceParams &sourceParams,
67 const QMediaEncoderSettings &encoderSettings);
68
69 static AVStream *createStream(const SourceParams &sourceParams, AVFormatContext *formatContext);
70
71 bool updateSourceFormatAndSize(const AVFrame *frame);
72
73 void updateConversions();
74
75 struct CreationResult
76 {
77 VideoFrameEncoderUPtr encoder;
78 AVPixelFormat targetFormat = AV_PIX_FMT_NONE;
79 };
80
81 static CreationResult create(AVStream *stream, const AVCodec *codec, HWAccelUPtr hwAccel,
82 const SourceParams &sourceParams,
83 const QMediaEncoderSettings &encoderSettings,
84 const AVPixelFormatSet &prohibitedTargetFormats = {});
85
86 void initTargetSize();
87
88 void initCodecFrameRate();
89
90 bool initTargetFormats(const AVPixelFormatSet &prohibitedTargetFormats);
91
92 void initStream();
93
94 bool initCodecContext();
95
96 bool open();
97
98 qint64 estimateDuration(const AVPacket &packet, bool isFirstPacket);
99
100private:
101 QMediaEncoderSettings m_settings;
102 AVStream *m_stream = nullptr;
103 const AVCodec *m_codec = nullptr;
104 HWAccelUPtr m_accel;
105
106 QSize m_sourceSize;
107 QSize m_targetSize;
108
109 qint64 m_lastPacketTime = AV_NOPTS_VALUE;
110 AVCodecContextUPtr m_codecContext;
111 SwsContextUPtr m_scaleContext;
112 AVPixelFormat m_sourceFormat = AV_PIX_FMT_NONE;
113 AVPixelFormat m_sourceSWFormat = AV_PIX_FMT_NONE;
114 AVPixelFormat m_targetFormat = AV_PIX_FMT_NONE;
115 AVPixelFormat m_targetSWFormat = AV_PIX_FMT_NONE;
116 bool m_downloadFromHW = false;
117 bool m_uploadToHW = false;
118
119 AVRational m_codecFrameRate = { .num: 0, .den: 1 };
120
121 int64_t m_prevPacketDts = AV_NOPTS_VALUE;
122 int64_t m_packetDtsOffset = 0;
123};
124}
125
126QT_END_NAMESPACE
127
128#endif
129

source code of qtmultimedia/src/plugins/multimedia/ffmpeg/recordingengine/qffmpegvideoframeencoder_p.h