gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash/cygnal Makefile.am alloc.cpp cygnal.cpp h...


From: Rob Savoye
Subject: [Gnash-commit] gnash/cygnal Makefile.am alloc.cpp cygnal.cpp h...
Date: Sun, 17 Dec 2006 02:34:58 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Rob Savoye <rsavoye>    06/12/17 02:34:58

Added files:
        cygnal         : Makefile.am alloc.cpp cygnal.cpp http.cpp 
                         http.h netstats.cpp netstats.h statistics.cpp 
                         statistics.h stream.cpp stream.h 

Log message:
                * cygnal: New directory for media server.
                * cygnal/cygnal.cpp: Main entry for server.
                * cygnal/Makefile.am: Makefile for media server.
                * cygnal/README: Server specific info file for developers.
                * cygnal/stream.cpp, stream.h: Streaming data class.
                * cygnal/netstats.cpp, netstats.h:  Collect statistics on
                network performance.
                * cygnal/statistics.cpp, statistics.h: Collect statistics on 
each
                movie being played for performance tweaking.
                * cygnal/http.c, http.h: Support for a simple subset of HTTP,
                enough to respond to GET requests.
                * cygnal/alloc.cpp: Threadsafe new & delete to keep STL 
containers
                working in a multi-threaded application.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/Makefile.am?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/alloc.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/cygnal.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/http.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/http.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/netstats.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/netstats.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/statistics.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/statistics.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/stream.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/stream.h?cvsroot=gnash&rev=1.1

Patches:
Index: Makefile.am
===================================================================
RCS file: Makefile.am
diff -N Makefile.am
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ Makefile.am 17 Dec 2006 02:34:58 -0000      1.1
@@ -0,0 +1,78 @@
+# 
+#   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+#
+#   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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = dejagnu
+
+AM_CPPFLAGS = # -Wall
+
+## WARNING: make sure GLIB_LIBS appears first
+## See: http://lists.gnu.org/archive/html/gnash-dev/2006-07/msg00076.html
+AM_LDFLAGS = \
+       ../libbase/libgnashbase.la \
+       ../libamf/libgnashamf.la \
+       $(GLIB_LIBS) \
+       $(LIBXML_LIBS) \
+       $(CURL_LIBS) \
+       $(BOOST_LIBS) \
+       $(PTHREAD_LIBS)
+
+INCLUDES = -I.. \
+        -I$(top_srcdir)        \
+        -I$(top_srcdir)/libamf \
+        -I$(top_srcdir)/libbase \
+        -I$(top_srcdir)/server \
+        $(LIBXML_CFLAGS) \
+       $(LIBXML_CFLAGS) \
+       $(DMALLOC_CFLAGS) \
+       $(CURL_CFLAGS) \
+       $(BOOST_CFLAGS) \
+       $(PTHREAD_CFLAGS)
+
+bin_PROGRAMS = cygnal
+
+cygnal_SOURCES = \
+       cygnal.cpp \
+       http.cpp \
+       alloc.cpp \
+       netstats.cpp \
+       stream.cpp \
+       statistics.cpp
+#      transcode.cpp
+#      flash.cpp
+
+noinst_HEADRRS = \
+       http.h \
+       netstats.h \
+       stream.h \
+       statistics.h
+#      transcode.h
+#      flash.h
+
+#      protocol.cpp protocol.h
+cygnal_LDADD = $(AM_LDFLAGS)
+
+# Rebuild with GCC 4.x Mudflap support
+mudflap:
+       @echo "Rebuilding with GCC Mudflap support"
+       $(MAKE) CXXFLAGS="$(CXXFLAGS) $(MUDFLAP_OPT)" LIBS="$(LIBS) 
$(MUDFLAP_LIB)"
+
+# EXTRA_PROGRAMS = talloc
+# talloc_SOURCES = talloc.cpp
+# talloc_LDADD = $(AM_LDFLAGS)

Index: alloc.cpp
===================================================================
RCS file: alloc.cpp
diff -N alloc.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ alloc.cpp   17 Dec 2006 02:34:58 -0000      1.1
@@ -0,0 +1,47 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/// This defines thread safe new/delete operators
+#include <new>
+#include <boost/thread/mutex.hpp>
+
+static boost::mutex mem_mutex;
+
+// Wrap new in a mutex, because it is not thread safe.
+void *
+operator new (std::size_t bytes) {
+    boost::mutex::scoped_lock lock(mem_mutex);
+    void *ptr = malloc (bytes);
+    return ptr;
+}
+
+// Wrap delete in a mutex, because it is not thread safe.
+void
+operator delete (void* vptr) {
+    boost::mutex::scoped_lock lock(mem_mutex);
+    free (vptr);
+}
+
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: cygnal.cpp
===================================================================
RCS file: cygnal.cpp
diff -N cygnal.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ cygnal.cpp  17 Dec 2006 02:34:58 -0000      1.1
@@ -0,0 +1,359 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <iostream>
+#include <signal.h>
+#include <vector>
+#include <sys/mman.h>
+#include <cerrno>
+
+#include "stream.h"
+#include "network.h"
+#include "log.h"
+#include "rc.h"
+#include "rtmp.h"
+#include "http.h"
+#include "limits.h"
+#include "netstats.h"
+#include "statistics.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+
+using gnash::log_msg;
+using namespace std;
+using namespace cygnal;
+using namespace gnash;
+using namespace amf;
+
+static void usage(const char *proc);
+static void version_and_copyright();
+static void cntrlc_handler(int sig);
+
+static void start_thread();
+static void rtmp_thread();
+static void http_thread();
+static void ssl_thread();
+static void stream_thread(struct thread_params *sendfile);
+
+namespace {
+gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
+gnash::RcInitFile& rcfile = gnash::RcInitFile::getDefaultInstance();
+}
+
+struct thread_params {
+    int netfd;
+    char filespec[256];
+    Statistics *statistics;
+};
+
+static struct sigaction  act;
+
+// The next few global variables have to be global because Boost
+// threads don't take arguments. Since these are set in main() before
+// any of the threads are started, and it's value should never change,
+// it's safe to use these without a mutex, as all threads share the
+// same read-only value.
+
+// This is the default path to look in for files to be streamed.
+const char *docroot;
+
+// This is the number of times a thread loop continues, for debugging only
+int thread_retries;
+
+// This is added to the default ports for testing so it doesn't
+// conflict with apache on the same machine.
+static int port_offset = 0;
+
+// end of globals
+
+
+int
+main(int argc, char *argv[])
+{
+    // scan for the two main long GNU options
+    int c;
+    for (c=0; c<argc; c++) {
+        if (strcmp("--help", argv[c]) == 0) {
+            version_and_copyright();
+            printf("\n");
+            usage(argv[0]);
+            exit(0);
+        }
+
+        if (strcmp("--version", argv[c]) == 0) {
+            version_and_copyright();
+            exit(0);
+        }
+    }
+
+    dbglogfile.setWriteDisk(false);
+    rcfile.loadFiles();
+//    rcfile.dump();
+
+    if (rcfile.useWriteLog()) {
+        dbglogfile.setWriteDisk(true);
+    }
+    
+    if (rcfile.verbosityLevel() > 0) {
+        dbglogfile.setVerbosity(rcfile.verbosityLevel());
+    }    
+    
+    if (rcfile.getRetries() > 0) {
+        thread_retries = rcfile.getRetries();
+    } else {
+       thread_retries = 3;
+    }
+    
+    if (rcfile.getDocumentRoot().size() > 0) {
+       docroot = rcfile.getDocumentRoot().c_str();
+       dbglogfile << "Document Root for media files is: "
+                  << docroot << endl;
+    } else {
+       docroot = "/var/www";
+    }
+    
+    while ((c = getopt (argc, argv, "hvwp:")) != -1) {
+       switch (c) {
+         case 'h':
+             usage (argv[0]);
+              exit(0);
+         case 'v':
+              dbglogfile.setVerbosity();
+             dbglogfile << "Verbose output turned on" << endl;
+             break;
+         case 'w':
+              dbglogfile.setWriteDisk(true);
+             dbglogfile << "Logging to disk enabled." << endl;
+             break;
+         case 'p':
+             dbglogfile << "Logging to disk enabled." << endl;
+             port_offset = strtol(optarg, NULL, 0);
+             break;
+        }
+    }
+    
+
+    // get the file name from the command line
+    while (optind < argc) {
+        dbglogfile << "Extraneous argument!" << endl;
+    }
+
+    // Remove the logfile that's created by default, since leaving a short
+    // file is confusing.
+    if (dbglogfile.getWriteDisk() == false) {
+        dbglogfile.removeLog();
+    }
+    
+    // Trap ^C so we can kill all the threads
+    act.sa_handler = cntrlc_handler;
+    sigaction (SIGINT, &act, NULL);
+
+    boost::thread rtmp_port(&rtmp_thread);
+    boost::thread http_port(&http_thread);
+    boost::thread ssl_port(&ssl_thread);
+
+    // wait for the thread to finish
+    rtmp_port.join();
+    http_port.join();
+    ssl_port.join();
+
+    dbglogfile << "All done I think..." << endl;
+    
+    return(0);
+}
+
+static void
+rtmp_thread()
+{
+    GNASH_REPORT_FUNCTION;
+    int retries = 0;
+    RTMPproto proto;
+    
+    Statistics st;
+    st.setFileType(NetStats::RTMP);
+    
+    proto.createServer(RTMP);
+    while (retries++ < thread_retries) {
+       printf("%s: Thread for RTMP port looping...\n", __PRETTY_FUNCTION__);
+       proto.newConnection(true);
+       st.startClock();
+       proto.handShakeWait();
+       proto.handShakeResponse();
+       proto.serverFinish();
+       
+       // Keep track of the network statistics
+       st.stopClock();
+       dbglogfile << "Bytes read: " << proto.getBytesIn() << endl;
+       dbglogfile << "Bytes written: " << proto.getBytesOut() << endl;
+       st.setBytes(proto.getBytesIn() + proto.getBytesOut());
+       st.addStats();
+       proto.resetBytesIn();
+       proto.resetBytesOut();  
+    }    
+}
+
+static void
+http_thread()
+{
+    GNASH_REPORT_FUNCTION;
+    int retries = 0;
+    HTTP www;
+    struct thread_params thread_data;
+    string url, filespec, parameters;
+    string::size_type pos;
+    int port = RTMPT + port_offset;
+    int filesize;
+    struct stat filestats;
+
+    www.createServer(port);
+    while (retries++ < thread_retries) {
+       printf("%s: Thread for port %d looping...\n", __PRETTY_FUNCTION__, 
port);
+       www.newConnection(true);
+       Statistics st;
+       st.setFileType(NetStats::RTMPT);
+       st.startClock();
+       thread_data.netfd = www.getFileFd();
+       url = docroot;
+       url += www.waitForGetRequest();
+       pos = url.find("?");
+       filespec = url.substr(0, pos);
+       parameters = url.substr(pos + 1, url.size());
+       // Get the file size for the HTTP header
+       if (stat(filespec.c_str(), &filestats) == 0) {
+           filesize = filestats.st_size;
+       } else {
+           filesize = 0;
+       }
+       www.sendGetReply(filesize);
+       strcpy(thread_data.filespec, filespec.c_str());
+       thread_data.statistics = &st;
+       
+       // Keep track of the network statistics
+       st.stopClock();
+//     dbglogfile << "Bytes read: " << www.getBytesIn() << endl;
+//     dbglogfile << "Bytes written: " << www.getBytesOut() << endl;
+//     st.setBytes(www.getBytesIn() + www.getBytesOut());
+       st.addStats();
+//     www.resetBytesIn();
+//     www.resetBytesOut();
+       
+       if (url != docroot) {
+           dbglogfile << "File to load is: " << filespec << endl;
+           dbglogfile << "Parameters are: " << parameters << endl;
+           memcpy(thread_data.filespec, filespec.c_str(), filespec.size());
+           boost::thread sendthr(boost::bind(&stream_thread, &thread_data));
+           sendthr.join();
+       }
+       // See if this is a persistant connection
+       if (!www.keepAlive()) {
+           www.closeConnection();
+       }
+    }
+//    st.dump();
+}
+
+static void
+ssl_thread()
+{
+    GNASH_REPORT_FUNCTION;
+    int retries = 0;
+    HTTP www;
+    RTMPproto proto;
+    struct thread_params loadfile;
+    string filespec;
+    int port = RTMPTS + port_offset;
+
+    Statistics st;
+    st.setFileType(NetStats::RTMPTS);    
+    
+    www.createServer(port);
+    
+    while (retries++ < thread_retries) {
+       printf("%s: Thread for port %d looping...\n", __PRETTY_FUNCTION__, 
port);
+       www.newConnection(true);
+       loadfile.netfd = www.getFileFd();
+       strcpy(loadfile.filespec, "Hello World");
+       boost::thread sendthr(boost::bind(&stream_thread, &loadfile));
+       sendthr.join();
+    }
+}
+
+
+static void
+stream_thread(struct  thread_params *params)
+{
+    GNASH_REPORT_FUNCTION;
+    
+    struct stat stats;
+    struct thread_params loadfile;
+    
+    dbglogfile << __PRETTY_FUNCTION__ << ": " << params->filespec << endl;
+    
+    Stream str;
+    str.open(params->filespec, params->netfd, params->statistics);
+    str.play();
+}
+
+// Trap Control-C so we can cleanly exit
+static void
+cntrlc_handler (int sig)
+{
+    log_msg("Got a ^C !\n");
+
+    exit(-1);
+}
+
+static void
+version_and_copyright()
+{
+    printf (
+"Cygnal " VERSION "\n"
+"Copyright (C) 2006 Free Software Foundation, Inc.\n"
+"Cygnal comes with NO WARRANTY, to the extent permitted by law.\n"
+"You may redistribute copies of Cygnal under the terms of the GNU General\n"
+"Public License.  For more information, see the file named COPYING.\n"
+       );
+}
+
+static void
+usage(const char *proc)
+{
+    printf(
+       "cygnal -- an streaming media server.\n"
+       "\n"
+       "usage: cygnal [options...]\n"
+       "  --help(-h)  Print this info.\n"
+       "  --version   Print the version numbers.\n"
+       "  --verbose (-v)   Output verbose debug info.\n"
+       "  --port-offset (-p)   RTMPT port offset.\n"
+       );
+}
+ 
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: http.cpp
===================================================================
RCS file: http.cpp
diff -N http.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ http.cpp    17 Dec 2006 02:34:58 -0000      1.1
@@ -0,0 +1,396 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/thread/mutex.hpp>
+#include <string>
+#include <iostream>
+#include <cstring>
+#include "http.h"
+#include "log.h"
+
+using namespace gnash;
+using namespace std;
+
+static boost::mutex stl_mutex;
+
+
+namespace cygnal
+{
+
+namespace {
+gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
+}
+
+static const int readsize = 1024;
+
+HTTP::HTTP()
+{
+//    GNASH_REPORT_FUNCTION;
+//    struct status_codes *status = new struct status_codes;
+    
+//    _status_codes(CONTINUE, status);
+}
+
+HTTP::~HTTP()
+{
+//    GNASH_REPORT_FUNCTION;
+}
+
+HTTP &
+HTTP::operator = (HTTP &obj)
+{
+    GNASH_REPORT_FUNCTION;
+//    this = obj;
+}
+
+string
+HTTP::waitForGetRequest(Network &net)
+{
+    GNASH_REPORT_FUNCTION;
+    
+}
+
+string
+HTTP::waitForGetRequest()
+{
+    GNASH_REPORT_FUNCTION;
+
+    char buffer[readsize+1];
+    memset(buffer, 0, readsize+1);
+    if (readNet(buffer, readsize) > 0) {
+        dbglogfile << "Read initial GET Request" << endl;
+    } else {
+        dbglogfile << "Couldn't read initial GET Request" << endl;
+    }
+    
+    extractMethod(buffer);
+//     extractReferer(buffer);
+//     extractHost(buffer);
+    extractAgent(buffer);
+    extractLanguage(buffer);
+    extractCharset(buffer);
+    extractConnection(buffer);
+//     extractEncoding(buffer);
+//     extractTE(buffer);
+//    dump();
+
+    // See if we got a legit GET request
+    if (strncmp(buffer, "GET ", 4) == 0) {
+        dbglogfile << "Got legit GET request: " << endl;
+    } else {
+        dbglogfile << "ERROR: Got bogus GET request!" << endl;
+    }
+
+    return _url;
+}
+
+bool
+HTTP::sendGetReply(int filesize)
+{
+    GNASH_REPORT_FUNCTION;
+    boost::posix_time::ptime now = 
boost::posix_time::microsec_clock::local_time();
+
+    now.time_of_day();
+    
+    const char reply[] =
+        "HTTP/1.1 200 OK\r\n"
+        "Date: Sun, 20 Apr 2006 04:20:00 GMT\r\n"
+        "Content-Type: application/futuresplash\r\n"
+        "Connection: close\r\n"
+        "Content-Length: XX      \r\n"
+        "\r\n"                  // All HTTP messages are followed by a blank 
line.
+        ;
+
+    // This is a bit ugly, but we splice the file size onto the request string
+    // without any memory allocation, which could incur a small performance 
hit.
+    char *length = strstr(reply, " XX");
+    sprintf(length, " %d", filesize);
+    
+    if (writeNet(reply, strlen(reply)) == strlen(reply)) {
+        dbglogfile << "Sent GET Reply: " << reply << endl;
+    } else {
+        dbglogfile << "Couldn't send GET Reply" << endl;
+    }    
+}
+
+// bool
+// HTTP::sendGetReply(Network &net)
+// {
+//     GNASH_REPORT_FUNCTION;    
+// }
+
+// This is what a GET request looks like.
+// GET 
/software/gnash/tests/flvplayer2.swf?file=http://localhost:4080/software/gnash/tests/lulutest.flv
 HTTP/1.1
+// User-Agent: Opera/9.01 (X11; Linux i686; U; en)
+// Host: localhost:4080
+// Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, 
image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
+// Accept-Language: en
+// Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
+// Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
+// Referer: http://localhost/software/gnash/tests/
+// Connection: Keep-Alive, TE
+// TE: deflate, gzip, chunked, identity, trailers
+string
+HTTP::extractMethod(const char *data) {
+//    GNASH_REPORT_FUNCTION;
+    
+    boost::mutex::scoped_lock lock(stl_mutex);
+    string body = data;
+    string::size_type start, end;
+    int length;
+
+    length = body.size();
+    start = body.find(" ", 0);
+    if (start == string::npos) {
+        return "error";
+    }
+    _method = body.substr(0, start);
+    end = body.find(" ", start+1);
+    if (end == string::npos) {
+        return "error";
+    }
+    _url = body.substr(start+1, end-start-1);
+    _version = body.substr(end+1, length);
+
+    end = _url.find("?", 0);
+//    _filespec = _url.substr(start+1, end);
+    return "error";
+}
+
+string 
+HTTP::extractReferer(const char *data) {
+//    GNASH_REPORT_FUNCTION;
+    
+    string body = data;
+    string::size_type start, end;
+    string pattern = "Referer: ";
+    
+    start = body.find(pattern, 0);
+    if (start == string::npos) {
+        return "error";
+    }
+    end =  body.find("\r\n", start);
+    if (end == string::npos) {
+        return "error";
+    }
+    
+    _referer = body.substr(start+pattern.size(), end-start-1);
+    return _referer;
+};
+
+string 
+HTTP::extractConnection(const char *data) {
+//    GNASH_REPORT_FUNCTION;
+    
+    string body = data;
+    string::size_type start, end;
+    string pattern = "Connection: ";
+    
+    start = body.find(pattern, 0);
+    if (start == string::npos) {
+        return "error";
+    }
+    end =  body.find("\r\n", start);
+    if (end == string::npos) {
+        return "error";
+    }
+    
+    _connection = body.substr(start+pattern.size(), end-start-1);
+    return _connection;
+}
+
+string
+HTTP::extractHost(const char *data) {
+//    GNASH_REPORT_FUNCTION;
+    
+    string body = data;
+    string::size_type start, end;
+    string pattern = "Host: ";
+    
+    start = body.find(pattern, 0);
+    if (start == string::npos) {
+        return "error";
+    }
+    end =  body.find("\r\n", start);
+    if (end == string::npos) {
+        return "error";
+    }
+    
+    _host = body.substr(start+pattern.size(), end-start-1);
+    return _host;
+}
+
+string 
+HTTP::extractAgent(const char *data) {
+//    GNASH_REPORT_FUNCTION;
+    
+    string body = data;
+    string::size_type start, end;
+    string pattern = "User-Agent: ";
+    
+    start = body.find(pattern, 0);
+    if (start == string::npos) {
+        return "error";
+    }
+    end =  body.find("\r\n", start);
+    if (end == string::npos) {
+        return "error";
+    }
+    
+    _agent = body.substr(start+pattern.size(), end-start-1);
+    return _agent;
+}
+
+string 
+HTTP::extractLanguage(const char *data) {
+//    GNASH_REPORT_FUNCTION;
+    
+    string body = data;
+    string::size_type start, end;
+    string pattern = "Accept-Language: ";
+    
+    start = body.find(pattern, 0);
+    if (start == string::npos) {
+        return "error";
+    }
+    end =  body.find("\r\n", start);
+    if (end == string::npos) {
+        return "error";
+    }
+    
+    _language = body.substr(start+pattern.size(), end-start-1);
+    return _language;
+}
+
+string 
+HTTP::extractCharset(const char *data) {
+//    GNASH_REPORT_FUNCTION;
+    
+    string body = data;
+    string::size_type start, end;
+    string pattern = "Accept-Charset: ";
+    
+    start = body.find(pattern, 0);
+    if (start == string::npos) {
+        return "error";
+    }
+    end =  body.find("\r\n", start);
+    if (end == string::npos) {
+        return "error";
+    }
+    
+    _charset = body.substr(start+pattern.size(), end-start-1);
+    return _charset;
+}
+
+string 
+HTTP::extractEncoding(const char *data) {
+//    GNASH_REPORT_FUNCTION;
+    
+    string body = data;
+    string::size_type start, end;
+    string pattern = "Accept-Encoding: ";
+    
+    start = body.find(pattern, 0);
+    if (start == string::npos) {
+        return "error";
+    }
+    end =  body.find("\r\n", start);
+    if (end == string::npos) {
+        return "error";
+    }
+    
+    _encoding = body.substr(start+pattern.size(), end-start-1);
+    return _encoding;
+}
+
+string 
+HTTP::extractTE(const char *data) {
+//    GNASH_REPORT_FUNCTION;
+    
+    string body = data;
+    string::size_type start, end;
+    string pattern = "TE: ";
+    
+    start = body.find(pattern, 0);
+    if (start == string::npos) {
+        return "error";
+    }
+    end =  body.find("\r\n", start);
+    if (end == string::npos) {
+        return "error";
+    }
+    
+    _te = body.substr(start+pattern.size(), end-start-1);
+    return _te;
+}
+
+bool
+HTTP::keepAlive(const char *data)
+{
+//    GNASH_REPORT_FUNCTION;
+
+    if (strcasestr(data, "Keep-Alive")) {
+       return true;
+    } else {
+       return false;
+    }
+}
+
+bool
+HTTP::keepAlive()
+{
+//    GNASH_REPORT_FUNCTION;
+    // FIXME: is their a way to make find case insensitive that's
+    // less than 20 lines long ?
+    return keepAlive(_connection.c_str());
+}
+
+void
+HTTP::dump() {
+    GNASH_REPORT_FUNCTION;
+    
+    boost::mutex::scoped_lock lock(stl_mutex);
+    
+    dbglogfile << "==== The HTTP header breaks down as follows: ====" << endl;
+    dbglogfile << "Filespec: " << _filespec.c_str() << endl;
+    dbglogfile << "URL: " << _url.c_str() << endl;
+    dbglogfile << "Version: " << _version.c_str() << endl;
+    dbglogfile << "Method: " << _method.c_str() << endl;
+    dbglogfile << "Referer: " << _referer.c_str() << endl;
+    dbglogfile << "Connection: " << _connection.c_str() << endl;
+    dbglogfile << "Host: " << _host.c_str() << endl;
+    dbglogfile << "User Agent: " << _agent.c_str() << endl;
+    dbglogfile << "Language: " << _language.c_str() << endl;
+    dbglogfile << "Charset: " << _charset.c_str() << endl;
+    dbglogfile << "Encoding: " << _encoding << endl;
+    dbglogfile << "TE: " << _te.c_str() << endl;
+    dbglogfile << "==== ==== ====" << endl;
+}
+
+} // end of cygnal namespace
+
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: http.h
===================================================================
RCS file: http.h
diff -N http.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ http.h      17 Dec 2006 02:34:58 -0000      1.1
@@ -0,0 +1,152 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef _HTTP_H_
+#define _HTTP_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string>
+#include <map>
+#include "network.h"
+
+using namespace std;
+using namespace gnash;
+
+namespace cygnal
+{
+    
+class HTTP : public Network
+{
+public:
+    typedef enum {
+        // 1xx: Informational - Request received, continuing process
+        CONTINUE = 100,
+        SWITCHPROTOCOLS = 101,
+        // 2xx: Success - The action was successfully received,
+        // understood, and accepted
+        OK = 200,
+        CREATED = 201,
+        ACCEPTED = 202,
+        NON_AUTHORITATIVE = 203,
+        NO_CONTENT = 204,
+        RESET_CONTENT = 205,
+        PARTIAL_CONTENT = 206,
+        // 3xx: Redirection - Further action must be taken in order to
+        // complete the request
+        MULTIPLE_CHOICES = 300,
+        MOVED_PERMANENTLY = 301,
+        FOUND = 302,
+        SEE_OTHER = 303,
+        NOT_MODIFIED = 304,
+        USE_PROXY = 305,
+        TEMPORARY_REDIRECT = 307,
+        // 4xx: Client Error - The request contains bad syntax or
+        // cannot be fulfilled
+        BAD_REQUEST = 400,
+        UNAUTHORIZED = 401,
+        PAYMENT_REQUIRED = 402,
+        FORBIDDEN = 403,
+        NOT_FOUND = 404,
+        METHOD_NOT_ALLOWED = 405,
+        NOT_ACCEPTABLE = 406,
+        PROXY_AUTHENTICATION_REQUIRED = 407,
+        REQUEST_TIMEOUT = 408,
+        CONFLICT = 409,
+        GONE = 410,
+        LENGTH_REQUIRED = 411,
+        PRECONDITION_FAILED = 412,
+        REQUEST_ENTITY_TOO_LARGE = 413,
+        REQUEST_URI_TOO_LARGE = 414,
+        UNSUPPORTED_MEDIA_TYPE = 415,
+        REQUESTED_RANGE_NOT_SATISFIABLE = 416,
+        EXPECTATION_FAILED = 417,
+        // 5xx: Server Error - The server failed to fulfill an apparently 
valid request
+        INTERNAL_SERVER_ERROR = 500,
+        NOT_IMPLEMENTED = 501,
+        BAD_GATEWAY = 502,
+        SERVICE_UNAVAILABLE = 503,
+        GATEWAY_TIMEOUT = 504,
+        HTTP_VERSION_NOT_SUPPORTED = 505
+    } http_status_e;
+    typedef enum {
+        OPTIONS,
+        GET,
+        HEAD,
+        POST,
+        PUT,
+        DELETE,
+        TRACE,
+        CONNECT
+    } http_method_e;
+    struct status_codes {
+        const char *code;
+        const char *msg;
+    };
+    HTTP();
+    ~HTTP();
+    std::string waitForGetRequest();
+    std::string waitForGetRequest(Network &net);
+    
+    // Handle the GET request response
+    bool sendGetReply(int filesize);
+//    bool sendGetReply(Network &net);
+
+    // Make copies of ourself
+    HTTP &operator = (HTTP &obj);
+
+    // These methods extract the fields in the HTTP header.
+    std::string extractMethod(const char *data);
+    std::string extractReferer(const char *data);
+    std::string extractConnection(const char *data);
+    std::string extractHost(const char *data);
+    std::string extractAgent(const char *data);
+    std::string extractLanguage(const char *data);
+    std::string extractCharset(const char *data);
+    std::string extractEncoding(const char *data);
+    std::string extractTE(const char *data);
+    bool keepAlive(const char *data);
+    bool keepAlive();
+    void dump();
+private:
+    std::string _filespec;
+    std::string _url;
+    std::map<int, struct status_codes *> _status_codes;
+    std::string _version;
+    std::string _method;
+    std::string _referer;
+    std::string _connection;
+    std::string _host;
+    std::string _agent;
+    std::string _language;
+    std::string _charset;
+    std::string _encoding;
+    std::string _te;
+};  
+    
+} // end of cygnal namespace
+
+// end of _HTTP_H_
+#endif
+
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: netstats.cpp
===================================================================
RCS file: netstats.cpp
diff -N netstats.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ netstats.cpp        17 Dec 2006 02:34:58 -0000      1.1
@@ -0,0 +1,68 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include "netstats.h"
+#include "log.h"
+
+using namespace gnash;
+
+namespace cygnal {
+
+NetStats::NetStats() {
+    GNASH_REPORT_FUNCTION;
+}
+
+NetStats::~NetStats() {
+    GNASH_REPORT_FUNCTION;    
+}
+
+boost::posix_time::ptime
+NetStats::startClock() {
+    GNASH_REPORT_FUNCTION;
+
+    _starttime = boost::posix_time::microsec_clock::local_time();
+    return _stoptime;
+}
+
+boost::posix_time::ptime
+NetStats::stopClock() {
+    GNASH_REPORT_FUNCTION;
+    
+    _stoptime = boost::posix_time::microsec_clock::local_time();
+    return _stoptime;
+}
+
+NetStats &
+NetStats::operator = (NetStats &stats) {
+    _starttime = stats.getStartTime();
+    _stoptime = stats.getStopTime();
+    _bytes = stats.getBytes();
+    _codec = stats.getCodec();
+    _type = stats.getFileType();
+}
+
+} // end of cygnal namespace
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: netstats.h
===================================================================
RCS file: netstats.h
diff -N netstats.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ netstats.h  17 Dec 2006 02:34:58 -0000      1.1
@@ -0,0 +1,93 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef __NETSTATS_H__
+#define __NETSTATS_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <boost/date_time/posix_time/posix_time.hpp> //include all types plus 
i/o
+
+namespace cygnal 
+{
+
+class NetStats {
+public:
+    NetStats();
+    ~NetStats();
+    typedef enum {
+        NO_CODEC,
+        OGG,
+        THEORA,
+        MP3,
+        MPEG4,
+        FLV,
+        VP6,
+        VP7
+    } codec_e;
+    typedef enum {
+        NO_FILETYPE,
+        RTMP,
+        RTMPT,
+        RTMPTS,
+        FLASH6,
+        FLASH7,
+        FLASH8,
+        FLASH9,
+        AUDIO,
+        VIDEO
+    } filetypes_e;
+    // start the clock counting down
+    boost::posix_time::ptime startClock();
+    // stop the clock from counting down
+    boost::posix_time::ptime stopClock();
+    
+    // Accessors to set to the private data
+    void setStartTime(boost::posix_time::ptime x) { _starttime = x; };
+    void setStopTime(boost::posix_time::ptime x) { _stoptime = x; };
+    void setBytes(int x) { _bytes = x; };
+    void setCodec(codec_e x) { _codec = x; };
+    void setFileType(filetypes_e x) { _type = x; };
+    // Accumulate the byts transferred
+    int addBytes(int x) { _bytes += x; return _bytes; };
+    
+    // Accessors to get to the private data
+    int getBytes() { return _bytes; };
+    codec_e getCodec() { return _codec; };
+    filetypes_e getFileType() { return _type; };
+    boost::posix_time::ptime getStartTime() { return _starttime; };
+    boost::posix_time::ptime getStopTime() { return _stoptime; };
+    boost::posix_time::time_duration getTimeSpan() { return _stoptime - 
_starttime; };
+    NetStats &operator = (NetStats &stats);
+private:
+    boost::posix_time::ptime _starttime;
+    boost::posix_time::ptime _stoptime;
+    int                      _bytes;
+    codec_e                  _codec;
+    filetypes_e              _type;
+};
+ 
+} // end of cygnal namespace
+
+#endif // __NETSTATS_H__
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: statistics.cpp
===================================================================
RCS file: statistics.cpp
diff -N statistics.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ statistics.cpp      17 Dec 2006 02:34:58 -0000      1.1
@@ -0,0 +1,133 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <boost/thread/mutex.hpp>
+#include <string>
+#include <list>
+#include <iostream>
+
+#include "log.h"
+#include "netstats.h"
+#include "statistics.h"
+
+using namespace gnash;
+using namespace std;
+
+namespace {
+gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
+}
+
+static boost::mutex io_mutex;
+
+// The string versions of the codec, used for debugging. If you add
+// another enum type to codec_e, you have to add the string
+// representation here or you'll get the wrong output.
+const char *codec_names[] = {
+    "NO_CODEC",
+    "Ogg",
+    "Theora",
+    "MP3",
+    "MPEG4",
+    "FLV",
+    "VP6",
+    "VP7"
+};
+
+// The string versions of the codec, used for debugging. If you add
+// another enum type to filetypes_e, you have to add the string
+// representation here or you'll get the wrong output.
+const char *filetype_names[] = {
+        "NO_FILETYPE",
+        "RTMP",
+        "RTMPT",
+        "RTMPTS",
+        "FLASH5",
+        "FLASH6",
+        "FLASH7",
+        "FLASH8",
+        "FLASH9",
+        "AUDIO",
+        "VIDEO"
+};
+
+namespace cygnal 
+{
+
+Statistics::Statistics() {
+}
+
+Statistics::~Statistics() {
+    dump();
+}
+
+float
+Statistics::getFPS() {
+    
+}
+
+int
+Statistics::getBitRate() {
+
+    return (getStartTime() - getStopTime()).seconds() / getBytes();
+}
+
+int
+Statistics::addStats() {
+    NetStats *st = new NetStats;
+
+    st->setStartTime(getStartTime());
+    st->setStopTime(getStopTime());
+    st->setBytes(getBytes());
+    st->setCodec(getCodec());
+    st->setFileType(getFileType());
+    
+    boost::mutex::scoped_lock lock(io_mutex);
+    _netstats.push_back(st);
+    
+    return _netstats.size();
+}
+
+void
+Statistics::dump() {   
+    boost::mutex::scoped_lock lock(io_mutex);
+    list<NetStats *>::iterator it;
+
+    for (it = _netstats.begin(); it != _netstats.end(); it++) {
+        NetStats *stats = (*it);
+        if (stats->getFileType() <= VIDEO) {
+            dbglogfile << "Stream type is: " << 
filetype_names[stats->getFileType()] << endl;
+        }
+        if (((stats->getFileType() == VIDEO) || (stats->getFileType() == 
AUDIO)) &&
+            stats->getCodec() <= VP7) {
+            dbglogfile << "Stream codec is: " << 
codec_names[stats->getCodec()];
+        }
+        dbglogfile << stats->getBytes() << " bytes were transfered in "
+                   << to_simple_string(stats->getTimeSpan()).c_str()
+                   << " seconds." << endl;
+    }
+}
+
+} // end of cygnal namespace
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: statistics.h
===================================================================
RCS file: statistics.h
diff -N statistics.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ statistics.h        17 Dec 2006 02:34:58 -0000      1.1
@@ -0,0 +1,83 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef __STATISTICS_H__
+#define __STATISTICS_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <boost/date_time/posix_time/posix_time.hpp> //include all types plus 
i/o
+#include <sys/time.h>
+#include <network.h>
+#include <list>
+
+#include "netstats.h"
+
+namespace cygnal 
+{
+
+class Statistics : public NetStats {
+public:
+    Statistics();
+    ~Statistics();
+    typedef enum {
+        NO_BROWSER,
+        MOZILLA,
+        FIREFOX,
+        OPERA,
+        KONQUEROR,
+        GALEON,
+        EPIPHANY,
+        SAFARI,
+        IE
+    } browser_e;
+    typedef enum {
+        NO_OSTYPE,
+        LINUX,
+        BSD,
+        DARWIN,
+        WIN32,
+        SOLARIS
+    } ostype_e;
+    void setIPaddr(in_addr_t x) { _ipaddr = x; };
+    void setBrowser(browser_e x) { _browser = x; } ;
+    int addStats();
+    // these make calculations on the collected network data.
+    float getFPS();
+    int getBitRate();
+    // Dump the collected network statistics in a human readable form.
+    void dump();
+    void clear();
+private:
+    in_addr_t           _ipaddr;
+    const char         *_filespec;
+    browser_e           _browser;
+    ostype_e            _os;
+    std::list<NetStats *> _netstats;
+};
+
+ 
+} // end of cygnal namespace
+
+#endif // __STATISTICS_H__
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: stream.cpp
===================================================================
RCS file: stream.cpp
diff -N stream.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ stream.cpp  17 Dec 2006 02:34:58 -0000      1.1
@@ -0,0 +1,330 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <iostream>
+#include <cerrno>
+#include <sys/mman.h>
+
+#include "stream.h"
+#include "network.h"
+#include "amf.h"
+#include "rtmp.h"
+#include "log.h"
+
+#include <boost/thread/mutex.hpp>
+static boost::mutex io_mutex;
+
+using namespace gnash;
+using namespace std;
+
+namespace cygnal {
+
+namespace {
+gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
+}
+
+#if 0
+static void
+sendfile_thread()
+{
+    GNASH_REPORT_FUNCTION;
+    
+    struct stat stats;
+    struct filedes loadfile;
+    int fd;
+    char *fdptr;
+    
+    memcpy(&loadfile, arg, sizeof(struct filedes));
+    
+    // Get the file stats
+    if (stat(loadfile.filespec, &stats) == 0) {
+
+       fd = open(loadfile.filespec, O_RDONLY);
+//     dbglogfile << "File " << loadfile.filespec
+//                << " is " << stats.st_size
+//                << " bytes in size." << endl;
+       if (fd) {
+           fdptr = static_cast<char *>(mmap(0, stats.st_size,
+                  PROT_READ, MAP_SHARED, fd, 0));
+       } else {
+           dbglogfile << "ERROR: Couldn't load "
+                      << loadfile.filespec << endl;
+       }
+       
+       if (fdptr == MAP_FAILED) {
+           dbglogfile << "ERROR: Couldn't map file "
+                      << loadfile.filespec << " into memory! "
+                      << strerror(errno) << endl;
+       } else {            
+           dbglogfile << "File " << loadfile.filespec
+                      << " mapped to: " << (void *)fdptr << endl;
+       }
+       
+//     if (stats.st_size > 1024*8) {
+//     }
+       
+//     if (stats.st_blksize > 10) {
+//     }
+
+//     if (stats.st_blocks > 10) {
+//     }
+    } else {
+       dbglogfile << "ERROR: File " << loadfile.filespec
+                  << " doesn't exist!" << endl;
+    }
+
+    int filesize = stats.st_size;
+    int blocksize = 8192;
+    char *tmpptr = fdptr;
+    int nbytes = 0;
+    Network net;
+    while ((_seekptr - _dataptr) <= RTMP_BODY_SIZE) {
+       if (filesize < RTMP_BODY_SIZE) {
+           nbytes = net.writeNet(loadfile.fd, tmpptr, filesize);
+           filesize = 0;
+       } else {
+           nbytes = net.writeNet(loadfile.fd, tmpptr, blocksize);
+           filesize -= blocksize;
+           tmpptr += blocksize;
+       }
+       
+       if (nbytes <= 0) {
+           dbglogfile << "Done..." << endl;
+           return &nbytes;
+       }
+    }
+          
+    close(fd);
+    munmap(fdptr, stats.st_size);
+}
+#endif
+
+Stream::Stream()
+    : _bytes(0),
+      _filefd(0),
+      _netfd(0),
+      _filespec(0),
+      _statistics(0),
+      _dataptr(0),
+      _seekptr(0),
+      _filesize(0)
+{
+    GNASH_REPORT_FUNCTION;
+    
+}
+
+Stream::~Stream() {
+    GNASH_REPORT_FUNCTION;
+    if (_filefd) {
+        close(_filefd);
+    }
+    if (_netfd) {
+        close(_netfd);
+    }
+}
+
+bool
+Stream::open(const char *filespec) {
+    GNASH_REPORT_FUNCTION;
+    
+    return open(filespec, _netfd);
+}
+
+bool
+Stream::open(const char *filespec, int netfd) {
+    GNASH_REPORT_FUNCTION;
+
+    struct stat stats;
+    return open(filespec, _netfd, _statistics);
+}
+
+bool
+Stream::open(const char *filespec, int netfd, Statistics  *statistics) {
+    GNASH_REPORT_FUNCTION;
+
+    struct stat st;
+
+    _netfd = netfd;
+    _statistics = statistics;
+
+    dbglogfile << "Trying to open " << filespec << endl;
+    
+    if (stat(filespec, &st) == 0) {
+        _filesize = st.st_size;
+        boost::mutex::scoped_lock lock(io_mutex);
+       _filefd = ::open(filespec, O_RDONLY);
+       dbglogfile << "File " << filespec
+                  << " is " << _filesize
+                  << " bytes in size." << endl;
+       if (_filefd) {
+           _dataptr = static_cast<unsigned char *>(mmap(0, _filesize,
+                  PROT_READ, MAP_SHARED, _filefd, 0));
+       } else {
+           dbglogfile << "ERROR: Couldn't load "
+                      << filespec << endl;
+            return false;
+       }
+       
+       if (_seekptr == MAP_FAILED) {
+           dbglogfile << "ERROR: Couldn't map file "
+                      << filespec << " into memory! "
+                      << strerror(errno) << endl;
+            return false;
+       } else {            
+           dbglogfile << "File " << filespec
+                      << " mapped to: " << (void *)_dataptr << endl;
+            _seekptr = _dataptr;
+            _state = OPEN;
+            return true;
+       }
+//     if (stats.st_size > 1024*8) {
+//     }
+       
+//     if (stats.st_blksize > 10) {
+//     }
+
+//     if (stats.st_blocks > 10) {
+//     }
+    } else {
+       dbglogfile << "ERROR: File " << filespec
+                  << " doesn't exist!" << endl;
+    }
+
+    
+    return true;
+}
+
+// Stream the movie
+bool
+Stream::play() {
+    GNASH_REPORT_FUNCTION;
+
+    return play(_netfd);
+}
+
+bool
+Stream::play(int netfd) {
+    GNASH_REPORT_FUNCTION;
+
+    _netfd = netfd;
+    _state = PLAY;
+
+    while (_state != DONE) {
+        switch (_state) {
+          case PLAY:
+              _state = DONE;
+              break;
+          case PREVIEW:
+              break;
+          case THUMBNAIL:
+              break;
+          case PAUSE:
+              break;
+          case SEEK:
+              break;
+          case UPLOAD:
+              break;
+          case MULTICAST:
+              break;
+          case DONE:
+              break;
+          default:
+              break;
+        }
+    }
+
+    int blocksize = 8192;
+    int nbytes = 0;
+    Network net;
+//    while ((_seekptr - _dataptr) >= 0) {
+    nbytes = net.writeNet(_netfd, (char *)_seekptr, _filesize);
+//    if (nbytes <= 0) {
+//        break;
+//    }
+    _statistics->addBytes(nbytes);
+    _bytes += nbytes;
+    _seekptr += nbytes;
+       
+    dbglogfile << "Done..." << endl;
+          
+    munmap(_dataptr, _filesize);
+    _seekptr = 0;
+
+    return true;
+}
+
+// Stream a preview, instead of the full movie.
+bool
+Stream::preview(const char *filespec, int frames) {
+    GNASH_REPORT_FUNCTION;
+
+    _state = PREVIEW;
+}
+
+// Stream a series of thumbnails
+bool
+Stream::thumbnail(const char *filespec, int quantity) {
+    GNASH_REPORT_FUNCTION;
+    
+    _state = THUMBNAIL;
+}
+
+// Pause the stream
+bool
+Stream::pause(int frame) {
+    GNASH_REPORT_FUNCTION;
+    
+    _state = PAUSE;
+}
+
+// Seek within the stream
+bool
+Stream::seek(int frame) {
+    GNASH_REPORT_FUNCTION;
+    
+    _state = SEEK;
+}
+
+// Upload a stream into a sandbox
+bool
+Stream::upload(const char *filespec) {
+    GNASH_REPORT_FUNCTION;
+    
+    _state = UPLOAD;
+}
+
+// Stream a single "real-time" source.
+bool Stream::multicast(const char *filespec) {
+    GNASH_REPORT_FUNCTION;
+    
+    _state = MULTICAST;
+}
+
+} // end of cygnal namespace
+
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: stream.h
===================================================================
RCS file: stream.h
diff -N stream.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ stream.h    17 Dec 2006 02:34:58 -0000      1.1
@@ -0,0 +1,84 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef __STREAM_H__
+#define __STREAM_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "statistics.h"
+
+namespace cygnal {
+
+class Stream {
+public:
+    typedef enum {
+        NO_STATE,
+        OPEN,
+        PLAY,
+        PREVIEW,
+        THUMBNAIL,
+        PAUSE,
+        SEEK,
+        UPLOAD,
+        MULTICAST,
+        DONE
+    } state_e;  
+    Stream();
+    ~Stream();
+    bool open(const char *filespec);
+    bool open(const char *filespec, int netfd);
+    bool open(const char *filespec, int netfd, Statistics  *statistics);
+    // Stream the movie
+    bool play();
+    bool play(int netfd);
+    // Stream a preview, instead of the full movie.
+    bool preview(const char *filespec, int frames);
+    // Stream a series of thumbnails
+    bool thumbnail(const char *filespec, int quantity);
+    // Pause the stream
+    bool pause(int frame);
+    // Seek within the stream
+    bool seek(int frame);
+    // Upload a stream into a sandbox
+    bool upload(const char *filespec);
+    // Stream a single "real-time" source.
+    bool multicast(const char *filespec);
+
+private:
+    state_e     _state;
+    int         _bytes;
+    int         _filefd;
+    int         _netfd;
+    char        *_filespec;
+    Statistics  *_statistics;
+    unsigned char *_dataptr;
+    unsigned char *_seekptr;
+    int          _filesize;
+};
+ 
+} // end of cygnal namespace
+
+
+#endif // __STREAM_H__
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:




reply via email to

[Prev in Thread] Current Thread [Next in Thread]