#include #include "convert.h" #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 input_getdestandsufix (std::string *sdir, std::string *ssufix) { GtkWidget *inputdest = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "input_entry_destpath")); GtkWidget *inputsufix = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn_input_filesufix")); if (sdir != NULL) *sdir = gtk_entry_get_text(GTK_ENTRY(inputdest)); if (ssufix != NULL) *ssufix = gtk_entry_get_text(GTK_ENTRY(inputsufix)); } void cb_input_btncapture (GtkWidget *widget, gpointer data) { std::string sdir, ssufix; printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); input_getdestandsufix(&sdir, &ssufix); output.SERStart(sdir, ssufix); }; void cb_input_btnsnapshot (GtkWidget *widget, gpointer data) { std::string sdir, ssufix; printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); input_getdestandsufix(&sdir, &ssufix); // output.Capture(sdir, ssufix); }; 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 // gpointer _OutputThread (gpointer data) { output.Thread (); return NULL; }; /* * */ Output::Output() { // @suppress("Class members should be properly initialized") printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); outputser = NULL; g_mutex_init (&mutexin); g_mutex_init (&muteximage); g_mutex_init (&mutextmp); g_mutex_init (&mutex); running = 1; inFrame.Delete(); mode = 0; thread = NULL; thread = g_thread_new("Output", _OutputThread, NULL); }; void Output::NotifyGTK () { gdk_threads_add_idle(cb_thread_output, NULL); } /* * open output file and set mode flag * all the other SER stuff will be set with the first frame */ void Output::SERStart (std::string destpath, std::string sufix) { time_t t = time(NULL); struct tm *tmptr; char fname[LEN_FILENAME]; char fullfname[LEN_FULLFILENAME]; // // check to create file, if not possible try creating the directory and create the file again tmptr = localtime(&t); strftime(fname, LEN_FILENAME, "%Y%m%d-%H%M%S", tmptr); snprintf (fullfname, LEN_FULLFILENAME, "%s/%s-%s.ser", destpath.c_str(), fname, sufix.c_str()); outputfilename = fullfname; printf ("%s:%d SERStart Destination File: %s\n", __FILE__, __LINE__, outputfilename.c_str()); mode |= OUTPUT_MODE_SER_STARTED; NotifyGTK(); }; /* * clode output file */ void Output::SERStop () { mode &= ~(OUTPUT_MODE_SER_STARTED); if (outputser) { // close SER and delete object --> deleting the object should also rewrite the write the header delete outputser; outputser = NULL; } NotifyGTK(); }; Output::~Output() { running = 0; if (thread) { g_thread_join (thread); thread = NULL; } }; 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()); if (inFrameNew) { printf ("%s:%d Output::NewFrame truncating one frame.\n", __FILE__, __LINE__); } LockInMutex(); inFrame.CopyFrom(rawframe); inFrameNew = 1; UnLockInMutex(); return 0; }; // // NewFrame: will set new frame // Thread: newFrame |------> Find Object --- not found ---> send gui information void Output::Thread() { while (running) { // check for new frame LockInMutex(); if (inFrameNew == 1) { if (mode & OUTPUT_MODE_SER_STARTED) { if (outputser == NULL) { // first frame of ser output int pixsize; int serformat; outputserw = inFrame.w; outputserh = inFrame.h; outputserfmt = inFrame.pixfmt; if (!ser_convert_type_to_ser(outputserfmt, &pixsize, &serformat)) { errormessage_display((char*)"windows-main", (char*)"Error", (char*)"Pixelformat [%s] not supported.", convert_from_pixelformat(outputserfmt).c_str()); SERStop(); } outputser = new SER(); outputser->setWidth(outputserw); outputser->setHeight(outputserh); outputser->setColorID(serformat); outputser->setPixelDepth(pixsize); if (outputser->setFile((char *)outputfilename.c_str()) == -1) { errormessage_display((char*)"windows-main", (char*)"Error", (char*)"Could not set output file [%s]. Error: %s", outputfilename.c_str(), strerror(errno)); SERStop(); } outputser->setObserver((char *)"FIXME:read username from OS"); outputser->setTelescope((char *)"FIXME:not implemented yet"); outputser->setInstrument((char *)"FIXME:just read device from dirver"); outputser->setNumberOfFrames(0); outputser->writeHeader(); } else { // // check if the frame type or size changed if (outputserw != inFrame.w || outputserh != inFrame.h || outputserfmt != inFrame.pixfmt) { errormessage_display((char*)"windows-main", (char*)"Error", (char*)"Frame format or dimensions changed.\n(%s @ %d x %d) != (%s @ %d x %d)\n", convert_from_pixelformat(outputserfmt).c_str(), outputserw, outputserh, convert_from_pixelformat(inFrame.pixfmt).c_str(), inFrame.w, inFrame.h); SERStop(); } } if (outputser != NULL) { // we need to check in case outputser got deleted. // // write frame outputser->appendFrame(inFrame.data); } } inFrameNew = 0; } UnLockInMutex(); usleep (10000); // sleep 10ms } }