diff options
Diffstat (limited to 'lib')
38 files changed, 3556 insertions, 0 deletions
| diff --git a/lib/aa_socket.cc b/lib/aa_socket.cc new file mode 100644 index 0000000..28ecead --- /dev/null +++ b/lib/aa_socket.cc @@ -0,0 +1,254 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +#include "aa_socket.h" + +//#include <string.h> + +#include <iostream> +using namespace std; + +#include <unistd.h> +//#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/types.h> +#include <sys/socket.h> + +#include <errno.h> + +#include <netinet/in.h> +#if defined(linux) +#include <endian.h> +#else +#include <sys/endian.h> +#endif /*defined(linux)*/ + +// for gethostbyname +#include <netdb.h> + +// These functions are wrappers, to preserve my nice method naming! +inline int _socket(int a,int b,int c){return socket(a,b,c);}  +inline int _connect(int a,const struct sockaddr *b,socklen_t c){return connect(a,b,c);} +inline int _listen(int a,int b){return listen(a,b);} +inline int _send(int a,char *b,unsigned int c, int d){return send(a,b,c,d);} + + +AASocket::AASocket() +{ +} + +AASocket::~AASocket() +{ +  int err = close(socket);  // close server +	if(err == -1) throw Network_error("close", strerror(errno)); +} + +void AASocket::connect(char *host, unsigned short port) +{ +  // create socket +  socket = _socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);  +  // PF_INET: ipv4, PF_INET6: ipv6 +  // tcp: IPPROTO_TCP +  // upd: IPPROTO_UDP + +  if (socket == -1) throw Network_error("socket", strerror(errno)); + +  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 + + + +	struct hostent *hp = gethostbyname(host); +	//	memcpy(&socketaddr.sin_addr.s_addr, *(hp->h_addr_list),sizeof(struct in_addr)); +	memcpy(&(socketaddr.sin_addr),*(hp->h_addr_list),sizeof(struct in_addr)); + +	// FIXME: gethostbyname() +	//  socketaddr.sin_addr.s_addr = inet_addr(host);  +  //inet_aton (ip, &socketaddr.sin_addr); +   +  int err = _connect(socket, (struct sockaddr*)&socketaddr, sizeof(socketaddr)); +	if(err == -1) throw Network_error("connect", strerror(errno)); +} + +void AASocket::listen(unsigned short port) +{ +	int err; + +	bind_socket = _socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +	if(bind_socket == -1) throw Network_error("tmp socket", strerror(errno)); +	 +	int optval = 1; +	err = setsockopt(bind_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); +	if(err == -1) throw Network_error("setsockopt", strerror(errno)); + +  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 +	 +	// bind socket to address specified by "sa" parameter +	err = bind(bind_socket, (struct sockaddr*)&socketaddr, sizeof(socketaddr)); +	if(err == -1) throw Network_error("bind", strerror(errno)); +	 +	err = _listen(bind_socket, 5); +	if(err == -1) throw Network_error("listen", strerror(errno)); + +  int csalen = sizeof(socketaddr); +  socket = accept(bind_socket,  +									(struct sockaddr*)&socketaddr,  +									(socklen_t*)&csalen); +	if(socket == -1) throw Network_error("accept", strerror(errno)); + +	err = close(bind_socket); // We don't need this anymore +  bind_socket = -1; +	if(err == -1) throw Network_error("tmp close", strerror(errno)); +} + + +void AASocket::force_close() +{ +  if(bind_socket != -1) close(bind_socket); // This should break the accept call +} + + +void AASocket::send(char* buf, unsigned int size) +{ +	//unsigned int newsize = size + sizeof(unsigned int); +	//	char *newbuf = new char[newsize]; + +	unsigned int nsize = htonl(size); +	int n = _send(socket, (char*)&nsize, sizeof(unsigned int), MSG_WAITALL); +	if(n == -1) throw Network_error("send", strerror(errno)); + +	n = _send(socket, buf, size, MSG_WAITALL); +	if(n == -1) throw Network_error("send", strerror(errno)); +} + + +int AASocket::receive(char* buf, unsigned int size) +{ +	unsigned int insize; +	 +	int n = recv(socket, &insize, sizeof(unsigned int), MSG_WAITALL); +	if(n == -1) throw Network_error("recv", strerror(errno)); + +	insize = ntohl(insize); +	if(insize > size) { +		char err_buf[256]; +		sprintf(err_buf, "Buffer is too small. Should be %d is %d." , insize, size); +		throw Network_error("receive", err_buf); +	} +	 +	n = recv(socket, buf, insize, MSG_WAITALL); +	if(n == -1) throw Network_error("recv", strerror(errno)); + +	return n; +} + + +void AASocket::send_string(string str) +{ +	this->send((char*)str.c_str(), str.length()); +} + + +string AASocket::receive_string() +{ +	char buf[1024]; +	memset(buf, 0, sizeof(buf)); + +	receive(buf, sizeof(buf)); + +  return string(buf); +} + + + +#ifdef TEST_SOCKET + +/** + * Test application for AASocket + * It should print the following to stdout: + * A: Hello, how are you? + * B: Fine thanks. + * A: What about you? + * B: I'm fine too. + */ + +#include <sys/types.h> +#include <unistd.h> + +#include <string> +#include <iostream> + +int main() +{ +	char buf[1024]; +	memset(buf, 0, sizeof(buf)); +  int f = fork(); +  switch(f) { +  case -1: // Fork error +    perror("Fork failed!"); +    return 1; + +  case 0:  // Forked child +		{ +			try { +				AASocket out; + +				sleep(1); // Make sure the other end is listening + +				// Test connect +				out.connect("127.0.0.1", 6666); + +				// Test raw communication send +				sprintf(buf, "Hello how are you?"); +				out.send(buf, sizeof(buf)); + +				// Test raw communication receive +				out.receive(buf, sizeof(buf)); +				std::cout << "B: " << buf << std::endl; + +				// Test string receive +				std::string q = out.receive_string(); +				std::cout << "B: " << q << std::endl; + +				// Test string send +				out.send_string(std::string("I'm fine too.")); +				return 0; +			} catch(Network_error e) { +				std::cerr << "Out: " << e.error << std::endl; +			} +		} +  default: // Parent +		{ +			try { +				AASocket in; +				 +				// Test listen +				in.listen(6666); + +				// Test raw communication receive +				in.receive(buf, sizeof(buf)); +				std::cout << "A: " << buf << std::endl; + +				// Test raw communication send +				sprintf(buf, "Fine thanks."); +				in.send(buf, sizeof(buf)); + +				// Test string send +				in.send_string(std::string("What about you?")); + +				// Test string receive	 +				std::string a = in.receive_string(); +				std::cout << "A: " << a << std::endl; +				return 0; +			} catch(Network_error e) { +				std::cerr << "In: " << e.error << std::endl; +			} +		} +	} +	return 0; +} +#endif/*TEST_SOCKET*/ diff --git a/lib/aa_socket.h b/lib/aa_socket.h new file mode 100644 index 0000000..0d02723 --- /dev/null +++ b/lib/aa_socket.h @@ -0,0 +1,42 @@ +#ifndef __SOCKET_H__ +#define __SOCKET_H__ + +#include <string> + +#include <netinet/in.h> +//#include <sys/socket.h> + + +/** + * Exceptions + */ +struct Network_error { +	Network_error(char *event, char *err) { +		error = std::string(err) + " - in " + std::string(event); +	} +	std::string error; +}; + +class AASocket { +public: +  AASocket(); +  ~AASocket(); + +  void listen(unsigned short port); +  void connect(char *ip, unsigned short port); +   +  void send(char* buf, unsigned int buf_size); +  int receive(char* buf, unsigned int buf_size); + +  void send_string(std::string buf); +  std::string receive_string(); + +	void force_close(); + +private: +  struct sockaddr_in socketaddr; +  int socket; +	int bind_socket; // Tmp socket for listen. +}; + +#endif/*__SOCKET_H__*/ diff --git a/lib/config.h b/lib/config.h new file mode 100644 index 0000000..e7101c9 --- /dev/null +++ b/lib/config.h @@ -0,0 +1,33 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            config.h + * + *  Thu Jul 28 12:46:38 CEST 2005 + *  Copyright  2004 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + *    This file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; if not, write to the Free Software + *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ + +#ifndef __CONFIG_IS_LOADED__ +#define __CONFIG_IS_LOADED__ + +#include "../config.h" + +#endif/*__CONFIG_IS_LOADED__*/ diff --git a/lib/daemon.cc b/lib/daemon.cc new file mode 100644 index 0000000..6e46bd5 --- /dev/null +++ b/lib/daemon.cc @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            daemon.cc + * + *  Thu Jun  9 10:27:59 CEST 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 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 "daemon.h" + +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> + +// For getgrent and getgrent +#include <sys/types.h> +#include <grp.h> +#include <pwd.h> + +// For strcmp +#include <string.h> + +Daemon::Daemon() +{} + +Daemon::~Daemon() +{} + +int Daemon::run(const char *user, const char* group) +{ +  int f; +  int fd; + +  // Fetch user id +  int uid = -1; +  struct passwd *p = getpwent(); +  while(p) { +    if(strcmp(p->pw_name, user) == 0) uid = p->pw_uid; +    p = getpwent(); +  } +  if(uid == -1) { +    fprintf(stderr, "Could not find user \"%s\" in /etc/passwd file.\n", user); +  } + +  // Fetch group id +  int gid = -1; +  struct group *g = getgrent(); +  while(g) { +    if(strcmp(g->gr_name, group) == 0) gid = g->gr_gid; +    g = getgrent(); +  } +  if(gid == -1) { +    fprintf(stderr, "Could not find group \"%s\" in /etc/group file.\n", group); +  } + +  chdir("/"); +  umask(0); + +  f = fork(); +  switch(f) { +  case -1: // Fork error +    perror("Fork in daemon.cc"); +    return 1; + +  case 0:  // Forked child +    // Switch to given group +    if(setgid(gid) != 0) { +      fprintf(stderr, "Failed to change to group \"%s\" (gid: %d), quitting.\n", group, gid); +      perror(""); +      fprintf(stderr, "Runnning daemon as current group\n"); +    } +     +    // Switch to given user +    if(setuid(uid) != 0) { +      fprintf(stderr, "Failed to change to user \"%s\" (uid: %d), quitting.\n", user, uid); +      perror(""); +      fprintf(stderr, "Runnning daemon as current user\n"); +    } +     +    // Redirect stdin, stdout and stderr to /dev/null +    fd = open("/dev/null", O_NOCTTY | O_RDWR, 0666); + +    dup2(0, fd); +    dup2(1, fd); +    dup2(2, fd); +     +    setsid(); + +    signal (SIGTERM, SIG_IGN); +    signal (SIGINT, SIG_IGN); +    signal (SIGHUP, SIG_IGN); + +    return daemon_main(); + +  default: // Parent +    // exit(0); +    return 0; +  } +} diff --git a/lib/daemon.h b/lib/daemon.h new file mode 100644 index 0000000..1bd663e --- /dev/null +++ b/lib/daemon.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            daemon.h + * + *  Thu Jun  9 10:27:59 CEST 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 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 __DAEMON_H__ +#define __DAEMON_H__ + +#include <sys/types.h> + +class Daemon { +public: +  Daemon(); +  virtual ~Daemon(); +   +  /** +   * Use NOBODY_GROUP and NOBODY_USER if no privileges are needed to run. +   */ +  int run(const char* user, const char* group); + +private: +  virtual int daemon_main() = 0; +}; + +#endif/*__DAEMON_H__*/ diff --git a/lib/file.cc b/lib/file.cc new file mode 100644 index 0000000..3a59334 --- /dev/null +++ b/lib/file.cc @@ -0,0 +1,240 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            file.cc + * + *  Thu Jun  9 15:31:38 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include <config.h> +#include "file.h" + +#include "miav_config.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +#include <errno.h> + +// For ntoh* +#include <netinet/in.h> + +#include <stdlib.h> + +File::File(char *fn, char* ext, Info *i) +{ +  char path[256]; + +  info = i; + +  savestate = SAVE; + +  filename = new char[strlen(fn) + 1]; +  extension = new char[strlen(ext) + 1]; + +  strcpy(filename, fn); +  strcpy(extension, ext); + +  num = 0; +  seqnum = 0; +  fd = -1; +   +  int pos = (int)strrchr(filename, '/'); +  memset(path, 0, sizeof(path)); + +  if(pos) { // pos is NULL, a file will be created in the current dir (Which is bad) +    pos -= (int)filename; // Make pos relative to the beginning of the string +    strncpy(path, filename, pos); +    createPath(path); +  } + +  Open(); +} + +File::~File() +{ +  close(fd); + +  info->info("This session contains the following files..."); +  for(unsigned int cnt = 0; cnt < filelist.size(); cnt ++) { +    info->info("[%s]", filelist[cnt].c_str()); +  } + +  std::string *trash = config->readString("server_trash"); +  std::string *later = config->readString("server_later"); + +  switch(savestate) { +  case NO_CHANGE: +    info->warn("File had no savestate!"); +    break; + +  case SAVE: +    info->info("Files in this session is to be saved."); +    break; + +  case DELETE: +    info->info("Files in this session is to be deleted (moved to trash)."); +    Move((char*)trash->c_str()); +    break; + +  case LATER: +    info->info("Files in this session is stored for later decisson."); +    Move((char*)later->c_str()); +    break; +  } + +  delete filename; +  delete extension; +} + +int File::Move(char *destination) +{ +  char newfile[256]; +  char filename[256]; + +  createPath(destination); +  for(unsigned int cnt = 0; cnt < filelist.size(); cnt ++) { +    // TODO: Check is the file exists... if not make som noise! +     + +    // TODO: Move file filelist[cnt] to the destination folder. +    strcpy(filename, (char*)filelist[cnt].c_str()); +    sprintf(newfile, "%s%s", destination, strrchr(filename, '/')); +    if(rename((char*)filelist[cnt].c_str(), newfile) == -1) +      info->error("Error moving file %s to %s:",  +                  (char*)filelist[cnt].c_str(), +                  newfile, +                  strerror(errno)); +  } +  return 0; +} + +int File::Open() +{ +  char fname[256]; + +  if(fd != -1) { +    close(fd); +    fd = -1; +  } + +  while(fd == -1) { +    if(seqnum) { +      // A sequence number > 0 +      sprintf(fname, "%s%.3d-%d.%s", filename, num, seqnum, extension); +    } else { +      // A sequence number of 0 +      sprintf(fname, "%s%.3d.%s", filename, num, extension); +    } +    fd = open(fname, O_CREAT | O_WRONLY | O_ASYNC | O_EXCL, //| O_LARGEFILE +              S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +    if(fd == -1) num ++; + +    // If more than 100 files are created in one day, something is terribly wrong! +    if(num > 100) { +      info->error("Something is wrong with the path [%s]!", fname); +      exit(1); +    } + +  } + +  std::string filename_string(fname); +  filelist.push_back(filename_string); + +  seqnum ++; + +  info->info("Output file: %s", fname); + +  return 0; +} + +int File::Write(void* data, int size) +{ +  int w; + +  w = write(fd, data, size); + +  if(w != size) { +    info->info("Wrapping file."); +    Open(); +    w = write(fd, data, size); +    if(w != size) { +      info->error("Out of diskspace!"); +      return -1; +    } +  } + +  return w; +} + +int File::createPath(char* path) +{ +  //  struct stat stats; +  char *subpath; + +  subpath = (char*)calloc(strlen(path) + 1, 1); + +  strcpy(subpath, path); + +  subpath[strrchr(subpath, '/') - subpath] = '\0'; +   +  if(strlen(subpath) > 0) createPath(subpath); + +  info->info("Checking and/or generating directory: %s", path); + +  //  stat(path, &stats); +  //if(!S_ISDIR(stats.st_mode) && S_ISREG(stats.st_mode))  +  mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH); +  // TODO: Check for creation errors! + +  free(subpath); +   +  return 0; +} + +void File::setSaveState(n_savestate s) +{ +  savestate = s; +  info->info("SETTING SAVESTATE TO: %d", savestate); +} + +#ifdef __TEST_FILE +#include "info_simple.h" + +int main(int argc, char *argv[]) { +  if(argc < 3) { +    fprintf(stderr, "usage:\n\ttest_file [filename] [extension]\n"); +    return 1; +  } + + +  InfoSimple info; +  File file(argv[1], argv[2], &info); + +  unsigned int val = 0x01234567; +  file.Write(val); + +} + +#endif/* __TEST_FILE*/ diff --git a/lib/file.h b/lib/file.h new file mode 100644 index 0000000..04947df --- /dev/null +++ b/lib/file.h @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            file.h + * + *  Thu Jun  9 15:31:38 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#ifndef __MIAV_FILE_H__ +#define __MIAV_FILE_H__ + +#include "info.h" +#include <stdio.h> + +#include <vector> +#include <string> + +#include <string.h> + +// For savestate_n +#include "package.h" + +class File { +public: +  File(char *filename, char* ext, Info* info); +  ~File(); + +  int Write(void* data, int size); +  /* +  int Write(char* data, int size); + +  int Write(unsigned long long int val); +  int Write(long long int val); +  int Write(long int val); +  int Write(unsigned long int val); +  int Write(int val); +  int Write(unsigned int val); +  int Write(short int val); +  int Write(unsigned short int val); +  */ + +  void setSaveState(n_savestate savestate); + +private: +  volatile n_savestate savestate; +  Info* info; + +  std::vector<std::string> filelist; + +  int Open(); + +  int Move(char *destination); + +  int fd; + +  int num; +  int seqnum; + +  char* filename; +  char* extension; + +  int createPath(char* path); +}; + +#endif/*__MIAV_FILE_H__*/ diff --git a/lib/frame.cc b/lib/frame.cc new file mode 100644 index 0000000..a274d89 --- /dev/null +++ b/lib/frame.cc @@ -0,0 +1,52 @@ +/* -*- 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 file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; if not, write to the Free Software + *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include <config.h> +#include "frame.h" + +#include "debug.h" + +#include <memory.h> +#include <stdlib.h> + +Frame::Frame(unsigned char *d, int sz) +{ +  if(sz) data = new unsigned char[sz]; +  if(sz && d) memcpy(data, d, sz); +  size = sz; +  number = 0; +  memset(timecode, 0, sizeof(timecode)); + +  endOfFrameStream = false; +} + +Frame::~Frame() +{ +  delete data; +  data = NULL; +  size = 0; +} + diff --git a/lib/frame.h b/lib/frame.h new file mode 100644 index 0000000..988f460 --- /dev/null +++ b/lib/frame.h @@ -0,0 +1,58 @@ +/* -*- 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 file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; if not, write to the Free Software + *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#ifndef __FRAME_H__ +#define __FRAME_H__ + +// Definition of vector +#include <vector> + +class Frame { +public: +  Frame(unsigned char *d, int sz); +  ~Frame(); +   +  unsigned char *data; +  unsigned int size; + +  unsigned int number; + +  unsigned int bitrate; + +  bool mute; + +  bool shoot; +  int freeze; // 1 is freeze, -1 is unfreeze +  bool record; +  char timecode[12]; + +  bool endOfFrameStream; +}; + +typedef std::vector< Frame* > FrameVector; + +#endif/*__FRAME_H__*/ diff --git a/lib/frame_stream.h b/lib/frame_stream.h new file mode 100644 index 0000000..bc0b9a2 --- /dev/null +++ b/lib/frame_stream.h @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            frame_stream.h + * + *  Thu Jul 28 17:15:27 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#ifndef __MIAV_FRAME_STREAM_H__ +#define __MIAV_FRAME_STREAM_H__ + +class frame_stream { +public: +  frame_stream() {} +  virtual ~frame_stream() {} + +  virtual unsigned char *readFrame() = 0; +}; + + +#endif/*__MIAV_FRAME_STREAM_H__*/ +   diff --git a/lib/info.cc b/lib/info.cc new file mode 100644 index 0000000..701a705 --- /dev/null +++ b/lib/info.cc @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            info.cc + * + *  Mon Jun 13 22:16:18 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include <config.h> +#include "info.h" + +#include <time.h> + +Info::Info() { +  pthread_mutex_init (&mutex, NULL); +} + +void Info::log(char *fmt, ...) +{ +  //  const time_t t; +  FILE *fp; +  char buf[1024]; +   +  pthread_mutex_lock(&mutex); +  // Beginning of safezone +   +  fp = fopen(log_filename.c_str(), "a"); +  if(!fp) { +    fprintf(stderr, "Log file %s could not be opened in writemode.\n", log_filename.c_str()); +    return; +  } +   +  va_list argp; +  va_start(argp, fmt); +  vsprintf(buf, fmt, argp); +  va_end(argp); +   +  time_t t = time(NULL); +  char sdate[32]; +  memset(sdate, 0, sizeof(sdate)); +  strftime(sdate, sizeof(sdate), "%d %b %H:%M:%S", localtime(&t)); + +  fprintf(fp, "%s miav[%d] %s\n", sdate, getpid(), buf); +  //  fprintf(stderr, "%s miav[%d] %s\n", sdate, getpid(), buf); +   +  fclose(fp); +   +  // End of safezone +  pthread_mutex_unlock(&mutex); +} diff --git a/lib/info.h b/lib/info.h new file mode 100644 index 0000000..d533051 --- /dev/null +++ b/lib/info.h @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            info.h + * + *  Tue May  3 09:04:04 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + *    This file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; if not, write to the Free Software + *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#ifndef __MIAV_INFO_H__ +#define __MIAV_INFO_H__ + +#include "miav_config.h" +// Cyclic include :( +class MiavConfig; + +#include <time.h> +#include <sys/types.h> +#include <unistd.h> +#include <stdarg.h> +#include <pthread.h> +#include <semaphore.h> +#include <string> +using namespace std; + +class Info { +public: +  Info(); +  virtual ~Info() {} + +  virtual void error(char* fmt, ...) = 0; +  virtual void warn(char* fmt, ...) = 0; +  virtual void info(char* fmt, ...) = 0; +  void log(char* fmt, ...); + +protected: +  MiavConfig *config; + +  pthread_mutex_t mutex; +  string log_filename; +}; + +#endif/*__MIAV_INFO_H__*/ diff --git a/lib/info_simple.cc b/lib/info_simple.cc new file mode 100644 index 0000000..a3db393 --- /dev/null +++ b/lib/info_simple.cc @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            info_simple.cc + * + *  Tue Sep 20 17:00:25 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#include "info_simple.h" + +#include <stdio.h> +#include <stdarg.h> + +InfoSimple::InfoSimple(): Info() +{ +} + +InfoSimple::~InfoSimple() +{ +  pthread_mutex_destroy(&mutex); +} + +void InfoSimple::error(char *fmt, ...) +{ +  char buf[1024]; + +  pthread_mutex_lock(&mutex); +  // Beginning of safezone + +	va_list argp; +	va_start(argp, fmt); +	vsprintf(buf, fmt, argp); +	va_end(argp); + +  // End of safezone +  pthread_mutex_unlock(&mutex); + +  fprintf(stderr, "Error: %s\n", buf); +} + +void InfoSimple::warn(char *fmt, ...) +{ +  char buf[1024]; + +  pthread_mutex_lock(&mutex); +  // Beginning of safezone + +	va_list argp; +	va_start(argp, fmt); +	vsprintf(buf, fmt, argp); +	va_end(argp); + +  // End of safezone +  pthread_mutex_unlock(&mutex); + +  fprintf(stderr, "Warning: %s\n", buf); +} + +void InfoSimple::info(char *fmt, ...) +{ +  char buf[1024]; + +  pthread_mutex_lock(&mutex); +  // Beginning of safezone + +	va_list argp; +	va_start(argp, fmt); +	vsprintf(buf, fmt, argp); +	va_end(argp); + +  // End of safezone +  pthread_mutex_unlock(&mutex); + +  fprintf(stderr, "Info: %s\n", buf); +} diff --git a/lib/info_simple.h b/lib/info_simple.h new file mode 100644 index 0000000..302a371 --- /dev/null +++ b/lib/info_simple.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            info_simple.h + * + *  Tue Sep 20 17:00:25 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#ifndef __MIAV_INFO_SIMPLE_H__ +#define __MIAV_INFO_SIMPLE_H__ + +#include "info.h" + +class InfoSimple: public Info { +public: +  InfoSimple(); +  ~InfoSimple(); + +  void error(char* fmt, ...); +  void warn(char* fmt, ...); +  void info(char* fmt, ...); + +private: +}; + +#endif/*__MIAV_INFO_SIMPLE_H__*/ diff --git a/lib/jpeg_mem_dest.cc b/lib/jpeg_mem_dest.cc new file mode 100644 index 0000000..439c9a8 --- /dev/null +++ b/lib/jpeg_mem_dest.cc @@ -0,0 +1,137 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            jpeg_mem_dest.cc + * + *  Thu Jul 28 16:40:08 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include <config.h> +#include "jpeg_mem_dest.h" + +#define OUTPUT_BUF_SIZE  4096	/* choose an efficiently ?? size */ + +/* Expanded data destination object for stdio output */ +typedef struct { +  struct jpeg_destination_mgr pub; /* public fields */ + +  JOCTET * outbuff;		/* target buffer */ +  size_t * size; +} mem_destination_mgr; + +typedef mem_destination_mgr * mem_dest_ptr; + +/* + * Initialize destination --- called by jpeg_start_compress + * before any data is actually written. + */ +void init_destination (j_compress_ptr cinfo) +{ +  mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; + +  *dest->size = 0; +  dest->pub.next_output_byte = dest->outbuff; +  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} + +/* + * Terminate destination --- called by jpeg_finish_compress + * after all data has been written.  Usually needs to flush buffer. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ +void term_destination (j_compress_ptr cinfo) +{ +  mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; +  size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + +  /* Write any data remaining in the buffer */ +  if (datacount > 0) { +    dest->outbuff+=datacount; +    *dest->size+=datacount; +  } +} + +/* + * Empty the output buffer --- called whenever buffer fills up. + * + * In typical applications, this should write the entire output buffer + * (ignoring the current state of next_output_byte & free_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been dumped. + * + * In applications that need to be able to suspend compression due to output + * overrun, a FALSE return indicates that the buffer cannot be emptied now. + * In this situation, the compressor will return to its caller (possibly with + * an indication that it has not accepted all the supplied scanlines).  The + * application should resume compression after it has made more room in the + * output buffer.  Note that there are substantial restrictions on the use of + * suspension --- see the documentation. + * + * When suspending, the compressor will back up to a convenient restart point + * (typically the start of the current MCU). next_output_byte & free_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point will be regenerated after resumption, so do not + * write it out when emptying the buffer externally. + */ +boolean empty_output_buffer (j_compress_ptr cinfo) +{ +  mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; + +  dest->outbuff+=OUTPUT_BUF_SIZE; +  *dest->size+=OUTPUT_BUF_SIZE; + +  dest->pub.next_output_byte = dest->outbuff; +  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + +  return TRUE; +} + +/* + * Prepare for output to a memory buffer. + . The caller must have already allocated the buffer, and is responsible + * for closing it after finishing compression. + */ +void jpeg_mem_dest (j_compress_ptr cinfo, char * outbuff, size_t * size) +{ +  mem_dest_ptr dest; + +  /* The destination object is made permanent so that multiple JPEG images +   * can be written to the same file without re-executing jpeg_stdio_dest. +   * This makes it dangerous to use this manager and a different destination +   * manager serially with the same JPEG object, because their private object +   * sizes may be different.  Caveat programmer. +   */ +  if (cinfo->dest == NULL) {	/* first time for this JPEG object? */ +    cinfo->dest = (struct jpeg_destination_mgr *) +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, +				  sizeof(mem_destination_mgr)); +  } + +  dest = (mem_dest_ptr) cinfo->dest; +  dest->pub.init_destination = init_destination; +  dest->pub.empty_output_buffer = empty_output_buffer; +  dest->pub.term_destination = term_destination; +  dest->outbuff = (JOCTET *)outbuff; +  dest->size = (size_t *)size; +} diff --git a/lib/jpeg_mem_dest.h b/lib/jpeg_mem_dest.h new file mode 100644 index 0000000..b1ff103 --- /dev/null +++ b/lib/jpeg_mem_dest.h @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            jpeg_mem_dest.h + * + *  Thu Jul 28 16:40:08 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +//#include "config.h" +#ifndef __MIAV_JPEG_MEM_DEST_H__ +#define __MIAV_JPEG_MEM_DEST_H__ + +#include <stdio.h> + +extern "C" { +#include <jpeglib.h> +} + +void jpeg_mem_dest (j_compress_ptr cinfo, char * outbuff, size_t * size); + +#endif/*__MIAV_JPEG_MEM_DEST_H__*/ diff --git a/lib/miav_config.cc b/lib/miav_config.cc new file mode 100644 index 0000000..adfa5c5 --- /dev/null +++ b/lib/miav_config.cc @@ -0,0 +1,492 @@ +/* -*- 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 file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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 *config; + +MiavConfig::MiavConfig(char *file, Info *i) +{ +  info = i; +  configs = NULL; +   +  filename = string(file); + +  // Read config file +  FILE* fp = fopen(file, "r"); +   +  if(!fp) { +    if(info) info->error("Error reading configuration file %s\n", file); +    else fprintf(stderr, "Error reading configuration file %s\n", file); +    return; +  } +  fseek(fp, 0, SEEK_END); +  int fsz = ftell(fp) + 1; +  fseek(fp, 0, SEEK_SET); +   +  char *raw = (char*)calloc(fsz, 1); +  fread(raw, 1, fsz, fp); + +  fclose(fp); + +  configs = parse(raw); + +  free(raw); +} + +MiavConfig::~MiavConfig() +{ +  _cfg *die = NULL; +  _cfg *cfg = configs; + +  while(cfg) { +    if(die) free(die); +    die = cfg; +    cfg = cfg->next; +  } +  if(die) free(die); +} + +/** + * Prints a reasonable error message when a parse error occurres. + */ +void MiavConfig::parseError(char* msg, _cfg* cfg) +{ +  if(info) info->error("Error parsing file %s at line %d:\n\t%s\n\t%s\n",  +                       filename.c_str(),  +                       cfg->line, +                       cfg->orig, +                       msg); +  else fprintf(stderr, "Error parsing file %s at line %d:\n\t%s\n\t%s\n", +               filename.c_str(),  +               cfg->line, +               cfg->orig, +               msg); +} + +_cfg* MiavConfig::readLines(char* raw) +{ +  int line = 1; +   +  _cfg *first = (_cfg*)calloc(1, sizeof(_cfg)); +  _cfg *current = first; +  _cfg *next = NULL; + +  char *nl = strchr(raw, '\n'); + +  while(nl != NULL) { +    int len = nl - raw; + +    current->line = line; + +    current->orig = (char*) calloc(len + 1, 1); +    strncpy(current->orig, raw, len); + +    // Find next newline +    raw = nl+1; +    nl = strchr(raw, '\n'); + +    line++; + +    // Add _cfg +    if(nl != NULL) { +      next = (_cfg*)calloc(1, sizeof(_cfg)); +      current->next = next; +      current = next; +    } else { +      current->next = NULL; +    } +  } + +  return first; +} + +_cfg* MiavConfig::parseLines(_cfg *cfg) +{ +  if(cfg == NULL) return NULL; + +  char *l = cfg->left = (char*)calloc(1, strlen(cfg->orig)); +  char *r = cfg->right = (char*)calloc(1, strlen(cfg->orig)); + +  char *p = cfg->orig; + +  // Skip leftmost whitespace +  while(p < cfg->orig + strlen(cfg->orig) && strchr("\t ", *p)) { +    p++; +  } + +  // Empty line, with whitespaces +  if(p == cfg->orig + strlen(cfg->orig)) { +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next); +  } + +  // Parse left side +  while(p < cfg->orig + strlen(cfg->orig) && !strchr("\t ", *p)) { +    if(strchr("#", *p)) { +      if(l != cfg->left) parseError("Incomplete line.", cfg); +      _cfg* next = cfg->next; +      free(cfg->orig); +      free(cfg->left); +      free(cfg->right); +      free(cfg); +      return parseLines(next); +    } + +    if(strchr("=", *p)) break; + +    if(strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_", *p)) { +      *l = *p; +      l++; +    } else { +      char buf[256]; +      sprintf(buf, "Invalid left hand side character at [%s].", p); +      parseError(buf, cfg); +      _cfg* next = cfg->next; +      free(cfg->orig); +      free(cfg->left); +      free(cfg->right); +      free(cfg); +      return parseLines(next); +    } + +    p++; +  } + +  // Skip whitespace +  while(p < cfg->orig + strlen(cfg->orig) && strchr("\t ", *p)) { +    p++; +  } + +  if(*p != '=') { +     parseError("Expected '='.", cfg); +      _cfg* next = cfg->next; +      free(cfg->orig); +      free(cfg->left); +      free(cfg->right); +      free(cfg); +      return parseLines(next); +  } +  p++; // Get past the '=' + +  // Skip whitespace +  while(p < cfg->orig + strlen(cfg->orig) && strchr("\t ", *p)) { +    p++; +  } + +  // Parse right hand side +  int instring = 0; +  while(p < cfg->orig + strlen(cfg->orig) && !(strchr("\t ", *p) && instring != 1)) { +    if(*p == '\"') instring++; +    if(instring > 2) { +      parseError("Too many '\"'.", cfg); +      _cfg* next = cfg->next; +      free(cfg->orig); +      free(cfg->left); +      free(cfg->right); +      free(cfg); +      return parseLines(next); +    }  +     +    if(instring == 1) { +      // Accept all chars +      *r= *p; +      r++; +    } else { +      // Accept only those chars valid for the data types. +      if(strchr("truefalseyesnoTRUEFALSEYESNO1234567890\",.-", *p)) { +        if(*p == ',') *r= '.'; +        *r = *p; +        r++; +      } else if(!strchr("\n", *p)) { +        char buf[256]; +        sprintf(buf, "Invalid right hand side character at [%s].", p); +        parseError(buf, cfg); +        _cfg* next = cfg->next; +        free(cfg->orig); +        free(cfg->left); +        free(cfg->right); +        free(cfg); +        return parseLines(next); +      } +      if(*p == '#') break; +    } + +    p++; +  } + +  // Skip whitespace +  while(p < cfg->orig + strlen(cfg->orig) && strchr("\t ", *p)) { +    p++; +  } + +  // Detect if whitespace ocurred inside righthand value. +  if(p != cfg->orig + strlen(cfg->orig)) { +    parseError("Invalid use of whitespace.", cfg); +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next); +  } + +  // Check for instring (string not ended) +  if(instring == 1) { +    parseError("String not closed.", cfg); +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next); +  } + +  // Check for empty line +  if(l == cfg->left && r == cfg->right) { +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next); +  } + +  // Check for empty left side. +  if(l == cfg->left) { +    parseError("Empty left side.", cfg); +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next); +  } + +  // Check for empty right side. +  if(r == cfg->right) { +    parseError("Empty right side.", cfg); +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next); +  } + +  cfg->next = parseLines(cfg->next); +  return cfg; +} + + +_cfg *MiavConfig::createSemantics(_cfg *cfg) { +  if(cfg == NULL) return NULL; + +  cfg->type = CONFIG_UNKNOWN; + +  // Boolean - true +  if(strcasecmp(cfg->right, "yes") == 0 || +     strcasecmp(cfg->right, "true")  == 0) { +    cfg->type = CONFIG_BOOL; +    cfg->boolval = true; +  } + +  // Boolean - false +  if(strcasecmp(cfg->right, "no") == 0 || +     strcasecmp(cfg->right, "false") == 0) { +    cfg->type = CONFIG_BOOL; +    cfg->boolval = false; +  } + +  // String +  if(cfg->right[0] == '\"') { +    cfg->type = CONFIG_STRING; +    cfg->right[strlen(cfg->right) - 1] = '\0'; +    cfg->stringval = new string(cfg->right + 1); +     +  } + +  // Number +  bool number = true; +  char *p = cfg->right; +  while(p < cfg->right + strlen(cfg->right)) { +    if(!strchr("01234567890.-", *p)) number = false; +    p++; +  } +     +  // Integer +  if(number && strstr(cfg->right, ".") == NULL ) { +    cfg->type = CONFIG_INT; +    cfg->intval = atoi(cfg->right); +  } + +  // Float +  if(number && strstr(cfg->right, ".") != NULL) { +    cfg->type = CONFIG_FLOAT; +    cfg->floatval = atof(cfg->right); +  } + +  if(cfg->type == CONFIG_UNKNOWN) { +    parseError("Unknown type (see 'man miav.conf' for valid right hand sides).", cfg); +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return createSemantics(next); +  } + +  // Create name +  cfg->name = new string(cfg->left); + +  cfg->next = createSemantics(cfg->next); +  return cfg; +} + + +_cfg* MiavConfig::parse(char* raw) +{ +  _cfg *first = readLines(raw); +  first = parseLines(first); + +  first = createSemantics(first); + +  /* +  _cfg* cfg = first; +  while(cfg) { +    printf("Node:\n"); +    printf("\tLine: [%d]\n", cfg->line); +    printf("\tOrig: [%s]\n", cfg->orig); +    printf("\tLeft: [%s]\n", cfg->left); +    printf("\tRight: [%s]\n", cfg->right); + +    switch(cfg->type) { +    case CONFIG_INT: +      printf("\tInt value: %d\n", cfg->intval); +      break; +    case CONFIG_BOOL: +      printf("\tBool value: %d\n", cfg->boolval); +      break; +    case CONFIG_FLOAT: +      printf("\tFloat value: %f\n", cfg->floatval); +      break; +    case CONFIG_STRING: +      printf("\tString value: %s\n", cfg->stringval->c_str()); +      break; +    case CONFIG_UNKNOWN: +      printf("\tUnknown type: %s\n", cfg->right); +      break; +    } + +    cfg= cfg->next; +  } +  */ +  return first; +} + +int MiavConfig::readInt(char *node) +{ +  _cfg* n = findNode(node); +  if(n) { +    if(n->type == CONFIG_INT) return n->intval; +    parseError("Expected integer.", n); +  } +  return 0; +} + +bool MiavConfig::readBool(char *node) +{ +  _cfg* n = findNode(node);  +  if(n) { +    if(n->type == CONFIG_BOOL) return n->boolval; +    if(n->type == CONFIG_INT) return (n->intval != 0); +    parseError("Expected boolean.", n); +  } +  return false; +} + +string *MiavConfig::readString(char *node) +{ +  _cfg* n = findNode(node); +  if(n) { +    if(n->type == CONFIG_STRING) return n->stringval; +    parseError("Expected string.", n); +  } +  return &emptyString; +} + +float MiavConfig::readFloat(char *node) +{ +  _cfg* n = findNode(node); +  if(n) { +    if(n->type == CONFIG_FLOAT) return n->floatval; +    if(n->type == CONFIG_INT) return (float)n->intval; +    parseError("Expected float.", n); +  } +  return 0.0f; +} + +_cfg *MiavConfig::findNode(char* node) +{ +  _cfg *cfg = configs; + +  while(cfg) { +    if(!strcmp(node, cfg->name->c_str())) return cfg; +    cfg = cfg->next; +  } +  if(info) info->error("Missing line in configuration file: \"%s\"!\n", node); +  else fprintf(stderr, "Missing line in configuration file: \"%s\"!\n", node); + +  return NULL; +} + +#ifdef __TEST_MIAV_CONFIG + +int main(int argc, char *argv[]) { +  if(argc < 2) { +    fprintf(stderr, "usage:\n\tmiav_config [filename]\n"); +    return 1; +  } + +  MiavConfig cfg(argv[1]); +  printf("Server user: [%s]\n", cfg.readString("server_user")->c_str()); +  printf("Resolution: [%f]\n", cfg.readFloat("screensize")); +  printf("Resolution (as int): [%d]\n", cfg.readInt("screensize")); +  printf("Width: [%d]\n", cfg.readInt("pixel_width")); +  printf("Width (as float): [%f]\n", cfg.readFloat("pixel_width")); +  printf("Frame quality: [%d]\n", cfg.readInt("frame_quality")); +  printf("Skip frames: [%d]\n", cfg.readBool("player_skip_frames")); +  printf("Skip frames (as int): [%d]\n", cfg.readInt("player_skip_frames")); +  printf("Frame quality (as bool): [%d]\n", cfg.readBool("frame_quality")); + +} + +#endif/* __TEST_MIAV_CONFIG*/ diff --git a/lib/miav_config.h b/lib/miav_config.h new file mode 100644 index 0000000..a8658f1 --- /dev/null +++ b/lib/miav_config.h @@ -0,0 +1,98 @@ +/* -*- 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 file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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; + +#include "info.h" +// Cyclic include :( +class Info; + +typedef enum { +  CONFIG_UNKNOWN, +  CONFIG_INT, +  CONFIG_BOOL, +  CONFIG_FLOAT, +  CONFIG_STRING +} ConfigType; + + +typedef struct __cfg { +  // For parsing +  char* orig; +  int line; +  char* left; +  char* right; + +  // For traversal +  string *name; +  ConfigType type; +  int intval; +  bool boolval; +  float floatval; +  string *stringval; + +  struct __cfg* next; +} _cfg; + +class MiavConfig { +public: +  MiavConfig(char *file, Info *info = NULL); +  ~MiavConfig(); + +  int readInt(char *node); +  bool readBool(char *node); +  string *readString(char *node); +  float readFloat(char *node); + +protected: +  Info *info; +  string filename; + +  _cfg *createSemantics(_cfg *cfg); +  _cfg* readLines(char* raw); +  _cfg* parseLines(_cfg *cfg); +  _cfg *parse(char* raw); +  string emptyString; + + +#if 0 +  _cfg *addConfig(_cfg *parent, char* conf); +  char *strip(char* conf); +#endif + +  void parseError(char* msg, _cfg *cfg); +  _cfg *findNode(char* node); +  _cfg *configs; +}; + +extern MiavConfig *config; + +#endif/*__MIAV_MIAV_CONFIG_H__*/ diff --git a/lib/mutex.cc b/lib/mutex.cc new file mode 100644 index 0000000..483d71a --- /dev/null +++ b/lib/mutex.cc @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            mutex.cc + * + *  Sat Oct  8 17:44:09 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#include "mutex.h" + +Mutex::Mutex() +{ +  pthread_mutex_init (&mutex, NULL); +} + +Mutex::~Mutex() +{ +  pthread_mutex_destroy(&mutex); +} + +void Mutex::lock() +{ +  pthread_mutex_lock( &mutex ); +} + +void Mutex::unlock() +{ +  pthread_mutex_unlock( &mutex ); +} diff --git a/lib/mutex.h b/lib/mutex.h new file mode 100644 index 0000000..0b1f4e7 --- /dev/null +++ b/lib/mutex.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            mutex.h + * + *  Sat Oct  8 17:44:09 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#ifndef __MIAV_MUTEX_H__ +#define __MIAV_MUTEX_H__ + +#include <pthread.h> + +class Mutex { +public: +  Mutex(); +  ~Mutex(); + +  void lock(); +  void unlock(); + +private: +  pthread_mutex_t mutex; +}; + +#endif/*__MIAV_MUTEX_H__*/ diff --git a/lib/network.cc b/lib/network.cc new file mode 100644 index 0000000..799bc98 --- /dev/null +++ b/lib/network.cc @@ -0,0 +1,151 @@ +/* -*- 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 file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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, Info *ginfo) +{ +  info = ginfo; +  s = gs; +} + +Network::~Network() +{ +} + +int Network::write(void *buf, int size) +{ +  if(!s->isConnected()) { +    //    info->error("Write attempted to a socket not connected!"); +    return -1; +  } +  int n = send(s->ssocket, buf, size, MSG_WAITALL); + +  if(n == -1) { +    info->error("An error occurred!"); +  } + +  return n; +} + +int Network::read(void *buf, int size) +{ +  if(!s->isConnected()) { +    //    info->error("Read attempted from a socket not connected!"); +    return -1; +  } +  int n = recv(s->ssocket, buf, size, MSG_WAITALL); + +  if(n == -1) { +    info->error("An error occurred!"); +  } + +  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]; + +  if(!s->isConnected()) { +    //    info->error("Write attempted to a socket not connected!"); +    return -1; +  } + +  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) { +    info->error("A network error ocurred during sendPackage!"); +    return -1; +  } + +  return n; +} + +int Network::recvPackage(n_header *h, void* buf, int bufsz) +{	 +  struct msghdr msg; +  struct iovec iovecs[2]; + +  if(!s->isConnected()) { +    //    info->error("Read attempted to a socket not connected!"); +    return -1; +  } + +  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) { +    info->error("A network error ocurred during recvPackage!"); +    return -1; +  } + +  if(msg.msg_iovlen != 2) { +    info->error("Wrong package format!"); +    return -1; +  } +  return n; +} + diff --git a/lib/network.h b/lib/network.h new file mode 100644 index 0000000..f64310e --- /dev/null +++ b/lib/network.h @@ -0,0 +1,55 @@ +/* -*- 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 file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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" +#include "info.h" + +class Network { +public: +  Network(Socket *gs, Info* ginfo); +  ~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: +  Info *info; +  Socket *s; +}; + +#endif/*__NETWORK_H__*/ + + diff --git a/lib/package.h b/lib/package.h new file mode 100644 index 0000000..a16557a --- /dev/null +++ b/lib/package.h @@ -0,0 +1,63 @@ +/* -*- 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 file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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 { +  NO_CHANGE = 0, +  SAVE, +  DELETE, +  LATER +} n_savestate; + +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; +      n_savestate savestate; +      bool mute; +    } h_data; +    struct { +      int fisk;  +    } h_info; +  } header; +} n_header; + + +#endif/*__PACKAGE_H__*/ + + diff --git a/lib/queue.h b/lib/queue.h new file mode 100644 index 0000000..3cb6fbc --- /dev/null +++ b/lib/queue.h @@ -0,0 +1,248 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            queue.h + * + *  Tue Nov  9 10:57:20 CET 2004 + *  Copyright  2004 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + * Originally from: + * RTVideoRec Realtime video recoder and encoder for Linux + * + * Copyright (C) 2004  B. Stultiens + */ + +/* + *    This file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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 "thread.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(); +  T *peek(); +   +  void lock(); +  void unlock(); + +  int length(); + +private: +  volatile bool locked; +  int limit; +  buf_t *head; +  buf_t *tail; +  int count; +  pthread_mutex_t mutex; +  T *_pop(); +}; + +/** + * Initialize queue + */ +template<typename T> +Queue<T>::Queue(int glimit) +{ +  locked = false; +  pthread_mutex_init (&mutex, NULL); +  limit = glimit; +  count = 0; +  head = NULL; +  tail = NULL; +} + +/** + * Clean up queue. + */ +template<typename T> +Queue<T>::~Queue() +{  +  if(count != 0) { +    fprintf(stderr, "Queue not empty (%d)\n", count); +    while(T *t = _pop()) delete t; +  } +  pthread_mutex_destroy(&mutex); +} + +/** + * Push element on queue. + */ +template<typename T> +void Queue<T>::push(T *t) +{ +  if(locked) { +    delete t; +    return; +  } + +  pthread_mutex_lock(&mutex); + +  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; +    pthread_mutex_unlock(&mutex); +    return; +  } +   +  b->next = tail; +  b->prev = NULL; +  if(tail) +    tail->prev = b; +  tail = b; +  count++; +   +  pthread_mutex_unlock(&mutex); +} + +/** + * Pop element from queue. + * If queue is empty, NULL is returned. + */ +template<typename T> +T *Queue<T>::pop() +{ +  pthread_mutex_lock(&mutex); +  T *d = _pop(); +  pthread_mutex_unlock(&mutex); +  return d; +} + +/** + * Pop helper method + * If queue is empty, NULL is returned. + */ +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; +} + +/** + * Peek foremost element in queue + * If queue is empty, NULL is returned. + */ +template<typename T> +T *Queue<T>::peek() +{ +  //  pthread_mutex_lock(&mutex); +  T *d; + +  //  assert(count >= 0); +   +  if(count == 0) { +    return NULL; +  } +   +  d = (T*)head->data; +  //  pthread_mutex_unlock(&mutex); +  return d; +} + +/** + * Print current length of queue + */ +template<typename T> +int Queue<T>::length() +{ +  int length; +  pthread_mutex_lock(&mutex); +  length = count; +  pthread_mutex_unlock(&mutex); +  return length; +} + +/** + * Lock the queue (all elements pushed from this point will be deleted.) + */ +template<typename T> +void Queue<T>::lock() +{ +  fprintf(stderr, "Lock this motherfucker..."); fflush(stderr); +  locked = true; +  fprintf(stderr, "done\n"); fflush(stderr); +} + +/** + * Unlock the queue. + */ +template<typename T> +void Queue<T>::unlock() +{ +  fprintf(stderr, "Unlock this motherfucker..."); fflush(stderr); +  locked = false; +  fprintf(stderr, "done\n"); fflush(stderr); +} + +#endif + diff --git a/lib/semaphore.cc b/lib/semaphore.cc new file mode 100644 index 0000000..147bd24 --- /dev/null +++ b/lib/semaphore.cc @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            semaphore.cc + * + *  Sat Oct  8 17:44:13 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#include "semaphore.h" + +Semaphore::Semaphore() +{ +  sem_init(&semaphore, 0, 0); +} + +Semaphore::~Semaphore() +{ +  sem_destroy(&semaphore); +} + +void Semaphore::post() +{ +  sem_post(&semaphore); +} + +void Semaphore::wait() +{ +  sem_wait(&semaphore); +} diff --git a/lib/semaphore.h b/lib/semaphore.h new file mode 100644 index 0000000..85f4c09 --- /dev/null +++ b/lib/semaphore.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            semaphore.h + * + *  Sat Oct  8 17:44:13 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#ifndef __MIAV_SEMAPHORE_H__ +#define __MIAV_SEMAPHORE_H__ + +#include </usr/include/semaphore.h> + +class Semaphore { +public: +  Semaphore(); +  ~Semaphore(); + +  void post(); +  void wait(); + +private: +  sem_t semaphore; +}; + +#endif/*__MIAV_SEMAPHORE_H__*/ diff --git a/lib/socket.cc b/lib/socket.cc new file mode 100644 index 0000000..2ae88dc --- /dev/null +++ b/lib/socket.cc @@ -0,0 +1,150 @@ +/* -*- 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 file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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" + +#include <errno.h> + +Socket::Socket(Info *ginfo) +{ +  info = ginfo; +  connected = false; +  err = 0; +} + +Socket::Socket(u_short port, Info *ginfo) +{ +  info = ginfo; +  connected = false; +  err = 0; + +  // 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; +    info->error("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 +} + + +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(info); + +  if(err) { +    //info->error("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) { +      info->error("Socket: bind() failed! %s", strerror(errno)); +      return s; +    } +     +    // start listen for connection - kernel will accept connection  +    // requests (max 5 in queue) +    err = listen(ssocket, 5); +    if(err) { +      info->error("Socket: listen() failed! %s", strerror(errno)); +      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) { +    s.connected = false; +    err = 1; +    info->error("Socket: accept() failed! %s", strerror(errno)); +    return s; +  } + +  connected = true; +  s.connected = true; +  return s; +} + + +int Socket::sconnect(char *ip) +{ +  if(err) { +    connected = false; +    info->error("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) { +    connected = false; +    info->error("Socket: connect() failed! %s", strerror(errno)); +    return err; +  } +  //  fprintf(stderr, "Socket connected\n"); +  connected = true; +  return 0; +} + + +bool Socket::isConnected() +{ +  return connected; +} + +bool Socket::hasError() +{ +  return err != 0; +} diff --git a/lib/socket.h b/lib/socket.h new file mode 100644 index 0000000..df2a133 --- /dev/null +++ b/lib/socket.h @@ -0,0 +1,61 @@ +/* -*- 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 file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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> + +#include "info.h" + +class Socket { +public: +  Socket(Info *ginfo); +  Socket(u_short port, Info *ginfo); +  ~Socket(); +  Socket slisten(); +  int sconnect(char *ip); +  bool isConnected(); +  bool hasError(); + +  struct sockaddr_in socketaddr; +  int ssocket; +  bool connected; + +private: +  Info *info; +  int err; +}; + +#endif/*__SOCKET_H__*/ diff --git a/lib/thread.cc b/lib/thread.cc new file mode 100644 index 0000000..147cf00 --- /dev/null +++ b/lib/thread.cc @@ -0,0 +1,56 @@ +/* -*- 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 file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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> + +static void* thread_run(void *data) { +  Thread *t = (Thread*)data; +  t->thread_main(); +  return NULL; +} + +Thread::Thread() +{ +} + +Thread::~Thread() +{ +} + +void Thread::run() +{ +  pthread_attr_init(&attr); +   +  pthread_create(&tid, &attr, thread_run, this); +} + +void Thread::wait_stop() +{ +  pthread_join(tid, NULL); +} diff --git a/lib/thread.h b/lib/thread.h new file mode 100644 index 0000000..3d58d74 --- /dev/null +++ b/lib/thread.h @@ -0,0 +1,49 @@ +/* -*- 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 file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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(); + +  void run(); +  void wait_stop(); + +  virtual void thread_main() = 0; +   +private: +  pthread_attr_t attr; +  pthread_t tid; +}; + +#endif/*__THREAD_H__*/ diff --git a/lib/threadsafe_queue.cc b/lib/threadsafe_queue.cc new file mode 100644 index 0000000..89f2d6a --- /dev/null +++ b/lib/threadsafe_queue.cc @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            threadsafe_queue.cc + * + *  Tue Sep 27 14:43:45 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#include "threadsafe_queue.h" +/* +template <typename T> +ThreadSafeQueue<T>::ThreadSafeQueue() +{ +  pthread_mutex_init (&mutex, NULL); +  sem_init(&semaphore, 0, 0); +} + +template <typename T> +ThreadSafeQueue<T>::~ThreadSafeQueue() +{ +  pthread_mutex_destroy(&mutex); +  sem_destroy(&semaphore); +} + +*/ diff --git a/lib/threadsafe_queue.h b/lib/threadsafe_queue.h new file mode 100644 index 0000000..b6d5725 --- /dev/null +++ b/lib/threadsafe_queue.h @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            threadsafe_queue.h + * + *  Tue Sep 27 14:01:01 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#ifndef __MIAV_THREADSAFE_QUEUE_H__ +#define __MIAV_THREADSAFE_QUEUE_H__ + +#include "mutex.h" +#include "semaphore.h" + +template <typename T> +class ThreadSafeQueue { +public: +  ThreadSafeQueue() { +    //    pthread_mutex_init (&mutex, NULL); +    //    sem_init(&semaphore, 0, 0); +  } + +  virtual ~ThreadSafeQueue() { +    //    pthread_mutex_destroy(&mutex); +    //sem_destroy(&semaphore); +  } + +  virtual void push(T t) = 0; +  virtual T pop() = 0; +  virtual int size() = 0; + +protected: +  //  pthread_mutex_t mutex; +  Mutex mutex; +  //sem_t semaphore; +  Semaphore semaphore; +}; + +#endif/*__MIAV_THREADSAFE_QUEUE_H__*/ diff --git a/lib/threadsafe_queue_fifo.cc b/lib/threadsafe_queue_fifo.cc new file mode 100644 index 0000000..6dbcb67 --- /dev/null +++ b/lib/threadsafe_queue_fifo.cc @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            threadsafe_queue_fifo.cc + * + *  Tue Sep 27 14:01:10 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#include "threadsafe_queue_fifo.h" + +ThreadSafeQueueFIFO::ThreadSafeQueueFIFO() +{ +} + +ThreadSafeQueueFIFO::~ThreadSafeQueueFIFO() +{ +} + +void ThreadSafeQueueFIFO::push(FrameVector *framevector) +{ +  mutex.lock(); +  queue.push(framevector); +  mutex.unlock(); +   +  semaphore.post(); +} + +FrameVector *ThreadSafeQueueFIFO::pop() +{ +  semaphore.wait(); +   +  FrameVector *framevector; +   +  mutex.lock(); +  framevector = queue.front(); +  queue.pop(); +  mutex.unlock(); +   +  return framevector; +} + +int ThreadSafeQueueFIFO::size() +{ +  int sz; +   +  mutex.lock(); +  sz = queue.size(); +  mutex.unlock(); +   +  return sz; +} diff --git a/lib/threadsafe_queue_fifo.h b/lib/threadsafe_queue_fifo.h new file mode 100644 index 0000000..ee3ac3b --- /dev/null +++ b/lib/threadsafe_queue_fifo.h @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            threadsafe_queue_fifo.h + * + *  Tue Sep 27 14:01:10 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#ifndef __MIAV_THREADSAFE_QUEUE_FIFO_H__ +#define __MIAV_THREADSAFE_QUEUE_FIFO_H__ + +#include "threadsafe_queue.h" + +#include "frame.h" + +#include <queue> + +class ThreadSafeQueueFIFO: public ThreadSafeQueue<FrameVector*> { +public: +  ThreadSafeQueueFIFO(); +  ~ThreadSafeQueueFIFO(); + +  void push(FrameVector* framevector); +  FrameVector* pop(); +  int size(); + +private: +  std::queue<FrameVector*> queue; +}; + +#endif/*__MIAV_THREADSAFE_QUEUE_FIFO_H__*/ diff --git a/lib/threadsafe_queue_priority.cc b/lib/threadsafe_queue_priority.cc new file mode 100644 index 0000000..df7ae8c --- /dev/null +++ b/lib/threadsafe_queue_priority.cc @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            threadsafe_queue_priority.cc + * + *  Tue Sep 27 14:01:24 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#include "threadsafe_queue_priority.h" + +#include "util.h" + +ThreadSafeQueuePriority::ThreadSafeQueuePriority(Info* i, unsigned int number)  +  //  : ThreadSafeQueue< Frame* >() +{ +  info = i; +  framenumber = number; +} + +ThreadSafeQueuePriority::~ThreadSafeQueuePriority() +{ +} + +void ThreadSafeQueuePriority::push(Frame *frame) +{ +  // Lock mutex +  //  pthread_mutex_lock( &mutex ); +  mutex.lock(); +  queue.push(frame); +  //  pthread_mutex_unlock( &mutex ); +  mutex.unlock(); +  // Unlock mutex + +  //  sem_post(&semaphore); +  semaphore.post(); +} + +Frame *ThreadSafeQueuePriority::pop() +{ +  semaphore.wait(); +  //  sem_wait(&semaphore); + +  Frame *tmpframe = NULL; +  Frame *frame = NULL; + +  while( frame == NULL ) { +    // Lock mutex +    //    pthread_mutex_lock( &mutex ); +    mutex.lock(); + +    tmpframe = queue.top(); +     +    if(tmpframe && tmpframe->number == framenumber ) { +      queue.pop(); +      frame = tmpframe; +      framenumber++; +    } +     +    //    pthread_mutex_unlock( &mutex ); +    mutex.unlock(); +    // Unlock mutex + +    if(frame == NULL) sleep_0_2_frame(); +  } + +  return frame; +} + +int ThreadSafeQueuePriority::size() +{ +  int sz; + +  // Lock mutex +  //  pthread_mutex_lock( &mutex ); +  mutex.lock(); +  sz = queue.size(); +  //  pthread_mutex_unlock( &mutex ); +  mutex.unlock(); +  // Unlock mutex + +  return sz; +} diff --git a/lib/threadsafe_queue_priority.h b/lib/threadsafe_queue_priority.h new file mode 100644 index 0000000..8d3cdf1 --- /dev/null +++ b/lib/threadsafe_queue_priority.h @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            threadsafe_queue_priority.h + * + *  Tue Sep 27 14:01:24 CEST 2005 + *  Copyright  2005 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of MIaV. + * + *  MIaV 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. + * + *  MIaV 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 MIaV; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "config.h" +#ifndef __MIAV_THREADSAFE_QUEUE_PRIORITY_H__ +#define __MIAV_THREADSAFE_QUEUE_PRIORITY_H__ + +#include "threadsafe_queue.h" + +#include "frame.h" + +#include <queue> +#include <functional> + +#include "info.h" + +// Method for use, when comparing Frames in priority queue. +template <typename T> +struct priority : std::binary_function<T, T, bool> { +  bool operator() (const T& a, const T& b) const { +    return ((Frame*)a)->number > ((Frame*)b)->number; +  } +}; + +class ThreadSafeQueuePriority: public ThreadSafeQueue< Frame* > { +public: +  ThreadSafeQueuePriority(Info *info, unsigned int framenumber = 0); +  ~ThreadSafeQueuePriority(); + +  void push(Frame *frame); +  Frame *pop(); +  int size(); + +private: +  Info* info; + +  unsigned int framenumber; +  std::priority_queue< Frame*, std::vector<Frame*>, priority<Frame*> > queue; +}; + +#endif/*__MIAV_THREADSAFE_QUEUE_PRIORITY_H__*/ diff --git a/lib/util.cc b/lib/util.cc new file mode 100644 index 0000000..11f1402 --- /dev/null +++ b/lib/util.cc @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            util.cc + * + *  Sun Oct 31 12:12:20 CET 2004 + *  Copyright  2004 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + * Originally from: + * RTVideoRec Realtime video recoder and encoder for Linux + * + * Copyright (C) 2004  B. Stultiens + */ + +/* + *    This file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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> + +// For nanosleep +#include <time.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; +} + +void sleep_1_frame() +{ +  // Sleep 1/25th of a second + +  struct timespec ts; + +  ts.tv_sec = 0; +  ts.tv_nsec = 1000000000L / 25L;	// 1000ms / 25 +  nanosleep(&ts, NULL); +} + +void sleep_0_2_frame() +{ +  // Sleep 1/25th of a second + +  struct timespec ts; + +  ts.tv_sec = 0; +  ts.tv_nsec = 8000000L;//1000000000L / 25L * 0.2;	// 1000ms / 25 +  nanosleep(&ts, NULL); +} diff --git a/lib/util.h b/lib/util.h new file mode 100644 index 0000000..ef21e06 --- /dev/null +++ b/lib/util.h @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            util.h + * + *  Mon Nov  8 10:49:33 CET 2004 + *  Copyright  2004 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + * Originally from: + * RTVideoRec Realtime video recoder and encoder for Linux + * + * Copyright (C) 2004  B. Stultiens + */ + +/* + *    This file is part of MIaV. + * + *    MIaV 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. + * + *    MIaV 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 MIaV; 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 + +#include <stdio.h> +//#include <stdlib.h> + +//#ifdef __cplusplus +//extern "C" { +//#endif + +void *xmalloc(size_t s); +void *xrealloc(void *b, size_t s); + +void sleep_1_frame(); +void sleep_0_2_frame(); +//#ifdef __cplusplus +//} +//#endif + +#endif | 
