summaryrefslogtreecommitdiffstats
path: root/src/plugins/multimedia/gstreamer/common/qgstvideorenderersink_p.h
blob: 99d1b0ac8b42bdadfadf3980fef194f2d35ad08e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (C) 2016 Jolla Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#ifndef QGSTVIDEORENDERERSINK_P_H
#define QGSTVIDEORENDERERSINK_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <QtMultimedia/private/qtmultimediaglobal_p.h>
#include <gst/video/gstvideosink.h>
#include <gst/video/video.h>

#include <QtCore/qlist.h>
#include <QtCore/qmutex.h>
#include <QtCore/qqueue.h>
#include <QtCore/qpointer.h>
#include <QtCore/qwaitcondition.h>
#include <qvideoframeformat.h>
#include <qvideoframe.h>
#include <common/qgstvideobuffer_p.h>
#include <common/qgst_p.h>

QT_BEGIN_NAMESPACE
class QVideoSink;

class QGstVideoRenderer : public QObject
{
public:
    explicit QGstVideoRenderer(QGstreamerVideoSink *sink);
    ~QGstVideoRenderer();

    const QGstCaps &caps();

    bool start(const QGstCaps& caps);
    void stop();
    void unlock();
    bool proposeAllocation(GstQuery *query);

    void flush();

    GstFlowReturn render(GstBuffer *buffer);

    bool event(QEvent *event) override;
    bool query(GstQuery *query);
    void gstEvent(GstEvent *event);

private slots:
    bool handleEvent(QMutexLocker<QMutex> *locker);

private:
    void notify();
    bool waitForAsyncEvent(QMutexLocker<QMutex> *locker, QWaitCondition *condition, unsigned long time);
    static QGstCaps createSurfaceCaps(QGstreamerVideoSink *);

    void gstEventHandleTag(GstEvent *);
    void gstEventHandleEOS(GstEvent *);

    QPointer<QGstreamerVideoSink> m_sink;

    QMutex m_mutex;
    QWaitCondition m_setupCondition;
    QWaitCondition m_renderCondition;

    // --- accessed from multiple threads, need to hold mutex to access
    GstFlowReturn m_renderReturn = GST_FLOW_OK;
    bool m_active = false;

    const QGstCaps m_surfaceCaps;

    QGstCaps m_startCaps;
    QGstBufferHandle m_renderBuffer;

    bool m_notified = false;
    bool m_stop = false;
    bool m_flush = false;
    bool m_frameMirrored = false;
    QtVideo::Rotation m_frameRotationAngle = QtVideo::Rotation::None;

    // --- only accessed from one thread
    QVideoFrameFormat m_format;
    GstVideoInfo m_videoInfo{};
    bool m_flushed = true;
    QGstCaps::MemoryFormat memoryFormat = QGstCaps::CpuMemory;
};

class QGstVideoRendererSink
{
public:
    GstVideoSink parent{};

    static QGstVideoRendererSink *createSink(QGstreamerVideoSink *surface);
    static void setSink(QGstreamerVideoSink *surface);

private:
    static GType get_type();
    static void class_init(gpointer g_class, gpointer class_data);
    static void base_init(gpointer g_class);
    static void instance_init(GTypeInstance *instance, gpointer g_class);

    static void finalize(GObject *object);

    static void handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d);

    static GstStateChangeReturn change_state(GstElement *element, GstStateChange transition);

    static GstCaps *get_caps(GstBaseSink *sink, GstCaps *filter);
    static gboolean set_caps(GstBaseSink *sink, GstCaps *caps);

    static gboolean propose_allocation(GstBaseSink *sink, GstQuery *query);

    static gboolean stop(GstBaseSink *sink);

    static gboolean unlock(GstBaseSink *sink);

    static GstFlowReturn show_frame(GstVideoSink *sink, GstBuffer *buffer);
    static gboolean query(GstBaseSink *element, GstQuery *query);
    static gboolean event(GstBaseSink *element, GstEvent * event);

private:
    QGstVideoRenderer *renderer = nullptr;
};


class QGstVideoRendererSinkClass
{
public:
    GstVideoSinkClass parent_class;
};

QT_END_NAMESPACE

#endif