An operator was consistently confused by having 3 on a left camera
and 4 on a right camera, and wanted L3 and R4 labels, so here goes :-)
There's no auto-import from Nageru at this point; it needs to be set
using --source-label NUM:LABEL (or -l NUM:LABEL) from the command line.
fprintf(stderr, " --http-port PORT which port to listen on for output\n");
fprintf(stderr, " --tally-url URL URL to get tally color from (polled every 100 ms)\n");
fprintf(stderr, " --midi-mapping=FILE start with the given MIDI controller mapping\n");
fprintf(stderr, " --http-port PORT which port to listen on for output\n");
fprintf(stderr, " --tally-url URL URL to get tally color from (polled every 100 ms)\n");
fprintf(stderr, " --midi-mapping=FILE start with the given MIDI controller mapping\n");
+ fprintf(stderr, " -l --source-label NUM:LABEL label source NUM as LABEL, if visible\n");
}
void parse_flags(int argc, char *const argv[])
}
void parse_flags(int argc, char *const argv[])
{ "cue-in-point-padding", required_argument, 0, OPTION_CUE_IN_POINT_PADDING },
{ "cue-out-point-padding", required_argument, 0, OPTION_CUE_OUT_POINT_PADDING },
{ "midi-mapping", required_argument, 0, OPTION_MIDI_MAPPING },
{ "cue-in-point-padding", required_argument, 0, OPTION_CUE_IN_POINT_PADDING },
{ "cue-out-point-padding", required_argument, 0, OPTION_CUE_OUT_POINT_PADDING },
{ "midi-mapping", required_argument, 0, OPTION_MIDI_MAPPING },
+ { "source-label", required_argument, 0, 'l' },
{ 0, 0, 0, 0 }
};
for (;;) {
int option_index = 0;
{ 0, 0, 0, 0 }
};
for (;;) {
int option_index = 0;
- int c = getopt_long(argc, argv, "w:h:r:q:d:", long_options, &option_index);
+ int c = getopt_long(argc, argv, "w:h:r:q:d:l:", long_options, &option_index);
case 'd':
global_flags.working_directory = optarg;
break;
case 'd':
global_flags.working_directory = optarg;
break;
+ case 'l': {
+ int prefix_len;
+ unsigned channel_idx;
+ if (sscanf(optarg, "%u:%n", &channel_idx, &prefix_len) == 1) {
+ const char *label = optarg + prefix_len;
+ global_flags.source_labels[channel_idx] = label;
+ } else {
+ fprintf(stderr, "Invalid source label format (must be on the form NUM:LABEL)\n");
+ exit(1);
+ }
+ break;
+ }
case OPTION_HTTP_PORT:
global_flags.http_port = atoi(optarg);
break;
case OPTION_HTTP_PORT:
global_flags.http_port = atoi(optarg);
break;
#include "defs.h"
#include <string>
#include "defs.h"
#include <string>
+#include <unordered_map>
struct Flags {
int width = 1280, height = 720;
struct Flags {
int width = 1280, height = 720;
double cue_out_point_padding_seconds = 0.0; // Can be changed in the menus.
bool cue_out_point_padding_set = false;
std::string midi_mapping_filename; // Empty for none.
double cue_out_point_padding_seconds = 0.0; // Can be changed in the menus.
bool cue_out_point_padding_set = false;
std::string midi_mapping_filename; // Empty for none.
+ std::unordered_map<unsigned, std::string> source_labels;
};
extern Flags global_flags;
};
extern Flags global_flags;
+ // Figure out how large the texture needs to be.
+ {
+ QImage img(overlay_width, overlay_height, QImage::Format_Grayscale8);
+ QPainter painter(&img);
+ QFont font = painter.font();
+ font.setPointSize(12);
+ QFontMetrics metrics(font);
+ overlay_base_width = lrint(metrics.boundingRect(QString::fromStdString(text)).width() + 8.0);
+ overlay_base_height = lrint(metrics.height());
+ }
+
float dpr = QGuiApplication::primaryScreen()->devicePixelRatio();
overlay_width = lrint(overlay_base_width * dpr);
overlay_height = lrint(overlay_base_height * dpr);
float dpr = QGuiApplication::primaryScreen()->devicePixelRatio();
overlay_width = lrint(overlay_base_width * dpr);
overlay_height = lrint(overlay_base_height * dpr);
+ // Work around OpenGL alignment issues.
+ while (overlay_width % 4 != 0) ++overlay_width;
+
+ // Now do the actual drawing.
overlay_image.reset(new QImage(overlay_width, overlay_height, QImage::Format_Grayscale8));
overlay_image->setDevicePixelRatio(dpr);
overlay_image->fill(0);
overlay_image.reset(new QImage(overlay_width, overlay_height, QImage::Format_Grayscale8));
overlay_image->setDevicePixelRatio(dpr);
overlay_image->fill(0);
std::shared_ptr<Frame> current_frame; // So that we hold on to the pixels.
std::shared_ptr<Frame> current_secondary_frame; // Same.
std::shared_ptr<Frame> current_frame; // So that we hold on to the pixels.
std::shared_ptr<Frame> current_secondary_frame; // Same.
- static constexpr int overlay_base_width = 16, overlay_base_height = 16;
+ int overlay_base_width = 16, overlay_base_height = 16;
int overlay_width = overlay_base_width, overlay_height = overlay_base_height;
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.
int overlay_width = overlay_base_width, overlay_height = overlay_base_height;
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.
display->setAutoFillBackground(true);
layout->addWidget(display);
display->setAutoFillBackground(true);
layout->addWidget(display);
- display->set_overlay(to_string(i + 1));
+ if (global_flags.source_labels.count(i + 1)) {
+ display->set_overlay(global_flags.source_labels[i + 1]);
+ } else {
+ display->set_overlay(to_string(i + 1));
+ }
QPushButton *preview_btn = new QPushButton(this);
preview_btn->setMaximumSize(20, 17);
QPushButton *preview_btn = new QPushButton(this);
preview_btn->setMaximumSize(20, 17);