diff --git a/compile_commands.json b/compile_commands.json index 4b966b0..761f8c2 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -4,5 +4,11 @@ "command": "c++ -Iflowy.p -I. -I.. -I/usr/include/sigc++-3.0 -I/usr/lib/x86_64-linux-gnu/sigc++-3.0/include -I/usr/include/gtk-4.0/unix-print -I/usr/include/gtk-4.0 -I/usr/include/gio-unix-2.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/fribidi -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/x86_64-linux-gnu -I/usr/include/pixman-1 -I/usr/include/uuid -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/graphene-1.0 -I/usr/lib/x86_64-linux-gnu/graphene-1.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gtkmm-4.0 -I/usr/lib/gtkmm-4.0/include -I/usr/include/pangomm-2.48 -I/usr/lib/pangomm-2.48/include -I/usr/include/giomm-2.68 -I/usr/lib/giomm-2.68/include -I/usr/include/glibmm-2.68 -I/usr/lib/glibmm-2.68/include -I/usr/include/cairomm-1.16 -I/usr/lib/cairomm-1.16/include -I/usr/include/gstreamer-1.0 -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -g -pthread -mfpmath=sse -msse -msse2 -MD -MQ flowy.p/src_main.cpp.o -MF flowy.p/src_main.cpp.o.d -o flowy.p/src_main.cpp.o -c ../src/main.cpp", "file": "../src/main.cpp", "output": "flowy.p/src_main.cpp.o" + }, + { + "directory": "/home/talksik/Code/flowy/client/build", + "command": "c++ -Iflowy.p -I. -I.. -I/usr/include/sigc++-3.0 -I/usr/lib/x86_64-linux-gnu/sigc++-3.0/include -I/usr/include/gtk-4.0/unix-print -I/usr/include/gtk-4.0 -I/usr/include/gio-unix-2.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/fribidi -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/x86_64-linux-gnu -I/usr/include/pixman-1 -I/usr/include/uuid -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/graphene-1.0 -I/usr/lib/x86_64-linux-gnu/graphene-1.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gtkmm-4.0 -I/usr/lib/gtkmm-4.0/include -I/usr/include/pangomm-2.48 -I/usr/lib/pangomm-2.48/include -I/usr/include/giomm-2.68 -I/usr/lib/giomm-2.68/include -I/usr/include/glibmm-2.68 -I/usr/lib/glibmm-2.68/include -I/usr/include/cairomm-1.16 -I/usr/lib/cairomm-1.16/include -I/usr/include/gstreamer-1.0 -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -g -pthread -mfpmath=sse -msse -msse2 -MD -MQ flowy.p/src_local_capture.cpp.o -MF flowy.p/src_local_capture.cpp.o.d -o flowy.p/src_local_capture.cpp.o -c ../src/local_capture.cpp", + "file": "../src/local_capture.cpp", + "output": "flowy.p/src_local_capture.cpp.o" } ] diff --git a/meson.build b/meson.build index 298bd06..cf6c5d4 100644 --- a/meson.build +++ b/meson.build @@ -4,7 +4,10 @@ gtkmm_dep = dependency('gtkmm-4.0', version: '>= 4.6.0') gstreamer_dep = dependency('gstreamer-1.0') exe_file = executable('flowy', - 'src/main.cpp', + sources: [ + 'src/main.cpp', + 'src/local_capture.cpp' + ], dependencies: [gtkmm_dep, gstreamer_dep], win_subsystem: 'windows', ) diff --git a/src/local_capture.cpp b/src/local_capture.cpp new file mode 100644 index 0000000..82d1280 --- /dev/null +++ b/src/local_capture.cpp @@ -0,0 +1,79 @@ + +#include "local_capture.h" +#include "gst/gstbus.h" +#include "gst/gstelement.h" +#include "gst/gstelementfactory.h" +#include + +LocalCapture::LocalCapture() { + std::cout << "initializing local capture" << std::endl; + + GstElement *video = gst_element_factory_make("v4l2src", "video"); + GstElement *videoconvert = + gst_element_factory_make("videoconvert", "videoconvert"); + gtksink = gst_element_factory_make("autovideosink", "sink"); + + if (!video || !videoconvert || !gtksink) { + std::cerr << "failed to create elements" << std::endl; + return; + } + + m_pipeline = gst_pipeline_new("local_capture"); + + gst_bin_add_many(GST_BIN(m_pipeline), video, videoconvert, gtksink, nullptr); + if (!gst_element_link_many(video, videoconvert, gtksink, nullptr)) { + g_printerr("Elements could not be linked.\n"); + } + + /* Start playing */ + gst_element_set_state(m_pipeline, GST_STATE_PAUSED); + + m_bus = gst_element_get_bus(m_pipeline); + gst_bus_add_watch( + m_bus, + [](GstBus *bus, GstMessage *msg, gpointer data) { + std::cout << "message type: " << GST_MESSAGE_TYPE(msg) << std::endl; + + switch (GST_MESSAGE_TYPE(msg)) { + case GST_MESSAGE_ERROR: { + GError *err; + gchar *debug; + gst_message_parse_error(msg, &err, &debug); + g_printerr("Error: %s\n", err->message); + g_error_free(err); + g_free(debug); + break; + } + case GST_MESSAGE_EOS: + g_print("End of stream\n"); + break; + default: + break; + } + + return (int)G_SOURCE_CONTINUE; + }, + nullptr); + + std::cout << "local capture ready" << std::endl; +} + +void LocalCapture::start() { + if (m_isRunning) { + return; + } + + std::cout << "starting local capture" << std::endl; + m_isRunning = true; + gst_element_set_state(m_pipeline, GST_STATE_PLAYING); +} + +void LocalCapture::pause() { + if (!m_isRunning) { + return; + } + + std::cout << "pausing local capture" << std::endl; + m_isRunning = false; + gst_element_set_state(m_pipeline, GST_STATE_PAUSED); +} diff --git a/src/local_capture.h b/src/local_capture.h new file mode 100644 index 0000000..4a00623 --- /dev/null +++ b/src/local_capture.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +class LocalCapture { +public: + LocalCapture(); + void start(); + void pause(); + ~LocalCapture() { + gst_object_unref(m_bus); + gst_element_set_state(m_pipeline, GST_STATE_NULL); + gst_object_unref(m_pipeline); + } + bool isRunning() const { return m_isRunning; } + GstElement *gtksink; + +private: + bool m_isRunning; + gboolean bus_watch(GMainLoop *loop); + GstElement *m_pipeline; + GstBus *m_bus; +}; diff --git a/src/main.cpp b/src/main.cpp index 79d0ee7..e022084 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,62 +1,47 @@ #include "gtkmm/button.h" +#include #include #include #include +#include "gtkmm/widget.h" +#include "local_capture.h" + #include "main.h" -void test_gstreamer() { - GstElement *pipeline = nullptr; - GstBus *bus = nullptr; - GstMessage *msg = nullptr; - - // building pipeline - pipeline = - gst_parse_launch("playbin " - "uri=https://www.freedesktop.org/software/gstreamer-sdk/" - "data/media/sintel_trailer-480p.webm", - nullptr); - - // start playing - gst_element_set_state(pipeline, GST_STATE_PLAYING); - - // wait until error or EOS ( End Of Stream ) - bus = gst_element_get_bus(pipeline); - msg = gst_bus_timed_pop_filtered( - bus, GST_CLOCK_TIME_NONE, - static_cast(GST_MESSAGE_ERROR | GST_MESSAGE_EOS)); - - // free memory - if (msg != nullptr) - gst_message_unref(msg); - gst_object_unref(bus); - gst_element_set_state(pipeline, GST_STATE_NULL); - gst_object_unref(pipeline); -} - MyWindow::MyWindow() { + set_title("flowy"); - set_title("Basic application"); + m_localCapture = new LocalCapture(); + + //GtkWidget *area; + // g_object_get(m_localCapture->gtksink, "widget", &area, NULL); + // Gtk::Widget *widget = Glib::wrap(area); + // set_child(*widget); Gtk::Button button("start capture"); - button.signal_clicked().connect( - sigc::mem_fun(*this, &MyWindow::startCapture)); - + sigc::mem_fun(*this, &MyWindow::toggleCapture)); set_default_size(800, 450); - set_child(button); } MyWindow::~MyWindow() {} -void MyWindow::startCapture() { std::cout << "start capture" << std::endl; } +void MyWindow::toggleCapture() { + if (m_localCapture->isRunning()) { + m_localCapture->pause(); + button.set_label("start capture"); + } else { + m_localCapture->start(); + button.set_label("stop capture"); + } +} int main(int argc, char **argv) { gst_init(&argc, &argv); - test_gstreamer(); - auto app = Gtk::Application::create("org.gtkmm.examples.base"); + auto app = Gtk::Application::create("live.flowy.client"); return app->make_window_and_run(argc, argv); } diff --git a/src/main.h b/src/main.h index a024285..f66c295 100644 --- a/src/main.h +++ b/src/main.h @@ -1,3 +1,6 @@ +#pragma once + +#include "local_capture.h" #include class MyWindow : public Gtk::Window { @@ -7,5 +10,8 @@ public: public: Gtk::Button button; - void startCapture(); + void toggleCapture(); + +private: + LocalCapture *m_localCapture; };