96 lines
2.0 KiB
C++
96 lines
2.0 KiB
C++
// 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;
|
|
}
|