*.pb.h
*.pb.cc
*.moc.cpp
+ui_*.h
futatabi
frames/*.jpeg
+.ycm_extra_conf.py
LDLIBS=$(shell pkg-config --libs $(PKG_MODULES)) -pthread -lavformat -lavcodec -lavutil -lswscale
# Qt objects
-OBJS_WITH_MOC =
+OBJS_WITH_MOC = mainwindow.o
OBJS += $(OBJS_WITH_MOC)
OBJS += $(OBJS_WITH_MOC:.o=.moc.o)
all: futatabi
+mainwindow.o: ui_mainwindow.h
+
futatabi: $(OBJS) $(CEF_LIBS)
$(CXX) -o $@ $^ $(LDFLAGS) $(LDLIBS)
+#include <assert.h>
#include <stdio.h>
+#include <stdint.h>
+
+#include <chrono>
#include <memory>
+#include <mutex>
+#include <string>
+#include <thread>
+#include <vector>
extern "C" {
#include <libavformat/avformat.h>
}
+#include <QApplication>
+
+#include "mainwindow.h"
#include "ffmpeg_raii.h"
+#define MAX_STREAMS 16
+
using namespace std;
+using namespace std::chrono;
+
+string filename_for_frame(unsigned stream_idx, int64_t pts)
+{
+ char filename[256];
+ snprintf(filename, sizeof(filename), "frames/cam%d-pts%09ld.jpeg", stream_idx, pts);
+ return filename;
+}
+
+mutex frame_mu;
+vector<int64_t> frames[MAX_STREAMS];
+
+int thread_func();
-int main(void)
+int main(int argc, char **argv)
{
av_register_all();
avformat_network_init();
+ QApplication app(argc, argv);
+ MainWindow mainWindow;
+ mainWindow.show();
+
+ thread(thread_func).detach();
+
+ return app.exec();
+}
+
+int thread_func()
+{
auto format_ctx = avformat_open_input_unique("example.mp4", nullptr, nullptr);
if (format_ctx == nullptr) {
fprintf(stderr, "%s: Error opening file\n", "example.mp4");
}
fprintf(stderr, "Got a frame from camera %d, pts = %ld, size = %d\n",
pkt.stream_index, pkt.pts, pkt.size);
- char filename[256];
- snprintf(filename, sizeof(filename), "frames/cam%d-pts%09ld.jpeg", pkt.stream_index, pkt.pts);
- FILE *fp = fopen(filename, "wb");
+ string filename = filename_for_frame(pkt.stream_index, pkt.pts);
+ FILE *fp = fopen(filename.c_str(), "wb");
if (fp == nullptr) {
- perror(filename);
+ perror(filename.c_str());
exit(1);
}
fwrite(pkt.data, pkt.size, 1, fp);
fclose(fp);
+
+ assert(pkt.stream_index < MAX_STREAMS);
+ frames[pkt.stream_index].push_back(pkt.pts);
+
+ this_thread::sleep_for(milliseconds(1000) / 120);
}
return 0;
--- /dev/null
+#include "mainwindow.h"
+
+#include "ui_mainwindow.h"
+
+MainWindow *global_mainwindow = nullptr;
+
+MainWindow::MainWindow()
+ : ui(new Ui::MainWindow)
+{
+ global_mainwindow = this;
+ ui->setupUi(this);
+}
--- /dev/null
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <stdbool.h>
+#include <sys/types.h>
+#include <QMainWindow>
+
+namespace Ui {
+class MainWindow;
+} // namespace Ui
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow();
+
+private:
+ Ui::MainWindow *ui;
+};
+
+extern MainWindow *global_mainwindow;
+
+#endif
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1038</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <widget class="QWidget" name="gridLayoutWidget">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>381</width>
+ <height>211</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="1">
+ <widget class="QGraphicsView" name="input2_display"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QGraphicsView" name="input1_display"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QGraphicsView" name="input3_display"/>
+ </item>
+ <item row="1" column="1">
+ <widget class="QGraphicsView" name="input4_display"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="label">
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>240</y>
+ <width>261</width>
+ <height>17</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Current inputs</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QGraphicsView" name="preview_display">
+ <property name="geometry">
+ <rect>
+ <x>410</x>
+ <y>20</y>
+ <width>281</width>
+ <height>192</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QGraphicsView" name="live_display">
+ <property name="geometry">
+ <rect>
+ <x>705</x>
+ <y>20</y>
+ <width>291</width>
+ <height>192</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_2">
+ <property name="geometry">
+ <rect>
+ <x>470</x>
+ <y>240</y>
+ <width>191</width>
+ <height>17</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Preview output</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_3">
+ <property name="geometry">
+ <rect>
+ <x>760</x>
+ <y>230</y>
+ <width>191</width>
+ <height>17</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Current output</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>