diff options
author | deva <deva> | 2005-03-24 12:14:44 +0000 |
---|---|---|
committer | deva <deva> | 2005-03-24 12:14:44 +0000 |
commit | 9466b3042bc7314915a15f499bd0b087f569654d (patch) | |
tree | 29c41f6ba46b9b92d91b92578720e1beee44fc9d /src | |
parent | b5a6a93dcc7a83f5c4f8fd1894e303ae58804e0b (diff) |
Initial revision
Diffstat (limited to 'src')
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 */ |