From b03406e31c5e5d4f8a4e065b03e68330885a3832 Mon Sep 17 00:00:00 2001 From: deva Date: Sun, 10 Apr 2005 20:38:45 +0000 Subject: lots of styff! --- TODO | 64 ++++++++++++++++++++++++++++++++++++++++++++--- src/camera.cc | 4 +-- src/camera.h | 3 ++- src/encoder.cc | 9 +++---- src/encoder.h | 4 ++- src/img_encoder.h | 14 ++++++++--- src/mainwindow.cc | 75 ++++++++++++++++++++++++++++++++++++++++++------------- src/mainwindow.h | 9 +++++++ src/messagebox.cc | 41 ++++++++++++++++++++++++++++-- src/messagebox.h | 9 +++++-- src/miav.conf | 14 +++++++---- src/package.h | 8 ++++++ src/server.cc | 25 +++++++++++++------ src/util.h | 3 +++ 14 files changed, 230 insertions(+), 52 deletions(-) diff --git a/TODO b/TODO index 1bbef10..7e9ff73 100644 --- a/TODO +++ b/TODO @@ -16,9 +16,10 @@ Mainwindow: [x] - Make generic gui layout code. [x] - Make icons. [x] - Make statusbar. - [ ] - Make flashing record bar. - [ ] - Show network connection in statusbar. - [ ] - Show camera connection in statusbar. + [x] - Make flashing record bar. + [ ] - Show network connection status in statusbar. + [ ] - Show camera connection status in statusbar. + [x] - Save movie messagebox (yes/no/dunno) [ ] - Test it. CPRQueryDialog: @@ -30,6 +31,10 @@ CPRQueryDialog: [ ] - Make icons? [ ] - Test it. +Encoder: + [ ] - Send savestate signal. + [ ] - Make all data sent before deleting network object. (flush) + Decoder: [ ] - Enable sound decoding for the network stream. @@ -47,6 +52,9 @@ ImgEncoder: MovEncoder: [ ] - Enable sound. +Main: + [ ] - Save movie signal handling. + ========================================================================== TASKS (common) ========================================================================== @@ -85,4 +93,52 @@ Destructor: - Cleanup getNextFrame: - - returns: AVframe pointer \ No newline at end of file + - returns: AVframe pointer + +========================================================================== + SAVE THE MOVIE? +========================================================================== +When the stop button is clicked, a msg box pops up, "Save? [yes, no, dunno]" +network connection is no killed before this has been answered, and an empty +frame has been send to the server with the answer. + +On the serverside, a variable describing wether the file is to be saved (SAVE), +deleted (DELETE), og scheduled for later descision (LATER). + +It is initialized with LATER, in order to prevent errors due to a malfunction +leading to a disconnection. + +If a flag is recieved, the state is overwritten. + +If the state is SAVE, when the connection is terminated, the file is moved to +a folder containing permanent data store. + +If the state is DELETE, the file is moved to a folder containing files scheduled +for deletion, when more space is needed (no files are removed at this point) + +If the state is LATER, the file is moved to a folder containing files with this +purpose. + +A cron job examines this folder regularly (test how often). +If a file has been here for more than a week, the administrator is contacted by +email. + +========================================================================== + Semphores and mutexes in the client network architechture +========================================================================== +,-----------. +| DV stream | +`-----------' + | + V +,-----------. +| Decoder | +`-----------' + | \ + V \ +,-----------. \ +| Player | \ +`-----------' \ + \ ,-----------. + ->| Encoder | + `-----------' diff --git a/src/camera.cc b/src/camera.cc index 9e9fd82..772d48a 100644 --- a/src/camera.cc +++ b/src/camera.cc @@ -146,9 +146,9 @@ void Camera::start() else errorstatus->pushError("Camera not initialized."); } -void Camera::stop() +void Camera::stop(n_savestate save) { - if(initialized) encoder->stop(); + if(initialized) encoder->stop(save); else errorstatus->pushError("Camera not initialized."); } diff --git a/src/camera.h b/src/camera.h index 25e1972..e5b4cee 100644 --- a/src/camera.h +++ b/src/camera.h @@ -43,6 +43,7 @@ using namespace std; #include "decoder.h" #include "encoder.h" #include "player.h" +#include "package.h" #include "thread.h" #include "ffframe.h" @@ -65,7 +66,7 @@ public: // Camera actions void start(); - void stop(); + void stop(n_savestate save); void freeze(); void unfreeze(); void snapshot(); diff --git a/src/encoder.cc b/src/encoder.cc index 3a4ade2..ca8fb4f 100644 --- a/src/encoder.cc +++ b/src/encoder.cc @@ -69,18 +69,14 @@ Encoder::~Encoder() void Encoder::encode() { DVFrame *f; - printf("0\n"); while(*running) { - printf("1\n"); sem_wait(sem); - printf("2\n"); pthread_mutex_lock(mutex); f = queue->pop(); pthread_mutex_unlock(mutex); - printf("3\n"); if((f && record) || (freeze_request != freeze_value) || (shoot_request != shoot_value)) { @@ -91,6 +87,7 @@ void Encoder::encode() h.header.h_data.freeze = (freeze_request != freeze_value); h.header.h_data.snapshot = (shoot_request != shoot_value); h.header.h_data.record = record; + h.header.h_data.savestate = NO_CHANGE; if(freeze_request != freeze_value) freeze_value = freeze_request; if(shoot_request != shoot_value) shoot_value = shoot_request; @@ -147,7 +144,9 @@ void Encoder::start() { } -void Encoder::stop() { +void Encoder::stop(n_savestate save) { + // TODO: set save state in package header. + // TODO: Flush not yet sent video packages. record = 0; if(s) { if(n) delete n; diff --git a/src/encoder.h b/src/encoder.h index 554839c..75788b4 100644 --- a/src/encoder.h +++ b/src/encoder.h @@ -37,6 +37,8 @@ #include "util.h" #include +#include "package.h" + #include "thread.h" #include @@ -62,7 +64,7 @@ public: void setCpr(char *newcpr); void start(); - void stop(); + void stop(n_savestate save); void freeze(); void shoot(); diff --git a/src/img_encoder.h b/src/img_encoder.h index 25779ce..79f4184 100644 --- a/src/img_encoder.h +++ b/src/img_encoder.h @@ -23,16 +23,22 @@ #ifndef __RTVIDEOREC_IMGENCODER_H #define __RTVIDEOREC_IMGENCODER_H +#include "dvframe.h" +#include "util.h" + #include #include #include #include extern "C" { +#ifdef HAVE_STDLIB_H +#undef HAVE_STDLIB_H +#endif #include +#ifdef HAVE_STDLIB_H +#undef HAVE_STDLIB_H +#endif } -#include - -#include "util.h" #define VIDEO_BUFFER_SIZE (1024*1024) // FIXME: One size fits all... @@ -60,5 +66,5 @@ class ImgEncoder { // AVPacket pkt; }; -#endif +#endif /*__RTVIDEOREC_IMGENCODER_H*/ diff --git a/src/mainwindow.cc b/src/mainwindow.cc index 8bfc53e..85b04cd 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -52,6 +52,9 @@ MainWindow::MainWindow( QWidget* parent, const char* name ) { error = new Error(); MiavConfig cfg("miav.conf", error); + video_width = cfg.readInt("video_width"); + video_height = cfg.readInt("video_height"); + int resolution_w = cfg.readInt("pixel_width"); int resolution_h = cfg.readInt("pixel_height"); while(error->hasError()) { @@ -65,16 +68,6 @@ MainWindow::MainWindow( QWidget* parent, const char* name ) resize(resolution_w, resolution_h); // Load images -/* - QPainter *paint = new QPainter(); - QPicture *pic = new QPicture(); - pic->load(fname, "svg"); - paint->begin(this); - paint->setWindow(pic->boundingRect()); - paint->drawPicture(0, 0, *pic); - paint->end(); - */ - pix_record = new QPixmap(); pix_record->load( PIXMAP_RECORD ); @@ -99,6 +92,10 @@ MainWindow::MainWindow( QWidget* parent, const char* name ) pix_logo = new QPixmap(); pix_logo->load( PIXMAP_LOGO_SMALL ); + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), SLOT(redraw_edge())); + rec_edge_counter = 0.0f; + createGui(); show(); @@ -158,11 +155,11 @@ void MainWindow::createGui() img_recedge = new QLabel(this); img_recedge->setBackgroundColor(QColor(160,160,160)); - img_recedge->setFixedSize(740,596); + img_recedge->setFixedSize(video_width + 20, video_height + 20); img_live = new VideoWidget(img_recedge); // img_live->setErasePixmap( *pix_dummy ); - img_live->setFixedSize(720,576); + img_live->setFixedSize(video_width, video_height); img_live->move(10,10); g1->addMultiCellWidget ( img_recedge, 0, 0, 0, 2, Qt::AlignHCenter); @@ -216,6 +213,17 @@ void MainWindow::createGui() status->message( TXT_READY ); } +#define GREY 160 +#define SPEED 0.1f +void MainWindow::redraw_edge() +{ + rec_edge_counter += SPEED; + float val = abs(sin(rec_edge_counter)); + img_recedge->setBackgroundColor(QColor((int) ((255 - GREY) * val + GREY), + (int) (GREY - (GREY * val)), + (int) (GREY - (GREY * val)))); +} + QPushButton *MainWindow::createButton(char *caption, int width, int height) { QPushButton *btn = new QPushButton(caption, this); @@ -264,16 +272,47 @@ void MainWindow::checkErrors() void MainWindow::rec_clicked() { - recording = 1 - recording; - if(recording) { - img_recedge->setBackgroundColor(red); + if(!recording) { + recording = 1; + // Start flashing the edge + rec_edge_counter = 0.0f; + timer->start(200); btn_rec->setPixmap(*pix_stop); camera->start(); checkErrors(); } else { - img_recedge->setBackgroundColor(QColor(160,160,160)); - btn_rec->setPixmap(*pix_record); - camera->stop(); + switch(MessageBox(this, + TXT_ASK_SAVE_TITLE, + TXT_ASK_SAVE, + TYPE_YES_NO_MAYBE_CANCEL, + ICON_QUESTION).exec()) { + case MSG_YES: + recording = 0; + camera->stop(SAVE); + timer->stop(); + img_recedge->setBackgroundColor(QColor(160,160,160)); + btn_rec->setPixmap(*pix_record); + break; + + case MSG_NO: + recording = 0; + camera->stop(DELETE); + timer->stop(); + img_recedge->setBackgroundColor(QColor(160,160,160)); + btn_rec->setPixmap(*pix_record); + break; + + case MSG_MAYBE: + recording = 0; + camera->stop(LATER); + timer->stop(); + img_recedge->setBackgroundColor(QColor(160,160,160)); + btn_rec->setPixmap(*pix_record); + break; + + case MSG_CANCEL: + break; + } checkErrors(); } } diff --git a/src/mainwindow.h b/src/mainwindow.h index 25a938b..3b8f73c 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -35,6 +35,7 @@ using namespace std; #include #include #include +#include #include "videowidget.h" #include "camera.h" @@ -50,6 +51,8 @@ using namespace std; #define TXT_ERROR_TITLE "Der er opstået en fejl!" #define TXT_READY "Klar..." #define TXT_CPRDLG_TITLE "CPRQueryDialog" +#define TXT_ASK_SAVE_TITLE "Vil du gemme filmen?" +#define TXT_ASK_SAVE "Vil du gemme filmen permanent?" /** * Images @@ -80,6 +83,7 @@ public slots: void rec_clicked(); void shoot_clicked(); void freeze_clicked(); + void redraw_edge(); private: Error *error; @@ -103,6 +107,8 @@ private: QLabel *lbl_cpr; QLabel *lbl_name; + float rec_edge_counter; + QTimer *timer; QLabel *img_recedge; QLabel *img_history[NUM_HISTORY]; @@ -119,7 +125,10 @@ private: bool recording; bool frozen; + // Configuration values float unit; + int video_width; + int video_height; QPushButton *createButton(char *caption, int width, int height); QLabel *createLabel(char *caption, int width, int height); diff --git a/src/messagebox.cc b/src/messagebox.cc index 63bbeee..1975eac 100644 --- a/src/messagebox.cc +++ b/src/messagebox.cc @@ -72,9 +72,9 @@ MessageBox::MessageBox(QWidget* parent, pix_icon->load( PIXMAP_WARNING ); break; case TYPE_YES_NO: - pix_icon->load( PIXMAP_QUESTION ); - break; + case TYPE_YES_NO_MAYBE: case TYPE_YES_NO_CANCEL: + case TYPE_YES_NO_MAYBE_CANCEL: pix_icon->load( PIXMAP_QUESTION ); break; } @@ -134,6 +134,20 @@ MessageBox::MessageBox(QWidget* parent, connect(bno, SIGNAL( clicked() ), SLOT(bno_clicked())); break; } + case TYPE_YES_NO_MAYBE: + { + QPushButton *byes = createButton(f, TXT_YES ); + QPushButton *bno = createButton(f, TXT_NO ); + QPushButton *bmaybe = createButton(f, TXT_MAYBE ); + QGridLayout *glayout = new QGridLayout(f, 1, 3, 20, 20); + glayout->addWidget(bno, 0, 0); + glayout->addWidget(byes, 0, 1); + glayout->addWidget(bmaybe, 0, 2); + connect(byes, SIGNAL( clicked() ), SLOT(byes_clicked())); + connect(bno, SIGNAL( clicked() ), SLOT(bno_clicked())); + connect(bmaybe, SIGNAL( clicked() ), SLOT(bmaybe_clicked())); + break; + } case TYPE_YES_NO_CANCEL: { QPushButton *byes = createButton(f, TXT_YES ); @@ -148,6 +162,23 @@ MessageBox::MessageBox(QWidget* parent, connect(bno, SIGNAL( clicked() ), SLOT(bno_clicked())); break; } + case TYPE_YES_NO_MAYBE_CANCEL: + { + QPushButton *byes = createButton(f, TXT_YES ); + QPushButton *bcancel = createButton(f, TXT_CANCEL ); + QPushButton *bno = createButton(f, TXT_NO ); + QPushButton *bmaybe = createButton(f, TXT_MAYBE ); + QGridLayout *glayout = new QGridLayout(f, 1, 4, 20, 20); + glayout->addWidget(bno, 0, 0); + glayout->addWidget(bcancel, 0, 1); + glayout->addWidget(byes, 0, 2); + glayout->addWidget(bmaybe, 0, 3); + connect(bmaybe, SIGNAL( clicked() ), SLOT(bmaybe_clicked())); + connect(byes, SIGNAL( clicked() ), SLOT(byes_clicked())); + connect(bcancel, SIGNAL( clicked() ), SLOT(bcancel_clicked())); + connect(bno, SIGNAL( clicked() ), SLOT(bno_clicked())); + break; + } } } @@ -185,4 +216,10 @@ void MessageBox::bno_clicked() { done(MSG_NO); } + +void MessageBox::bmaybe_clicked() +{ + done(MSG_MAYBE); +} + #endif/*USE_GUI*/ diff --git a/src/messagebox.h b/src/messagebox.h index 313d395..72b703f 100644 --- a/src/messagebox.h +++ b/src/messagebox.h @@ -50,14 +50,17 @@ typedef enum { MSG_YES, MSG_NO, MSG_CANCEL, - MSG_OK + MSG_OK, + MSG_MAYBE } msg_val; typedef enum { TYPE_OK, TYPE_OK_CANCEL, TYPE_YES_NO, + TYPE_YES_NO_MAYBE, TYPE_YES_NO_CANCEL, + TYPE_YES_NO_MAYBE_CANCEL, } msg_type; @@ -65,9 +68,10 @@ typedef enum { * Textstrings */ #define TXT_OK "Ok" -#define TXT_CANCEL "Annuler" +#define TXT_CANCEL "Annulér" #define TXT_YES "Ja" #define TXT_NO "Nej" +#define TXT_MAYBE "Måske" /** * Images @@ -94,6 +98,7 @@ public slots: void bcancel_clicked(); void byes_clicked(); void bno_clicked(); + void bmaybe_clicked(); private: QPixmap *pix_icon; diff --git a/src/miav.conf b/src/miav.conf index ba2ceda..c0f5c89 100644 --- a/src/miav.conf +++ b/src/miav.conf @@ -3,16 +3,20 @@ # # Cpr Database configuration -fisk = - = true cpr_host = "cpr.j.auh.dk" cpr_port = 10301 cpr_timeout = 10000 +# Video source +#video_width = 720 +#video_height = 576 +video_width = 500 +video_height = 370 + # Size of the screen in inches -screensize = 19.0 -pixel_width = 1024 -pixel_height = 768 +screensize = 14.0 +pixel_width = 800 +pixel_height = 600 # How and where to connect to the miav server? server_addr = "192.168.0.10" diff --git a/src/package.h b/src/package.h index db0e5a0..94580ee 100644 --- a/src/package.h +++ b/src/package.h @@ -27,6 +27,13 @@ #ifndef __MIAVLIB_PACKAGE_H__ #define __MIAVLIB_PACKAGE_H__ +typedef enum { + NO_CHANGE = 0, + SAVE, + DELETE, + LATER +} n_savestate; + typedef enum { DATA_HEADER = 0x0001, INFO_HEADER = 0x0002 @@ -40,6 +47,7 @@ typedef struct { bool record; bool freeze; bool snapshot; + n_savestate savestate; } h_data; struct { int fisk; diff --git a/src/server.cc b/src/server.cc index 22b691f..44abe2d 100644 --- a/src/server.cc +++ b/src/server.cc @@ -63,14 +63,20 @@ MovEncoder *newMovEncoder(char* cpr) char fname[256]; time_t t = time(NULL); ltime = localtime(&t); - sprintf(fname, "%.2d%.2d%.2d%.2d%.2d%.2d-%s.mpg", ltime->tm_year + 1900, ltime->tm_mon, - ltime->tm_mday, ltime->tm_hour, ltime->tm_min, ltime->tm_sec, cpr); + sprintf(fname, "%.2d%.2d%.2d%.2d%.2d%.2d-%s.mpg", + ltime->tm_year + 1900, + ltime->tm_mon, + ltime->tm_mday, + ltime->tm_hour, + ltime->tm_min, + ltime->tm_sec, cpr); enc = new MovEncoder(fname); return enc; } void newConnection(Socket *s) -{ +{ + n_savestate savestate = LATER; n_header h; DVFrame *f; DVFrame *freeze_frame = NULL; @@ -91,6 +97,7 @@ void newConnection(Socket *s) printf("\tcpr: %s\t", h.header.h_data.cpr); printf("\tfrz: %d\t", h.header.h_data.freeze); printf("\tsht: %d\n", h.header.h_data.snapshot); + printf("\tsave: %d\n", h.header.h_data.savestate); if(h.header.h_data.snapshot) { if(freeze_frame) { @@ -107,6 +114,10 @@ void newConnection(Socket *s) enc->encode(f); } + if(h.header.h_data.savestate) { + savestate = h.header.h_data.savestate; + } + if(h.header.h_data.freeze) { if(freeze_frame) delete freeze_frame; freeze_frame = f; @@ -116,14 +127,12 @@ void newConnection(Socket *s) f = new DVFrame(); } + + // TODO: Use save state + delete f; if(enc) delete enc; printf("Connection end[pid: %d]...\n", getpid()); } -/* -int main(int argc, char *argv[]) -{ -} -*/ diff --git a/src/util.h b/src/util.h index b82b782..7921e41 100644 --- a/src/util.h +++ b/src/util.h @@ -22,6 +22,9 @@ #ifndef __RTVIDEOREC_UTIL_H #define __RTVIDEOREC_UTIL_H +#include +//#include + //#ifdef __cplusplus //extern "C" { //#endif -- cgit v1.2.3