3 #include <QDialogButtonBox>
6 #include <movit/resource_pool.h>
7 #include <movit/util.h>
12 #include "ui_analyzer.h"
17 : ui(new Ui::Analyzer)
21 //connect(ui->button_box, &QDialogButtonBox::accepted, [this]{ this->close(); });
23 ui->input_box->addItem("Live", Mixer::OUTPUT_LIVE);
24 ui->input_box->addItem("Preview", Mixer::OUTPUT_PREVIEW);
25 unsigned num_channels = global_mixer->get_num_channels();
26 for (unsigned channel_idx = 0; channel_idx < num_channels; ++channel_idx) {
27 Mixer::Output channel = static_cast<Mixer::Output>(Mixer::OUTPUT_INPUT0 + channel_idx);
28 string name = global_mixer->get_channel_name(channel);
29 ui->input_box->addItem(QString::fromStdString(name), channel);
32 connect(ui->grab_btn, &QPushButton::clicked, bind(&Analyzer::grab_clicked, this));
33 connect(ui->input_box, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), bind(&Analyzer::signal_changed, this));
36 surface = create_surface(QSurfaceFormat::defaultFormat());
37 context = create_context(surface);
39 if (!make_current(context, surface)) {
44 glGenBuffers(1, &pbo);
45 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo);
46 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, global_flags.width * global_flags.height * 4, NULL, GL_STREAM_READ);
51 if (!make_current(context, surface)) {
55 glDeleteBuffers(1, &pbo);
57 if (resource_pool != nullptr) {
58 resource_pool->clean_context();
60 delete_context(context);
61 delete surface; // TODO?
64 void Analyzer::grab_clicked()
66 Mixer::Output channel = static_cast<Mixer::Output>(ui->input_box->currentData().value<int>());
68 if (!make_current(context, surface)) {
73 Mixer::DisplayFrame frame;
74 if (!global_mixer->get_display_frame(channel, &frame)) {
75 printf("Not ready yet\n");
79 // Set up an FBO to render into.
80 if (resource_pool == nullptr) {
81 resource_pool = frame.chain->get_resource_pool();
83 assert(resource_pool == frame.chain->get_resource_pool());
85 GLuint fbo_tex = resource_pool->create_2d_texture(GL_RGBA8, global_flags.width, global_flags.height);
87 GLuint fbo = resource_pool->create_fbo(fbo_tex);
90 glWaitSync(frame.ready_fence.get(), /*flags=*/0, GL_TIMEOUT_IGNORED);
94 glDisable(GL_FRAMEBUFFER_SRGB);
96 frame.chain->render_to_fbo(fbo, global_flags.width, global_flags.height);
99 // Read back to memory.
100 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
102 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
104 glReadPixels(0, 0, global_flags.width, global_flags.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, BUFFER_OFFSET(0));
107 unsigned char *buf = (unsigned char *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
110 int r_hist[256] = {0}, g_hist[256] = {0}, b_hist[256] = {0};
111 const unsigned char *ptr = buf;
112 for (int y = 0; y < global_flags.width; ++y) {
113 for (int x = 0; x < global_flags.height; ++x) {
125 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
127 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
129 glBindFramebuffer(GL_FRAMEBUFFER, 0);
133 for (unsigned i = 0; i < 256; ++i) { printf(" %d", r_hist[i]); }
136 for (unsigned i = 0; i < 256; ++i) { printf(" %d", g_hist[i]); }
139 for (unsigned i = 0; i < 256; ++i) { printf(" %d", b_hist[i]); }
142 resource_pool->release_2d_texture(fbo_tex);
144 resource_pool->release_fbo(fbo);
148 void Analyzer::signal_changed()
150 Mixer::Output channel = static_cast<Mixer::Output>(ui->input_box->currentData().value<int>());
151 ui->display->set_output(channel);