[xiph-commits] r3132 - liboggplay/trunk/plugin

shans at svn.annodex.net shans at svn.annodex.net
Thu Jun 28 17:27:49 PDT 2007


Author: shans
Date: 2007-06-28 17:27:49 -0700 (Thu, 28 Jun 2007)
New Revision: 3132

Added:
   liboggplay/trunk/plugin/plugin_cmml.c
   liboggplay/trunk/plugin/plugin_cmml.h
Log:
Actual asynchronous recieve functionality



Added: liboggplay/trunk/plugin/plugin_cmml.c
===================================================================
--- liboggplay/trunk/plugin/plugin_cmml.c	                        (rev 0)
+++ liboggplay/trunk/plugin/plugin_cmml.c	2007-06-29 00:27:49 UTC (rev 3132)
@@ -0,0 +1,368 @@
+/*
+   Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+   Organisation (CSIRO) Australia
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   - Neither the name of CSIRO Australia nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+   PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * plugin_cmml.c
+ * 
+ * Shane Stephens <shane.stephens at annodex.net>
+ *
+ * oggplay_* functions in this file dodgily copied from oggplay_tcp_reader.c
+ * because poor widdle windows can't handle even mildy complicated cases of
+ * #include dependencies.  Honestly, I wonder if that child will ever grow
+ * up normal.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <oggplay/oggplay.h>
+
+#ifdef WIN32
+#include <process.h>
+#include <io.h>
+
+#else
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/fcntl.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <time.h>
+#include <netdb.h>
+#include <unistd.h>
+#endif
+
+#include <assert.h>
+#include <pthread.h>
+
+#include "plugin_cmml.h"
+
+#define PRINT_BUFFER(s,m) \
+    printf("%s: in_mem: %d size: %d pos: %d stored: %d\n", \
+            s, m->amount_in_memory, m->buffer_size, \
+            m->current_position, m->stored_offset);
+
+#ifndef WIN32
+typedef int SOCKET;
+#define INVALID_SOCKET  -1
+#endif
+
+#define START_TIMEOUT(ref) \
+  (ref) = oggplay_sys_time_in_ms()
+
+#ifdef WIN32 
+#define CHECK_ERROR(error) \
+  (WSAGetLastError() == WSA##error)
+#else
+#define CHECK_ERROR(error) \
+  (errno == error)
+#endif
+
+#define RETURN_ON_TIMEOUT_OR_CONTINUE(ref)        \
+  if (oggplay_sys_time_in_ms() - (ref) > 500) {   \
+    return E_OGGPLAY_TIMEOUT;                     \
+  } else {                                        \
+    oggplay_millisleep(10);                       \
+    continue;                                     \
+  }
+
+static SOCKET
+oggplay_create_socket() {
+  SOCKET sock;
+
+#ifdef WIN32	
+  WORD                  wVersionRequested;
+  WSADATA               wsaData;
+#ifdef HAVE_WINSOCK2        
+  wVersionRequested = MAKEWORD(2,2);
+#else
+  wVersionRequested = MAKEWORD(1,1);
+#endif    
+  if (WSAStartup(wVersionRequested, &wsaData) == -1) {
+    printf("Socket open error\n");
+    return INVALID_SOCKET;
+  }
+  if (wsaData.wVersion != wVersionRequested) {
+    printf("Incorrect winsock version [%d]\n", wVersionRequested);
+    WSACleanup();
+    return INVALID_SOCKET;
+  }
+#endif
+
+  sock = socket(PF_INET, SOCK_STREAM, 0);
+  if (sock == INVALID_SOCKET) {
+    printf("Could not create socket\n");
+#ifdef WIN32
+    WSACleanup();
+#endif
+    return INVALID_SOCKET;
+  }
+
+  return sock;
+}
+
+/*
+ * this function guarantees it will return malloced versions of host and 
+ * path
+ */
+static void
+oggplay_hostname_and_path(char *location, char *proxy, int proxy_port,
+                                  char **host, int *port, char **path) {
+
+
+  char  * colon;
+  char  * slash;
+  char  * end_of_host;
+
+  /* if we have a proxy installed this is all dead simple */
+  if (proxy != NULL) {
+    *host = strdup(proxy);
+    *port = proxy_port;
+    *path = strdup(location);
+    return;
+  }
+
+  /* find start_pos */
+  if (strncmp(location, "http://", 7) == 0) {
+    location += 7;
+  }
+
+  colon = strchr(location, ':');
+  slash = strchr(location, '/');
+
+  /*
+   * if both are null, then just set the simple defaults and return
+   */
+  if (colon == NULL && slash == NULL) {
+    *host = strdup(location);
+    *port = 80;
+    *path = strdup("/");
+    return;
+  }
+
+  /* 
+   * if there's a slash and it's before colon, there's no port.  Hence, after
+   * this code, the only time that there's a port is when colon is non-NULL
+   */
+  if (slash != NULL && colon > slash) {
+    colon = NULL;
+  }
+
+  /*
+   * we might as well extract the port now.  We can also work out where
+   * the end of the hostname is, as it's either the colon (if there's a port)
+   * or the slash (if there's no port)
+   */
+  if (colon != NULL) {
+    *port = (int)strtol(colon+1, NULL, 10);
+    end_of_host = colon;
+  } else {
+    *port = 80;
+    end_of_host = slash;
+  }
+
+  *host = strdup(location);
+  (*host)[end_of_host - location] = '\0';
+
+  if (slash == NULL) {
+    *path = strdup("/");
+    return;
+  }
+
+  *path = strdup(slash);
+
+}
+
+static OggPlayErrorCode
+oggplay_connect_to_host(SOCKET socket, struct sockaddr *addr) {
+
+  ogg_int64_t           time_ref;
+
+  START_TIMEOUT(time_ref);
+
+  while (connect(socket, addr, sizeof(struct sockaddr_in)) < 0) {
+    if (
+        CHECK_ERROR(EINPROGRESS) || CHECK_ERROR(EALREADY)
+#ifdef WIN32
+          /* see http://msdn2.microsoft.com/en-us/library/ms737625.aspx */
+        || CHECK_ERROR(EWOULDBLOCK) || CHECK_ERROR(EINVAL)
+#endif      
+    ) {
+      RETURN_ON_TIMEOUT_OR_CONTINUE(time_ref);
+    } 
+    else if CHECK_ERROR(EISCONN) 
+    {
+      break;
+    }
+    printf("Could not connect to host; error code is %d\n", errno);
+    return CHECK_ERROR(ETIMEDOUT) ? E_OGGPLAY_TIMEOUT : 
+                                              E_OGGPLAY_SOCKET_ERROR;
+  }
+
+  return E_OGGPLAY_OK;
+
+}
+
+char *
+get_all_cmml(char *location, char *proxy, int proxy_port) {
+
+  char              * host;
+  char              * path;
+  int                 port;
+  char                http_request_header[1024];
+  SOCKET              socket                = oggplay_create_socket();
+  struct sockaddr_in  addr;
+  struct hostent    * he;
+  int                 r;
+  char              * buffer                = NULL;
+  int                 n_chunks              = 0;
+  int                 bytes_read            = 0;
+  
+  if (socket == INVALID_SOCKET) return NULL;
+
+  oggplay_hostname_and_path(location, proxy, proxy_port, &host, &port, &path);
+
+  snprintf(http_request_header, 1024,
+      "GET %s HTTP/1.0\n"
+      "Host: %s\n"
+      "User-Agent: AnnodexFirefoxPlugin/0.1\n"
+      "Accept: */*\n"
+      "Connection: Keep-Alive\n\n", path, host);
+
+  he = gethostbyname(host);
+
+  free(host);
+  free(path);
+
+  if (he == NULL) {
+    return NULL;
+  }
+
+  memcpy(&addr.sin_addr.s_addr, he->h_addr, he->h_length);
+  addr.sin_family = AF_INET;
+  addr.sin_port = htons(port);
+
+  r = oggplay_connect_to_host(socket, (struct sockaddr *)&addr);
+  if (r != E_OGGPLAY_OK) return NULL;
+
+#ifdef WIN32
+  r = send(socket, http_request_header, strlen(http_request_header), 0);
+#else
+  r = write(socket, http_request_header, strlen(http_request_header));
+#endif
+
+  if (r < 0) return NULL;
+
+#define CHUNK_SIZE    2048
+
+  while (1) {
+
+    n_chunks ++;
+    buffer = realloc(buffer, CHUNK_SIZE * n_chunks);
+
+#ifdef WIN32
+    r = recv(socket, buffer + bytes_read, CHUNK_SIZE, 0);
+#else
+    r = read(socket, buffer + bytes_read, CHUNK_SIZE);
+#endif
+
+    if (r < 0) {
+      free(buffer);
+#ifdef WIN32
+      closesocket(socket);
+#else
+      close(socket);
+#endif
+      return NULL;
+    }
+
+    if (r == 0) {
+      buffer[bytes_read] = '\0';
+#ifdef WIN32
+      closesocket(socket);
+#else
+      close(socket);
+#endif
+      return buffer;
+    }
+
+    bytes_read += r;
+  }
+
+}
+
+typedef struct {
+  char              * file;
+  char              * proxy;
+  int                 proxyPort;
+  nsPluginInstance  * plugin;
+} CmmlThreadInfo;
+
+static void *
+cmml_thread(void *handle) {
+
+  CmmlThreadInfo  * info = (CmmlThreadInfo *)handle;
+  char            * cmml;
+
+  cmml = get_all_cmml(info->file, info->proxy, info->proxyPort);
+  if (cmml == NULL) {
+    return NULL;
+  }
+
+  onCMMLData(info->plugin, &cmml, 1, 1);
+  return NULL;
+
+}
+
+void
+start_cmml_thread(nsPluginInstance *i, const char *movie, char *proxy, 
+                                                            int proxyPort) {
+
+  CmmlThreadInfo  * info;
+  char            * mdot  = strrchr(movie, '.');
+  char            * fname = malloc(mdot - movie + 6);
+  pthread_t         thread;
+  
+  strcpy(fname, movie);
+  strcpy(fname + (mdot - movie), ".cmml");
+
+  info = malloc(sizeof(CmmlThreadInfo));
+  info->file      = fname;
+  info->proxy     = proxy;
+  info->proxyPort = proxyPort;
+  info->plugin    = i;
+
+  pthread_create(&thread, NULL, cmml_thread, (void *)info);
+
+}

Added: liboggplay/trunk/plugin/plugin_cmml.h
===================================================================
--- liboggplay/trunk/plugin/plugin_cmml.h	                        (rev 0)
+++ liboggplay/trunk/plugin/plugin_cmml.h	2007-06-29 00:27:49 UTC (rev 3132)
@@ -0,0 +1,52 @@
+/*
+   Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+   Organisation (CSIRO) Australia
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   - Neither the name of CSIRO Australia nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+   PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * plugin_cmml.c
+ * 
+ * Shane Stephens <shane.stephens at annodex.net>
+ *
+ * oggplay_* functions in this file dodgily copied from oggplay_tcp_reader.c
+ * because poor widdle windows can't handle even mildy complicated cases of
+ * #include dependencies.  Honestly, I wonder if that child will ever grow
+ * up normal.
+ */
+#ifndef _PLUGIN_CMML_H
+#define _PLUGIN_CMML_H
+
+#include "plugin_c.h"
+
+void
+start_cmml_thread(nsPluginInstance *i, const char *movie, char *proxy, 
+                                                            int proxyPort);
+
+#endif



More information about the commits mailing list