summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordeva <deva>2005-03-24 12:14:44 +0000
committerdeva <deva>2005-03-24 12:14:44 +0000
commit9466b3042bc7314915a15f499bd0b087f569654d (patch)
tree29c41f6ba46b9b92d91b92578720e1beee44fc9d /src
parentb5a6a93dcc7a83f5c4f8fd1894e303ae58804e0b (diff)
Initial revision
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/aboutwindow.cc89
-rw-r--r--src/aboutwindow.h77
-rw-r--r--src/camera.cc131
-rw-r--r--src/camera.h81
-rw-r--r--src/cprquerydialog.cc376
-rw-r--r--src/cprquerydialog.h136
-rw-r--r--src/decoder.cc171
-rw-r--r--src/decoder.h65
-rw-r--r--src/dvframe.cc41
-rw-r--r--src/dvframe.h47
-rw-r--r--src/encoder.cc158
-rw-r--r--src/encoder.h89
-rw-r--r--src/ffframe.cc38
-rw-r--r--src/ffframe.h38
-rw-r--r--src/img_encoder.cc161
-rw-r--r--src/img_encoder.h63
-rw-r--r--src/mainwindow.cc305
-rw-r--r--src/mainwindow.h100
-rw-r--r--src/messagebox.cc197
-rw-r--r--src/messagebox.h66
-rw-r--r--src/miav.cc120
-rw-r--r--src/miav.h36
-rw-r--r--src/miav_config.cc99
-rw-r--r--src/miav_config.h57
-rw-r--r--src/mov_encoder.cc207
-rw-r--r--src/mov_encoder.h57
-rw-r--r--src/network.cc139
-rw-r--r--src/network.h52
-rw-r--r--src/package.h53
-rw-r--r--src/player.cc155
-rw-r--r--src/player.h77
-rw-r--r--src/queue.h130
-rw-r--r--src/server.cc129
-rw-r--r--src/server.h44
-rw-r--r--src/socket.cc134
-rw-r--r--src/socket.h56
-rw-r--r--src/thread.cc34
-rw-r--r--src/thread.h42
-rw-r--r--src/util.cc56
-rw-r--r--src/util.h36
-rw-r--r--src/videowidget.cc46
-rw-r--r--src/videowidget.h45
43 files changed, 4233 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 40e37ee..75e6f85 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,3 @@
-#frekin' wierd
## TODO: Move ffmpeg, libxml and libsdl into configure.in
AM_CXXFLAGS := $(CXXFLAGS) $(EXTRA_CXXFLAGS) -I../include $(QT_CXXFLAGS) \
diff --git a/src/aboutwindow.cc b/src/aboutwindow.cc
new file mode 100644
index 0000000..6630d4c
--- /dev/null
+++ b/src/aboutwindow.cc
@@ -0,0 +1,89 @@
+/***************************************************************************
+ * aboutwindow.cc
+ *
+ * Sun Aug 22 21:57:49 2004
+ * Copyright 2004 deva
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+#ifdef USE_GUI
+
+#include "aboutwindow.h"
+
+#include <qpainter.h>
+#include <qfont.h>
+
+#include <config.h>
+//"miav-grab.h"
+
+AboutWindow::AboutWindow( QWidget* parent, const char* name )
+ : QDialog( parent, name )
+{
+ resize(320,460);
+// setModal(true);
+ pix_logo = new QPixmap();
+ pix_logo->load("miav-logo-512x512.png");
+
+ setBackgroundColor(QColor(150,150,150));
+
+ btn_ok = new QPushButton(this);
+ btn_ok->setText("OK");
+ btn_ok->move(200, 410);
+ btn_ok->resize( 95, 40 );
+ btn_ok->setFont( QFont( "Arial", 12, QFont::Bold ) );
+
+ QObject::connect( btn_ok, SIGNAL(clicked()), this, SLOT(close()) );
+
+ show();
+}
+
+AboutWindow::~AboutWindow()
+{
+}
+
+void AboutWindow::paintEvent( QPaintEvent *event )
+{
+ if(!event) return; // Just to get rid og the compile warning!
+ QPainter painter;
+ painter.begin(this);
+
+ painter.drawPixmap(-200,-50, *pix_logo);
+
+ painter.setBrush( Dense4Pattern );
+ painter.drawRect(25,25,270,377);
+
+ painter.setBrush( SolidPattern );
+ painter.setFont( QFont( "Arial", 18, QFont::Bold ) );
+ painter.setPen( Qt::black );
+ painter.drawText(58,58, "MIAV-Grab v" VERSION);
+ painter.setPen( Qt::red );
+ painter.drawText(60,60, "MIAV-Grab v" VERSION);
+
+ painter.setPen( Qt::white );
+ painter.setFont( QFont( "Arial", 11, QFont::Bold ) );
+ painter.drawText(30,70, 270, 357, 0, ABOUT_INFO);
+
+ painter.setPen( Qt::white );
+ painter.setFont( QFont( "Arial", 8, QFont::Bold ) );
+ painter.drawText(30,165, 270, 357, 0, GPL_LICENSE);
+
+ painter.end();
+}
+
+#endif /*USE_GUI*/
diff --git a/src/aboutwindow.h b/src/aboutwindow.h
new file mode 100644
index 0000000..a8437b5
--- /dev/null
+++ b/src/aboutwindow.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+ * aboutwindow.h
+ *
+ * Sun Aug 22 21:58:22 2004
+ * Copyright 2004 deva
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+#ifdef USE_GUI
+
+#ifndef __ABOUTWINDOW_H__
+#define __ABOUTWINDOW_H__
+
+#include <qdialog.h>
+//#include <qlabel.h>
+#include <qpixmap.h>
+//#include <qtextedit.h>
+#include <qpushbutton.h>
+
+#define ABOUT_INFO "\
+Official homepage:\n\
+ http://www.aasimon.org/miav\n\
+Author:\n\
+ Bent Bisballe (deva@aasimon.org)\n\
+Copyright (c) 2004"
+
+#define GPL_LICENSE "\
+This program is free software; you can\n\
+redistribute it and/or modify it under the terms\n\
+of the GNU General Public License as published\n\
+by the Free Software Foundation; either version\n\
+2 of the License, or (at your option) any later\n\
+version.\n\
+ This program is distributed in the hope that\n\
+it will be useful, but WITHOUT ANY WARRANTY;\n\
+without even the implied warranty of\n\
+MERCHANTABILITY or FITNESS FOR A PARTI-\n\
+CULAR PURPOSE. See the GNU Library General\n\
+Public License for more details.\n\
+ You should have received a copy of the GNU\n\
+General Public License along with this program;\n\
+if not, write to the Free Software Foundation,\n\
+Inc., 59 Temple Place - Suite 330, Boston,\n\
+MA 02111-1307, USA."
+
+class AboutWindow : public QDialog
+{
+ Q_OBJECT
+public:
+ AboutWindow(QWidget* parent = 0, const char* name = 0);
+ ~AboutWindow();
+ virtual void paintEvent( QPaintEvent *event );
+
+private:
+ QPushButton *btn_ok;
+ QPixmap *pix_logo;
+};
+
+#endif /* __ABOUTWINDOW_H__ */
+
+#endif /*USE_GUI*/
diff --git a/src/camera.cc b/src/camera.cc
new file mode 100644
index 0000000..574caf3
--- /dev/null
+++ b/src/camera.cc
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * camera.cc
+ *
+ * Fri Oct 29 12:46:38 CEST 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+#ifdef USE_GUI
+
+#include "camera.h"
+
+Camera::Camera(const char *ip, const int port)
+{
+ pthread_mutex_init (&mutex, NULL);
+ //mutex = PTHREAD_MUTEX_INITIALIZER;
+
+ AVFormatContext *ifmtctx;
+ AVFormatContext *ofmtctx;
+
+ running = 1;
+
+ int channel = 0;
+ char *device = "/dev/dv1394";
+
+ av_register_all();
+
+ encode_queue = new Queue<DVFrame>(); // infinite size
+ player_queue = new Queue<FFFrame>(1); // fixed size of 1
+
+ sem_init(&encode_sem, 0, 0);
+ sem_init(&player_sem, 0, 0);
+
+ decoder = new Decoder(device,
+ channel,
+ &encode_sem,
+ &player_sem,
+ encode_queue,
+ player_queue,
+ &mutex,
+ &running);
+ // ifmtctx = decoder->fc;
+ if(!decoder->fc) return;
+
+ encoder = new Encoder(ip, port,
+ &encode_sem,
+ encode_queue,
+ &mutex,
+ &running);
+ ofmtctx = encoder->fc;
+
+ player = new Player(&running,
+ &player_sem,
+ player_queue,
+ &mutex);
+
+ pthread_create (&decodetid, NULL, thread_run, decoder);
+ pthread_create (&encodetid, NULL, thread_run, encoder);
+ pthread_create (&playertid, NULL, thread_run, player);
+}
+
+Camera::~Camera()
+{
+ // Signal to the threads to stop
+ running = 0;
+
+ pthread_join(decodetid, NULL);
+ pthread_join(playertid, NULL);
+ pthread_join(encodetid, NULL);
+
+ delete decoder;
+ delete encoder;
+ delete player;
+
+ sem_destroy(&encode_sem);
+ sem_destroy(&player_sem);
+
+ delete player_queue;
+ delete encode_queue;
+}
+
+void Camera::setCpr(char *newcpr)
+{
+ encoder->setCpr(newcpr);
+}
+
+
+void Camera::start()
+{
+ encoder->stop();
+}
+
+void Camera::stop()
+{
+ encoder->start();
+}
+
+void Camera::freeze()
+{
+ player->stop();
+ encoder->freeze();
+}
+
+void Camera::unfreeze()
+{
+ player->start();
+}
+
+void Camera::snapshot()
+{
+ encoder->shoot();
+}
+
+#endif/* USE_GUI */
diff --git a/src/camera.h b/src/camera.h
new file mode 100644
index 0000000..5190954
--- /dev/null
+++ b/src/camera.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * camera.h
+ *
+ * Fri Oct 29 12:46:38 CEST 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+#ifdef USE_GUI
+
+#ifndef __CAMERA_H__
+#define __CAMERA_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <avformat.h>
+
+#include "util.h"
+#include <queue.h>
+#include "decoder.h"
+#include "encoder.h"
+#include "player.h"
+
+#include "thread.h"
+#include "ffframe.h"
+#include <dvframe.h>
+
+#include <qwidget.h>
+
+class Camera {
+public:
+ Camera(const char *ip,
+ const int port);
+ ~Camera();
+ void setCpr(char *newcpr);
+ void start();
+ void stop();
+ void freeze();
+ void unfreeze();
+ void snapshot();
+
+private:
+ pthread_t playertid;
+ pthread_t decodetid;
+ pthread_t encodetid;
+ volatile int running;
+
+ Encoder *encoder;
+ Decoder *decoder;
+ Player *player;
+
+ Queue<DVFrame> *encode_queue;
+ Queue<FFFrame> *player_queue;
+ sem_t encode_sem;
+ sem_t player_sem;
+ pthread_mutex_t mutex;// = PTHREAD_MUTEX_INITIALIZER;
+};
+
+
+#endif/*__CAMERA_H__*/
+
+#endif/* USE_GUI */
diff --git a/src/cprquerydialog.cc b/src/cprquerydialog.cc
new file mode 100644
index 0000000..d5d3c44
--- /dev/null
+++ b/src/cprquerydialog.cc
@@ -0,0 +1,376 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * cprquerydialog.cc
+ *
+ * Sat Feb 19 17:05:43 CET 2005
+ * Copyright 2005 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+#ifdef USE_GUI
+
+#include <qframe.h>
+
+#include "messagebox.h"
+#include "cprquerydialog.h"
+#include "miav_config.h"
+
+CPRQueryDialog::CPRQueryDialog(QLabel *lcpr,
+ QLabel *lname,
+ QWidget *parent,
+ const char *name,
+ bool modal)
+ : QDialog( parent, name, modal)
+{
+ MiavConfig cfg("cprquery.conf");
+
+ lbl_name = lname;
+ lbl_cpr = lcpr;
+
+ //Read configuration
+ CPR_HOST = cfg.readString("cpr_host");
+ CPR_PORT = cfg.readInt("cpr_port");
+
+ cpr[0] = '\0';
+ internalCpr[0] = '\0';
+
+ cprSocket = new QSocket(this);
+ connect(cprSocket, SIGNAL(readyRead()), SLOT(cprSocket_readyRead()));
+ connect(cprSocket, SIGNAL(connected()), SLOT(cprSocket_connected()));
+ ccw = new MessageBox(this, "Confirm", "Ugyldigt CPR nummer, brug det alligevel?", TYPE_YES_NO_CANCEL);
+ /*
+
+ // connect(btn_cpr, SIGNAL(clicked()), SLOT(bcancel_clicked()));
+
+ //show();
+ //run(0);
+ */
+
+ lbl_cpr->setText("Indtast CPR");
+
+ // Generate input buttons
+ //digits = pos;
+
+ QFrame *topf = new QFrame(this);
+ topf->setFrameStyle(QFrame::Box | QFrame::Raised);
+ topf->setLineWidth(3);
+ QHBoxLayout *bl = new QHBoxLayout(this);
+ bl->addWidget(topf);
+
+ QGridLayout *gl = new QGridLayout(topf, 4, 3, 10, 2);
+ QButton *b1 = createButton(topf, "1", 1);
+ QButton *b2 = createButton(topf, "2", 2);
+ QButton *b3 = createButton(topf, "3", 3);
+ QButton *b4 = createButton(topf, "4", 4);
+ QButton *b5 = createButton(topf, "5", 5);
+ QButton *b6 = createButton(topf, "6", 6);
+ QButton *b7 = createButton(topf, "7", 7);
+ QButton *b8 = createButton(topf, "8", 8);
+ QButton *b9 = createButton(topf, "9", 9);
+ QButton *b0 = createButton(topf, "0", 0);
+ QButton *bbs = createButton(topf, "<-", 10);
+ QButton *bca = createButton(topf, "CA", 11);
+
+ gl->addWidget(b1, 0,0);
+ gl->addWidget(b2, 0,1);
+ gl->addWidget(b3, 0,2);
+ gl->addWidget(b4, 1,0);
+ gl->addWidget(b5, 1,1);
+ gl->addWidget(b6, 1,2);
+ gl->addWidget(b7, 2,0);
+ gl->addWidget(b8, 2,1);
+ gl->addWidget(b9, 2,2);
+ gl->addWidget(b0, 3,1);
+ gl->addWidget(bbs, 3,2);
+ gl->addWidget(bca, 3,0);
+
+ /* Setup signals */
+ connect(b1, SIGNAL(clicked()), SLOT(b_1_clicked()));
+ connect(b2, SIGNAL(clicked()), SLOT(b_2_clicked()));
+ connect(b3, SIGNAL(clicked()), SLOT(b_3_clicked()));
+ connect(b4, SIGNAL(clicked()), SLOT(b_4_clicked()));
+ connect(b5, SIGNAL(clicked()), SLOT(b_5_clicked()));
+ connect(b6, SIGNAL(clicked()), SLOT(b_6_clicked()));
+ connect(b7, SIGNAL(clicked()), SLOT(b_7_clicked()));
+ connect(b8, SIGNAL(clicked()), SLOT(b_8_clicked()));
+ connect(b9, SIGNAL(clicked()), SLOT(b_9_clicked()));
+ connect(b0, SIGNAL(clicked()), SLOT(b_0_clicked()));
+ connect(bbs,SIGNAL(clicked()), SLOT(b_b_clicked()));
+ connect(bca,SIGNAL(clicked()), SLOT(b_c_clicked()));
+
+ this->move(175,150);
+ show();
+}
+
+CPRQueryDialog::~CPRQueryDialog()
+{
+ delete ccw;
+}
+
+QPushButton *CPRQueryDialog::createButton(QWidget *parent, const char *text, int value)
+/* A genric button-creater */
+{
+ char buf[32];
+ sprintf(buf, "%d", value);
+ QPushButton *q = new QPushButton(this, buf);
+
+ QFont f("Lucida", 48);
+ q->setFixedSize(150, 100);
+ q->setText(text);
+ q->setFont(f);
+ return q;
+}
+
+/* Event function for handling buttonclicks.
+ * For button 0-9 the values is sent back.
+ * Backspace and clear are handled via special
+ * signals.
+ * When 10 digits has been input we close the form
+ */
+void CPRQueryDialog::b_1_clicked() { insert_digit(1); }
+void CPRQueryDialog::b_2_clicked() { insert_digit(2); }
+void CPRQueryDialog::b_3_clicked() { insert_digit(3); }
+void CPRQueryDialog::b_4_clicked() { insert_digit(4); }
+void CPRQueryDialog::b_5_clicked() { insert_digit(5); }
+void CPRQueryDialog::b_6_clicked() { insert_digit(6); }
+void CPRQueryDialog::b_7_clicked() { insert_digit(7); }
+void CPRQueryDialog::b_8_clicked() { insert_digit(8); }
+void CPRQueryDialog::b_9_clicked() { insert_digit(9); }
+void CPRQueryDialog::b_0_clicked() { insert_digit(0);}
+void CPRQueryDialog::b_b_clicked() { remove_digit();}
+void CPRQueryDialog::b_c_clicked() { remove_all();}
+
+void CPRQueryDialog::b_clicked(int value)
+{
+ printf("%d\n", value);
+ switch(value) {
+ case 10:
+ if (digits>0) digits--;
+ emit bbs_clicked();
+ break;
+ case 11:
+ digits = 0;
+ emit bca_clicked();
+ break;
+ default:
+ digits++;
+ emit number_clicked(value);
+ }
+ if (digits == 10){
+ digits = 0;
+ accept();
+ }
+}
+
+void CPRQueryDialog::run(int pos)
+/* This is where the mgui thread starts.
+ * Open a inputwindow and prepare to receive a cpr
+ */
+{
+
+ // iw = new CPRQueryDialog(this, "Input", true, pos);
+
+
+ // TODO : Reconnect
+ /*
+ if (this->exec() == QDialog::Accepted) {
+#ifdef WITH_DV
+ camera->setCpr(cpr);
+#endif
+ verifycpr(cpr);
+ }
+ */
+}
+
+void CPRQueryDialog::remove_digit()
+/* Remove one digit from the selected cpr
+ * Used when the user pushes backspace in
+ * the inputwindow
+ */
+{
+ int temp;
+ temp = strlen(cpr);
+ if (temp == 7) /* Remove two characters due to the hyphen */
+ strcpy(cpr+temp-2, "\0");
+ else if ((temp >0) && (temp <=11))
+ strcpy(cpr+temp-1, "\0");
+ lbl_cpr->setText(cpr);
+}
+
+void CPRQueryDialog::remove_all()
+/* Clear the selected cpr */
+{
+ strcpy(cpr, "");
+ lbl_cpr->setText(cpr);
+}
+
+void CPRQueryDialog::insert_digit(int value)
+/* Respond to what the user types in the inputWindow */
+{
+ char temp[2];
+ switch(strlen(cpr)) {
+ case 5: // Automaticaly add a hyphen after the sixth digit
+ sprintf(temp, "%d-", value);
+ strcat(cpr, temp);
+ lbl_cpr->setText(cpr);
+ break;
+ case 10:
+ sprintf(temp, "%d", value);
+ strcat(cpr, temp);
+ lbl_cpr->setText(cpr);
+ verifycpr(cpr);
+ break;
+ default:
+ sprintf(temp, "%d", value);
+ strcat(cpr, temp);
+ lbl_cpr->setText(cpr);
+ break;
+ }
+}
+
+void CPRQueryDialog::verifycpr(char *cpr)
+/* Test a cpr via test_cpr().
+ * If cpr is invalid, then ask user what
+ * to do via confirmCprWindow
+ */
+{
+ strncpy(internalCpr, cpr, 6);
+ strncpy(internalCpr+6, cpr+7, 4);
+ internalCpr[10] = 0;
+
+ if (!(test_cpr(internalCpr))) {
+ switch(ccw->exec()) {
+ case MSG_CANCEL:
+ bedit_clicked();
+ break;
+ case MSG_NO:
+ bcancel_clicked();
+ break;
+ case MSG_YES:
+ accept();
+ break;
+ }
+ } else {
+ cprSocket->connectToHost(CPR_HOST->c_str(), CPR_PORT);
+ accept();
+ }
+}
+
+
+void CPRQueryDialog::bcancel_clicked()
+/* Clears all data - alerts user if measurements are not stored */
+{
+ cpr[0]= '\0';
+ lbl_cpr->setText("Indtast CPR");
+ lbl_name->setText("");
+ run(0);
+}
+
+void CPRQueryDialog::bedit_clicked()
+/* This is used when the user enters a cpr that is not valid and wishes to edit
+ * the cpr.
+ */
+{
+ cpr[10]= '\0';
+ lbl_cpr->setText(cpr);
+ lbl_name->setText("");
+ run(9);
+}
+
+
+int CPRQueryDialog::test_cpr(const char *s)
+/* Checks that a cpr i valid via a modulo11 test */
+{
+ int sum = 0;
+ int ctl;
+ const char *cptr;
+
+ if(strlen(s) != 10)
+ return 0;
+
+ for(cptr = s; *cptr; cptr++)
+ {
+ if(!isdigit(*cptr))
+ return 0;
+ }
+ sum += (s[0] - '0') * 4;
+ sum += (s[1] - '0') * 3;
+ sum += (s[2] - '0') * 2;
+ sum += (s[3] - '0') * 7;
+ sum += (s[4] - '0') * 6;
+ sum += (s[5] - '0') * 5;
+ sum += (s[6] - '0') * 4;
+ sum += (s[7] - '0') * 3;
+ sum += (s[8] - '0') * 2;
+ ctl = 11 - (sum % 11);
+ if(ctl == 11)
+ ctl = 0;
+ return s[9] - '0' == ctl;
+}
+
+void CPRQueryDialog::cprSocket_readyRead()
+/* Uses a patients cpr to look up his or hers name
+ * via the departments cpr-server.
+ * This is called by the cprSocket when the socket is ready
+ */
+{
+ QString name;
+ QString firstname;
+ QString lastname;
+ int timeout = 0;
+ if (!cprSocket->canReadLine())
+ return;
+ while(cprSocket->canReadLine()) {
+ QString s = cprSocket->readLine();
+ if (s.startsWith("0001")) {
+ name.append(s.right(s.length()-4));
+ lastname.append(s.right(s.length()-4));
+ name.setLength(name.length()-1);
+ if (name.length())
+ name += QString(", ");
+
+ }
+ if (s.startsWith("0002")) {
+ name.append(s.right(s.length()-4));
+ firstname.append(s.right(s.length()-4));
+ name.setLength(name.length()-1);
+ cprSocket->close();
+ lbl_name->setText(name);
+ return;
+ }
+ if (timeout>1000)
+ {
+ lbl_name->setText(NAME_NOT_AVAILABLE);
+ return;
+ }
+ timeout++;
+ }
+}
+
+
+void CPRQueryDialog::cprSocket_connected()
+/* Writes the selected cpr to the cpr-server
+ * when the cprSocket is connected.
+ */
+{
+ cprSocket->writeBlock(internalCpr, 10);
+ cprSocket->writeBlock("\n", 1);
+}
+
+#endif /* USE_GUI */
diff --git a/src/cprquerydialog.h b/src/cprquerydialog.h
new file mode 100644
index 0000000..56f800c
--- /dev/null
+++ b/src/cprquerydialog.h
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * cprquerydialog.h
+ *
+ * Sat Feb 19 17:05:42 CET 2005
+ * Copyright 2005 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __MIAV_CPRQUERYDIALOG_H__
+#define __MIAV_CPRQUERYDIALOG_H__
+
+#define CPR_EDIT 8
+#define CPR_CLEAR 9
+#define NAME_NOT_AVAILABLE "Kunne ikke slå navn op i cpr-database"
+
+#include <config.h>
+#ifdef USE_GUI
+
+#include <qdialog.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qfont.h>
+
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qdialog.h>
+#include <qlabel.h>
+
+#include <qsocket.h>
+#include <qtextedit.h>
+#include <qstring.h>
+#include <qwidget.h>
+
+#include <qevent.h>
+
+#include <qpushbutton.h>
+
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qdialog.h>
+
+#include <string>
+using namespace std;
+
+#include <qdialog.h>
+#include <qlabel.h>
+#include <qsocket.h>
+
+#include "messagebox.h"
+
+
+
+class CPRQueryDialog : public QDialog {
+ Q_OBJECT
+public:
+ CPRQueryDialog(QLabel *lcpr,
+ QLabel *lname,
+ QWidget * parent = 0,
+ const char * name = 0,
+ bool modal = FALSE);
+ ~CPRQueryDialog();
+
+public slots:
+ void bcancel_clicked();
+ void bedit_clicked();
+ void remove_digit();
+ void remove_all();
+ void insert_digit(int value);
+ void cprSocket_readyRead();
+ void cprSocket_connected();
+
+private:
+ QLabel *lbl_cpr;
+ QLabel *lbl_name;
+
+ MessageBox *ccw;
+
+ QSocket *cprSocket;
+ char cpr[12];
+ char internalCpr[11];
+
+ void verifycpr(char *cpr);
+ void run(int pos);
+ int test_cpr(const char *s);
+
+ /*Configuration*/
+ string *CPR_HOST;
+ int CPR_PORT;
+
+signals:
+ void bbs_clicked();
+ void bca_clicked();
+ void number_clicked(int);
+
+public slots:
+ void b_1_clicked();
+ void b_2_clicked();
+ void b_3_clicked();
+ void b_4_clicked();
+ void b_5_clicked();
+ void b_6_clicked();
+ void b_7_clicked();
+ void b_8_clicked();
+ void b_9_clicked();
+ void b_0_clicked();
+ void b_b_clicked();
+ void b_c_clicked();
+
+private:
+ void b_clicked(int value);
+ QPushButton *createButton(QWidget *parent, const char *text, int value);
+ int digits;
+};
+
+#endif/*__MIAV_CPRQUERYDIALOG_H__*/
+
+#endif /* USE_GUI */
diff --git a/src/decoder.cc b/src/decoder.cc
new file mode 100644
index 0000000..2171b1a
--- /dev/null
+++ b/src/decoder.cc
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 Bent Bisballe
+ * Copyright (C) 2004 B. Stultiens
+ * Copyright (C) 2004 Koen Otter and Glenn van der Meyden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <config.h>
+
+#include "decoder.h"
+
+Decoder::Decoder(char *device,
+ int channel,
+ sem_t *gencode_sem,
+ sem_t *gplayer_sem,
+ Queue<DVFrame> *gencode_queue,
+ Queue<FFFrame> *gplayer_queue,
+ pthread_mutex_t *gmutex,
+ volatile int *grunning)
+{
+ encode_sem = gencode_sem;
+ player_sem = gplayer_sem;
+ encode_queue = gencode_queue;
+ player_queue = gplayer_queue;
+ mutex = gmutex;
+ running = grunning;
+
+ AVFormatContext *ifc;
+ AVFormatParameters dvpars;
+ AVInputFormat *iformat;
+ AVCodec *dec_codec;
+
+ memset(&dvpars, 0, sizeof(dvpars));
+
+ if(!(iformat = av_find_input_format("dv1394"))) {
+ fprintf(stderr, "Failed to get input format dv1394\n");
+ exit(1);
+ }
+
+ dvpars.device = device; /* "/dev/dv1394"; */
+ dvpars.channel = channel;
+ dvpars.standard = "pal";
+
+ if(av_open_input_file(&ifc, "", iformat, 0, &dvpars) < 0) {
+ fprintf(stderr, "Device is in use\n");
+ fc = NULL; return;
+ }
+ if(av_find_stream_info(ifc) < 0) {
+ fprintf (stderr, "Could not find enough parameters\n");
+ fc = NULL; return;
+ }
+
+ dump_format(ifc, 1, "", 0);
+
+ if(!(dec_codec = avcodec_find_decoder(ifc->streams[0]->codec.codec_id))) {
+ printf("Unsupported codec for input stream \n");
+ fc = NULL; return;
+ }
+
+ if(avcodec_open(&ifc->streams[0]->codec, dec_codec) < 0) {
+ printf("Error while opening codec for input stream\n");
+ fc = NULL; return;
+ }
+
+ fc = ifc;
+}
+
+Decoder::~Decoder()
+{
+ avcodec_close(&fc->streams[0]->codec);
+ av_close_input_file(fc);
+}
+
+void Decoder::decode()
+{
+ if(fc == NULL) {
+ printf("Decoder not initialized.\n");
+ return;
+ }
+
+ while(*running) {
+ AVPacket pkt;
+ uint8_t *ptr;
+ int len;
+ SDL_Event user_event;
+
+ av_read_packet(fc, &pkt);
+ len = pkt.size;
+ ptr = pkt.data;
+ /* NOTE: we only decode video, we only need the data from stream_index 0 */
+ /* (stream 0: video, stream 1: audio) */
+
+ while(pkt.stream_index == 0 && len > 0) {
+ int ret;
+ int got_picture;
+ // buf_t *buf = buf_alloc();
+ FFFrame *fff = new FFFrame();
+ DVFrame *dvf = new DVFrame();
+ dvf->type = DVF_VIDEO;
+
+ memcpy(dvf->frame, ptr, len);
+
+ // fprintf(stderr, "DVBufferSize: [%d]bytes\n", len);
+ ret = avcodec_decode_video(&fc->streams[0]->codec,
+ fff->frame, &got_picture, ptr, len);
+
+ if(ret < 0) {
+ fprintf(stderr, "Error while decoding stream\n");
+ exit(1);
+ }
+
+ len -= ret;
+ ptr += ret;
+
+ pthread_mutex_lock(mutex);
+ encode_queue->push(dvf);
+ player_queue->push(fff);
+ pthread_mutex_unlock(mutex);
+
+ sem_post(encode_sem);
+
+ user_event.type = SDL_USEREVENT;
+ user_event.user.code = 0;
+ user_event.user.data1 = NULL;
+ user_event.user.data2 = NULL;
+ SDL_PushEvent(&user_event);
+ }
+
+ /* // For later use, when audio must be implemented
+ while(pkt.stream_index == 1 && len > 0) {
+ DVFrame *dvf = new DVFrame();
+ dvf->type = DVF_AUDIO;
+
+ memcpy(dvf->frame, ptr, sizeof(dvf->frame));
+
+ ptr += sizeof(dvf->frame);
+ len -= sizeof(dvf->frame);
+
+ pthread_mutex_lock(mutex);
+ encode_queue->push(dvf);
+ pthread_mutex_unlock(mutex);
+
+ sem_post(encode_sem);
+ }
+ */
+ av_free_packet(&pkt);
+ }
+
+ /* Kick the others so they wake up with empty queues */
+ sem_post(encode_sem);
+ pthread_exit(NULL);
+}
+
+void Decoder::run() {
+ decode();
+}
diff --git a/src/decoder.h b/src/decoder.h
new file mode 100644
index 0000000..ad323b1
--- /dev/null
+++ b/src/decoder.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 Bent Bisballe
+ * Copyright (C) 2004 B. Stultiens
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <config.h>
+#ifndef __RTVIDEOREC_DECODER_H
+#define __RTVIDEOREC_DECODER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <avformat.h>
+#include <SDL/SDL.h>
+
+#include <queue.h>
+#include "encoder.h"
+#include "player.h"
+
+#include "thread.h"
+#include "ffframe.h"
+#include <dvframe.h>
+
+class Decoder : public Thread {
+ public:
+ Decoder(char *device,
+ int channel,
+ sem_t *gencode_sem,
+ sem_t *gplayer_sem,
+ Queue<DVFrame> *gencode_queue,
+ Queue<FFFrame> *gplayer_queue,
+ pthread_mutex_t *gmutex,
+ volatile int *grunning);
+ ~Decoder();
+ void run();
+
+ AVFormatContext *fc;
+ sem_t *encode_sem;
+ sem_t *player_sem;
+ Queue<DVFrame> *encode_queue;
+ Queue<FFFrame> *player_queue;
+ pthread_mutex_t *mutex;
+ volatile int *running;
+
+ private:
+ void decode();
+};
+
+#endif
diff --git a/src/dvframe.cc b/src/dvframe.cc
new file mode 100644
index 0000000..229332c
--- /dev/null
+++ b/src/dvframe.cc
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * frame.cc
+ *
+ * Mon Nov 15 19:45:07 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+
+#include "dvframe.h"
+
+#include <memory.h>
+
+DVFrame::DVFrame()
+{
+ // frame = avcodec_alloc_frame();
+ memset(frame, 0, sizeof(frame));
+}
+
+DVFrame::~DVFrame()
+{
+ // av_free(frame);
+}
+
diff --git a/src/dvframe.h b/src/dvframe.h
new file mode 100644
index 0000000..a9e948c
--- /dev/null
+++ b/src/dvframe.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * frame.h
+ *
+ * Mon Nov 15 19:45:07 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+#ifndef __DVFRAME_H__
+#define __DVFRAME_H__
+
+//#include <avformat.h>
+
+#define DVPACKAGE_SIZE 144000
+
+typedef enum {
+ DVF_AUDIO = 0x01,
+ DVF_VIDEO = 0x02
+} DVFrameType;
+
+
+class DVFrame {
+public:
+ DVFrame();
+ ~DVFrame();
+ DVFrameType type;
+ char frame[DVPACKAGE_SIZE];
+};
+
+#endif/*__DVFRAME_H__*/
diff --git a/src/encoder.cc b/src/encoder.cc
new file mode 100644
index 0000000..3da7443
--- /dev/null
+++ b/src/encoder.cc
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 Bent Bisballe
+ * Copyright (C) 2004 B. Stultiens
+ * Copyright (C) 2004 Koen Otter and Glenn van der Meyden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include "encoder.h"
+
+Encoder::Encoder(const char *gip,
+ const int gport,
+ sem_t *gsem,
+ Queue<DVFrame> *gqueue,
+ pthread_mutex_t *gmutex,
+ volatile int *grunning)
+{
+ sprintf(ip, gip);
+ port = gport;
+ memset(cpr, 0, sizeof(cpr));
+
+ printf("[ip: %s]\n", ip);
+ printf("[port: %d]\n", port);
+
+ sem = gsem;
+ queue = gqueue;
+ mutex = gmutex;
+ running = grunning;
+
+ record = 0;
+
+ sem_init(&record_sem, 0, 0);
+
+ s = NULL;
+ n = NULL;
+
+ shoot_request = 0;
+ shoot_value = 0;
+ freeze_request = 0;
+ freeze_value = 0;
+
+}
+
+Encoder::~Encoder()
+{
+ if(n) delete n;
+ if(s) delete s;
+}
+
+
+void Encoder::setCpr(char *newcpr)
+{
+ sprintf(cpr, newcpr);
+}
+
+
+void Encoder::encode()
+{
+ DVFrame *f;
+
+ while(*running) {
+ sem_wait(sem);
+
+ /*
+ pthread_mutex_lock(mutex);
+ while((f = queue->pop())) delete f;
+ pthread_mutex_unlock(mutex);
+
+ while(record) {
+ sem_wait(sem);
+ */
+
+ pthread_mutex_lock(mutex);
+ f = queue->pop();
+ pthread_mutex_unlock(mutex);
+
+ if((f && record) || (freeze_request != freeze_value) || (shoot_request != shoot_value)) {
+ fprintf(stderr, "Rec!\n");
+ n_header h;
+
+ h.header_type = DATA_HEADER;
+ sprintf(h.header.h_data.cpr, cpr);
+ h.header.h_data.freeze = (freeze_request != freeze_value);
+ h.header.h_data.snapshot = (shoot_request != shoot_value);
+ h.header.h_data.record = record;
+
+ if(freeze_request != freeze_value) freeze_value = freeze_request;
+ if(shoot_request != shoot_value) shoot_value = shoot_request;
+
+ n->sendPackage(&h, f->frame, sizeof(f->frame));
+ }
+
+ if(f) delete f;
+ //}
+ }
+ pthread_exit(NULL);
+}
+
+void Encoder::freeze()
+{
+ if(!s) {
+ s = new Socket(port);
+ s->sconnect(ip);
+ n = new Network(s);
+ }
+ freeze_request = 1 - freeze_request;
+}
+
+void Encoder::shoot()
+{
+ if(!s) {
+ s = new Socket(port);
+ s->sconnect(ip);
+ n = new Network(s);
+ }
+ shoot_request = 1 - shoot_request;
+}
+
+void Encoder::run() {
+ encode();
+}
+
+void Encoder::start() {
+ printf("GO!\n");
+ if(!s) {
+ s = new Socket(port);
+ s->sconnect(ip);
+ n = new Network(s);
+ }
+ record = 1;
+}
+
+void Encoder::stop() {
+ printf("STOP!\n");
+ if(s) {
+ if(n) delete n;
+ delete s;
+ s = NULL;
+ n = NULL;
+ }
+ record = 0;
+}
diff --git a/src/encoder.h b/src/encoder.h
new file mode 100644
index 0000000..d517ff5
--- /dev/null
+++ b/src/encoder.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 Bent Bisballe
+ * Copyright (C) 2004 B. Stultiens
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <config.h>
+#ifndef __RTVIDEOREC_ENCODER_H
+#define __RTVIDEOREC_ENCODER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <avformat.h>
+
+#include <miav.h>
+
+#include "util.h"
+#include <queue.h>
+
+#include "thread.h"
+#include <dvframe.h>
+
+#define VIDEO_BUFFER_SIZE (1024*1024) /* FIXME: One size fits all... */
+
+
+
+class Encoder : public Thread {
+ public:
+ Encoder(const char *gip,
+ const int gport,
+ sem_t *gsem,
+ Queue<DVFrame> *gqueue,
+ pthread_mutex_t *gmutex,
+ volatile int *grunning);
+ ~Encoder();
+
+ void setCpr(char *newcpr);
+
+ void start();
+ void stop();
+
+ void freeze();
+ void shoot();
+
+ void run();
+
+ AVFormatContext *fc;
+ sem_t *sem;
+ Queue<DVFrame> *queue;
+ pthread_mutex_t *mutex;
+ volatile int *running;
+
+ private:
+ int port;
+ char ip[32];
+ char cpr[32];
+
+ volatile int record;
+
+ volatile int shoot_request;
+ int shoot_value;
+ volatile int freeze_request;
+ int freeze_value;
+
+ sem_t record_sem;
+ void encode();
+
+ Socket *s;
+ Network *n;
+};
+
+#endif
+
diff --git a/src/ffframe.cc b/src/ffframe.cc
new file mode 100644
index 0000000..cdce5ae
--- /dev/null
+++ b/src/ffframe.cc
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * frame.cc
+ *
+ * Mon Nov 15 19:45:07 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "ffframe.h"
+
+FFFrame::FFFrame()
+{
+ frame = avcodec_alloc_frame();
+}
+
+FFFrame::~FFFrame()
+{
+ av_free(frame);
+}
+
diff --git a/src/ffframe.h b/src/ffframe.h
new file mode 100644
index 0000000..5b02780
--- /dev/null
+++ b/src/ffframe.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * frame.h
+ *
+ * Mon Nov 15 19:45:07 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+#ifndef __FFFRAME_H__
+#define __FFFRAME_H__
+
+#include <avformat.h>
+
+class FFFrame {
+public:
+ FFFrame();
+ ~FFFrame();
+ AVFrame *frame;
+};
+
+#endif/*__FFFRAME_H__*/
diff --git a/src/img_encoder.cc b/src/img_encoder.cc
new file mode 100644
index 0000000..2f6d8b7
--- /dev/null
+++ b/src/img_encoder.cc
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 Bent Bisballe
+ * Copyright (C) 2004 B. Stultiens
+ * Copyright (C) 2004 Koen Otter and Glenn van der Meyden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "img_encoder.h"
+#include <stdio.h>
+//#include <setjmp.h>
+
+//av_alloc_format_context
+//av_destruct_packet_nofree
+
+ImgEncoder::ImgEncoder()
+{
+ //////////////////// GLOBAL INIT
+ av_register_all();
+
+ //////////////////// DECODE INIT
+ AVCodec *deccodec;
+
+ // find the dvvideo decoder
+ deccodec = avcodec_find_decoder(CODEC_ID_DVVIDEO);
+ if (!deccodec) {
+ fprintf(stderr, "codec not found\n");
+ exit(1);
+ }
+
+ dcc= avcodec_alloc_context();
+
+ // open it
+ if (avcodec_open(dcc, deccodec) < 0) {
+ fprintf(stderr, "could not open codec\n");
+ exit(1);
+ }
+}
+
+ImgEncoder::~ImgEncoder()
+{
+ // FIXME: free: deccodec and dcc
+}
+
+void ImgEncoder::encode(DVFrame *dvframe,
+ char *filename,
+ int quality)
+{
+ int ret;
+ AVFrame *rawframe = avcodec_alloc_frame();
+
+ ///////////////////////// DECODE
+ uint8_t *ptr;
+ int got_picture = 1;
+ int len;
+
+ ptr = (uint8_t *)dvframe->frame;
+ len = sizeof(dvframe->frame);
+
+ ret = avcodec_decode_video(dcc, rawframe, &got_picture, ptr, len);
+
+ if(!ret) {
+ printf("Decoder fuckup!\n");
+ return;
+ }
+
+ // TODO: Do image convertion here!
+ AVPicture pict;
+ avpicture_alloc(&pict,PIX_FMT_RGB24, 720, 576);
+
+ img_convert(&pict, PIX_FMT_RGB24, (AVPicture *)rawframe,
+ PIX_FMT_YUV420P, 720, 576);
+ printf("converted\n");
+ writeJPEGFile(filename, quality, (JSAMPLE*)(pict.data[0]), 720, 576);
+ printf("written\n");
+
+ avpicture_free(&pict);
+ av_free(rawframe);
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+
+void ImgEncoder::writeJPEGFile(char *filename,
+ int quality,
+ JSAMPLE * image_buffer, // Points to large array of R,G,B-order data
+ int image_width, // Number of columns in image
+ int image_height // Number of rows in image
+)
+{
+ /*
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+
+ FILE * outfile; // target file
+ JSAMPROW row_pointer[1]; // pointer to JSAMPLE row[s]
+ int row_stride; // physical row width in image buffer
+
+ // Step 1: allocate and initialize JPEG compression object
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+
+ // Step 2: specify data destination (eg, a file)
+ if ((outfile = fopen(filename, "wb")) == NULL) {
+ fprintf(stderr, "can't open %s\n", filename);
+ exit(1);
+ }
+ jpeg_stdio_dest(&cinfo, outfile);
+
+ // Step 3: set parameters for compression
+ cinfo.image_width = image_width; // image width and height, in pixels
+ cinfo.image_height = image_height;
+ cinfo.input_components = 3; // # of color components per pixel
+/*
+typedef enum {
+ JCS_UNKNOWN, // error/unspecified
+ JCS_GRAYSCALE, // monochrome
+ JCS_RGB, // red/green/blue
+ JCS_YCbCr, // Y/Cb/Cr (also known as YUV)
+ JCS_CMYK, // C/M/Y/K
+ JCS_YCCK // Y/Cb/Cr/K
+} J_COLOR_SPACE;
+* /
+ cinfo.in_color_space = JCS_RGB; // colorspace of input image
+
+ jpeg_set_defaults(&cinfo);
+
+ jpeg_set_quality(&cinfo, quality, TRUE); // limit to baseline-JPEG values
+
+ // Step 4: Start compressor
+ jpeg_start_compress(&cinfo, TRUE);
+
+ // Step 5: while (scan lines remain to be written)
+ row_stride = image_width * 3; // JSAMPLEs per row in image_buffer
+
+ while (cinfo.next_scanline < cinfo.image_height) {
+ row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
+ (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
+
+ // Step 6: Finish compression
+ jpeg_finish_compress(&cinfo);
+ fclose(outfile);
+
+ // Step 7: release JPEG compression object
+ jpeg_destroy_compress(&cinfo);
+ */
+}
diff --git a/src/img_encoder.h b/src/img_encoder.h
new file mode 100644
index 0000000..7f1da7e
--- /dev/null
+++ b/src/img_encoder.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 Bent Bisballe
+ * Copyright (C) 2004 B. Stultiens
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __RTVIDEOREC_IMGENCODER_H
+#define __RTVIDEOREC_IMGENCODER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <avformat.h>
+#include <jpeglib.h>
+
+#include <dvframe.h>
+
+#include "util.h"
+
+#define VIDEO_BUFFER_SIZE (1024*1024) // FIXME: One size fits all...
+
+class ImgEncoder {
+ public:
+ ImgEncoder();
+ ~ImgEncoder();
+ void encode(DVFrame *frame, char* filename, int quality);
+ void writeJPEGFile(char *filename,
+ int quality,
+ JSAMPLE * image_buffer, // Points to large array of R,G,B-order data
+ int image_width, // Number of columns in image
+ int image_height); // Number of rows in image
+
+ private:
+ // Decoder
+ AVFormatContext *dfc;
+ AVCodecContext *dcc;
+
+ // Encoder
+ AVFormatContext *efc;
+ AVCodecContext *ecc;
+ AVPacket epkt;
+ unsigned char *video_buffer;
+ // AVPacket pkt;
+};
+
+#endif
+
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
new file mode 100644
index 0000000..77b8d94
--- /dev/null
+++ b/src/mainwindow.cc
@@ -0,0 +1,305 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * mainwindow.cc
+ *
+ * Sat Aug 21 19:49:34 2004
+ * Copyright 2004 deva
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+#ifdef USE_GUI
+
+#include "mainwindow.h"
+
+#include <qpainter.h>
+#include <qpicture.h>
+
+#include <qpushbutton.h>
+#include <qfont.h>
+#include <qpixmap.h>
+#include <qimage.h>
+#include <qlayout.h>
+#include <qstatusbar.h>
+
+//#include "mgui_alert.h"
+//#include "mgui_datasocket.h"
+
+#include "miav_config.h"
+
+#include <config.h>
+//"miav-grab.h"
+
+
+//#define WITH_DV
+MainWindow::MainWindow( QWidget* parent, const char* name )
+ : QWidget( parent, name, WStyle_Customize | WStyle_NoBorder )
+{
+ // statusBar();
+ // statusBar()->message("fisk");
+ // statusBar()->setSizeGripEnabled(false);
+
+ MiavConfig cfg("miav.conf");
+ /** /
+ int resolution_w = 1280; // TODO: Read actual resolution
+ int resolution_h = 1024; // TODO: Read actual resolution
+ /**/
+ /**/
+ int resolution_w = 1024; // TODO: Read actual resolution
+ int resolution_h = 768; // TODO: Read actual resolution
+ /**/
+ unit = ((float)resolution_w / (float)(cfg.readFloat("screensize") * 3.1f));
+
+ move(0,0);
+ resize(resolution_w, resolution_h);
+
+ // Load images
+ pix_record = new QPixmap();
+ pix_record->load( "record.png" );
+/*
+ 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_stop = new QPixmap();
+ pix_stop->load( "stop.png" );
+
+ pix_camera = new QPixmap();
+ pix_camera->load( "camera.png" );
+
+ pix_dummy = new QPixmap();
+ pix_dummy->load( "dummy.png" );
+
+ pix_logo = new QPixmap();
+ pix_logo->load( "miav-logo-64x64.png" );
+
+ createGui();
+ show();
+
+ // camera = new Camera("192.168.0.10", 30000);
+
+ recording = false;
+ frozen = false;
+
+ aboutwindow = NULL;
+
+ // CPRQueryDialog dlg(lbl_cpr, lbl_name, this, "CPRQueryDialog");
+ // dlg.exec();
+ // Open the CPR Dialog
+ cpr_clicked();
+}
+
+MainWindow::~MainWindow()
+{
+ if(camera) delete camera;
+ delete btn_cpr;
+ if(aboutwindow) delete aboutwindow;
+}
+
+void MainWindow::createGui()
+{
+ // Layout widgets
+
+ /* _________________________________________________
+ *(0) __________________________ | ______________ |
+ * | | | | | | | | |
+ * |(1) | | | |(2) | |
+ * | | | | | | | | |
+ * | | | | | | | | |
+ * | | | | | | |______________| |
+ * | | | | | | | | |
+ * | | | | | | | | |
+ * | | | | | | | | |
+ * | |________|________|________| | | | |
+ * | | | | | | |______________| |
+ * | |________|________|________| | | | |
+ * | | | | | | | | |
+ * | |________|________|________| | | | |
+ * | | | | | | | | |
+ * | |________|________|________| | |______________| |
+ * |______________________________|__________________|
+ * |______________________________|__________________|
+ */
+
+ QGridLayout *g0 = new QGridLayout(this, 2, 2, 0, -1, "g0");
+ QGridLayout *g1 = new QGridLayout(3, 4, -1, "g1");
+ g0->addLayout(g1, 0, 0);
+ QGridLayout *g2 = new QGridLayout(1, NUM_HISTORY, -1, "g2");
+ g0->addLayout(g2, 0, 1);
+
+ img_recedge = new QLabel(this);
+ img_recedge->setBackgroundColor(QColor(160,160,160));
+ img_recedge->setFixedSize(740,596);
+
+ img_live = new VideoWidget(img_recedge);
+ // img_live->setErasePixmap( *pix_dummy );
+ img_live->setFixedSize(720,576);
+ img_live->move(10,10);
+ g1->addMultiCellWidget ( img_recedge, 0, 0, 0, 2, Qt::AlignHCenter);
+
+ // CPR/NAME LABEL + CPR button
+ lbl_cpr = createLabel("200379-1613", 18, 3);
+ g1->addMultiCellWidget ( lbl_cpr, 1, 1, 0, 1);
+
+ btn_cpr = createButton("NYT CPR", 8, 3);
+ btn_cpr->setFocus();
+ QObject::connect( btn_cpr, SIGNAL(clicked()), this, SLOT(cpr_clicked()) );
+ // Will also be connected in the MGUI code
+ g1->addWidget(btn_cpr, 1, 2);
+
+ lbl_name = createLabel("Bent Bisballe Kjær Nyeng Jensen", 18, 2);
+ g1->addMultiCellWidget ( lbl_name, 2, 2, 0, 2);
+
+ // Rec + Shot + Freeze buttons
+ btn_rec = createButton("", 8, 3);
+ btn_rec->setPixmap(*pix_record);
+ QObject::connect( btn_rec, SIGNAL(clicked()), this, SLOT(rec_clicked()) );
+ g1->addWidget(btn_rec, 3, 0);
+
+ btn_shoot = createButton("", 8, 3);
+ btn_shoot->setPixmap(*pix_camera);
+ QObject::connect( btn_shoot, SIGNAL(clicked()), this, SLOT(shoot_clicked()) );
+ g1->addWidget(btn_shoot, 3, 1);
+
+ btn_freeze = createButton("FREEZE", 8, 3);
+ // btn_freeze->setPixmap(*pix_logo);
+ QObject::connect( btn_freeze, SIGNAL(clicked()), this, SLOT(freeze_clicked()) );
+ g1->addWidget(btn_freeze, 3, 2);
+
+ // History widgets
+ for(int i = 0; i < NUM_HISTORY; i++) {
+ img_history[i] = new QLabel(this);
+ img_history[i]->setPixmap(*pix_dummy);
+ img_history[i]->setFixedSize(240,192);
+ g2->addWidget(img_history[i], i, 0, Qt::AlignHCenter);
+ }
+
+ // Statusbar
+ lbl_status = createLabel("STATUS", 18, 1);
+ lbl_status->setFrameStyle(QFrame::TabWidgetPanel | QFrame::Sunken);
+ lbl_status->setLineWidth(1);
+ g0->addWidget(lbl_status, 4, 0);
+
+ lbl_version = createLabel("MIaV-Grab v" VERSION, 18, 1);
+ lbl_version->setFrameStyle(QFrame::TabWidgetPanel | QFrame::Sunken);
+ lbl_version->setLineWidth(1);
+ lbl_version->setFixedHeight((int)unit);
+ g0->addWidget(lbl_version, 4, 1);
+
+ /* // About icon
+ btn_logo = new QPushButton("", this);
+ btn_logo->setPixmap(*pix_logo);
+ btn_logo->setFixedSize(74,74);
+ btn_logo->move(940,10);
+ btn_logo->setFlat(true);
+ QObject::connect( btn_logo, SIGNAL(clicked()), this, SLOT(logo_clicked()) );
+ */
+ //lbl_version->setFont( QFont( "Arial", 8, QFont::Light ) );
+ //lbl_version->setFixedSize(90,10);
+ //lbl_version->move(928,81);
+
+}
+
+QPushButton *MainWindow::createButton(char *caption, int width, int height)
+{
+ QPushButton *btn = new QPushButton(caption, this);
+ btn->setFont( QFont( "Arial", (int)(unit * height / 2), QFont::Bold ) );
+ btn->setFixedHeight((int)(unit * height));
+ return btn;
+}
+
+QLabel *MainWindow::createLabel(char *caption, int width, int height)
+{
+ QLabel *lbl = new QLabel(caption, this);
+ lbl->setFont( QFont( "Arial", (int)(unit * height / 2), (height>1)?QFont::Bold:QFont::Normal ) );
+ lbl->setFixedHeight((int)(unit * height));
+ return lbl;
+}
+
+void MainWindow::message(char *msg)
+{
+ lbl_status->setText(msg);
+}
+
+void MainWindow::logo_clicked()
+{
+ if(aboutwindow)
+ delete aboutwindow;
+ aboutwindow = new AboutWindow(0, "About MIAV-Grab");
+}
+
+void MainWindow::cpr_clicked()
+{
+ CPRQueryDialog dlg(lbl_cpr, lbl_name, this, "CPRQueryDialog");
+ printf("Cpr Dialog returned: %d\n", dlg.exec());
+}
+
+void MainWindow::rec_clicked()
+{
+ recording = 1 - recording;
+ if(recording) {
+ img_recedge->setBackgroundColor(red);
+ btn_rec->setPixmap(*pix_stop);
+ camera->stop();
+ } else {
+ img_recedge->setBackgroundColor(QColor(160,160,160));
+ btn_rec->setPixmap(*pix_record);
+ camera->start();
+ }
+}
+
+void MainWindow::shoot_clicked()
+{
+ QImage image;
+
+ camera->snapshot();
+
+ image = img_live->getScreenshot();
+ image = image.smoothScale(img_history[0]->width(), img_history[0]->height());
+
+ QPixmap pixmap;
+ for(int cnt = (NUM_HISTORY-1); cnt > 0; cnt--) {
+ pixmap = *img_history[cnt-1]->pixmap();
+ img_history[cnt]->setPixmap(pixmap);
+ }
+ img_history[0]->setPixmap(image);
+
+ if(frozen) {
+ camera->unfreeze();
+ btn_freeze->setOn(false);
+ frozen = false;
+ }
+}
+
+void MainWindow::freeze_clicked()
+{
+ if(frozen) {
+ camera->unfreeze();
+ frozen = false;
+ } else {
+ camera->freeze();
+ frozen = true;
+ }
+}
+
+#endif /*USE_GUI*/
diff --git a/src/mainwindow.h b/src/mainwindow.h
new file mode 100644
index 0000000..51cdcca
--- /dev/null
+++ b/src/mainwindow.h
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * mainwindow.h
+ *
+ * Sat Aug 21 19:50:13 2004
+ * Copyright 2004 deva
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+#ifdef USE_GUI
+
+#ifndef __MAINWINDOW_H__
+#define __MAINWINDOW_H__
+
+#include <string>
+using namespace std;
+
+#include <qwidget.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+
+#include "aboutwindow.h"
+#include "videowidget.h"
+#include "camera.h"
+#include "cprquerydialog.h"
+
+#define NUM_HISTORY 3
+
+class MainWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ MainWindow(QWidget* parent = 0, const char* name = 0);
+ ~MainWindow();
+
+ void message(char* msg);
+
+public slots:
+ void cpr_clicked();
+ void logo_clicked();
+ void rec_clicked();
+ void shoot_clicked();
+ void freeze_clicked();
+
+private:
+ void createGui();
+
+ Camera *camera;
+ AboutWindow *aboutwindow;
+
+ QPixmap *pix_camera;
+ QPixmap *pix_record;
+ QPixmap *pix_stop;
+ QPixmap *pix_dummy;
+ QPixmap *pix_logo;
+
+ QLabel *lbl_version;
+ QLabel *lbl_status;
+ QLabel *lbl_cpr;
+ QLabel *lbl_name;
+
+ QLabel *img_recedge;
+ QLabel *img_history[NUM_HISTORY];
+
+ QPushButton *btn_logo;
+ QPushButton *btn_cpr;
+ QPushButton *btn_rec;
+ QPushButton *btn_shoot;
+ QPushButton *btn_freeze;
+
+ VideoWidget *img_live;
+
+ bool recording;
+ bool frozen;
+
+ float unit;
+
+ QPushButton *createButton(char *caption, int width, int height);
+ QLabel *createLabel(char *caption, int width, int height);
+};
+
+#endif
+
+#endif /*USE_GUI*/
diff --git a/src/messagebox.cc b/src/messagebox.cc
new file mode 100644
index 0000000..47799b7
--- /dev/null
+++ b/src/messagebox.cc
@@ -0,0 +1,197 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * messagebox.cc
+ *
+ * Fri Feb 25 20:23:19 CET 2005
+ * Copyright 2005 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "messagebox.h"
+
+////////////////////////////////////////////////////////////////////////////////////////
+/* If the cpr input by the user is not valid, this dialog
+ * ask the user what to do. Edit the number, use it as it is,
+ * or clear the number.
+ */
+
+MessageBox::MessageBox(QWidget* parent, const char* name, const char* text, msg_type type)
+ : QDialog(parent, name, TRUE)
+{
+ QFrame *topf = new QFrame(this);
+ topf->setFrameStyle(QFrame::Box | QFrame::Raised);
+ topf->setLineWidth(3);
+ QVBoxLayout *bl = new QVBoxLayout(this);
+ bl->addWidget(topf);
+
+ QLabel *lbl_text = new QLabel(topf);
+ // text->setText("CPR ikke gyldigt, ønsker du at forsætte?");
+ lbl_text->setText(text);
+ lbl_text->setFont(QFont("Lucida", 18));
+ QFrame *f = new QFrame(topf);
+
+ QVBoxLayout *blayout = new QVBoxLayout(topf, 20, 20);
+ blayout->addWidget(lbl_text);
+ blayout->addWidget(f);
+
+ switch(type) {
+ case TYPE_OK: {
+ QPushButton *bok = createButton(f, "Ok");
+ QGridLayout *glayout = new QGridLayout(f, 1, 1, 20, 20);
+ glayout->addWidget(bok, 0, 0);
+ connect(bok, SIGNAL( clicked() ), SLOT(bok_clicked()));
+ break;
+ }
+ case TYPE_OK_CANCEL: {
+ QPushButton *bok = createButton(f, "Ok");
+ QPushButton *bcancel = createButton(f, "Cancel");
+ QGridLayout *glayout = new QGridLayout(f, 1, 2, 20, 20);
+ glayout->addWidget(bcancel, 0, 1);
+ glayout->addWidget(bok, 0, 2);
+ connect(bcancel, SIGNAL( clicked() ), SLOT(bcancel_clicked()));
+ connect(bok, SIGNAL( clicked() ), SLOT(bok_clicked()));
+ break;
+ }
+ case TYPE_YES_NO: {
+ QPushButton *byes = createButton(f, "Ja");
+ QPushButton *bno = createButton(f, "Nej");
+ QGridLayout *glayout = new QGridLayout(f, 1, 2, 20, 20);
+ glayout->addWidget(bno, 0, 0);
+ glayout->addWidget(byes, 0, 1);
+ connect(byes, SIGNAL( clicked() ), SLOT(byes_clicked()));
+ connect(bno, SIGNAL( clicked() ), SLOT(bno_clicked()));
+ break;
+ }
+ case TYPE_YES_NO_CANCEL: {
+ QPushButton *byes = createButton(f, "Ja");
+ QPushButton *bcancel = createButton(f, "Cancel");
+ QPushButton *bno = createButton(f, "Nej");
+ QGridLayout *glayout = new QGridLayout(f, 1, 3, 20, 20);
+ glayout->addWidget(bno, 0, 0);
+ glayout->addWidget(bcancel, 0, 1);
+ glayout->addWidget(byes, 0, 2);
+ connect(byes, SIGNAL( clicked() ), SLOT(byes_clicked()));
+ connect(bcancel, SIGNAL( clicked() ), SLOT(bcancel_clicked()));
+ connect(bno, SIGNAL( clicked() ), SLOT(bno_clicked()));
+ break;
+ }
+ }
+}
+
+QPushButton *MessageBox::createButton(QWidget *parent, const char *text)
+{
+ QPushButton *q = new QPushButton(parent);
+ q->setText(text);
+ q->setFont(QFont("Lucida", 18));
+ q->setFixedSize(200, 75);
+ return q;
+}
+
+void MessageBox::bok_clicked()
+{
+ done(MSG_OK);
+}
+
+void MessageBox::bcancel_clicked()
+{
+ done(MSG_CANCEL);
+}
+
+void MessageBox::byes_clicked()
+{
+ done(MSG_YES);
+}
+
+void MessageBox::bno_clicked()
+{
+ done(MSG_NO);
+}
+
+
+/*
+////////////////////////////////////////////////////////////////////////////////////////
+// A generic alert dialog that can either give the user a choice
+// (yes or no - returns true or false) or simply give a statement and await the users
+// acknowledgement (OK - returns true)
+//
+
+Alert::Alert(QWidget *parent, const char *text, bool single, const char* name, bool mode)
+: QDialog(parent, name, mode)
+// Sets up the dialog. Two buttons if mode=true otherwise one button
+{
+
+ QPushButton *b_true; ;
+ QPushButton *b_false;
+
+ QFrame *topf = new QFrame(this);
+ topf->setFrameStyle(QFrame::Box | QFrame::Raised);
+ topf->setLineWidth(3);
+ QVBoxLayout *bl1 = new QVBoxLayout(topf, 20, 20);
+
+ QLabel *l_text = new QLabel(topf);
+ QFont font("Lucida", 18);
+ l_text->setText(text);
+ l_text->setFont(font);
+
+ QFrame *f = new QFrame(topf);
+ QHBoxLayout *bl2 = new QHBoxLayout(f, 20, 20);
+
+
+ QVBoxLayout *toplayout = new QVBoxLayout(this);
+ toplayout->addWidget(topf);
+ bl1->addWidget(l_text);
+ bl1->addWidget(f);
+ if(!single)
+ {
+ b_true = createButton(f, M_YES);
+ b_false = createButton(f, M_NO);
+ bl2->addWidget(b_false);
+ bl2->addWidget(b_true);
+ connect(b_false, SIGNAL(clicked()), SLOT(false_clicked()));
+ connect(b_true, SIGNAL(clicked()), SLOT(true_clicked()));
+ }
+ else
+ {
+ b_true = createButton(f, M_OK);
+ bl2->addWidget(b_true);
+ connect(b_true, SIGNAL(clicked()), SLOT(true_clicked()));
+ }
+
+}
+
+QPushButton *Alert::createButton(QWidget *parent, const char *text)
+{
+ QPushButton *q = new QPushButton(parent);
+ QFont font("Lucida", 18);
+ q->setFont(font);
+ q->setText(text);
+ q->setFixedSize(200,75);
+ return q;
+}
+
+void Alert::true_clicked()
+{
+ accept();
+}
+
+void Alert::false_clicked()
+{
+ reject();
+}
+*/
diff --git a/src/messagebox.h b/src/messagebox.h
new file mode 100644
index 0000000..11a1c05
--- /dev/null
+++ b/src/messagebox.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * messagebox.h
+ *
+ * Fri Feb 25 20:23:19 CET 2005
+ * Copyright 2005 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __MIAV_MESSAGEBOX_H__
+#define __MIAV_MESSAGEBOX_H__
+
+#include <qdialog.h>
+#include <qwidget.h>
+#include <qframe.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qlabel.h>
+
+typedef enum {
+ MSG_YES,
+ MSG_NO,
+ MSG_CANCEL,
+ MSG_OK
+} msg_val;
+
+typedef enum {
+ TYPE_OK,
+ TYPE_OK_CANCEL,
+ TYPE_YES_NO,
+ TYPE_YES_NO_CANCEL,
+} msg_type;
+
+class MessageBox : public QDialog
+{
+ Q_OBJECT
+public:
+ MessageBox(QWidget* parent = 0, const char* name = "", const char* text = "", msg_type type = TYPE_OK);
+
+public slots:
+ void bok_clicked();
+ void bcancel_clicked();
+ void byes_clicked();
+ void bno_clicked();
+
+private:
+ QPushButton *createButton(QWidget *parent, const char *text);
+};
+
+#endif/*__MIAV_MESSAGEBOX_H__*/
diff --git a/src/miav.cc b/src/miav.cc
new file mode 100644
index 0000000..4d53bc5
--- /dev/null
+++ b/src/miav.cc
@@ -0,0 +1,120 @@
+/***************************************************************************
+ * miav.cc
+ *
+ * Sat Aug 21 17:32:24 2004
+ * Copyright 2004 deva
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "server.h"
+#include "socket.h"
+
+#ifdef USE_GUI
+#include <qapplication.h>
+#include "mainwindow.h"
+#include <miav.h>
+#endif /* USE_GUI */
+
+#include <stdio.h>
+
+enum {
+ MODE_GRAB,
+ MODE_SERVER
+};
+
+/**
+ * This function starts the MIaV gui.
+ */
+int grab(int argc, char *argv[]) {
+#ifdef USE_GUI
+ QApplication miav_grab( argc, argv );
+ MainWindow mainwindow;
+ miav_grab.setMainWidget( &mainwindow );
+ return miav_grab.exec();
+#else /* USE_GUI */
+ printf("Error: MIaV was not compiled with GUI support...\n");
+ return 0;
+#endif /* USE_GUI */
+}
+
+/**
+ * This function starts the MIaV server.
+ */
+int server(int argc, char *argv[]) {
+ pid_t childpid; // variable to store the child's pid
+
+ signal(SIGCLD, SIG_IGN); // Ved SIGCHILD til IGNORE maa wait/waitpid ikke kaldes
+ // (ellers kommer der kernel-brok)
+
+ if(argc < 1) {
+ printf("Usage: miav server [port]\n");
+ printf("[port] Is the port number the server will be listening to.\n");
+ return 1;
+ }
+
+ printf("Listening on port %d\n",atoi(argv[0]));
+ Socket *s = new Socket(atoi(argv[0]));
+
+ while(1) {
+ Socket *sc = new Socket(s->slisten());
+ if(sc->isConnected()) {
+ childpid = fork();
+
+ if(childpid == -1) {
+ // fork() returns -1 on failure
+ perror("fork");
+ exit(1);
+ } else if(childpid == 0) {
+ // fork() returns 0 to the child process
+ delete s; // Close listen socket.
+ newConnection(sc);
+ delete sc; // Close communication socket.
+ exit(0);
+ } else {
+ // fork() returns new pid to the parent process
+ }
+ }
+ }
+ delete s;
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int mode = MODE_GRAB;
+
+ if(argc < 2) {
+ printf("Usage: miav [mode] [mode options]\n");
+ printf("[mode] can be one of the following: grab or server.\n");
+ return 1;
+ }
+
+ if(!strcmp(argv[1], "grab")) mode = MODE_GRAB;
+ if(!strcmp(argv[1], "server")) mode = MODE_SERVER;
+
+ switch(mode) {
+ case MODE_GRAB:
+ return grab(argc - 2, &argv[2]);
+ case MODE_SERVER:
+ return server(argc - 2, &argv[2]);
+ }
+ return 0;
+}
diff --git a/src/miav.h b/src/miav.h
new file mode 100644
index 0000000..d6d860e
--- /dev/null
+++ b/src/miav.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * miav.h
+ *
+ * Mon Nov 8 09:59:24 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#ifndef __LIBMIAV_H__
+#define __LIBMIAV_H__
+
+#include "util.h"
+
+#include "network.h"
+#include "socket.h"
+#include "queue.h"
+
+#endif/*__LIBMIAV_H__*/
diff --git a/src/miav_config.cc b/src/miav_config.cc
new file mode 100644
index 0000000..2af0ef1
--- /dev/null
+++ b/src/miav_config.cc
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * miav_config.cc
+ *
+ * Sat Feb 19 14:13:19 CET 2005
+ * Copyright 2005 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "miav_config.h"
+
+MiavConfig::MiavConfig(char *file)
+{
+ configs = NULL;
+
+ _cfg *cfg;
+
+ // TODO: Read config from file.
+
+ // Add a config
+ configs = cfg = (_cfg*) malloc(sizeof(_cfg));
+ cfg->name = new string("cpr_host");
+ cfg->stringval = new string("cpr.j.auh.dk");
+ cfg->next = (_cfg*) malloc(sizeof(_cfg));
+
+ // Add another config
+ cfg = cfg->next;
+ cfg->name = new string("cpr_port");
+ cfg->intval = 10301;
+ cfg->next = (_cfg*) malloc(sizeof(_cfg));
+
+ // Add another config
+ cfg = cfg->next;
+ cfg->name = new string("screensize");
+ cfg->floatval = 19.0f;
+ cfg->next = NULL;
+}
+
+MiavConfig::~MiavConfig()
+{
+ _cfg *die = NULL;
+ _cfg *cfg = configs;
+
+ while(cfg) {
+ if(die) free(die);
+ die = cfg;
+ cfg = cfg->next;
+ }
+ if(die) free(die);
+}
+
+int MiavConfig::readInt(char *node)
+{
+ return findNode(node)->intval;
+}
+
+bool MiavConfig::readBool(char *node)
+{
+ return findNode(node)->boolval;
+}
+
+string *MiavConfig::readString(char *node)
+{
+ return findNode(node)->stringval;
+}
+
+float MiavConfig::readFloat(char *node)
+{
+ return findNode(node)->floatval;
+}
+
+_cfg *MiavConfig::findNode(char* node)
+{
+ _cfg *cfg = configs;
+
+ while(cfg) {
+ if(!strcmp(node, cfg->name->c_str())) return cfg;
+ cfg = cfg->next;
+ }
+ fprintf(stderr, "ERROR: Request for nonexisting node \"%s\"!\n", node);
+ exit(1);
+}
diff --git a/src/miav_config.h b/src/miav_config.h
new file mode 100644
index 0000000..4b062e0
--- /dev/null
+++ b/src/miav_config.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * miav_config.h
+ *
+ * Sat Feb 19 14:13:19 CET 2005
+ * Copyright 2005 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#ifndef __MIAV_MIAV_CONFIG_H__
+#define __MIAV_MIAV_CONFIG_H__
+
+#include <string>
+using namespace std;
+
+typedef struct __cfg {
+ string *name;
+ bool boolval;
+ int intval;
+ string *stringval;
+ float floatval;
+ struct __cfg* next;
+} _cfg;
+
+class MiavConfig {
+public:
+ MiavConfig(char *file);
+ ~MiavConfig();
+
+ int readInt(char *node);
+ bool readBool(char *node);
+ string *readString(char *node);
+ float readFloat(char *node);
+
+private:
+ _cfg *findNode(char* node);
+ _cfg *configs;
+};
+
+#endif/*__MIAV_MIAV_CONFIG_H__*/
diff --git a/src/mov_encoder.cc b/src/mov_encoder.cc
new file mode 100644
index 0000000..92b2657
--- /dev/null
+++ b/src/mov_encoder.cc
@@ -0,0 +1,207 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 Bent Bisballe
+ * Copyright (C) 2004 B. Stultiens
+ * Copyright (C) 2004 Koen Otter and Glenn van der Meyden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "mov_encoder.h"
+
+//av_alloc_format_context
+//av_destruct_packet_nofree
+
+MovEncoder::MovEncoder(const char *filename)
+{
+ //////////////////// GLOBAL INIT
+ av_register_all();
+
+ //////////////////// ENCODE INIT
+ AVStream *st;
+ AVCodec *enc_codec;
+
+ if(!(efc = av_alloc_format_context())) {
+ fprintf(stderr, "Could not alloc output format context\n");
+ exit(1);
+ }
+
+ efc->oformat = guess_format("mpeg", NULL, NULL);
+ //efc->oformat = guess_format(NULL, filename, NULL);
+
+ if(!(st = av_new_stream(efc, 0))) {
+ fprintf(stderr, "Could not alloc stream\n");
+ switch((int)st) {
+ case AVERROR_UNKNOWN : printf("unknown error\n");
+ break;
+ case AVERROR_IO : printf("i/o error\n");
+ break;
+ case AVERROR_NUMEXPECTED : printf("number syntax expected in filename\n");
+ break;
+ case AVERROR_INVALIDDATA : printf("invalid data found\n");
+ break;
+ case AVERROR_NOMEM : printf("not enough memory\n");
+ break;
+ case AVERROR_NOFMT : printf("unknown format\n");
+ break;
+ case AVERROR_NOTSUPP : printf("operation not supported\n");
+ break;
+ }
+ exit(1);
+ }
+
+ enc_codec = avcodec_find_encoder(CODEC_ID_MPEG2VIDEO);
+ if(!enc_codec) {
+ printf("Unsupported codec for output stream\n");
+ exit(1);
+ }
+ avcodec_get_context_defaults(&st->codec);
+ ecc = &st->codec;
+ ecc->codec_id = CODEC_ID_MPEG2VIDEO;
+ ecc->bit_rate = 8192*1000;
+ ecc->bit_rate_tolerance = 8000*1000;
+ ecc->frame_rate = 25;
+ ecc->frame_rate_base = 1;
+
+ ecc->width = 720;
+ ecc->height = 576;
+ ecc->pix_fmt = PIX_FMT_YUV420P;
+ ecc->gop_size = 0;
+ ecc->mb_decision = FF_MB_DECISION_SIMPLE;
+ ecc->qmin = 2;
+ ecc->qmax = 31;
+ ecc->mb_qmin = 2;
+ ecc->mb_qmax = 31;
+ ecc->max_qdiff = 3;
+ ecc->qblur = 0.5;
+ ecc->qcompress = 0.5;
+ ecc->rc_eq = "tex^qComp";
+ ecc->debug= 0;
+
+ ecc->rc_override_count=0;
+ ecc->rc_max_rate = 0;
+ ecc->rc_min_rate = 0;
+ ecc->rc_buffer_size = 0;
+ ecc->rc_buffer_aggressivity = 1.0;
+ ecc->rc_initial_cplx= 0;
+ ecc->i_quant_factor = -0.8;
+ ecc->b_quant_factor = 1.25;
+ ecc->i_quant_offset = 0.8;
+ ecc->b_quant_offset = 1.25;
+ ecc->dct_algo = 0;
+ ecc->idct_algo = 0;
+ ecc->strict_std_compliance = 0;
+ ecc->me_method = ME_EPZS;
+
+ if(avcodec_open(&st->codec, enc_codec) < 0) {
+ printf("Error while opening codec for stream\n");
+ exit(1);
+ }
+
+ if(url_fopen(&efc->pb, filename, URL_RDWR) < 0) {
+ fprintf(stderr, "Could not open '%s'\n", filename);
+ exit(1);
+ }
+
+ if(av_set_parameters(efc, NULL) < 0) {
+ fprintf(stderr, "%s: Invalid encoding parameters\n", filename);
+ exit(1);
+ }
+
+ dump_format(efc, 0, filename, 1);
+
+ if(av_write_header(efc) < 0) {
+ fprintf(stderr, "Could not write header for output file \n");
+ exit(1);
+ }
+
+ video_buffer = (unsigned char *)av_malloc(VIDEO_BUFFER_SIZE);
+
+ av_init_packet(&epkt);
+
+ epkt.stream_index = efc->streams[0]->index;
+
+ // ecc = &efc->streams[0]->codec;
+
+ //////////////////// DECODE INIT
+ AVCodec *deccodec;
+ // AVCodecContext *dcc= NULL;
+ printf("Video decoding\n");
+
+ /* find the dvvideo decoder */
+ deccodec = avcodec_find_decoder(CODEC_ID_DVVIDEO);
+ if (!deccodec) {
+ fprintf(stderr, "codec not found\n");
+ exit(1);
+ }
+
+ dcc= avcodec_alloc_context();
+
+ /* open it */
+ if (avcodec_open(dcc, deccodec) < 0) {
+ fprintf(stderr, "could not open codec\n");
+ exit(1);
+ }
+}
+
+MovEncoder::~MovEncoder()
+{
+ av_free(video_buffer);
+ url_fclose(&efc->pb);
+}
+
+void MovEncoder::encode(DVFrame *dvframe)
+{
+ int ret;
+ AVFrame *rawframe = avcodec_alloc_frame();
+
+ ///////////////////////// DECODE
+ uint8_t *ptr;
+ int got_picture = 1;
+ int len;
+
+ ptr = (uint8_t *)dvframe->frame;
+ len = sizeof(dvframe->frame);
+
+ ret = avcodec_decode_video(dcc,//&dfc->streams[0]->codec,
+ rawframe, &got_picture, ptr, len);
+
+ if(!ret) {
+ printf("Decoder fuckup!\n");
+ return;
+ }
+
+ ///////////////////////// ENCODE
+
+ ret = avcodec_encode_video(ecc, video_buffer, VIDEO_BUFFER_SIZE, rawframe);
+
+ if(!ret) {
+ printf("MovEncoder fuckup!\n");
+ return;
+ }
+
+ epkt.data = video_buffer;
+ epkt.size = ret;
+
+ if(ecc->coded_frame) epkt.pts = ecc->coded_frame->pts;
+
+ if(ecc->coded_frame && ecc->coded_frame->key_frame) epkt.flags |= PKT_FLAG_KEY;
+
+ av_write_frame(efc, &epkt);
+
+ av_free(rawframe);
+}
diff --git a/src/mov_encoder.h b/src/mov_encoder.h
new file mode 100644
index 0000000..eb67350
--- /dev/null
+++ b/src/mov_encoder.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 Bent Bisballe
+ * Copyright (C) 2004 B. Stultiens
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __RTVIDEOREC_ENCODER_H
+#define __RTVIDEOREC_ENCODER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <avformat.h>
+
+#include <dvframe.h>
+
+#include "util.h"
+
+#define VIDEO_BUFFER_SIZE (1024*1024) // FIXME: One size fits all...
+
+class MovEncoder {
+ public:
+ MovEncoder(const char *filename);
+ ~MovEncoder();
+ void encode(DVFrame *frame);
+
+ private:
+ // Decoder
+ AVFormatContext *dfc;
+ AVCodecContext *dcc;
+
+ // Encoder
+ AVFormatContext *efc;
+ AVCodecContext *ecc;
+ AVPacket epkt;
+ unsigned char *video_buffer;
+ // AVPacket pkt;
+};
+
+#endif
+
diff --git a/src/network.cc b/src/network.cc
new file mode 100644
index 0000000..8e99855
--- /dev/null
+++ b/src/network.cc
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * network.cc
+ *
+ * Wed Nov 3 21:23:14 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "network.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+
+Network::Network(Socket *gs)
+{
+ s = gs;
+}
+
+Network::~Network()
+{
+}
+
+int Network::write(void *buf, int size)
+{
+ if(!s->isConnected()) {
+ fprintf(stderr, "Write attempted to a socket not connected!\n");
+ return 0;
+ }
+ int n = send(s->ssocket, buf, size, MSG_WAITALL);
+
+ if(n == -1) printf("An error occurred!\n");
+
+ // printf("Sent: %s\n", buf);
+
+ return n;
+}
+
+int Network::read(void *buf, int size)
+{
+ if(!s->isConnected()) {
+ fprintf(stderr, "Read attempted from a socket not connected!\n");
+ return 0;
+ }
+ int n = recv(s->ssocket, buf, size, MSG_WAITALL);
+
+ if(n == -1) printf("An error occurred!\n");
+
+ // printf("Recieved: %s\n", buf);
+
+ return n;
+}
+
+/*
+struct msghdr {
+ void *msg_name // Optional address.
+ socklen_t msg_namelen // Size of address.
+ struct iovec *msg_iov // Scatter/gather array.
+ int msg_iovlen // Members in msg_iov.
+ void *msg_control // Ancillary data; see below.
+ socklen_t msg_controllen // Ancillary data buffer len.
+ int msg_flags // Flags on received message.
+};
+*/
+
+int Network::sendPackage(n_header *h, void* buf, int bufsz)
+{
+ struct msghdr msg;
+ struct iovec iovecs[2];
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.msg_iov = iovecs;
+ msg.msg_iovlen = 2;
+
+ msg.msg_iov[0].iov_base = h;
+ msg.msg_iov[0].iov_len = sizeof(*h);
+
+ msg.msg_iov[1].iov_base = buf;
+ msg.msg_iov[1].iov_len = bufsz;
+
+ int n = sendmsg(s->ssocket, &msg, 0);
+ if(n < 0) {
+ perror("sendmsg");
+ return -1;
+ }
+
+ return n;
+}
+
+int Network::recvPackage(n_header *h, void* buf, int bufsz)
+{
+ struct msghdr msg;
+ struct iovec iovecs[2];
+
+ memset(&msg, 0, sizeof(msg));
+
+ iovecs[0].iov_base = h;
+ iovecs[0].iov_len = sizeof(*h);
+
+ iovecs[1].iov_base = buf;
+ iovecs[1].iov_len = bufsz;
+
+ msg.msg_iov = iovecs;
+ msg.msg_iovlen = 2;
+
+ int n = recvmsg(s->ssocket, &msg, MSG_WAITALL);
+
+ if(n < 0) {
+ perror("recvmsg");
+ return -1;
+ }
+
+ if(msg.msg_iovlen != 2) {
+ fprintf(stderr, "Wrong package format!\n");
+ return -1;
+ }
+ return n;
+}
+
diff --git a/src/network.h b/src/network.h
new file mode 100644
index 0000000..72d5826
--- /dev/null
+++ b/src/network.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * network.h
+ *
+ * Wed Nov 3 21:23:14 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#ifndef __MIAVLIB_NETWORK_H__
+#define __MIAVLIB_NETWORK_H__
+
+#include "socket.h"
+#include "package.h"
+
+class Network {
+public:
+ Network(Socket *gs);
+ ~Network();
+
+ // Raw communication
+ int write(void *buf, int size);
+ int read(void *buf, int size);
+
+ // Package communication
+ int sendPackage(n_header *h, void* buf, int bufsz);
+ int recvPackage(n_header *h, void* buf, int bufsz);
+
+private:
+ Socket *s;
+};
+
+#endif/*__NETWORK_H__*/
+
+
diff --git a/src/package.h b/src/package.h
new file mode 100644
index 0000000..db0e5a0
--- /dev/null
+++ b/src/package.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * package.h
+ *
+ * Tue Nov 9 10:57:20 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#ifndef __MIAVLIB_PACKAGE_H__
+#define __MIAVLIB_PACKAGE_H__
+
+typedef enum {
+ DATA_HEADER = 0x0001,
+ INFO_HEADER = 0x0002
+} n_header_type;
+
+typedef struct {
+ n_header_type header_type;
+ union {
+ struct {
+ char cpr[32]; // Can hold wierd cpr numbers as well (not only danish)
+ bool record;
+ bool freeze;
+ bool snapshot;
+ } h_data;
+ struct {
+ int fisk;
+ } h_info;
+ } header;
+} n_header;
+
+
+#endif/*__PACKAGE_H__*/
+
+
diff --git a/src/player.cc b/src/player.cc
new file mode 100644
index 0000000..a860afa
--- /dev/null
+++ b/src/player.cc
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 Bent Bisballe
+ * Copyright (C) 2004 B. Stultiens
+ * Copyright (C) 2004 Koen Otter and Glenn van der Meyden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <config.h>
+#ifdef USE_GUI
+
+#include "player.h"
+
+Player::Player(volatile int *grunning,
+ sem_t *gsem,
+ Queue<FFFrame> *gqueue,
+ pthread_mutex_t *gmutex)
+{
+ running = grunning;
+ sem = gsem;
+ queue = gqueue;
+ mutex = gmutex;
+
+ sem_init(&play_sem, 0, 1);
+
+ if(SDL_Init(SDL_INIT_VIDEO) < 0) {
+ fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
+ exit(1);
+ }
+ screen = SDL_SetVideoMode(DISPLAYWIDTH,
+ DISPLAYHEIGHT,
+ 16,
+ SDL_HWSURFACE|SDL_ANYFORMAT|SDL_HWACCEL);
+ if(!screen) {
+ fprintf(stderr, "Unable to set %dx%d video: %s\n",
+ DISPLAYWIDTH, DISPLAYHEIGHT, SDL_GetError());
+ exit(1);
+ }
+
+ overlay = SDL_CreateYUVOverlay(DISPLAYWIDTH, DISPLAYHEIGHT, SDL_IYUV_OVERLAY, screen);
+}
+
+Player::~Player()
+{
+ if(overlay)
+ SDL_FreeYUVOverlay(overlay);
+ SDL_Quit();
+}
+
+void Player::player()
+{
+ SDL_Event event;
+ SDL_Rect rect;
+ FFFrame *f;
+ AVPicture pict;
+ int i;
+ struct timespec ts;
+
+ // rect.x = 20;
+ // rect.y = 182;
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = DISPLAYWIDTH;
+ rect.h = DISPLAYHEIGHT;
+
+ //+++++Reference to the overlay pixels/pitches, only after creating a new overlay+++++
+ for(i = 0; i < 3; i++) {
+ pict.data[i] = overlay->pixels[i];
+ pict.linesize[i] = overlay->pitches[i];
+ }
+
+ while(*running) {
+ // Wait for the semaphore to be free... then run
+ sem_wait(&play_sem);
+ sem_post(&play_sem);
+
+ if(!SDL_WaitEvent(&event)) break; // FIXME: Gracefull exit...
+
+ switch(event.type) {
+ case SDL_KEYDOWN:
+ switch(event.key.keysym.sym) {
+ case SDLK_q:
+ case SDLK_ESCAPE:
+ goto quitit;
+ default:
+ break;
+ }
+ break;
+
+ case SDL_USEREVENT:
+ pthread_mutex_lock(mutex);
+ f = queue->pop();
+ pthread_mutex_unlock(mutex);
+ if(!f) break;
+
+ img_convert(&pict, PIX_FMT_YUV420P, (AVPicture *)f->frame,
+ PIX_FMT_YUV420P, DISPLAYWIDTH, DISPLAYHEIGHT);
+
+ SDL_LockYUVOverlay(overlay);
+ overlay->pixels = pict.data;
+ SDL_UnlockYUVOverlay(overlay);
+ SDL_DisplayYUVOverlay(overlay, &rect);
+ break;
+
+ case SDL_QUIT:
+ quitit:
+ *running = 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+ /* Remove any late buffer */
+ /* We don't care, the encoder finishes them all */
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100000000L; // 100ms
+ nanosleep(&ts, NULL);
+
+ pthread_mutex_lock(mutex);
+ f = queue->pop();
+ pthread_mutex_unlock(mutex);
+ if(f) delete f;
+}
+
+void Player::run()
+{
+ player();
+}
+
+void Player::start()
+{
+ sem_post(&play_sem);
+}
+
+void Player::stop()
+{
+ sem_wait(&play_sem);
+}
+
+#endif /* USE_GUI */
diff --git a/src/player.h b/src/player.h
new file mode 100644
index 0000000..e33c4e7
--- /dev/null
+++ b/src/player.h
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 Bent Bisballe
+ * Copyright (C) 2004 B. Stultiens
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+#ifdef USE_GUI
+
+#ifndef __RTVIDEOREC_PLAYER_H
+#define __RTVIDEOREC_PLAYER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <semaphore.h>
+#include <pthread.h>
+#include <time.h>
+#include <SDL/SDL.h>
+#include <avformat.h>
+
+#include "util.h"
+#include <queue.h>
+
+#include "thread.h"
+#include "ffframe.h"
+
+#include <qwidget.h>
+
+#define DISPLAYWIDTH 720 /* FIXME: These numbers suck! */
+#define DISPLAYHEIGHT 576
+
+class Player : public Thread {
+ public:
+ Player(volatile int *grunning,
+ sem_t *gsem,
+ Queue<FFFrame> *gqueue,
+ pthread_mutex_t *gmutex);
+ ~Player();
+
+ void start();
+ void stop();
+
+ void run();
+
+ private:
+ void player();
+
+ volatile int *running;
+ sem_t *sem;
+ Queue<FFFrame> *queue;
+ pthread_mutex_t *mutex;
+
+ sem_t play_sem;
+
+ SDL_Surface *screen;
+ SDL_Overlay *overlay;
+};
+
+#endif
+
+#endif /* USE_GUI */
diff --git a/src/queue.h b/src/queue.h
new file mode 100644
index 0000000..7352071
--- /dev/null
+++ b/src/queue.h
@@ -0,0 +1,130 @@
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 Bent Bisballe
+ * Copyright (C) 2004 B. Stultiens
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+#ifndef __RTVIDEOREC_QUEUE_H
+#define __RTVIDEOREC_QUEUE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <avformat.h>
+#include <avcodec.h>
+
+#include "util.h"
+
+typedef struct __buf_t {
+ struct __buf_t *next;
+ struct __buf_t *prev;
+ void *data;
+} buf_t;
+
+
+template<typename T>
+class Queue {
+ public:
+ Queue(int glimit = 0);
+ ~Queue();
+
+ void push(T *t);
+ T *pop();
+
+ private:
+ int limit;
+ buf_t *head;
+ buf_t *tail;
+ int count;
+ pthread_mutex_t mutex;
+};
+
+template<typename T>
+Queue<T>::Queue(int glimit)
+{
+ limit = glimit;
+ count = 0;
+ head = NULL;
+ tail = NULL;
+}
+
+template<typename T>
+Queue<T>::~Queue()
+{
+ if(count != 0) {
+ fprintf(stderr, "Queue not empty (%d)\n", count);
+ while(T *t = pop()) delete t;
+ }
+}
+
+template<typename T>
+void Queue<T>::push(T *t)
+{
+ buf_t *b = (buf_t*)xmalloc(sizeof(*b));
+ b->data = (void*)t;
+
+ assert(b != NULL);
+
+ if(limit && count > 0) {
+ T* tmp = (T*)pop();
+ delete tmp;
+ }
+
+ if(!head) {
+ head = tail = b;
+ b->next = b->prev = NULL;
+ count = 1;
+ return;
+ }
+
+ b->next = tail;
+ b->prev = NULL;
+ if(tail)
+ tail->prev = b;
+ tail = b;
+ count++;
+}
+
+template<typename T>
+T *Queue<T>::pop()
+{
+ T *d;
+ buf_t *b;
+
+ assert(count >= 0);
+
+ if(count == 0)
+ return NULL;
+
+ b = head;
+ if(b->prev)
+ b->prev->next = NULL;
+ head = b->prev;
+ if(b == tail)
+ tail = NULL;
+ count--;
+
+ d = (T*)b->data;
+ free(b);
+ return d;
+}
+
+#endif
+
diff --git a/src/server.cc b/src/server.cc
new file mode 100644
index 0000000..22b691f
--- /dev/null
+++ b/src/server.cc
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * miav-rec.cc
+ *
+ * Mon Nov 8 11:35:01 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "server.h"
+#include "miav.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mov_encoder.h"
+#include "img_encoder.h"
+
+void saveFrameAsImage(char* cpr, DVFrame *f)
+{
+ char fname[256];
+ ImgEncoder imgenc;
+
+ sprintf(fname, "image-%s-%d.jpeg", cpr, rand());
+
+ imgenc.encode(f, fname, 100); // Quality is between 0...100, where 100 is best.
+}
+/*
+struct tm
+{
+ int tm_sec; // Seconds. [0-60] (1 leap second)
+ int tm_min; // Minutes. [0-59]
+ int tm_hour; // Hours. [0-23]
+ int tm_mday; // Day. [1-31]
+ int tm_mon; // Month. [0-11]
+ int tm_year; // Year - 1900.
+ int tm_wday; // Day of week. [0-6]
+ int tm_yday; // Days in year.[0-365]
+ int tm_isdst; // DST. [-1/0/1]
+};
+*/
+
+MovEncoder *newMovEncoder(char* cpr)
+{
+ MovEncoder *enc;
+ struct tm *ltime;
+ 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);
+ enc = new MovEncoder(fname);
+ return enc;
+}
+
+void newConnection(Socket *s)
+{
+ n_header h;
+ DVFrame *f;
+ DVFrame *freeze_frame = NULL;
+ MovEncoder *enc = NULL;
+
+ f = new DVFrame();
+
+ printf("New connection[pid: %d]...\n", getpid());
+
+ Network n = Network(s);
+ while(int ret = n.recvPackage(&h, (void*)f->frame, DVPACKAGE_SIZE)) {
+ if(ret == -1) {
+ fprintf(stderr, "An error occurred...!\n");
+ break;
+ }
+ printf("Read: %d bytes\t", ret);
+ printf("\ttyp: %d\t", h.header_type);
+ 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);
+
+ if(h.header.h_data.snapshot) {
+ if(freeze_frame) {
+ saveFrameAsImage(h.header.h_data.cpr, freeze_frame);
+ delete freeze_frame;
+ freeze_frame = NULL;
+ } else {
+ saveFrameAsImage(h.header.h_data.cpr, f);
+ }
+ }
+
+ if(h.header.h_data.record) {
+ if(!enc) enc = newMovEncoder(h.header.h_data.cpr);
+ enc->encode(f);
+ }
+
+ if(h.header.h_data.freeze) {
+ if(freeze_frame) delete freeze_frame;
+ freeze_frame = f;
+ } else {
+ delete f;
+ }
+
+ f = new DVFrame();
+ }
+ delete f;
+ if(enc) delete enc;
+
+ printf("Connection end[pid: %d]...\n", getpid());
+
+}
+/*
+int main(int argc, char *argv[])
+{
+}
+*/
diff --git a/src/server.h b/src/server.h
new file mode 100644
index 0000000..fd28f33
--- /dev/null
+++ b/src/server.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * server.h
+ *
+ * Mon Nov 8 11:35:01 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SERVER_H__
+#define __SERVER_H__
+
+#include <unistd.h> // Symbolic Constants
+#include <sys/types.h> // Primitive System Data Types
+#include <errno.h> // Errors
+#include <stdio.h> // Input/Output
+#include <sys/wait.h> // Wait for Process Termination
+#include <stdlib.h> // General Utilities
+
+#include <time.h>
+
+#include "dvframe.h"
+#include "socket.h"
+
+void newConnection(Socket *s);
+
+
+#endif/*__SERVER_H__*/
diff --git a/src/socket.cc b/src/socket.cc
new file mode 100644
index 0000000..7cee58a
--- /dev/null
+++ b/src/socket.cc
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * socket.cc
+ *
+ * Mon Nov 8 10:49:33 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+
+#include "socket.h"
+
+Socket::Socket()
+{
+ connected = false;
+ err = 0;
+}
+
+Socket::Socket(u_short port)
+{
+ connected = false;
+ err = 0;
+
+ // printf("Socket on port: %d\n", port);
+
+ // create socket
+ ssocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // PF_INET: ipv4, PF_INET6: ipv6
+ // tcp: IPPROTO_TCP
+ // upd: IPPROTO_UDP
+ if (ssocket < 0) {
+ err = 1;
+ perror("Socket: socket() failed");
+ }
+
+ socketaddr.sin_family = AF_INET; // Use "internet protocol" IP
+ socketaddr.sin_port = htons(port); // connect to that port
+ socketaddr.sin_addr.s_addr = INADDR_ANY;// INADDR_ANY puts your IP address automatically
+
+ // fprintf(stderr, "Socket created\n");
+}
+
+
+Socket::~Socket()
+{
+ // if(err) perror("Socket: No socket to kill");
+ // printf("Socket: I'm melting...[%d]\n", ssocket);
+ if(ssocket >= 0) close(ssocket); // close server socket
+}
+
+
+Socket Socket::slisten()
+{
+ Socket s = Socket();
+
+ if(err) {
+ perror("Socket: No socket present");
+ return s;
+ }
+ if(!connected) {
+ // bind socket to address specified by "sa" parameter
+ err = bind(ssocket, (struct sockaddr*)&socketaddr, sizeof(socketaddr));
+
+ if (err) {
+ perror("Socket: bind() failed");
+ return s;
+ }
+
+ // start listen for connection - kernel will accept connection requests (max 5 in queue)
+ err = listen(ssocket, 5);
+ if(err) {
+ perror("Socket: listen() failed");
+ return s;
+ }
+ }
+
+ // accept new connection and get its connection descriptor
+ int csalen = sizeof(s.socketaddr);
+
+ s.ssocket = accept(ssocket, (struct sockaddr*)&s.socketaddr, (socklen_t*)&csalen);
+ if (s.ssocket < 0) {
+ err = 1;
+ perror("Socket: accept() failed");
+ return s;
+ }
+
+ fprintf(stderr, "Socket connected\n");
+ connected = true;
+ s.connected = true;
+ return s;
+}
+
+
+int Socket::sconnect(char *ip)
+{
+ if(err) {
+ perror("Socket: No socket present");
+ return err;
+ }
+
+ // FIXME: gethostbyname()
+ socketaddr.sin_addr.s_addr = inet_addr(ip);
+ //inet_aton (ip, &socketaddr.sin_addr);
+
+ err = connect(ssocket, (struct sockaddr*)&socketaddr, sizeof(socketaddr));
+ if (err) {
+ perror("Socket: connect() failed");
+ return err;
+ }
+ // fprintf(stderr, "Socket connected\n");
+ connected = true;
+ return 0;
+}
+
+
+bool Socket::isConnected()
+{
+ return connected;
+}
diff --git a/src/socket.h b/src/socket.h
new file mode 100644
index 0000000..d0d85af
--- /dev/null
+++ b/src/socket.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * socket.h
+ *
+ * Mon Nov 8 10:49:33 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#ifndef __MIAVLIB_SOCKET_H__
+#define __MIAVLIB_SOCKET_H__
+
+#include <stdio.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+class Socket {
+public:
+ Socket();
+ Socket(u_short port);
+ ~Socket();
+ Socket slisten();
+ int sconnect(char *ip);
+ bool isConnected();
+
+ struct sockaddr_in socketaddr;
+ int ssocket;
+ bool connected;
+
+private:
+ int err;
+};
+
+#endif/*__SOCKET_H__*/
diff --git a/src/thread.cc b/src/thread.cc
new file mode 100644
index 0000000..c6b4d95
--- /dev/null
+++ b/src/thread.cc
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * thread.cc
+ *
+ * Sun Oct 31 12:12:20 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+
+#include "thread.h"
+#include <stdio.h>
+
+void* thread_run(void *data) {
+ Thread *t = (Thread*)data;
+ t->run();
+ return NULL;
+}
diff --git a/src/thread.h b/src/thread.h
new file mode 100644
index 0000000..ecf0487
--- /dev/null
+++ b/src/thread.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * thread.h
+ *
+ * Sun Oct 31 12:12:20 CET 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#ifndef __THREAD_H__
+#define __THREAD_H__
+
+#include <pthread.h>
+#include <semaphore.h>
+
+class Thread {
+public:
+ Thread() {}
+ virtual ~Thread() {}
+ virtual void run() = 0;
+};
+
+void* thread_run(void *data);
+
+#endif/*__THREAD_H__*/
diff --git a/src/util.cc b/src/util.cc
new file mode 100644
index 0000000..5edf990
--- /dev/null
+++ b/src/util.cc
@@ -0,0 +1,56 @@
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 B. Stultiens
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "util.h"
+
+void *xmalloc(size_t s)
+{
+ void *p;
+ assert(s > 0);
+
+ p = malloc(s);
+ if(!p) {
+ fprintf(stderr, "Out of memory in xmalloc\n");
+ exit(1);
+ }
+ memset(p, 0, s);
+ return p;
+}
+
+void *xrealloc(void *b, size_t s)
+{
+ void *p;
+ assert(s > 0);
+
+ if(!b) return xmalloc(s);
+
+ p = realloc(b, s);
+ if(!p) {
+ fprintf(stderr, "Out of memory in xrealloc\n");
+ exit(1);
+ }
+ return p;
+}
diff --git a/src/util.h b/src/util.h
new file mode 100644
index 0000000..b82b782
--- /dev/null
+++ b/src/util.h
@@ -0,0 +1,36 @@
+/*
+ * RTVideoRec Realtime video recoder and encoder for Linux
+ *
+ * Copyright (C) 2004 B. Stultiens
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+#ifndef __RTVIDEOREC_UTIL_H
+#define __RTVIDEOREC_UTIL_H
+
+//#ifdef __cplusplus
+//extern "C" {
+//#endif
+
+void *xmalloc(size_t s);
+void *xrealloc(void *b, size_t s);
+
+//#ifdef __cplusplus
+//}
+//#endif
+
+#endif
diff --git a/src/videowidget.cc b/src/videowidget.cc
new file mode 100644
index 0000000..64758bd
--- /dev/null
+++ b/src/videowidget.cc
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * videowidget.cc
+ *
+ * Fri Sep 3 14:36:37 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+
+#ifdef USE_GUI
+
+#include "videowidget.h"
+
+VideoWidget::VideoWidget(QWidget *parent) : QWidget(parent, "")
+{
+ // A welltested hack to force SDL to draw in the QWidget
+ QString ids;
+ setenv("SDL_WINDOWID", ids.setNum(winId()), 1);
+}
+
+VideoWidget::~VideoWidget()
+{
+}
+
+QPixmap VideoWidget::getScreenshot()
+{
+ return QPixmap::grabWindow (winId());
+}
+
+#endif /* USE_GUI */
diff --git a/src/videowidget.h b/src/videowidget.h
new file mode 100644
index 0000000..52669ed
--- /dev/null
+++ b/src/videowidget.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * videowidget.h
+ *
+ * Fri Sep 3 14:36:46 2004
+ * Copyright 2004 Bent Bisballe
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+#ifdef USE_GUI
+
+#ifndef __VIDEOWIDGET_H__
+#define __VIDEOWIDGET_H__
+
+#include <qwidget.h>
+#include <qpixmap.h>
+
+class VideoWidget : public QWidget {
+Q_OBJECT
+ public:
+ VideoWidget(QWidget *parent);
+ ~VideoWidget();
+ QPixmap getScreenshot();
+
+ private:
+};
+
+#endif /* __VIDEOWIDGET_H__ */
+
+#endif /* USE_GUI */