|
|
|
@ -6,9 +6,60 @@
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#include "gui.h"
|
|
|
|
|
#include "output.h"
|
|
|
|
|
#include "configuration.h"
|
|
|
|
|
#include "error.h"
|
|
|
|
|
|
|
|
|
|
extern GtkBuilder *_builder_; // work around for threads
|
|
|
|
|
extern Output output;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* callback from output thread
|
|
|
|
|
*/
|
|
|
|
|
gboolean cb_thread_output (gpointer data) {
|
|
|
|
|
int mode = output.GetStatus();
|
|
|
|
|
GtkWidget *btncapture = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn_inputcapture"));
|
|
|
|
|
GtkWidget *btnstop = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn_inputstop"));
|
|
|
|
|
GtkWidget *btnsnapshot = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn_inputsnapshot"));
|
|
|
|
|
GtkWidget *btninputdest = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "input_btn_destpath"));
|
|
|
|
|
GtkWidget *inputdest = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "input_entry_destpath"));
|
|
|
|
|
|
|
|
|
|
if (mode & OUTPUT_MODE_SER_STARTED) {
|
|
|
|
|
gtk_widget_set_sensitive(btnstop, true);
|
|
|
|
|
gtk_widget_set_sensitive(btncapture, false);
|
|
|
|
|
gtk_widget_set_sensitive(btnsnapshot, false);
|
|
|
|
|
gtk_widget_set_sensitive(btninputdest, false);
|
|
|
|
|
gtk_widget_set_sensitive(inputdest, false);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
gtk_widget_set_sensitive(btnstop, false);
|
|
|
|
|
gtk_widget_set_sensitive(btncapture, true);
|
|
|
|
|
gtk_widget_set_sensitive(btnsnapshot, true);
|
|
|
|
|
gtk_widget_set_sensitive(btninputdest, true);
|
|
|
|
|
gtk_widget_set_sensitive(inputdest, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cb_input_btncapture (GtkWidget *widget, gpointer data) {
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
GtkWidget *inputdest = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "input_entry_destpath"));
|
|
|
|
|
std::string s = gtk_entry_get_text(GTK_ENTRY(inputdest));
|
|
|
|
|
output.SERStart(s);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cb_input_btnsnapshot (GtkWidget *widget, gpointer data) {
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void cb_input_btnstop (GtkWidget *widget, gpointer data) {
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
output.SERStop();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// C / C++ Wrapper for the thread function
|
|
|
|
|
//
|
|
|
|
@ -19,6 +70,9 @@ gpointer _OutputThread (gpointer data) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
Output::Output() { // @suppress("Class members should be properly initialized")
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
|
@ -30,9 +84,36 @@ Output::Output() { // @suppress("Class members should be properly initialized")
|
|
|
|
|
inFrame.Delete();
|
|
|
|
|
thread = NULL;
|
|
|
|
|
thread = g_thread_new("Output", _OutputThread, NULL);
|
|
|
|
|
mode = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Output::NotifyGTK () {
|
|
|
|
|
gdk_threads_add_idle(cb_thread_output, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* open output file and set mode flag
|
|
|
|
|
*/
|
|
|
|
|
void Output::SERStart (std::string destpath) {
|
|
|
|
|
printf ("%s:%d SERStart Destination Folder: %s\n", __FILE__, __LINE__, destpath.c_str());
|
|
|
|
|
|
|
|
|
|
mode |= OUTPUT_MODE_SER_STARTED;
|
|
|
|
|
// start SER output
|
|
|
|
|
NotifyGTK();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* clode output file
|
|
|
|
|
*/
|
|
|
|
|
void Output::SERStop () {
|
|
|
|
|
mode &= ~(OUTPUT_MODE_SER_STARTED);
|
|
|
|
|
// stop SER output
|
|
|
|
|
NotifyGTK();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Output::~Output() {
|
|
|
|
|
running = 0;
|
|
|
|
@ -47,7 +128,10 @@ Output::~Output() {
|
|
|
|
|
int Output::NewFrame(VideoFrameRaw *rawframe) {
|
|
|
|
|
if (rawframe == NULL) return -1;
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d Output::NewFrame Frame Raw: %d x %d Type: %s\n", __FILE__, __LINE__, rawframe->w, rawframe->h, convert_from_pixelformat(rawframe->pixfmt).c_str());
|
|
|
|
|
// printf ("%s:%d Output::NewFrame Frame Raw: %d x %d Type: %s\n", __FILE__, __LINE__, rawframe->w, rawframe->h, convert_from_pixelformat(rawframe->pixfmt).c_str());
|
|
|
|
|
if (inFrameNew) {
|
|
|
|
|
printf ("%s:%d Output::NewFrame truncating one frame.\n", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LockInMutex();
|
|
|
|
|
inFrame.CopyFrom(rawframe);
|
|
|
|
@ -57,11 +141,6 @@ int Output::NewFrame(VideoFrameRaw *rawframe) {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Output::NewImage() {
|
|
|
|
|
// newimage = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// NewFrame: will set new frame
|
|
|
|
|
// Thread: newFrame |------> Find Object --- not found ---> send gui information
|
|
|
|
@ -69,26 +148,20 @@ void Output::Thread() {
|
|
|
|
|
while (running) {
|
|
|
|
|
// check for new frame
|
|
|
|
|
LockInMutex();
|
|
|
|
|
|
|
|
|
|
if (inFrameNew == 1) {
|
|
|
|
|
if (mode & OUTPUT_MODE_SER_STARTED) {
|
|
|
|
|
// for now display error message
|
|
|
|
|
errormessage_display((char*)"windows-main", (char*)"Error", (char*)"Writing SER files is not finished yet.");
|
|
|
|
|
SERStop();
|
|
|
|
|
}
|
|
|
|
|
inFrameNew = 0;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// do some other stuff use if possible only the oldFrame data
|
|
|
|
|
ComposeOutput();
|
|
|
|
|
UnLockInMutex();
|
|
|
|
|
|
|
|
|
|
// copy output image for gtk
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
UnLockInMutex();
|
|
|
|
|
|
|
|
|
|
UnLockInMutex();
|
|
|
|
|
|
|
|
|
|
usleep (10000); // sleep 10ms
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Output::ComposeOutput() {
|
|
|
|
|
// printf ("%s:%d inFrame (w:%d h:%d)\n", __FILE__, __LINE__, inFrame.w, inFrame.h);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|