webcam from gstreamer
v4l2src -> videoconvert -> glupload -> glcolorconvert -> qml6glsink
This commit is contained in:
95
poc006/src/qt_gst_helpers.cpp
Normal file
95
poc006/src/qt_gst_helpers.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
// file: poc-qt/poc006/src/qt_gst_helpers.cpp
|
||||
|
||||
#include "qt_gst_helpers.h"
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWindow>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QObject>
|
||||
#include <QRunnable>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
class SetPlaying : public QRunnable
|
||||
{
|
||||
public:
|
||||
explicit SetPlaying(GstElement* pipeline)
|
||||
: pipeline_(pipeline ? GST_ELEMENT(gst_object_ref(pipeline)) : nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
~SetPlaying() override
|
||||
{
|
||||
if (pipeline_) {
|
||||
gst_object_unref(pipeline_);
|
||||
pipeline_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
if (pipeline_) {
|
||||
gst_element_set_state(pipeline_, GST_STATE_PLAYING);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GstElement* pipeline_;
|
||||
};
|
||||
|
||||
QQuickItem* find_video_item(QQmlApplicationEngine& engine)
|
||||
{
|
||||
const auto roots = engine.rootObjects();
|
||||
if (roots.isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto* root_window = qobject_cast<QQuickWindow*>(roots.first());
|
||||
if (!root_window) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return root_window->findChild<QQuickItem*>("videoItem");
|
||||
}
|
||||
|
||||
bool bind_sink_widget(std::uintptr_t sink_ptr, QQuickItem* item)
|
||||
{
|
||||
if (sink_ptr == 0 || item == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* sink = reinterpret_cast<GstElement*>(sink_ptr);
|
||||
|
||||
g_object_set(sink, "widget", item, nullptr);
|
||||
|
||||
// Recommandé pour propager correctement le contexte GL Qt/GStreamer
|
||||
gst_element_set_state(sink, GST_STATE_READY);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool schedule_pipeline_play(QQmlApplicationEngine& engine, std::uintptr_t pipeline_ptr)
|
||||
{
|
||||
if (pipeline_ptr == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto roots = engine.rootObjects();
|
||||
if (roots.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* root_window = qobject_cast<QQuickWindow*>(roots.first());
|
||||
if (!root_window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* pipeline = reinterpret_cast<GstElement*>(pipeline_ptr);
|
||||
|
||||
root_window->scheduleRenderJob(
|
||||
new SetPlaying(pipeline),
|
||||
QQuickWindow::BeforeSynchronizingStage
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user