📄 sonic-snap-gui.cxx
字号:
// GUI app sonic-snap// by Bram Stolk#include <stdio.h>#include <assert.h>#include <string.h>#include <unistd.h>#include <sys/time.h>#include <time.h>#include <pthread.h>#include <FL/Fl.H>#include <FL/Fl_Button.H>#include <FL/Fl_Check_Button.H>#include <FL/Fl_Window.H>#include <FL/Fl_Slider.H>#include <FL/Fl_Choice.H>#include <FL/Fl_Output.H>#include <FL/fl_draw.H>#include <FL/fl_message.H>#include <FL/fl_file_chooser.H>#include <FL/fl_ask.H>#include "sonixcam.h"#ifdef FAME#include "videoencoder.h"#endifstatic int width=352;static int height=288;static SonixCam *cam=0;#ifdef FAMEstatic VideoEncoder *encoder=0;#endifstatic Fl_Window *window=0;static Fl_Output *o_fps;static Fl_Check_Button *b_stream;static Fl_Check_Button *b_hist;static Fl_Check_Button *b_norm;static Fl_Check_Button *b_autog;static Fl_Button *b_ppm;static Fl_Check_Button *b_mpeg;static Fl_Button *b_about;static Fl_Button *b_quit;static Fl_Slider *s_gain;static Fl_Choice *c_comp;static pthread_t threadid;class CamView : public Fl_Widget{ public: CamView(): Fl_Widget(0,0,width,height,"camview") {} ~CamView() {} void draw(void) { assert(cam); unsigned char *pixels = cam->GetImage(); assert(pixels); fl_draw_image(pixels, 0, 0, width, height); }};static double elapsed(void){ static struct timespec prev; static bool first=true; static struct timespec curr; int ok; ok = clock_gettime(CLOCK_REALTIME, &curr); if (ok) perror("clock_gettime"); double delta; if (first) { first = false; delta = 0.0; } else { delta = curr.tv_sec - prev.tv_sec; delta += (curr.tv_nsec - prev.tv_nsec) / 1000000000.0; } prev = curr; return delta;}// Auxiliary func for FPS calculation.static float timestamp(void){ static struct timeval tv0; static struct timeval tv1; static bool first=true; int rv; if (first) { rv=gettimeofday(&tv0, 0); if (rv) perror("gettimeofday"); assert(!rv); first=false; } rv=gettimeofday(&tv1, 0); if (rv) perror("gettimeofday"); assert(!rv);// fprintf(stderr,"usec=%d\n", tv1.tv_usec); return tv1.tv_sec - tv0.tv_sec + (tv1.tv_usec - tv0.tv_usec) / 1000000.0;}static void adjust_gain(void){ if (b_autog->value()) { float gc = cam->AnalyzeGainChange(0.00025); float gain = cam->GetGain(); gain += gc; if (gain>1.0) gain=1.0; if (gain<0.0) gain=0.0; cam->SetGain(gain); s_gain->value(gain); }}//static void *readthread(void *arg)static void idle_cb(void *arg){// while (1)// { CamView *cv = reinterpret_cast<CamView*>(arg); if (cam->Sustain()) { cv->redraw();#ifdef FAME if (encoder) encoder->AddFrame(cam->GetImage());#endif adjust_gain(); // Do FPS calculations static int framecount=0; if (!(framecount++ & 15)) {#if 0 static float start = 0.0; float end = timestamp(); float delta = end - start; fprintf(stderr,"framecount=%d, start=%f, end=%f, delta=%f\n", framecount, start, end, delta); if (start && delta >= 0.0) { static char line[80]; sprintf(line,"Frame Rate: %4.1f FPS", 16 / delta); o_fps->value(line); } start = end;#else double delta = elapsed(); if (delta) { static char line[80]; sprintf(line,"Frame Rate: %4.1f FPS", 16 / delta); o_fps->value(line); }#endif } } else { usleep(5000); }// } return;}static void about_cb(Fl_Widget *o){ fl_message ( "This program is (c)2004 by Bram Stolk.\n" "sn9c102 decompressor by Bertrik Sikken.\n" );}static void hist_cb(Fl_Widget *o){ Fl_Check_Button *b = (Fl_Check_Button*)o; cam->ShowHistograms(b->value());}static void comp_cb(Fl_Widget *o){#if 0 Fl_Check_Button *b = (Fl_Check_Button*)o; cam->SetCompression(b->value());#else Fl_Choice *c = (Fl_Choice*)o; if (c->value() == 0) { cam->SetCompression(false); return; } if (c->value() == 1) { cam->SetCompression(true); cam->SetJPEG(0); return; } if (c->value() == 2) { cam->SetCompression(true); cam->SetJPEG(1); return; }#endif}static void norm_cb(Fl_Widget *o){ Fl_Check_Button *b = (Fl_Check_Button*)o; cam->DoNormalize(b->value());}static void autog_cb(Fl_Widget *o){ Fl_Check_Button *b = (Fl_Check_Button*)o; cam->DoAutoGain(b->value());}static void quit_cb(Fl_Widget *o){ delete window;}static void gain_cb(Fl_Widget *o){ Fl_Slider *s = (Fl_Slider*)o; cam->SetGain(s->value());}static void stream_cb(Fl_Widget *o){ Fl_Check_Button *b = (Fl_Check_Button*)o; if (b->value()) { cam->StartCapture(); b_hist->activate(); c_comp->activate(); b_norm->activate(); s_gain->activate(); b_autog->activate();#ifdef FAME b_mpeg->activate();#endif } else { cam->StopCapture(); b_hist->deactivate(); c_comp->deactivate(); b_norm->deactivate(); s_gain->deactivate(); b_autog->deactivate(); b_mpeg->deactivate(); }}static void mpeg_cb(Fl_Widget *o){#ifdef FAME Fl_Check_Button *b = (Fl_Check_Button*)o; if (b->value()) { char *fname = fl_file_chooser("Capture to MPEG", 0,0); if (!fname) { b->value(0); return; } encoder = new VideoEncoder(fname, width, height); } else { delete encoder; encoder = 0; }#endif} static void captureppm_cb(Fl_Widget *o){ int sz=width*height*3; unsigned char *img = new unsigned char[sz]; memcpy(img, cam->GetImage(), sz); char *fname = fl_file_chooser("Capture to PPM", 0,0); if (!fname) { delete [] img; return; } FILE *f=fopen(fname,"wb"); if (!f) { fl_alert("Cannot open file %s for writing", fname); delete [] img; return; } fprintf(f,"P6 %d %d %d\n", width, height, 255); int rv=fwrite(img, sz, 1, f); assert(rv==1); fclose(f); delete [] img;}int main(int argc, char *argv[]){ char *devname = "/dev/video0"; if (argc==3 || argc > 4 || (argc > 1 && argv[1][0]=='-')) { fprintf(stderr,"Usage: %s [/dev/video0] [352 288]\n", argv[0]); exit(1); } if (argc > 1) devname = argv[1]; if (argc==4) { width=atoi(argv[2]); height=atoi(argv[3]); } struct timespec res; int ok = clock_getres(CLOCK_REALTIME, &res); if (ok) perror("clock_getres"); fprintf(stderr,"Clock resolution is %d nanoseconds\n", res.tv_nsec); cam = new SonixCam(devname, width, height); window = new Fl_Window(width,height+240,cam->GetName()); CamView *cv = new CamView(); int vpos = height; o_fps = new Fl_Output(0,vpos,width,20); vpos+=20; o_fps->value("FPS: 0"); b_stream = new Fl_Check_Button(0,vpos,width,20,"Stream"); b_stream->callback(stream_cb); vpos+=20; b_hist = new Fl_Check_Button(0,vpos,width,20,"Histograms"); b_hist->callback(hist_cb); vpos+=20; b_norm = new Fl_Check_Button(0,vpos,width,20,"Normalize"); b_norm->callback(norm_cb); vpos+=20; b_autog = new Fl_Check_Button(0,vpos,width,20,"Auto Gain"); b_autog->callback(autog_cb); vpos+=20; c_comp = new Fl_Choice(width/2,vpos,width/2,20,"Compression"); c_comp->callback(comp_cb); vpos+=20; c_comp->add("Off", 0,0); c_comp->add("Low Quality", 0,0); c_comp->add("High Quality", 0,0); b_ppm = new Fl_Button(0,vpos,width,20,"Capture image as PPM"); b_ppm->callback(captureppm_cb); vpos+=20; b_mpeg = new Fl_Check_Button(0,vpos,width,20,"Capture as MPEG"); b_mpeg->callback(mpeg_cb); vpos+=20; b_about = new Fl_Button(0,vpos,width,20,"About"); b_about->callback(about_cb); vpos+=20; b_quit = new Fl_Button(0,vpos,width,20,"Quit"); b_quit->callback(quit_cb); vpos+=20; s_gain = new Fl_Slider(0,vpos,width,20,"gain"); s_gain->type(FL_HOR_NICE_SLIDER); s_gain->callback(gain_cb); vpos+=20; window->end(); Fl::visual(FL_RGB); b_stream->value(true); stream_cb(b_stream); b_hist->value(true); hist_cb(b_hist); c_comp->value(2); comp_cb(c_comp); b_norm->value(true); norm_cb(b_norm); s_gain->value(0.5); gain_cb(s_gain);#ifndef FAME b_mpeg->deactivate();#endif window->show(); cv->show();#if 1 Fl::add_idle(idle_cb, cv);#else int rv = pthread_create(&threadid, 0, readthread, (void*) cv); if (rv) perror("pthread_create"); assert(!rv);#endif Fl::run(); cam->StopCapture(); delete cam;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -