// file: poc-qt/poc006/src/qt_gst_helpers.cpp #include "qt_gst_helpers.h" #include #include #include #include #include #include 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(roots.first()); if (!root_window) { return nullptr; } return root_window->findChild("videoItem"); } bool bind_sink_widget(std::uintptr_t sink_ptr, QQuickItem* item) { if (sink_ptr == 0 || item == nullptr) { return false; } auto* sink = reinterpret_cast(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(roots.first()); if (!root_window) { return false; } auto* pipeline = reinterpret_cast(pipeline_ptr); root_window->scheduleRenderJob( new SetPlaying(pipeline), QQuickWindow::BeforeSynchronizingStage ); return true; }