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
4#ifndef QFFMPEGFRAME_P_H
5#define QFFMPEGFRAME_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qffmpeg_p.h"
19#include "playbackengine/qffmpegcodec_p.h"
20#include "playbackengine/qffmpegpositionwithoffset_p.h"
21#include "QtCore/qsharedpointer.h"
22#include "qpointer.h"
23#include "qobject.h"
24
25#include <optional>
26
27QT_BEGIN_NAMESPACE
28
29namespace QFFmpeg {
30
31struct Frame
32{
33 struct Data
34 {
35 Data(const LoopOffset &offset, AVFrameUPtr f, const Codec &codec, qint64, quint64 sourceId)
36 : loopOffset(offset), codec(codec), frame(std::move(f)), sourceId(sourceId)
37 {
38 Q_ASSERT(frame);
39 if (frame->pts != AV_NOPTS_VALUE)
40 pts = codec.toUs(ts: frame->pts);
41 else
42 pts = codec.toUs(ts: frame->best_effort_timestamp);
43
44 if (frame->sample_rate && codec.context()->codec_type == AVMEDIA_TYPE_AUDIO)
45 duration = qint64(1000000) * frame->nb_samples / frame->sample_rate;
46
47 if (auto frameDuration = getAVFrameDuration(frame: *frame)) {
48 duration = codec.toUs(ts: frameDuration);
49 } else {
50 const auto &avgFrameRate = codec.stream()->avg_frame_rate;
51 duration = mul(a: qint64(1000000), b: { .num: avgFrameRate.den, .den: avgFrameRate.num }).value_or(u: 0);
52 }
53 }
54 Data(const LoopOffset &offset, const QString &text, qint64 pts, qint64 duration,
55 quint64 sourceId)
56 : loopOffset(offset), text(text), pts(pts), duration(duration), sourceId(sourceId)
57 {
58 }
59
60 QAtomicInt ref;
61 LoopOffset loopOffset;
62 std::optional<Codec> codec;
63 AVFrameUPtr frame;
64 QString text;
65 qint64 pts = -1;
66 qint64 duration = -1;
67 quint64 sourceId = 0;
68 };
69 Frame() = default;
70
71 Frame(const LoopOffset &offset, AVFrameUPtr f, const Codec &codec, qint64 pts,
72 quint64 sourceIndex)
73 : d(new Data(offset, std::move(f), codec, pts, sourceIndex))
74 {
75 }
76 Frame(const LoopOffset &offset, const QString &text, qint64 pts, qint64 duration,
77 quint64 sourceIndex)
78 : d(new Data(offset, text, pts, duration, sourceIndex))
79 {
80 }
81 bool isValid() const { return !!d; }
82
83 AVFrame *avFrame() const { return data().frame.get(); }
84 AVFrameUPtr takeAVFrame() { return std::move(data().frame); }
85 const Codec *codec() const { return data().codec ? &data().codec.value() : nullptr; }
86 qint64 pts() const { return data().pts; }
87 qint64 duration() const { return data().duration; }
88 qint64 end() const { return data().pts + data().duration; }
89 QString text() const { return data().text; }
90 quint64 sourceId() const { return data().sourceId; };
91 const LoopOffset &loopOffset() const { return data().loopOffset; };
92 qint64 absolutePts() const { return pts() + loopOffset().pos; }
93 qint64 absoluteEnd() const { return end() + loopOffset().pos; }
94
95private:
96 Data &data() const
97 {
98 Q_ASSERT(d);
99 return *d;
100 }
101
102private:
103 QExplicitlySharedDataPointer<Data> d;
104};
105
106} // namespace QFFmpeg
107
108QT_END_NAMESPACE
109
110Q_DECLARE_METATYPE(QFFmpeg::Frame);
111
112#endif // QFFMPEGFRAME_P_H
113

source code of qtmultimedia/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegframe_p.h