1// Copyright (C) 2016 Jolla 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 QGSTVIDEORENDERERSINK_P_H
5#define QGSTVIDEORENDERERSINK_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 <QtMultimedia/private/qtmultimediaglobal_p.h>
19#include <gst/video/gstvideosink.h>
20#include <gst/video/video.h>
21
22#include <QtCore/qlist.h>
23#include <QtCore/qmutex.h>
24#include <QtCore/qqueue.h>
25#include <QtCore/qpointer.h>
26#include <QtCore/qwaitcondition.h>
27#include <qvideoframeformat.h>
28#include <qvideoframe.h>
29#include <qgstvideobuffer_p.h>
30#include <qgst_p.h>
31
32QT_BEGIN_NAMESPACE
33class QVideoSink;
34
35class QGstVideoRenderer : public QObject
36{
37 Q_OBJECT
38public:
39 QGstVideoRenderer(QGstreamerVideoSink *sink);
40 ~QGstVideoRenderer();
41
42 QGstCaps caps();
43
44 bool start(const QGstCaps& caps);
45 void stop();
46 void unlock();
47 bool proposeAllocation(GstQuery *query);
48
49 void flush();
50
51 GstFlowReturn render(GstBuffer *buffer);
52
53 bool event(QEvent *event) override;
54 bool query(GstQuery *query);
55 void gstEvent(GstEvent *event);
56
57private slots:
58 bool handleEvent(QMutexLocker<QMutex> *locker);
59
60private:
61 void notify();
62 bool waitForAsyncEvent(QMutexLocker<QMutex> *locker, QWaitCondition *condition, unsigned long time);
63 void createSurfaceCaps();
64
65 QPointer<QGstreamerVideoSink> m_sink;
66
67 QMutex m_mutex;
68 QWaitCondition m_setupCondition;
69 QWaitCondition m_renderCondition;
70
71 // --- accessed from multiple threads, need to hold mutex to access
72 GstFlowReturn m_renderReturn = GST_FLOW_OK;
73 bool m_active = false;
74
75 QGstCaps m_surfaceCaps;
76
77 QGstCaps m_startCaps;
78 GstBuffer *m_renderBuffer = nullptr;
79
80 bool m_notified = false;
81 bool m_stop = false;
82 bool m_flush = false;
83 bool m_frameMirrored = false;
84 QVideoFrame::RotationAngle m_frameRotationAngle = QVideoFrame::Rotation0;
85
86 // --- only accessed from one thread
87 QVideoFrameFormat m_format;
88 GstVideoInfo m_videoInfo;
89 bool m_flushed = true;
90 QGstCaps::MemoryFormat memoryFormat = QGstCaps::CpuMemory;
91};
92
93class Q_MULTIMEDIA_EXPORT QGstVideoRendererSink
94{
95public:
96 GstVideoSink parent;
97
98 static QGstVideoRendererSink *createSink(QGstreamerVideoSink *surface);
99 static void setSink(QGstreamerVideoSink *surface);
100
101private:
102 static GType get_type();
103 static void class_init(gpointer g_class, gpointer class_data);
104 static void base_init(gpointer g_class);
105 static void instance_init(GTypeInstance *instance, gpointer g_class);
106
107 static void finalize(GObject *object);
108
109 static void handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d);
110
111 static GstStateChangeReturn change_state(GstElement *element, GstStateChange transition);
112
113 static GstCaps *get_caps(GstBaseSink *sink, GstCaps *filter);
114 static gboolean set_caps(GstBaseSink *sink, GstCaps *caps);
115
116 static gboolean propose_allocation(GstBaseSink *sink, GstQuery *query);
117
118 static gboolean stop(GstBaseSink *sink);
119
120 static gboolean unlock(GstBaseSink *sink);
121
122 static GstFlowReturn show_frame(GstVideoSink *sink, GstBuffer *buffer);
123 static gboolean query(GstBaseSink *element, GstQuery *query);
124 static gboolean event(GstBaseSink *element, GstEvent * event);
125
126private:
127 QGstVideoRenderer *renderer = nullptr;
128};
129
130
131class QGstVideoRendererSinkClass
132{
133public:
134 GstVideoSinkClass parent_class;
135};
136
137QT_END_NAMESPACE
138
139#endif
140

source code of qtmultimedia/src/plugins/multimedia/gstreamer/common/qgstvideorenderersink_p.h