-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathQQuickGstreamerItem.cpp
More file actions
104 lines (85 loc) · 2.36 KB
/
QQuickGstreamerItem.cpp
File metadata and controls
104 lines (85 loc) · 2.36 KB
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
#include "QQuickGstreamerItem.h"
#include <QQmlEngine>
#include <QQuickWindow>
#include <QGuiApplication>
#include <QRunnable>
#include <QDebug>
#include <gst/gst.h>
QQuickGstreamerItem::QQuickGstreamerItem(QQuickItem *parent)
: QQuickItem(parent)
{
connect(this, &QQuickGstreamerItem::windowChanged, this, &QQuickGstreamerItem::onWindowChanged);
}
QQuickGstreamerItem::~QQuickGstreamerItem()
{
teardownPipeline();
}
void QQuickGstreamerItem::setPipelineDesc(const QString &desc)
{
if (m_pipelineDesc == desc)
return;
m_pipelineDesc = desc;
m_readyWidgets.clear();
m_needsSetup = true;
emit pipelineDescChanged();
}
void QQuickGstreamerItem::setVideoObject(QObject *obj)
{
if (m_videoItem == obj)
return;
m_videoItem = qobject_cast<QQuickItem*>(obj);
if (m_pipeline && m_readyWidgets.contains(m_videoItem) && m_readyWidgets[m_videoItem])
ensureSinkBound();
else {
m_needsSetup = true;
}
emit videoObjectChanged();
}
void QQuickGstreamerItem::onWindowChanged(QQuickWindow *win)
{
connect(win, &QQuickWindow::beforeSynchronizing, this, &QQuickGstreamerItem::onBeforeSynchronizing);
}
void QQuickGstreamerItem::onBeforeSynchronizing()
{
if (!m_needsSetup)
return;
teardownPipeline();
createPipeline();
ensureSinkBound();
gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
m_needsSetup = false;
m_readyWidgets[m_videoItem] = true;
}
void QQuickGstreamerItem::teardownPipeline()
{
if (m_pipeline) {
gst_element_set_state(m_pipeline, GST_STATE_NULL);
gst_object_unref(m_pipeline);
m_pipeline = nullptr;
}
}
void QQuickGstreamerItem::ensureSinkBound()
{
if (!m_videoItem || !m_pipeline)
return;
GstElement *sink = gst_bin_get_by_name(GST_BIN(m_pipeline), "sink");
if (!sink)
return;
g_object_set(G_OBJECT(sink), "widget", m_videoItem.data(), nullptr);
gst_object_unref(sink);
}
void QQuickGstreamerItem::createPipeline()
{
if (m_pipelineDesc.isEmpty())
return;
GError *err = nullptr;
m_pipeline = gst_parse_launch(m_pipelineDesc.toUtf8().constData(), &err);
if (err) {
qDebug() << "Failed to create pipeline: " << err->message;
g_error_free(err);
if (m_pipeline) {
gst_object_unref(m_pipeline);
m_pipeline = nullptr;
}
}
}