check_error();
chain->finalize();
check_error();
+
+ overlay_chain.reset(new EffectChain(overlay_width, overlay_height, resource_pool));
+ overlay_input = (movit::FlatInput *)overlay_chain->add_input(new FlatInput(image_format, FORMAT_GRAYSCALE, GL_UNSIGNED_BYTE, overlay_width, overlay_height));
+
+ overlay_chain->add_output(inout_format, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED);
+ overlay_chain->finalize();
}
void JPEGFrameView::resizeGL(int width, int height)
void JPEGFrameView::paintGL()
{
+ glViewport(0, 0, width(), height());
if (current_frame == nullptr) {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
check_error();
chain->render_to_screen();
+
+ if (overlay_image != nullptr) {
+ if (overlay_input_needs_refresh) {
+ overlay_input->set_pixel_data(overlay_image->bits());
+ }
+ glViewport(width() - overlay_width, 0, overlay_width, overlay_height);
+ overlay_chain->render_to_screen();
+ }
}
void JPEGFrameView::setDecodedFrame(std::shared_ptr<Frame> frame)
emit clicked();
}
}
+
+void JPEGFrameView::set_overlay(const string &text)
+{
+ if (text.empty()) {
+ overlay_image.reset();
+ return;
+ }
+
+ overlay_image.reset(new QImage(overlay_width, overlay_height, QImage::Format_Grayscale8));
+ overlay_image->fill(0);
+ QPainter painter(overlay_image.get());
+
+ painter.setPen(Qt::white);
+ QFont font = painter.font();
+ font.setPointSize(12);
+ painter.setFont(font);
+
+ painter.drawText(QRectF(0, 0, overlay_width, overlay_height), Qt::AlignCenter, QString::fromStdString(text));
+
+ // Don't refresh immediately; we might not have an OpenGL context here.
+ overlay_input_needs_refresh = true;
+}
#include <stdint.h>
#include <movit/effect_chain.h>
+#include <movit/flat_input.h>
#include <movit/ycbcr_input.h>
#include <memory>
unsigned get_stream_idx() const { return current_stream_idx; }
void setDecodedFrame(std::shared_ptr<Frame> frame);
-
+ void set_overlay(const std::string &text); // Blank for none.
signals:
void clicked();
std::shared_ptr<Frame> current_frame; // So that we hold on to the pixels.
movit::YCbCrInput *ycbcr_input;
movit::YCbCrFormat ycbcr_format;
+
+ static constexpr int overlay_width = 16, overlay_height = 16;
+ std::unique_ptr<QImage> overlay_image; // If nullptr, no overlay.
+ std::unique_ptr<movit::EffectChain> overlay_chain; // Just to get the overlay on screen in the easiest way possible.
+ movit::FlatInput *overlay_input;
+ bool overlay_input_needs_refresh = false;
};
#endif // !defined(_JPEG_FRAME_VIEW_H)
connect(preview_1, &QShortcut::activated, ui->preview_1_btn, &QPushButton::click);
connect(ui->input1_display, &JPEGFrameView::clicked, ui->preview_1_btn, &QPushButton::click);
connect(ui->preview_1_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(0); });
+ ui->input1_display->set_overlay("1");
QShortcut *preview_2 = new QShortcut(QKeySequence(Qt::Key_2), this);
connect(preview_2, &QShortcut::activated, ui->preview_2_btn, &QPushButton::click);
connect(ui->input2_display, &JPEGFrameView::clicked, ui->preview_2_btn, &QPushButton::click);
connect(ui->preview_2_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(1); });
+ ui->input2_display->set_overlay("2");
QShortcut *preview_3 = new QShortcut(QKeySequence(Qt::Key_3), this);
connect(preview_3, &QShortcut::activated, ui->preview_3_btn, &QPushButton::click);
connect(ui->input3_display, &JPEGFrameView::clicked, ui->preview_3_btn, &QPushButton::click);
connect(ui->preview_3_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(2); });
+ ui->input3_display->set_overlay("3");
QShortcut *preview_4 = new QShortcut(QKeySequence(Qt::Key_4), this);
connect(preview_4, &QShortcut::activated, ui->preview_4_btn, &QPushButton::click);
connect(ui->input4_display, &JPEGFrameView::clicked, ui->preview_4_btn, &QPushButton::click);
connect(ui->preview_4_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(3); });
+ ui->input4_display->set_overlay("4");
connect(ui->playlist_duplicate_btn, &QPushButton::clicked, this, &MainWindow::playlist_duplicate);