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 QFFMPEGMEDIADATAHOLDER_P_H
5#define QFFMPEGMEDIADATAHOLDER_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 <QtCore/private/qexpected_p.h>
19#include <QtMultimedia/qmediametadata.h>
20#include <QtMultimedia/qvideoframe.h>
21#include <QtMultimedia/private/qplatformmediaplayer_p.h>
22#include <QtMultimedia/private/qmultimediautils_p.h>
23#include <QtFFmpegMediaPluginImpl/private/qffmpegtime_p.h>
24#include <QtFFmpegMediaPluginImpl/private/qffmpeg_p.h>
25
26#include <array>
27#include <optional>
28
29QT_BEGIN_NAMESPACE
30
31namespace QFFmpeg {
32
33struct ICancelToken
34{
35 virtual ~ICancelToken() = default;
36 virtual bool isCancelled() const = 0;
37};
38
39using AVFormatContextUPtr = std::unique_ptr<AVFormatContext, AVDeleter<decltype(&avformat_close_input), &avformat_close_input>>;
40
41class MediaDataHolder
42{
43public:
44 struct StreamInfo
45 {
46 int avStreamIndex = -1;
47 bool isDefault = false;
48 QMediaMetaData metaData;
49 };
50
51 struct ContextError
52 {
53 QMediaPlayer::Error code{};
54 QString description;
55 };
56
57 using StreamsMap = std::array<QList<StreamInfo>, QPlatformMediaPlayer::NTrackTypes>;
58 using StreamIndexes = std::array<int, QPlatformMediaPlayer::NTrackTypes>;
59
60 MediaDataHolder() = default;
61 MediaDataHolder(AVFormatContextUPtr context, const std::shared_ptr<ICancelToken> &cancelToken);
62
63 static QPlatformMediaPlayer::TrackType trackTypeFromMediaType(int mediaType);
64
65 int activeTrack(QPlatformMediaPlayer::TrackType type) const;
66
67 const QList<StreamInfo> &streamInfo(QPlatformMediaPlayer::TrackType trackType) const;
68
69 TrackDuration duration() const { return m_duration; }
70
71 const QMediaMetaData &metaData() const { return m_metaData; }
72
73 bool isSeekable() const { return m_isSeekable; }
74
75 VideoTransformation transformation() const;
76
77 AVFormatContext *avContext();
78
79 int currentStreamIndex(QPlatformMediaPlayer::TrackType trackType) const;
80
81 using Maybe = q23::expected<std::shared_ptr<MediaDataHolder>, ContextError>;
82 static Maybe create(const QUrl &url, QIODevice *stream, const QPlaybackOptions &options,
83 const std::shared_ptr<ICancelToken> &cancelToken);
84
85 bool setActiveTrack(QPlatformMediaPlayer::TrackType type, int streamNumber);
86
87private:
88 void updateMetaData();
89
90 std::shared_ptr<ICancelToken> m_cancelToken; // NOTE: Cancel token may be accessed by
91 // AVFormatContext during destruction and
92 // must outlive the context object
93 AVFormatContextUPtr m_context;
94
95 bool m_isSeekable = false;
96
97 StreamIndexes m_currentAVStreamIndex = { -1, -1, -1 };
98 StreamsMap m_streamMap;
99 StreamIndexes m_requestedStreams = { -1, -1, -1 };
100 TrackDuration m_duration = TrackDuration(0);
101 QMediaMetaData m_metaData;
102 std::optional<QImage> m_cachedThumbnail;
103};
104
105} // namespace QFFmpeg
106
107QT_END_NAMESPACE
108
109#endif // QFFMPEGMEDIADATAHOLDER_P_H
110

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