#include #include #include #include #include #include #include #include #include "debug.h" #include "convert.h" #include "gui.h" #include "video.h" #include "configuration.h" #include "debayer.h" extern GtkBuilder *_builder_; // work around for threads GtkWidget *debug_da = NULL; GdkPixbuf *debug_pixbuf = NULL; VideoFrame debug_frame; int debug_uninit = 1; GMutex debug_mutex; time_t debug_time; #define LEN 2048 void debug_init() { debug_uninit = 0; g_mutex_init (&debug_mutex); debug_time = time(NULL); } void debug_tofile(char *fname, int isheader, char *fmt, ...) { struct timeval tv; va_list args; char buffer[LEN]; int fd, len; std::string fn; if (debug_uninit) debug_init(); debug_lock_mutex(); // locale set to C, floating points decimals are . std::string s = setlocale(LC_ALL, NULL); setlocale (LC_ALL, "C"); // append time to filename to the start of the filename struct tm *timetm = localtime(&debug_time); char timestr[64] = ""; strftime(timestr, 63, "%Y%m%d-%H%M%S", timetm); fn = "debug-" + (std::string)timestr + "-" + (std::string)fname; gettimeofday(&tv,NULL); #ifdef BUILD_WINDOWS fd = open(fn.c_str(), O_WRONLY | O_APPEND | O_CREAT); #else fd = open(fn.c_str(), O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); #endif if (fd < 0) errorexit((char*)"%s:%d could not open debug '%s' file. Error:%s\n", __FILE__, __LINE__, fname, strerror(errno)); if (isheader) snprintf (buffer, 32, "time,"); else snprintf (buffer, 32, "%lld,", (long long int) (tv.tv_sec)*1000 + (long long int) tv.tv_usec/1000); len = strlen (buffer); va_start (args, fmt); vsnprintf (buffer+len, LEN-1-len, fmt, args); va_end (args); buffer[LEN-1] = 0; write (fd, buffer, strlen(buffer)); close (fd); // reset locale to user setting setlocale (LC_ALL, s.c_str()); debug_unlock_mutex(); } gboolean debug_thread_cb (gpointer data) { debug_lock_mutex(); // // create video drawarea if needed if (debug_da == NULL) debug_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "debug-da")); if (debug_pixbuf == NULL) { debug_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, false, 8, 100, 100); memset (gdk_pixbuf_get_pixels(debug_pixbuf), 0, 3 * gdk_pixbuf_get_height(debug_pixbuf) * gdk_pixbuf_get_width(debug_pixbuf)); } debug_frame.ToPixbuf(&debug_pixbuf); // convert Frame to pixeldata // redraw drawarea on screen. gdk_window_invalidate_rect(gtk_widget_get_window(debug_da), NULL, true); debug_unlock_mutex(); return false; } inline void debug_lock_mutex() { g_mutex_lock(&debug_mutex); }; inline void debug_unlock_mutex() { g_mutex_unlock(&debug_mutex); }; void debug_drawraw(unsigned char *data, int pixfmt, int w, int h) { ConvertData cd; int size, bytesperpixel = 0; switch (pixfmt) { case (V4L2_PIX_FMT_SGRBG8): bytesperpixel = 1; break; case (V4L2_PIX_FMT_SGRBG16): bytesperpixel = 2; break; case (V4L2_PIX_FMT_BGR32): case (V4L2_PIX_FMT_RGB32): bytesperpixel = 4; break; case (V4L2_PIX_FMT_BGR24): case (V4L2_PIX_FMT_RGB24): bytesperpixel = 3; break; default: return; } size = bytesperpixel * w * h; debug_lock_mutex(); ConvertStart(&cd, pixfmt); Convert(&cd, &debug_frame, data, size, pixfmt, w, h); ConvertStop(&cd, pixfmt); gdk_threads_add_idle(debug_thread_cb, NULL); debug_unlock_mutex(); }; #define BT_BUF_SIZE 100 void debug_backtrace () { unsigned int nptrs; void *buffer[BT_BUF_SIZE]; char **strings; nptrs = backtrace(buffer, BT_BUF_SIZE); printf("backtrace() returned %d addresses\n", nptrs); /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) * would produce similar output to the following: */ strings = backtrace_symbols(buffer, nptrs); if (strings == NULL) { perror("backtrace_symbols"); exit(EXIT_FAILURE); } for (size_t j = 0; j < nptrs; j++) printf("%s\n", strings[j]); free(strings); };