webcam from gstreamer

v4l2src -> videoconvert -> glupload -> glcolorconvert -> qml6glsink
This commit is contained in:
2026-04-04 20:15:25 +02:00
parent 9cedf69d08
commit ec30e64417
9 changed files with 675 additions and 1 deletions

View 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;
}