[xiph-commits] r10216 - trunk/xiph-rtp

lu_zero at svn.xiph.org lu_zero at svn.xiph.org
Thu Oct 20 14:58:43 PDT 2005


Author: lu_zero
Date: 2005-10-20 14:58:37 -0700 (Thu, 20 Oct 2005)
New Revision: 10216

Added:
   trunk/xiph-rtp/vorbisrtp-client.c
   trunk/xiph-rtp/vorbisrtp.c
Removed:
   trunk/xiph-rtp/vorbisrtp-client2.c
   trunk/xiph-rtp/vorbisrtp2.c
Log:
Draft reference updated

Copied: trunk/xiph-rtp/vorbisrtp-client.c (from rev 10214, trunk/xiph-rtp/vorbisrtp-client2.c)
===================================================================
--- trunk/xiph-rtp/vorbisrtp-client2.c	2005-10-20 17:21:37 UTC (rev 10214)
+++ trunk/xiph-rtp/vorbisrtp-client.c	2005-10-20 21:58:37 UTC (rev 10216)
@@ -0,0 +1,494 @@
+/* Copyright (C) 2005 Xiph.org Foundation
+
+   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 the Xiph.org Foundation 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 FOUNDATION
+   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.
+*/
+
+/* sample RTP Vorbis client */
+
+/* compile with: gcc -g -O2 -Wall -o vorbisrtp-client vorbisrtp-client.c -logg 
+ * append -DCHECK -lvorbis to enable header checks*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ogg/ogg.h>
+#include <vorbis/codec.h>
+
+#define MAX_PACKET 1500
+
+#define MAX(x,y) (((x) > (y)) ? (x) : (y))
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+
+typedef struct ogg_context {
+	ogg_packet op;
+	ogg_stream_state os;
+	ogg_page og;
+
+	vorbis_info vi;
+	vorbis_comment vc;
+	vorbis_dsp_state vd;
+	vorbis_block vb;
+	int frag;
+	float **pcm;
+	unsigned int timestamp;
+} ogg_context_t; 
+
+
+int
+dump_packet_raw (unsigned char *data, const int len, FILE * out)
+{
+  int i, j, n;
+
+  i = 0;
+  while (i < len)
+    {
+      fprintf (out, " %04x ", i);
+      n = MIN (8, len - i);
+      for (j = 0; j < n; j++)
+	fprintf (out, " %02x", data[i + j]);
+      fprintf (out, " ");
+      n = MIN (16, len - i);
+      for (j = 8; j < 16; j++)
+	fprintf (out, " %02x", data[i + j]);
+      fprintf (out, "   ");
+      for (j = 0; j < n; j++)
+	fprintf (out, "%c", isprint (data[i + j]) ? data[i + j] : '.');
+      fprintf (out, "\n");
+      i += 16;
+    }
+
+  return 0;
+}
+
+int
+dump_packet_rtp (unsigned char *data, const int len, FILE * out)
+{
+  int V, P, X, CC, M, PT;
+  unsigned short sequence;
+  unsigned int timestamp, ssrc;
+  unsigned int ident;
+  int F, VDT, pkts;
+  int i, offset, length;
+
+  /* parse RTP header */
+  V = (data[0] & 0xc0) >> 6;
+  P = (data[0] & 0x40) >> 5;
+  X = (data[0] & 0x20) >> 4;
+  CC = (data[0] & 0x0f);
+  M = (data[1] & 0x80) >> 7;
+  PT = (data[1] & 0x7F);
+  sequence = ntohs (((unsigned short *) data)[1]);
+  timestamp = ntohl (((unsigned int *) data)[1]);
+  ssrc = ntohl (((unsigned int *) data)[2]);
+
+  fprintf (out, "RTP packet V:%d P:%d X:%d M:%d PT:%d", V, P, X, M, PT);
+  fprintf (out, "   seq %d", sequence);
+  fprintf (out, "   timestamp: %u\n", timestamp);
+  fprintf (out, " ssrc: 0x%08x", ssrc);
+  if (CC)
+    for (i = 0; i < CC; i++)
+      fprintf (out, " csrc: 0x%08x",
+	       ntohl (((unsigned int *) data)[3 + i]));
+  else
+    fprintf (out, " no csrc");
+  fprintf (out, "\n");
+  /* offset to payload header */
+  offset = (3 + CC) * 4;
+
+  /* parse Vorbis payload header */
+  ident = data[offset++]<<16;
+  ident += data[offset++]<<8;
+  ident += data[offset++];
+  F = (data[offset] & 0xc0) >> 6;
+  VDT = (data[offset] & 0x30) >> 4;
+  pkts = (data[offset] & 0x0F);
+  offset++;
+  
+  fprintf(out,"ident %06x, frag type %d, data type %d, pkts %d, size %d\n",
+		  ident,F,VDT,pkts,len-4*(CC+3));
+ 
+  for (i = 0; i < pkts; i++)
+    {
+      if (offset >= len)
+	{
+	  fprintf (stderr, "payload length overflow. corrupt packet?\n");
+	  return -1;
+	}
+      length = data[offset++]<<8;
+      length += data[offset++];
+      fprintf (out, "  data: %d bytes in block %d\n", length, i);
+      offset += length;
+    }
+  if (pkts == 0)
+    {
+      length = data[offset++]<<8;
+      length += data [offset++];
+      fprintf (out, "  data: %d bytes in fragment\n", length);
+      offset += length;
+    }
+
+  if (len - offset > 0)
+    fprintf (out, "  %d unused bytes at the end of the packet!\n",
+	     len - offset);
+
+  return 0;
+}
+
+int
+cfg_repack(ogg_context_t *ogg, FILE* out)
+{
+  ogg_packet id,co,cb;
+  char comment[] = 
+/*  Example
+ *  {3,118,111,114,98,105,115,
+	  29,0,0,0,
+	  	88,105,112,104,46,79,114,103,32,108,105,98,86,111,114,98,105,115,32,73,32,50,48,48,50,48,55,49,55,
+	  5,0,0,0, 
+	  	18,0,0,0,
+			65,114,116,105,115,116,61,76,97,99,117,110,97,32,67,111,105,108,
+		10,0,0,0,
+			84,105,116,108,101,61,67,111,108,100,
+		18,0,0,0,
+			65,108,98,117,109,61,73,110,32,97,32,82,101,118,101,114,105,101,
+		15,0,0,0,
+			71,101,110,114,101,61,72,97,114,100,32,82,111,99,107,
+		9,0,0,0,
+			89,101,97,114,61,49,57,57,57,
+  1};
+*/
+   /*quite minimal comment*/
+   { 3,'v','o','r','b','i','s', 
+   	10,0,0,0, 
+   		'v','o','r','b','i','s','-','r','t','p',
+   		0,0,0,0, 
+                1};
+  
+/* get the identification packet*/
+  id.packet = ogg->op.packet;
+  id.bytes = 30;
+  id.b_o_s = 1;
+  id.e_o_s = 0;
+  id.granulepos = 0;
+
+
+/* get the comment packet*/
+  co.packet = comment;
+  co.bytes = sizeof(comment);
+  co.b_o_s = 0;
+  co.e_o_s = 0;
+  co.granulepos = 0;
+
+/* get the setup packet*/
+  cb.packet = ogg->op.packet + 30;
+  cb.bytes = ogg->op.bytes - 30;
+  cb.b_o_s = 0;
+  cb.e_o_s = 0;
+  cb.granulepos = 0;
+
+/* get the sample rate from the info packet */
+  ogg->vi.rate=id.packet[12];
+  ogg->vi.rate+=id.packet[12+1]<<8;
+  ogg->vi.rate+=id.packet[12+2]<<8;
+  ogg->vi.rate+=id.packet[12+3]<<24;
+#if CHECK
+  fprintf(stderr,"parsed rate: %d\n",ogg->vi.rate);
+  vorbis_info_init(&ogg->vi);
+  vorbis_comment_init(&ogg->vc);
+  if(vorbis_synthesis_headerin(&ogg->vi,&ogg->vc,&id)<0){
+	      /* error case; not a vorbis header */
+	  fprintf(stderr,"Not valid identification\n");
+  } else fprintf(stderr,"  Valid identification\n");
+  if(vorbis_synthesis_headerin(&ogg->vi,&ogg->vc,&co)<0){
+	      /* error case; not a vorbis header */
+	  fprintf(stderr,"Not valid comment\n");
+  } else fprintf(stderr,"  Valid comment\n");
+  if(vorbis_synthesis_headerin(&ogg->vi,&ogg->vc,&cb)<0){
+	      /* error case; not a vorbis header */
+	  fprintf(stderr,"Not valid setup\n");
+  } else fprintf(stderr,"  Valid setup\n");
+  fprintf(stderr,"decoded rate: %d\n",ogg->vi.rate);
+#endif
+/* start the ogg*/
+  ogg_stream_init(&ogg->os,rand());
+
+  ogg_stream_packetin(&ogg->os,&id);
+  ogg_stream_packetin(&ogg->os,&co);
+  ogg_stream_packetin(&ogg->os,&cb);
+//  ogg->op.b_o_s=1;
+  do{
+    int result=ogg_stream_flush(&ogg->os,&ogg->og);
+    if(result==0)break;
+    fwrite(ogg->og.header,1,ogg->og.header_len,out);
+    fwrite(ogg->og.body,1,ogg->og.body_len,out);
+    }while(!ogg_page_eos(&ogg->og));
+  return 3;
+}
+
+int
+pkt_repack(ogg_context_t *ogg, FILE *out){
+  ogg_stream_packetin(&ogg->os,&ogg->op);
+  do{
+    int result=ogg_stream_pageout(&ogg->os,&ogg->og);
+    if(result==0)break;
+    fwrite(ogg->og.header,1,ogg->og.header_len,out);
+    fwrite(ogg->og.body,1,ogg->og.body_len,out);
+  }while(!ogg_page_eos(&ogg->og));
+  return 1;
+}
+
+	
+int
+dump_packet_ogg (unsigned char *data, const int len, FILE * out, ogg_context_t *ogg)
+{
+  int V, P, X, CC, M, PT;
+  unsigned short sequence;
+  unsigned int timestamp, ssrc;
+  unsigned int ident;
+  int F, VDT, pkts;
+  int i, offset, length, count = 0;
+  ogg_packet *op = &ogg->op;
+
+  /* parse RTP header */
+  V = (data[0] & 0xc0) >> 6;
+  P = (data[0] & 0x40) >> 5;
+  X = (data[0] & 0x20) >> 4;
+  CC = (data[0] & 0x0f);
+  M = (data[1] & 0x80) >> 7;
+  PT = (data[1] & 0x7F);
+  sequence = ntohs (((unsigned short *) data)[1]);
+  //FIXME not exactly ideal
+  timestamp = ntohl (((unsigned int *) data)[1]) - ogg->timestamp;
+  ogg->timestamp = ntohl (((unsigned int *) data)[1]);
+  ssrc = ntohl (((unsigned int *) data)[2]);
+  /* offset to payload header */
+  offset = (3 + CC) * 4;
+
+  /* parse Vorbis payload header */
+  ident = data[offset++]<<16;
+  ident += data[offset++]<<8;
+  ident += data[offset++];
+  F = (data[offset] & 0xc0) >> 6;
+  VDT = (data[offset] & 0x30) >> 4;
+  pkts = (data[offset] & 0x0F);
+  offset++;
+  
+  switch (F) {
+
+  case 0:
+    
+    break;
+  case 1:
+    op->bytes = 0;
+    
+  case 2:
+    length = data[offset++] << 8;
+    length += data[offset++];
+    op->packet = realloc (op->packet, length+op->bytes);
+    memcpy (op->packet + op->bytes, data + offset, length);
+    op->bytes += length;
+    return 0;
+  case 3:
+    length = data[offset++] << 8;
+    length += data[offset++];
+    op->packet = realloc (op->packet, length+op->bytes);
+    memcpy (op->packet + op->bytes, data + offset, length);
+    op->bytes += length;
+    pkts=1;
+    break;
+  default:
+    fprintf (stderr, " unknown frament?!\n");
+    return 0;
+  }
+  
+  switch (VDT) {
+
+  case 0:
+  for (i = 0; i < pkts; i++)
+    {
+      if (offset >= len)
+	{
+	  fprintf (stderr, "payload length overflow. corrupt packet?\n");
+	  return -1;
+	}
+      op->bytes = data[offset++]<<8;
+      op->bytes += data[offset++];
+      op->packet = &data[offset];
+      //FIXME should be a better way
+      op->granulepos+=timestamp*ogg->vi.rate/1000000L;
+      op->packetno++;
+      count += pkt_repack(ogg,out);
+      offset += op->bytes;
+      op->b_o_s=0;
+    }   
+    break;
+  case 1:
+    count = cfg_repack(ogg, out);
+    break;
+  default:
+    //ignore
+    break;
+    
+  }
+  if (F == 3) free(op->packet);
+
+  return count;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int RTPSocket, ret;
+  FILE *file;
+  int optval = 0, decode = 0, dump = 0, opt;
+  struct sockaddr_in us, them;
+  struct ip_mreq group;
+  unsigned char data[MAX_PACKET];
+  char *hostname = "227.0.0.1", *filename = "out.ogg";
+  unsigned int port = 4044;
+
+  ogg_context_t ogg;
+  memset(&ogg,0,sizeof(ogg_context_t)); 
+  fprintf (stderr,
+	   "||---------------------------------------------------------------------------||\n");
+
+  fprintf (stderr, "||  Vorbis RTP Client (draft-kerr-avt-vorbis-rtp-05)\n");
+
+  while ((opt = getopt (argc, argv, "i:p:f:")) != -1)
+    {
+      switch (opt)
+	{
+
+	  /*  Set IP address  */
+	case 'i':
+	  hostname = optarg;
+	  break;
+
+	  /*  Set port  */
+	case 'p':
+	  port = atoi (optarg);
+	  break;
+
+	  /*  Set TTL value  */
+	case 'f':
+	  filename = optarg;
+	  dump = 1;
+	  break;
+
+	  /* Unknown option  */
+	case '?':
+	  fprintf (stderr, "\n||  Unknown option `-%c'.\n", optopt);
+	  fprintf (stderr, "||  Usage: vorbisrtp-client [-i ip address] [-p port] [-f filename]");
+	  return 1;
+	}
+    }
+
+  fprintf (stderr, "Opening connection to %s port %d\n", hostname, port);
+
+  RTPSocket = socket (AF_INET, SOCK_DGRAM, 0);
+
+  if (RTPSocket < 0)
+    {
+      fprintf (stderr, "Unable to create socket.\n");
+      exit (1);
+    }
+
+  us.sin_family = AF_INET;
+  us.sin_addr.s_addr = htonl (INADDR_ANY);
+  us.sin_port = htons (port);
+  ret = bind (RTPSocket, (struct sockaddr *) &us, sizeof (us));
+  if (ret < 0)
+    {
+      fprintf (stderr, "Unable to bind socket!\n");
+      exit (1);
+    }
+
+  them.sin_family = AF_INET;
+  them.sin_addr.s_addr = inet_addr (hostname);
+  them.sin_port = htons (port);
+
+  if (!IN_MULTICAST (ntohl (them.sin_addr.s_addr)))
+    {
+      fprintf (stderr, "not a multicast address\n");
+    }
+  else
+    {
+      fprintf (stderr, "joining multicast group...\n");
+      group.imr_multiaddr.s_addr = them.sin_addr.s_addr;
+      group.imr_interface.s_addr = htonl (INADDR_ANY);
+      ret = setsockopt (RTPSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+			(void *) &group, sizeof (group));
+      if (ret < 0)
+	{
+	  fprintf (stderr, "cannot join multicast group!\n");
+	  exit (1);
+	}
+    }
+  if (dump)
+    {
+      if (strcmp (filename, "-"))
+	{
+	  file = fopen (filename, "wb");
+	  if (file == NULL)
+	    {
+	      fprintf (stderr, "Unable to open %s\n", filename);
+	      exit (1);
+	    }
+	}
+      else
+      {
+	      file = stdout;
+	      filename = "Standard Output";
+      }
+      
+      fprintf (stderr, "Dumping the stream to %s\n", filename);
+    }
+
+  while (1)
+    {
+      ret = recvfrom (RTPSocket, data, MAX_PACKET, 0, NULL, 0);
+      fprintf (stderr, "read %d bytes of data\n", ret);
+      
+      dump_packet_rtp (data, ret, stderr);
+      if (dump){
+	dump_packet_ogg (data, ret, file, &ogg);
+	fflush(NULL);
+      }
+    }
+
+  return 0;
+}

Deleted: trunk/xiph-rtp/vorbisrtp-client2.c
===================================================================
--- trunk/xiph-rtp/vorbisrtp-client2.c	2005-10-20 21:56:56 UTC (rev 10215)
+++ trunk/xiph-rtp/vorbisrtp-client2.c	2005-10-20 21:58:37 UTC (rev 10216)
@@ -1,494 +0,0 @@
-/* Copyright (C) 2005 Xiph.org Foundation
-
-   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 the Xiph.org Foundation 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 FOUNDATION
-   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.
-*/
-
-/* sample RTP Vorbis client */
-
-/* compile with: gcc -g -O2 -Wall -o vorbisrtp-client vorbisrtp-client.c -logg 
- * append -DCHECK -lvorbis to enable header checks*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <ogg/ogg.h>
-#include <vorbis/codec.h>
-
-#define MAX_PACKET 1500
-
-#define MAX(x,y) (((x) > (y)) ? (x) : (y))
-#define MIN(x,y) (((x) < (y)) ? (x) : (y))
-
-typedef struct ogg_context {
-	ogg_packet op;
-	ogg_stream_state os;
-	ogg_page og;
-
-	vorbis_info vi;
-	vorbis_comment vc;
-	vorbis_dsp_state vd;
-	vorbis_block vb;
-	int frag;
-	float **pcm;
-	unsigned int timestamp;
-} ogg_context_t; 
-
-
-int
-dump_packet_raw (unsigned char *data, const int len, FILE * out)
-{
-  int i, j, n;
-
-  i = 0;
-  while (i < len)
-    {
-      fprintf (out, " %04x ", i);
-      n = MIN (8, len - i);
-      for (j = 0; j < n; j++)
-	fprintf (out, " %02x", data[i + j]);
-      fprintf (out, " ");
-      n = MIN (16, len - i);
-      for (j = 8; j < 16; j++)
-	fprintf (out, " %02x", data[i + j]);
-      fprintf (out, "   ");
-      for (j = 0; j < n; j++)
-	fprintf (out, "%c", isprint (data[i + j]) ? data[i + j] : '.');
-      fprintf (out, "\n");
-      i += 16;
-    }
-
-  return 0;
-}
-
-int
-dump_packet_rtp (unsigned char *data, const int len, FILE * out)
-{
-  int V, P, X, CC, M, PT;
-  unsigned short sequence;
-  unsigned int timestamp, ssrc;
-  unsigned int ident;
-  int F, VDT, pkts;
-  int i, offset, length;
-
-  /* parse RTP header */
-  V = (data[0] & 0xc0) >> 6;
-  P = (data[0] & 0x40) >> 5;
-  X = (data[0] & 0x20) >> 4;
-  CC = (data[0] & 0x0f);
-  M = (data[1] & 0x80) >> 7;
-  PT = (data[1] & 0x7F);
-  sequence = ntohs (((unsigned short *) data)[1]);
-  timestamp = ntohl (((unsigned int *) data)[1]);
-  ssrc = ntohl (((unsigned int *) data)[2]);
-
-  fprintf (out, "RTP packet V:%d P:%d X:%d M:%d PT:%d", V, P, X, M, PT);
-  fprintf (out, "   seq %d", sequence);
-  fprintf (out, "   timestamp: %u\n", timestamp);
-  fprintf (out, " ssrc: 0x%08x", ssrc);
-  if (CC)
-    for (i = 0; i < CC; i++)
-      fprintf (out, " csrc: 0x%08x",
-	       ntohl (((unsigned int *) data)[3 + i]));
-  else
-    fprintf (out, " no csrc");
-  fprintf (out, "\n");
-  /* offset to payload header */
-  offset = (3 + CC) * 4;
-
-  /* parse Vorbis payload header */
-  ident = data[offset++]<<16;
-  ident += data[offset++]<<8;
-  ident += data[offset++];
-  F = (data[offset] & 0xc0) >> 6;
-  VDT = (data[offset] & 0x30) >> 4;
-  pkts = (data[offset] & 0x0F);
-  offset++;
-  
-  fprintf(out,"ident %06x, frag type %d, data type %d, pkts %d, size %d\n",
-		  ident,F,VDT,pkts,len-4*(CC+3));
- 
-  for (i = 0; i < pkts; i++)
-    {
-      if (offset >= len)
-	{
-	  fprintf (stderr, "payload length overflow. corrupt packet?\n");
-	  return -1;
-	}
-      length = data[offset++]<<8;
-      length += data[offset++];
-      fprintf (out, "  data: %d bytes in block %d\n", length, i);
-      offset += length;
-    }
-  if (pkts == 0)
-    {
-      length = data[offset++]<<8;
-      length += data [offset++];
-      fprintf (out, "  data: %d bytes in fragment\n", length);
-      offset += length;
-    }
-
-  if (len - offset > 0)
-    fprintf (out, "  %d unused bytes at the end of the packet!\n",
-	     len - offset);
-
-  return 0;
-}
-
-int
-cfg_repack(ogg_context_t *ogg, FILE* out)
-{
-  ogg_packet id,co,cb;
-  char comment[] = 
-/*  Example
- *  {3,118,111,114,98,105,115,
-	  29,0,0,0,
-	  	88,105,112,104,46,79,114,103,32,108,105,98,86,111,114,98,105,115,32,73,32,50,48,48,50,48,55,49,55,
-	  5,0,0,0, 
-	  	18,0,0,0,
-			65,114,116,105,115,116,61,76,97,99,117,110,97,32,67,111,105,108,
-		10,0,0,0,
-			84,105,116,108,101,61,67,111,108,100,
-		18,0,0,0,
-			65,108,98,117,109,61,73,110,32,97,32,82,101,118,101,114,105,101,
-		15,0,0,0,
-			71,101,110,114,101,61,72,97,114,100,32,82,111,99,107,
-		9,0,0,0,
-			89,101,97,114,61,49,57,57,57,
-  1};
-*/
-   /*quite minimal comment*/
-   { 3,'v','o','r','b','i','s', 
-   	10,0,0,0, 
-   		'v','o','r','b','i','s','-','r','t','p',
-   		0,0,0,0, 
-                1};
-  
-/* get the identification packet*/
-  id.packet = ogg->op.packet;
-  id.bytes = 30;
-  id.b_o_s = 1;
-  id.e_o_s = 0;
-  id.granulepos = 0;
-
-
-/* get the comment packet*/
-  co.packet = comment;
-  co.bytes = sizeof(comment);
-  co.b_o_s = 0;
-  co.e_o_s = 0;
-  co.granulepos = 0;
-
-/* get the setup packet*/
-  cb.packet = ogg->op.packet + 30;
-  cb.bytes = ogg->op.bytes - 30;
-  cb.b_o_s = 0;
-  cb.e_o_s = 0;
-  cb.granulepos = 0;
-
-/* get the sample rate from the info packet */
-  ogg->vi.rate=id.packet[12];
-  ogg->vi.rate+=id.packet[12+1]<<8;
-  ogg->vi.rate+=id.packet[12+2]<<8;
-  ogg->vi.rate+=id.packet[12+3]<<24;
-#if CHECK
-  fprintf(stderr,"parsed rate: %d\n",ogg->vi.rate);
-  vorbis_info_init(&ogg->vi);
-  vorbis_comment_init(&ogg->vc);
-  if(vorbis_synthesis_headerin(&ogg->vi,&ogg->vc,&id)<0){
-	      /* error case; not a vorbis header */
-	  fprintf(stderr,"Not valid identification\n");
-  } else fprintf(stderr,"  Valid identification\n");
-  if(vorbis_synthesis_headerin(&ogg->vi,&ogg->vc,&co)<0){
-	      /* error case; not a vorbis header */
-	  fprintf(stderr,"Not valid comment\n");
-  } else fprintf(stderr,"  Valid comment\n");
-  if(vorbis_synthesis_headerin(&ogg->vi,&ogg->vc,&cb)<0){
-	      /* error case; not a vorbis header */
-	  fprintf(stderr,"Not valid setup\n");
-  } else fprintf(stderr,"  Valid setup\n");
-  fprintf(stderr,"decoded rate: %d\n",ogg->vi.rate);
-#endif
-/* start the ogg*/
-  ogg_stream_init(&ogg->os,rand());
-
-  ogg_stream_packetin(&ogg->os,&id);
-  ogg_stream_packetin(&ogg->os,&co);
-  ogg_stream_packetin(&ogg->os,&cb);
-//  ogg->op.b_o_s=1;
-  do{
-    int result=ogg_stream_flush(&ogg->os,&ogg->og);
-    if(result==0)break;
-    fwrite(ogg->og.header,1,ogg->og.header_len,out);
-    fwrite(ogg->og.body,1,ogg->og.body_len,out);
-    }while(!ogg_page_eos(&ogg->og));
-  return 3;
-}
-
-int
-pkt_repack(ogg_context_t *ogg, FILE *out){
-  ogg_stream_packetin(&ogg->os,&ogg->op);
-  do{
-    int result=ogg_stream_pageout(&ogg->os,&ogg->og);
-    if(result==0)break;
-    fwrite(ogg->og.header,1,ogg->og.header_len,out);
-    fwrite(ogg->og.body,1,ogg->og.body_len,out);
-  }while(!ogg_page_eos(&ogg->og));
-  return 1;
-}
-
-	
-int
-dump_packet_ogg (unsigned char *data, const int len, FILE * out, ogg_context_t *ogg)
-{
-  int V, P, X, CC, M, PT;
-  unsigned short sequence;
-  unsigned int timestamp, ssrc;
-  unsigned int ident;
-  int F, VDT, pkts;
-  int i, offset, length, count = 0;
-  ogg_packet *op = &ogg->op;
-
-  /* parse RTP header */
-  V = (data[0] & 0xc0) >> 6;
-  P = (data[0] & 0x40) >> 5;
-  X = (data[0] & 0x20) >> 4;
-  CC = (data[0] & 0x0f);
-  M = (data[1] & 0x80) >> 7;
-  PT = (data[1] & 0x7F);
-  sequence = ntohs (((unsigned short *) data)[1]);
-  //FIXME not exactly ideal
-  timestamp = ntohl (((unsigned int *) data)[1]) - ogg->timestamp;
-  ogg->timestamp = ntohl (((unsigned int *) data)[1]);
-  ssrc = ntohl (((unsigned int *) data)[2]);
-  /* offset to payload header */
-  offset = (3 + CC) * 4;
-
-  /* parse Vorbis payload header */
-  ident = data[offset++]<<16;
-  ident += data[offset++]<<8;
-  ident += data[offset++];
-  F = (data[offset] & 0xc0) >> 6;
-  VDT = (data[offset] & 0x30) >> 4;
-  pkts = (data[offset] & 0x0F);
-  offset++;
-  
-  switch (F) {
-
-  case 0:
-    
-    break;
-  case 1:
-    op->bytes = 0;
-    
-  case 2:
-    length = data[offset++] << 8;
-    length += data[offset++];
-    op->packet = realloc (op->packet, length+op->bytes);
-    memcpy (op->packet + op->bytes, data + offset, length);
-    op->bytes += length;
-    return 0;
-  case 3:
-    length = data[offset++] << 8;
-    length += data[offset++];
-    op->packet = realloc (op->packet, length+op->bytes);
-    memcpy (op->packet + op->bytes, data + offset, length);
-    op->bytes += length;
-    pkts=1;
-    break;
-  default:
-    fprintf (stderr, " unknown frament?!\n");
-    return 0;
-  }
-  
-  switch (VDT) {
-
-  case 0:
-  for (i = 0; i < pkts; i++)
-    {
-      if (offset >= len)
-	{
-	  fprintf (stderr, "payload length overflow. corrupt packet?\n");
-	  return -1;
-	}
-      op->bytes = data[offset++]<<8;
-      op->bytes += data[offset++];
-      op->packet = &data[offset];
-      //FIXME should be a better way
-      op->granulepos+=timestamp*ogg->vi.rate/1000000L;
-      op->packetno++;
-      count += pkt_repack(ogg,out);
-      offset += op->bytes;
-      op->b_o_s=0;
-    }   
-    break;
-  case 1:
-    count = cfg_repack(ogg, out);
-    break;
-  default:
-    //ignore
-    break;
-    
-  }
-  if (F == 3) free(op->packet);
-
-  return count;
-}
-
-int
-main (int argc, char *argv[])
-{
-  int RTPSocket, ret;
-  FILE *file;
-  int optval = 0, decode = 0, dump = 0, opt;
-  struct sockaddr_in us, them;
-  struct ip_mreq group;
-  unsigned char data[MAX_PACKET];
-  char *hostname = "227.0.0.1", *filename = "out.ogg";
-  unsigned int port = 4044;
-
-  ogg_context_t ogg;
-  memset(&ogg,0,sizeof(ogg_context_t)); 
-  fprintf (stderr,
-	   "||---------------------------------------------------------------------------||\n");
-
-  fprintf (stderr, "||  Vorbis RTP Client (draft-ietf-avt-vorbis-rtp-01)\n");
-
-  while ((opt = getopt (argc, argv, "i:p:f:")) != -1)
-    {
-      switch (opt)
-	{
-
-	  /*  Set IP address  */
-	case 'i':
-	  hostname = optarg;
-	  break;
-
-	  /*  Set port  */
-	case 'p':
-	  port = atoi (optarg);
-	  break;
-
-	  /*  Set TTL value  */
-	case 'f':
-	  filename = optarg;
-	  dump = 1;
-	  break;
-
-	  /* Unknown option  */
-	case '?':
-	  fprintf (stderr, "\n||  Unknown option `-%c'.\n", optopt);
-	  fprintf (stderr, "||  Usage: vorbisrtp-client [-i ip address] [-p port] [-f filename]");
-	  return 1;
-	}
-    }
-
-  fprintf (stderr, "Opening connection to %s port %d\n", hostname, port);
-
-  RTPSocket = socket (AF_INET, SOCK_DGRAM, 0);
-
-  if (RTPSocket < 0)
-    {
-      fprintf (stderr, "Unable to create socket.\n");
-      exit (1);
-    }
-
-  us.sin_family = AF_INET;
-  us.sin_addr.s_addr = htonl (INADDR_ANY);
-  us.sin_port = htons (port);
-  ret = bind (RTPSocket, (struct sockaddr *) &us, sizeof (us));
-  if (ret < 0)
-    {
-      fprintf (stderr, "Unable to bind socket!\n");
-      exit (1);
-    }
-
-  them.sin_family = AF_INET;
-  them.sin_addr.s_addr = inet_addr (hostname);
-  them.sin_port = htons (port);
-
-  if (!IN_MULTICAST (ntohl (them.sin_addr.s_addr)))
-    {
-      fprintf (stderr, "not a multicast address\n");
-    }
-  else
-    {
-      fprintf (stderr, "joining multicast group...\n");
-      group.imr_multiaddr.s_addr = them.sin_addr.s_addr;
-      group.imr_interface.s_addr = htonl (INADDR_ANY);
-      ret = setsockopt (RTPSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-			(void *) &group, sizeof (group));
-      if (ret < 0)
-	{
-	  fprintf (stderr, "cannot join multicast group!\n");
-	  exit (1);
-	}
-    }
-  if (dump)
-    {
-      if (strcmp (filename, "-"))
-	{
-	  file = fopen (filename, "wb");
-	  if (file == NULL)
-	    {
-	      fprintf (stderr, "Unable to open %s\n", filename);
-	      exit (1);
-	    }
-	}
-      else
-      {
-	      file = stdout;
-	      filename = "Standard Output";
-      }
-      
-      fprintf (stderr, "Dumping the stream to %s\n", filename);
-    }
-
-  while (1)
-    {
-      ret = recvfrom (RTPSocket, data, MAX_PACKET, 0, NULL, 0);
-      fprintf (stderr, "read %d bytes of data\n", ret);
-      
-      dump_packet_rtp (data, ret, stderr);
-      if (dump){
-	dump_packet_ogg (data, ret, file, &ogg);
-	fflush(NULL);
-      }
-    }
-
-  return 0;
-}

Copied: trunk/xiph-rtp/vorbisrtp.c (from rev 10214, trunk/xiph-rtp/vorbisrtp2.c)
===================================================================
--- trunk/xiph-rtp/vorbisrtp2.c	2005-10-20 17:21:37 UTC (rev 10214)
+++ trunk/xiph-rtp/vorbisrtp.c	2005-10-20 21:58:37 UTC (rev 10216)
@@ -0,0 +1,809 @@
+/*****************************************************************************
+||  File: Vorbis RTP Server                                                 
+||  Authors: Phil Kerr, Luca Barbato
+||  Date: 05/01/2005
+||  Platform: Linux
+||
+||  Copyright (c) 2005, Fluendo / Xiph.Org
+||
+||  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 the Xiph.Org 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 COPYRIGHT OWNER 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.
+||
+||*****************************************************************************
+||
+||  Compile:  gcc vorbisrtp.c -o vorbisrtp -lvorbis -logg -fpack-struct -Wall
+||
+||  $Id:$                                                       
+||                  
+||****************************************************************************/
+/*  General includes                                                         */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+
+/*****************************************************************************/
+/*  Vorbis includes                                                          */
+/*****************************************************************************/
+
+#include <vorbis/codec.h>
+
+/*****************************************************************************/
+/*  Network includes                                                         */
+/*****************************************************************************/
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+/*****************************************************************************/
+/*  Data structs and variables                                               */
+/*****************************************************************************/
+
+ogg_int16_t convbuffer [4096];
+
+struct sockaddr_in rtpsock;
+int rtpsocket;
+
+/*****************************************************************************/
+/*  Vorbis packet header                                                     */
+/*                                                                           */
+/*  fragmentation flags work like so:                                        */
+/*                                                                           */
+/*  C F                                                                      */
+/*  0 0  Unfragmented packet (aka multi-packet..packet)                      */
+/*  0 1  First fragmented packet                                             */
+/*  1 0  Middle fragment                                                     */
+/*  1 1  Last fragment.                                                      */
+/*                                                                           */
+/*****************************************************************************/
+
+struct VorbisBitfields {
+    unsigned int cbident:24;
+    unsigned int frag_type:2;
+    unsigned int data_type:2;
+    unsigned int pkts:4;
+} VorbisBitfields;
+
+/*****************************************************************************/
+/*  RTP header                                                               */
+/*****************************************************************************/
+
+struct RTPHeaders {
+/*  v, p, x, cc flags  */
+    unsigned int flags1:8;
+
+/*  m, pt flags  */
+    unsigned int flags2:8;
+
+    unsigned int sequence:16;
+    unsigned int timestamp:32;
+    unsigned int ssrc:32;
+} RTPHeaders;
+
+/*****************************************************************************/
+/*  Prototypes                                                               */
+/*****************************************************************************/
+
+void progressmarker (int type);
+
+
+int createsocket (struct RTPHeaders *RTPHeaders, struct sockaddr_in *sockAddr, char *addr, unsigned int port, unsigned char TTL);
+void creatertp (unsigned char* vorbdata, int length, long timestamp, struct VorbisBitfields *vorbheader, int type);
+int sendrtp (struct RTPHeaders *RTPHeaders, int fd, struct sockaddr_in *sockAddr, const void *data, int len);
+
+int makevorbisheader (unsigned char *packet, int length, struct VorbisBitfields *vorbheader);
+int ogg_copy_packet(ogg_packet *dst, ogg_packet *src);
+
+
+/*****************************************************************************/
+/*  Print progress marker                                                    */
+/*****************************************************************************/
+
+void progressmarker (int type)
+{
+
+#if 0	
+/*===========================================================================*/
+/*  Prints output markers. 0 = normal, 1 = frag, 2 = last frag,              */
+/*  3 = comment, 4 = codebook, 5 = packed, 6 = config                        */
+/*===========================================================================*/
+
+/*  Output marker position  */
+    static int outmarkpos = 0;
+    switch (type) {
+        case 0:
+            fprintf (stdout, "."); /* normal */
+        break;
+
+        case 1:
+            fprintf (stdout, "+"); /* fragment */
+        break;
+
+        case 2:
+            fprintf (stdout, "|"); /* final fragment */
+        break;
+
+        case 3:
+            fprintf (stdout, "m"); /* metadata packet */
+        break;
+
+        case 4:
+            fprintf (stdout, "b"); /* setup header */
+        break;
+
+        case 5:
+            fprintf (stdout, "p"); /* packed */
+        break;
+
+        case 6:
+            fprintf (stdout, "c"); /* info header */
+        break;
+    };
+
+    fflush (NULL);
+
+    if (outmarkpos == 70) {
+        fprintf (stdout, "\n||  ");
+        outmarkpos = 0;
+    } else 
+        outmarkpos++;
+#endif
+    return;
+}
+
+/*****************************************************************************/
+/*  Creates RTP socket                                                       */
+/*****************************************************************************/
+
+int createsocket (struct RTPHeaders *RTPHeaders, struct sockaddr_in *sockAddr, char *addr, unsigned int port, unsigned char TTL)
+{
+    int RTPSocket, ret;
+    int optval = 0;
+    struct sockaddr_in sin;
+
+/*===========================================================================*/
+/*  Init RTP headers                                                         */
+/*===========================================================================*/
+
+/*  Sets v=2, p=0, x=0, cc=0  */
+    RTPHeaders -> flags1 = 0x80;
+
+/*  Sets m=0, pt=96  */
+    RTPHeaders -> flags2 = 0x60;
+
+    RTPHeaders -> sequence = htonl (rand () & 65535);
+    RTPHeaders -> timestamp = htonl (rand ());
+    RTPHeaders -> ssrc = htonl (rand ());
+
+/*===========================================================================*/
+/*  Create socket                                                            */
+/*===========================================================================*/
+
+    RTPSocket = socket (AF_INET, SOCK_DGRAM, 0);
+
+    if (RTPSocket < 0) {
+        fprintf (stderr, "Socket creation failed.\n");
+        exit (1);
+    }
+
+    sockAddr -> sin_family = sin.sin_family = AF_INET;
+    sockAddr -> sin_port = sin.sin_port = htons (port);
+    sockAddr -> sin_addr.s_addr = inet_addr (addr);
+
+    ret = setsockopt (RTPSocket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int));
+
+    if (ret < 0) {
+        fprintf (stderr, "setsockopt SO_REUSEADDR error\n");
+        exit (1);
+    }
+
+/*===========================================================================*/
+/*  Set multicast parameters                                                 */
+/*===========================================================================*/
+
+    if (IN_MULTICAST (ntohl (sockAddr -> sin_addr.s_addr))) {
+
+        ret = setsockopt (RTPSocket, IPPROTO_IP, IP_MULTICAST_TTL, &TTL, sizeof (char));
+
+        if (ret < 0) {
+            fprintf (stderr, "Multicast setsockopt TTL failed.\n");
+            exit (1);
+        }
+
+        optval = 1; 
+
+        ret = setsockopt (RTPSocket, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof (char));
+
+        if (ret < 0) {
+            fprintf (stderr, "Multicast setsockopt LOOP failed.\n");
+            exit (1);
+        }
+    }
+
+    return RTPSocket;
+}
+
+/*****************************************************************************/
+/*  Fills in the Vorbis RTP header in a packet.                              */
+/*****************************************************************************/
+
+int makevorbisheader (unsigned char *packet, int length, struct VorbisBitfields *vorbheader)
+{
+    if (length < 6) return -1;
+    printf("||  ident %06x, frag type %d, data type %d, pkts %02d, size %d\n",
+		    vorbheader->cbident, vorbheader -> frag_type,
+		    vorbheader -> data_type, vorbheader -> pkts,
+		    length);
+
+    packet[0] = (vorbheader->cbident&0xff0000)>>16;
+    packet[1] = (vorbheader->cbident&0xff00)>>8;
+    packet[2] = vorbheader->cbident&0xff;
+    
+    packet[3] = (vorbheader -> frag_type) << 6;
+    packet[3] |= (vorbheader -> data_type) << 4;
+    packet[3] |= (vorbheader -> pkts) & 0xf;
+    
+    return 0;
+}
+
+/*****************************************************************************/
+/*  Creates RTP packet from Vorbis frame.                                    */
+/*  Deals with fragmentation and multiple Vorbis frame RTP packets           */
+/*****************************************************************************/
+
+void creatertp (unsigned char* vorbdata, int length, long timestamp, struct VorbisBitfields *vorbheader, int type)
+{
+    int sleeptime, frag, position = 0;
+    unsigned short framesize;
+    unsigned char *packet;
+
+    const unsigned int max_payload = 1000;
+
+    /* we accumulate short frames between calls */
+    static int stacksize = 0;
+    static int stackcount = 0;
+    static unsigned char* framestack = NULL;
+
+/*===========================================================================*/
+/*  Set sleeptime value based on timestamp                                   */
+/*===========================================================================*/
+
+
+if (type)
+    sleeptime = 300; //  ((1 / (float) bitrate) * 1000000);
+else
+	sleeptime = timestamp;
+
+/*===========================================================================*/
+/*  Frame fragmentation                                                      */
+/*===========================================================================*/
+
+    if (length > max_payload) {
+        frag = 1;
+        while (length > max_payload) {        
+            /*  Set Vorbis header flags  */
+            vorbheader -> frag_type = frag;
+            vorbheader -> data_type = type;
+            vorbheader -> pkts = 0;
+
+            framesize = max_payload;
+
+            packet = malloc (framesize + 4 + 2);
+
+            makevorbisheader (packet, framesize + 2 + 4, vorbheader);
+ //           memcpy (packet + 4, &framesize, 2);
+            packet[4]=(framesize&0xff00)>>8;
+	    packet[5]=framesize&0xff;
+            memcpy (packet + 4 + 2, vorbdata + position, framesize);
+
+            /*  Swap RTP headers from host to network order  */
+            RTPHeaders.sequence = htons (RTPHeaders.sequence);
+
+            sendrtp (&RTPHeaders, rtpsocket, &rtpsock, packet, framesize + 4 + 2);
+
+            /*  Swap headers back to host order  */
+            RTPHeaders.sequence = ntohs (RTPHeaders.sequence);
+
+            length -= max_payload;
+            position += max_payload;
+            frag = 2;
+
+            RTPHeaders.sequence = RTPHeaders.sequence + 1;
+
+            progressmarker (1);
+
+            free (packet);
+        }
+
+        /*  Set Vorbis header flags  */
+        vorbheader -> frag_type = 3;
+        vorbheader -> data_type = type;
+        vorbheader -> pkts = 0;
+
+        framesize = length;
+
+        packet = malloc (length + 4 + 2);
+
+        makevorbisheader (packet, length + 4 + 2, vorbheader);
+        packet[4]=(framesize&0xff00)>>8;
+	packet[5]=framesize&0xff;
+        memcpy (packet + 4 + 2, vorbdata + position, length);
+
+        /*  Swap RTP headers from host to network order  */
+        RTPHeaders.sequence = htons (RTPHeaders.sequence);
+        RTPHeaders.timestamp = htonl (RTPHeaders.timestamp);
+
+        sendrtp (&RTPHeaders, rtpsocket, &rtpsock, packet, length + 4 + 2);
+
+        /*  Swap headers back to host order  */
+        RTPHeaders.sequence = htons (RTPHeaders.sequence);
+        RTPHeaders.timestamp = ntohl (RTPHeaders.timestamp);
+
+        /*  Increment RTP headers  */
+        RTPHeaders.sequence++;
+        RTPHeaders.timestamp += sleeptime;
+
+        progressmarker (2);
+
+        free (packet);
+        return;
+    }
+
+/*===========================================================================*/
+/*  Frame packing.  Used only for type 0 packets (raw Vorbis data)           */
+/*===========================================================================*/
+
+    if (length < max_payload && type == 0) {
+        if (length + stacksize < max_payload && stackcount < 15) {
+
+            framestack = realloc (framestack, (stacksize + (length + 2)));
+            
+	    framestack[stacksize++]= (length&0xff00)>>8;
+	    framestack[stacksize++]= length&0xff;
+	    
+            memcpy (framestack + (stacksize), vorbdata, length);
+            stackcount++;
+            stacksize += (length);
+        }
+
+        /* todo: we also need to be able to flush this at end-of-stream */
+
+        if (length + stacksize > max_payload || stackcount >= 15) {
+
+            /*  Set Vorbis header flags  */
+            vorbheader -> frag_type = 0;
+            vorbheader -> data_type = 0;
+            vorbheader -> pkts = stackcount;
+
+            packet = malloc (stacksize + 4);
+
+            makevorbisheader (packet, stacksize + 4, vorbheader);
+            memcpy (packet + 4, framestack, stacksize);
+
+            /*  Swap RTP headers from host to network order  */
+            RTPHeaders.sequence = htons (RTPHeaders.sequence);
+            RTPHeaders.timestamp = htonl (RTPHeaders.timestamp);
+
+            sendrtp (&RTPHeaders, rtpsocket, &rtpsock, packet, stacksize + 4);
+
+            /*  Swap headers back to host order  */
+            RTPHeaders.sequence = htons (RTPHeaders.sequence);
+            RTPHeaders.timestamp = ntohl (RTPHeaders.timestamp);
+
+            if (stackcount == 1) 
+                progressmarker (0);
+            else
+                progressmarker (5);
+
+            usleep (sleeptime);
+
+            RTPHeaders.sequence++;
+            RTPHeaders.timestamp += sleeptime;
+
+            stacksize = 0;
+            stackcount = 0;
+
+            free (packet);
+        }   
+        return;
+    } 
+
+/*===========================================================================*/
+/*  Send header packets (under max_payload octets) - No Packing              */
+/*===========================================================================*/
+
+    else if (length < max_payload) {
+
+        /*  Set Vorbis header flags  */
+        vorbheader -> frag_type = 0;
+        vorbheader -> data_type = type;
+        vorbheader -> pkts = 1;
+
+        framesize = (unsigned char) length;
+
+        packet = malloc (length + 4 + 2);
+
+        makevorbisheader (packet, length + 4 + 2, vorbheader);
+
+	packet[4]=(length&0xff00)>>8;
+	packet[5]=length&0xff;
+
+        memcpy (packet + 4 + 2, vorbdata, length);
+
+        /*  Swap RTP headers from host to network order  */
+        RTPHeaders.sequence = htons (RTPHeaders.sequence);
+        RTPHeaders.timestamp = htonl (RTPHeaders.timestamp);
+
+        sendrtp (&RTPHeaders, rtpsocket, &rtpsock, packet, length + 4 + 2);
+
+        /*  Swap headers back to host order  */
+        RTPHeaders.sequence = htons (RTPHeaders.sequence);
+        RTPHeaders.timestamp = ntohl (RTPHeaders.timestamp);
+
+        sleeptime = timestamp;
+        usleep (sleeptime);
+
+        RTPHeaders.sequence++;
+        RTPHeaders.timestamp += sleeptime;
+
+        free (packet);
+    }            
+}
+
+/*****************************************************************************/
+/*  Sends RTP packet                                                         */
+/*****************************************************************************/
+
+int sendrtp (struct RTPHeaders *RTPHeaders, int rtpsocket, struct sockaddr_in *sockAddr, const void *packet, int length)
+{
+    int ret;
+
+    char *outbuffer;
+
+    outbuffer = malloc (sizeof (struct RTPHeaders) + length);
+
+    memcpy (outbuffer,  RTPHeaders, sizeof (struct RTPHeaders));
+    memcpy (outbuffer + sizeof (struct RTPHeaders), packet, length);
+
+    ret = sendto (rtpsocket, outbuffer, sizeof (struct RTPHeaders) + length, 0, (struct sockaddr *) sockAddr, sizeof (*sockAddr));
+
+    free (outbuffer);
+    return (ret);
+}
+
+/*****************************************************************************/
+/*  Duplicates an Ogg packet                                                 */
+/*****************************************************************************/
+int ogg_copy_packet(ogg_packet *dst, ogg_packet *src)
+{
+  dst->packet = malloc(src->bytes);
+  memcpy(dst->packet, src->packet, src->bytes);
+  dst->bytes = src->bytes;
+  dst->b_o_s = src->b_o_s;
+  dst->e_o_s = src->e_o_s;
+
+  dst->granulepos = src->granulepos;
+  dst->packetno = src->packetno;
+#ifdef DEBUG
+  printf("||  bytes %ld bos %ld eos %ld gp %lld pno %lld\n",
+  dst->bytes, dst->b_o_s, dst->e_o_s, dst->granulepos, dst->packetno);
+#endif
+  return 0;
+}
+
+/*****************************************************************************/
+
+int main (int argc, char **argv) 
+{
+    ogg_sync_state oy;
+    ogg_stream_state os;
+    ogg_page og;
+    ogg_packet op;
+    ogg_packet header[3];
+  
+    vorbis_info vi; 
+
+    vorbis_comment vc;
+    vorbis_dsp_state vd;
+    vorbis_block vb;
+
+    char *buffer;
+    int  bytes;
+
+    char *filename;
+    FILE *file;
+    ogg_sync_init (&oy);
+
+    int i = 0;
+    int opt;
+
+    char *ip = "227.0.0.1";
+    unsigned int port = 4044;
+    unsigned int ttl  = 1;
+    long timestamp = 0, prev = 0;
+
+    fprintf (stderr, "||---------------------------------------------------------------------------||\n");
+    fprintf (stderr, "||  Vorbis RTP Server (draft-kerr-avt-vorbis-rtp-05)\n");	  
+
+/*===========================================================================*/
+/*  Command-line args processing                                             */
+/*===========================================================================*/
+
+    if (argc < 2) {
+        fprintf (stderr, "||\n||  No Vorbis file specified.\n");
+        fprintf (stderr, "||  Usage: vorbisrtp [-i ip address] [-p port] [-t ttl] filename\n\n");
+        exit (1);
+    }
+
+    while ((opt = getopt (argc, argv, "i:p:t:")) != -1) {
+        switch (opt)
+	    {
+
+        /*  Set IP address  */
+	    case 'i':
+    	        ip = optarg;
+	        break;
+
+        /*  Set port  */
+	    case 'p':
+	            port = atoi (optarg);
+	        break;
+
+        /*  Set TTL value  */
+	    case 't':
+    	        ttl = atoi (optarg);
+	        break;
+
+        /* Unknown option  */
+	    case '?':
+	            fprintf (stderr, "\n||  Unknown option `-%c'.\n", optopt);
+	        return 1;
+        }
+    }
+
+/*===========================================================================*/
+/*  Init RTP socket                                                          */
+/*===========================================================================*/
+
+    rtpsocket = createsocket (&RTPHeaders, &rtpsock, ip, port, ttl);
+
+/*===========================================================================*/
+/*  Print network details                                                    */
+/*===========================================================================*/
+
+    fprintf (stdout, "||---------------------------------------------------------------------------||\n");
+    fprintf (stdout, "||  Network setup\n");	  
+    fprintf (stdout, "||  IP Address= %s\n", ip);
+    fprintf (stdout, "||  Port = %d\n", port);
+    fprintf (stdout, "||  TTL = %d\n", ttl);
+    fprintf (stdout, "||\n");
+    fprintf (stdout, "||---------------------------------------------------------------------------||\n");
+
+/*===========================================================================*/
+/*  Open Vorbis file                                                         */
+/*===========================================================================*/
+
+    filename = argv [argc - 1];
+    file = fopen (filename, "rb");
+
+    if (file == NULL) {
+        fprintf (stderr, "||  Could not open file %s\n", filename);
+        exit (1);
+    }
+
+    fprintf (stdout, "||  Vorbis setup\n");
+    fprintf (stdout, "||  Filename: %s\n", filename);
+
+    int eos = 0;
+
+    buffer = ogg_sync_buffer (&oy, 4096);
+
+    bytes = fread (buffer, 1, 4096, file);
+
+    ogg_sync_wrote (&oy, bytes);
+    
+    if (ogg_sync_pageout (&oy, &og) != 1) {
+        if (bytes < 4096) {
+            fprintf (stdout, "||  Done\n");
+            exit (0);
+        }
+      
+        fprintf (stderr, "\n||  Input does not appear to be an Ogg bitstream.\n");
+        exit (1);
+    }
+  
+    ogg_stream_init (&os, ogg_page_serialno (&og));
+    
+    vorbis_info_init (&vi);
+    vorbis_comment_init (&vc);
+
+    if (ogg_stream_pagein (&os, &og) < 0) { 
+        fprintf (stderr, "||  Error reading first page of Ogg bitstream data.\n");
+        exit (1);
+    }
+    
+    if (ogg_stream_packetout (&os, &op) != 1) { 
+        fprintf (stderr, "||  Error reading initial header packet.\n");
+        exit (1);
+    }
+    
+    if (vorbis_synthesis_headerin (&vi, &vc, &op) < 0) { 
+        fprintf (stderr, "||  This Ogg bitstream does not contain Vorbis audio data.\n");
+        exit (1);
+    }
+
+    ogg_copy_packet(&(header[i]), &op);
+
+/*===========================================================================*/
+/*  Process comment and codebook headers                                     */
+/*===========================================================================*/
+
+    while (i < 2) {
+        while (i < 2) {
+            int result = ogg_sync_pageout (&oy, &og);
+
+        	if (result == 0) break; /* Need more data  */
+
+        	if (result == 1) {
+        	    ogg_stream_pagein (&os, &og); 
+
+                while(i < 2) {
+            	    result = ogg_stream_packetout (&os, &op);
+
+                    if (result == 0) break;
+                    
+                    if (result < 0) {
+                        fprintf (stderr, "||  Corrupt secondary header.  Exiting.\n");
+                        exit (1);
+    	            }
+
+
+                    vorbis_synthesis_headerin (&vi, &vc, &op);
+                    i++;
+
+                    ogg_copy_packet(&(header[i]), &op);
+                }
+            }
+        }
+
+        buffer = ogg_sync_buffer (&oy, 4096);
+        bytes = fread (buffer, 1, 4096, file);
+
+        if (bytes == 0 && i < 2) {
+            fprintf (stderr, "||  End of file before finding all Vorbis headers!\n");
+            exit (1);
+        }
+
+        ogg_sync_wrote (&oy, bytes);
+    }
+
+    VorbisBitfields.cbident = rand ();
+    
+    vorbis_synthesis_init (&vd, &vi);
+    vorbis_block_init (&vd, &vb);
+
+/*===========================================================================*/
+/*  Print details                                                            */
+/*===========================================================================*/
+
+    fprintf (stdout, "||  Bitstream is %d channel, %ldHz\n", vi.channels, vi.rate);
+    fprintf (stdout, "||  Encoded by: %s\n", vc.vendor);
+    fprintf (stdout, "||  Bitrates: min=%ld - nom=%ld - max=%ld\n", vi.bitrate_lower, vi.bitrate_nominal, vi.bitrate_upper);
+    fprintf (stdout, "||  Decode setup ident is 0x%06x\n", VorbisBitfields.cbident);
+    fprintf (stdout, "||\n");
+    fprintf (stdout, "||---------------------------------------------------------------------------||\n");
+    fprintf (stdout, "||  Processing\n");
+
+/*===========================================================================*/
+/*  Send the three headers inline                                            */
+/*===========================================================================*/
+{
+int conf_bytes = header[0].bytes+header[2].bytes;
+unsigned char *conf_packet=malloc(conf_bytes);
+
+    memcpy (conf_packet,header[0].packet,header[0].bytes);
+    memcpy (conf_packet+header[0].bytes,header[2].packet,header[2].bytes);
+    creatertp(conf_packet, conf_bytes, 0, &VorbisBitfields, 1);
+    progressmarker (6);
+
+free(conf_packet);
+}
+
+/*===========================================================================*/
+/*  Read raw Vorbis data and send RTP packet                                 */
+/*===========================================================================*/
+
+    while (!eos) {
+        while (!eos) {
+            int result = ogg_sync_pageout (&oy, &og);
+
+            if (result == 0) break; /* need more data  */
+
+            if (result < 0) {
+                fprintf (stderr, "\n||  Corrupt or missing data in bitstream; continuing....\n||  ");
+            } else {
+                ogg_stream_pagein (&os, &og); 
+
+                while (1) {
+                    result = ogg_stream_packetout (&os, &op);
+
+                    if (result == 0) break; /* need more data  */
+
+                    if (result < 0) {
+                        /* no reason to complain; already complained above  */
+            	    } else {
+#ifdef DEBUG
+			printf("||  bytes %ld bos %ld eos %ld gp %lld pno %lld\n", op.bytes, op.b_o_s, op.e_o_s, op.granulepos, op.packetno);
+#endif
+			creatertp ( op.packet, op.bytes, 
+					timestamp, &VorbisBitfields, 0);
+			timestamp = (vorbis_packet_blocksize(&vi,&op)+prev)/4*1000000L/vi.rate;
+			prev = vorbis_packet_blocksize(&vi,&op);
+            	    }
+                }
+
+                if (ogg_page_eos (&og)) eos = 1;
+            }
+        }
+
+        if (!eos) {
+            buffer = ogg_sync_buffer (&oy, 4096);
+            bytes = fread (buffer, 1, 4096, file);
+
+            ogg_sync_wrote (&oy, bytes);
+    
+            if (bytes == 0) eos = 1;
+        }
+    }
+
+    ogg_packet_clear (&(header[0]));
+    ogg_packet_clear (&(header[1]));
+    ogg_packet_clear (&(header[2]));
+
+    ogg_stream_clear (&os);
+  
+    vorbis_block_clear (&vb);
+    vorbis_dsp_clear (&vd);
+    vorbis_comment_clear (&vc);
+    vorbis_info_clear (&vi);
+
+    ogg_sync_clear (&oy);
+    fclose (file);
+
+    fprintf (stdout, "\n||---------------------------------------------------------------------------||\n");
+    fprintf (stdout, "||  Done.\n");
+    return (0);
+}
+
+/*****************************************************************************/
+/*  End                                                                      */
+/*****************************************************************************/

Deleted: trunk/xiph-rtp/vorbisrtp2.c
===================================================================
--- trunk/xiph-rtp/vorbisrtp2.c	2005-10-20 21:56:56 UTC (rev 10215)
+++ trunk/xiph-rtp/vorbisrtp2.c	2005-10-20 21:58:37 UTC (rev 10216)
@@ -1,809 +0,0 @@
-/*****************************************************************************
-||  File: Vorbis RTP Server                                                 
-||  Authors: Phil Kerr, Luca Barbato
-||  Date: 05/01/2005
-||  Platform: Linux
-||
-||  Copyright (c) 2005, Fluendo / Xiph.Org
-||
-||  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 the Xiph.Org 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 COPYRIGHT OWNER 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.
-||
-||*****************************************************************************
-||
-||  Compile:  gcc vorbisrtp.c -o vorbisrtp -lvorbis -logg -fpack-struct -Wall
-||
-||  $Id:$                                                       
-||                  
-||****************************************************************************/
-/*  General includes                                                         */
-/*****************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-
-/*****************************************************************************/
-/*  Vorbis includes                                                          */
-/*****************************************************************************/
-
-#include <vorbis/codec.h>
-
-/*****************************************************************************/
-/*  Network includes                                                         */
-/*****************************************************************************/
-
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-/*****************************************************************************/
-/*  Data structs and variables                                               */
-/*****************************************************************************/
-
-ogg_int16_t convbuffer [4096];
-
-struct sockaddr_in rtpsock;
-int rtpsocket;
-
-/*****************************************************************************/
-/*  Vorbis packet header                                                     */
-/*                                                                           */
-/*  fragmentation flags work like so:                                        */
-/*                                                                           */
-/*  C F                                                                      */
-/*  0 0  Unfragmented packet (aka multi-packet..packet)                      */
-/*  0 1  First fragmented packet                                             */
-/*  1 0  Middle fragment                                                     */
-/*  1 1  Last fragment.                                                      */
-/*                                                                           */
-/*****************************************************************************/
-
-struct VorbisBitfields {
-    unsigned int cbident:24;
-    unsigned int frag_type:2;
-    unsigned int data_type:2;
-    unsigned int pkts:4;
-} VorbisBitfields;
-
-/*****************************************************************************/
-/*  RTP header                                                               */
-/*****************************************************************************/
-
-struct RTPHeaders {
-/*  v, p, x, cc flags  */
-    unsigned int flags1:8;
-
-/*  m, pt flags  */
-    unsigned int flags2:8;
-
-    unsigned int sequence:16;
-    unsigned int timestamp:32;
-    unsigned int ssrc:32;
-} RTPHeaders;
-
-/*****************************************************************************/
-/*  Prototypes                                                               */
-/*****************************************************************************/
-
-void progressmarker (int type);
-
-
-int createsocket (struct RTPHeaders *RTPHeaders, struct sockaddr_in *sockAddr, char *addr, unsigned int port, unsigned char TTL);
-void creatertp (unsigned char* vorbdata, int length, long timestamp, struct VorbisBitfields *vorbheader, int type);
-int sendrtp (struct RTPHeaders *RTPHeaders, int fd, struct sockaddr_in *sockAddr, const void *data, int len);
-
-int makevorbisheader (unsigned char *packet, int length, struct VorbisBitfields *vorbheader);
-int ogg_copy_packet(ogg_packet *dst, ogg_packet *src);
-
-
-/*****************************************************************************/
-/*  Print progress marker                                                    */
-/*****************************************************************************/
-
-void progressmarker (int type)
-{
-
-#if 0	
-/*===========================================================================*/
-/*  Prints output markers. 0 = normal, 1 = frag, 2 = last frag,              */
-/*  3 = comment, 4 = codebook, 5 = packed, 6 = config                        */
-/*===========================================================================*/
-
-/*  Output marker position  */
-    static int outmarkpos = 0;
-    switch (type) {
-        case 0:
-            fprintf (stdout, "."); /* normal */
-        break;
-
-        case 1:
-            fprintf (stdout, "+"); /* fragment */
-        break;
-
-        case 2:
-            fprintf (stdout, "|"); /* final fragment */
-        break;
-
-        case 3:
-            fprintf (stdout, "m"); /* metadata packet */
-        break;
-
-        case 4:
-            fprintf (stdout, "b"); /* setup header */
-        break;
-
-        case 5:
-            fprintf (stdout, "p"); /* packed */
-        break;
-
-        case 6:
-            fprintf (stdout, "c"); /* info header */
-        break;
-    };
-
-    fflush (NULL);
-
-    if (outmarkpos == 70) {
-        fprintf (stdout, "\n||  ");
-        outmarkpos = 0;
-    } else 
-        outmarkpos++;
-#endif
-    return;
-}
-
-/*****************************************************************************/
-/*  Creates RTP socket                                                       */
-/*****************************************************************************/
-
-int createsocket (struct RTPHeaders *RTPHeaders, struct sockaddr_in *sockAddr, char *addr, unsigned int port, unsigned char TTL)
-{
-    int RTPSocket, ret;
-    int optval = 0;
-    struct sockaddr_in sin;
-
-/*===========================================================================*/
-/*  Init RTP headers                                                         */
-/*===========================================================================*/
-
-/*  Sets v=2, p=0, x=0, cc=0  */
-    RTPHeaders -> flags1 = 0x80;
-
-/*  Sets m=0, pt=96  */
-    RTPHeaders -> flags2 = 0x60;
-
-    RTPHeaders -> sequence = htonl (rand () & 65535);
-    RTPHeaders -> timestamp = htonl (rand ());
-    RTPHeaders -> ssrc = htonl (rand ());
-
-/*===========================================================================*/
-/*  Create socket                                                            */
-/*===========================================================================*/
-
-    RTPSocket = socket (AF_INET, SOCK_DGRAM, 0);
-
-    if (RTPSocket < 0) {
-        fprintf (stderr, "Socket creation failed.\n");
-        exit (1);
-    }
-
-    sockAddr -> sin_family = sin.sin_family = AF_INET;
-    sockAddr -> sin_port = sin.sin_port = htons (port);
-    sockAddr -> sin_addr.s_addr = inet_addr (addr);
-
-    ret = setsockopt (RTPSocket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int));
-
-    if (ret < 0) {
-        fprintf (stderr, "setsockopt SO_REUSEADDR error\n");
-        exit (1);
-    }
-
-/*===========================================================================*/
-/*  Set multicast parameters                                                 */
-/*===========================================================================*/
-
-    if (IN_MULTICAST (ntohl (sockAddr -> sin_addr.s_addr))) {
-
-        ret = setsockopt (RTPSocket, IPPROTO_IP, IP_MULTICAST_TTL, &TTL, sizeof (char));
-
-        if (ret < 0) {
-            fprintf (stderr, "Multicast setsockopt TTL failed.\n");
-            exit (1);
-        }
-
-        optval = 1; 
-
-        ret = setsockopt (RTPSocket, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof (char));
-
-        if (ret < 0) {
-            fprintf (stderr, "Multicast setsockopt LOOP failed.\n");
-            exit (1);
-        }
-    }
-
-    return RTPSocket;
-}
-
-/*****************************************************************************/
-/*  Fills in the Vorbis RTP header in a packet.                              */
-/*****************************************************************************/
-
-int makevorbisheader (unsigned char *packet, int length, struct VorbisBitfields *vorbheader)
-{
-    if (length < 6) return -1;
-    printf("||  ident %06x, frag type %d, data type %d, pkts %02d, size %d\n",
-		    vorbheader->cbident, vorbheader -> frag_type,
-		    vorbheader -> data_type, vorbheader -> pkts,
-		    length);
-
-    packet[0] = (vorbheader->cbident&0xff0000)>>16;
-    packet[1] = (vorbheader->cbident&0xff00)>>8;
-    packet[2] = vorbheader->cbident&0xff;
-    
-    packet[3] = (vorbheader -> frag_type) << 6;
-    packet[3] |= (vorbheader -> data_type) << 4;
-    packet[3] |= (vorbheader -> pkts) & 0xf;
-    
-    return 0;
-}
-
-/*****************************************************************************/
-/*  Creates RTP packet from Vorbis frame.                                    */
-/*  Deals with fragmentation and multiple Vorbis frame RTP packets           */
-/*****************************************************************************/
-
-void creatertp (unsigned char* vorbdata, int length, long timestamp, struct VorbisBitfields *vorbheader, int type)
-{
-    int sleeptime, frag, position = 0;
-    unsigned short framesize;
-    unsigned char *packet;
-
-    const unsigned int max_payload = 1000;
-
-    /* we accumulate short frames between calls */
-    static int stacksize = 0;
-    static int stackcount = 0;
-    static unsigned char* framestack = NULL;
-
-/*===========================================================================*/
-/*  Set sleeptime value based on timestamp                                   */
-/*===========================================================================*/
-
-
-if (type)
-    sleeptime = 300; //  ((1 / (float) bitrate) * 1000000);
-else
-	sleeptime = timestamp;
-
-/*===========================================================================*/
-/*  Frame fragmentation                                                      */
-/*===========================================================================*/
-
-    if (length > max_payload) {
-        frag = 1;
-        while (length > max_payload) {        
-            /*  Set Vorbis header flags  */
-            vorbheader -> frag_type = frag;
-            vorbheader -> data_type = type;
-            vorbheader -> pkts = 0;
-
-            framesize = max_payload;
-
-            packet = malloc (framesize + 4 + 2);
-
-            makevorbisheader (packet, framesize + 2 + 4, vorbheader);
- //           memcpy (packet + 4, &framesize, 2);
-            packet[4]=(framesize&0xff00)>>8;
-	    packet[5]=framesize&0xff;
-            memcpy (packet + 4 + 2, vorbdata + position, framesize);
-
-            /*  Swap RTP headers from host to network order  */
-            RTPHeaders.sequence = htons (RTPHeaders.sequence);
-
-            sendrtp (&RTPHeaders, rtpsocket, &rtpsock, packet, framesize + 4 + 2);
-
-            /*  Swap headers back to host order  */
-            RTPHeaders.sequence = ntohs (RTPHeaders.sequence);
-
-            length -= max_payload;
-            position += max_payload;
-            frag = 2;
-
-            RTPHeaders.sequence = RTPHeaders.sequence + 1;
-
-            progressmarker (1);
-
-            free (packet);
-        }
-
-        /*  Set Vorbis header flags  */
-        vorbheader -> frag_type = 3;
-        vorbheader -> data_type = type;
-        vorbheader -> pkts = 0;
-
-        framesize = length;
-
-        packet = malloc (length + 4 + 2);
-
-        makevorbisheader (packet, length + 4 + 2, vorbheader);
-        packet[4]=(framesize&0xff00)>>8;
-	packet[5]=framesize&0xff;
-        memcpy (packet + 4 + 2, vorbdata + position, length);
-
-        /*  Swap RTP headers from host to network order  */
-        RTPHeaders.sequence = htons (RTPHeaders.sequence);
-        RTPHeaders.timestamp = htonl (RTPHeaders.timestamp);
-
-        sendrtp (&RTPHeaders, rtpsocket, &rtpsock, packet, length + 4 + 2);
-
-        /*  Swap headers back to host order  */
-        RTPHeaders.sequence = htons (RTPHeaders.sequence);
-        RTPHeaders.timestamp = ntohl (RTPHeaders.timestamp);
-
-        /*  Increment RTP headers  */
-        RTPHeaders.sequence++;
-        RTPHeaders.timestamp += sleeptime;
-
-        progressmarker (2);
-
-        free (packet);
-        return;
-    }
-
-/*===========================================================================*/
-/*  Frame packing.  Used only for type 0 packets (raw Vorbis data)           */
-/*===========================================================================*/
-
-    if (length < max_payload && type == 0) {
-        if (length + stacksize < max_payload && stackcount < 15) {
-
-            framestack = realloc (framestack, (stacksize + (length + 2)));
-            
-	    framestack[stacksize++]= (length&0xff00)>>8;
-	    framestack[stacksize++]= length&0xff;
-	    
-            memcpy (framestack + (stacksize), vorbdata, length);
-            stackcount++;
-            stacksize += (length);
-        }
-
-        /* todo: we also need to be able to flush this at end-of-stream */
-
-        if (length + stacksize > max_payload || stackcount >= 15) {
-
-            /*  Set Vorbis header flags  */
-            vorbheader -> frag_type = 0;
-            vorbheader -> data_type = 0;
-            vorbheader -> pkts = stackcount;
-
-            packet = malloc (stacksize + 4);
-
-            makevorbisheader (packet, stacksize + 4, vorbheader);
-            memcpy (packet + 4, framestack, stacksize);
-
-            /*  Swap RTP headers from host to network order  */
-            RTPHeaders.sequence = htons (RTPHeaders.sequence);
-            RTPHeaders.timestamp = htonl (RTPHeaders.timestamp);
-
-            sendrtp (&RTPHeaders, rtpsocket, &rtpsock, packet, stacksize + 4);
-
-            /*  Swap headers back to host order  */
-            RTPHeaders.sequence = htons (RTPHeaders.sequence);
-            RTPHeaders.timestamp = ntohl (RTPHeaders.timestamp);
-
-            if (stackcount == 1) 
-                progressmarker (0);
-            else
-                progressmarker (5);
-
-            usleep (sleeptime);
-
-            RTPHeaders.sequence++;
-            RTPHeaders.timestamp += sleeptime;
-
-            stacksize = 0;
-            stackcount = 0;
-
-            free (packet);
-        }   
-        return;
-    } 
-
-/*===========================================================================*/
-/*  Send header packets (under max_payload octets) - No Packing              */
-/*===========================================================================*/
-
-    else if (length < max_payload) {
-
-        /*  Set Vorbis header flags  */
-        vorbheader -> frag_type = 0;
-        vorbheader -> data_type = type;
-        vorbheader -> pkts = 1;
-
-        framesize = (unsigned char) length;
-
-        packet = malloc (length + 4 + 2);
-
-        makevorbisheader (packet, length + 4 + 2, vorbheader);
-
-	packet[4]=(length&0xff00)>>8;
-	packet[5]=length&0xff;
-
-        memcpy (packet + 4 + 2, vorbdata, length);
-
-        /*  Swap RTP headers from host to network order  */
-        RTPHeaders.sequence = htons (RTPHeaders.sequence);
-        RTPHeaders.timestamp = htonl (RTPHeaders.timestamp);
-
-        sendrtp (&RTPHeaders, rtpsocket, &rtpsock, packet, length + 4 + 2);
-
-        /*  Swap headers back to host order  */
-        RTPHeaders.sequence = htons (RTPHeaders.sequence);
-        RTPHeaders.timestamp = ntohl (RTPHeaders.timestamp);
-
-        sleeptime = timestamp;
-        usleep (sleeptime);
-
-        RTPHeaders.sequence++;
-        RTPHeaders.timestamp += sleeptime;
-
-        free (packet);
-    }            
-}
-
-/*****************************************************************************/
-/*  Sends RTP packet                                                         */
-/*****************************************************************************/
-
-int sendrtp (struct RTPHeaders *RTPHeaders, int rtpsocket, struct sockaddr_in *sockAddr, const void *packet, int length)
-{
-    int ret;
-
-    char *outbuffer;
-
-    outbuffer = malloc (sizeof (struct RTPHeaders) + length);
-
-    memcpy (outbuffer,  RTPHeaders, sizeof (struct RTPHeaders));
-    memcpy (outbuffer + sizeof (struct RTPHeaders), packet, length);
-
-    ret = sendto (rtpsocket, outbuffer, sizeof (struct RTPHeaders) + length, 0, (struct sockaddr *) sockAddr, sizeof (*sockAddr));
-
-    free (outbuffer);
-    return (ret);
-}
-
-/*****************************************************************************/
-/*  Duplicates an Ogg packet                                                 */
-/*****************************************************************************/
-int ogg_copy_packet(ogg_packet *dst, ogg_packet *src)
-{
-  dst->packet = malloc(src->bytes);
-  memcpy(dst->packet, src->packet, src->bytes);
-  dst->bytes = src->bytes;
-  dst->b_o_s = src->b_o_s;
-  dst->e_o_s = src->e_o_s;
-
-  dst->granulepos = src->granulepos;
-  dst->packetno = src->packetno;
-#ifdef DEBUG
-  printf("||  bytes %ld bos %ld eos %ld gp %lld pno %lld\n",
-  dst->bytes, dst->b_o_s, dst->e_o_s, dst->granulepos, dst->packetno);
-#endif
-  return 0;
-}
-
-/*****************************************************************************/
-
-int main (int argc, char **argv) 
-{
-    ogg_sync_state oy;
-    ogg_stream_state os;
-    ogg_page og;
-    ogg_packet op;
-    ogg_packet header[3];
-  
-    vorbis_info vi; 
-
-    vorbis_comment vc;
-    vorbis_dsp_state vd;
-    vorbis_block vb;
-
-    char *buffer;
-    int  bytes;
-
-    char *filename;
-    FILE *file;
-    ogg_sync_init (&oy);
-
-    int i = 0;
-    int opt;
-
-    char *ip = "227.0.0.1";
-    unsigned int port = 4044;
-    unsigned int ttl  = 1;
-    long timestamp = 0, prev = 0;
-
-    fprintf (stderr, "||---------------------------------------------------------------------------||\n");
-    fprintf (stderr, "||  Vorbis RTP Server (draft-ietf-avt-vorbis-rtp-01)\n");	  
-
-/*===========================================================================*/
-/*  Command-line args processing                                             */
-/*===========================================================================*/
-
-    if (argc < 2) {
-        fprintf (stderr, "||\n||  No Vorbis file specified.\n");
-        fprintf (stderr, "||  Usage: vorbisrtp [-i ip address] [-p port] [-t ttl] filename\n\n");
-        exit (1);
-    }
-
-    while ((opt = getopt (argc, argv, "i:p:t:")) != -1) {
-        switch (opt)
-	    {
-
-        /*  Set IP address  */
-	    case 'i':
-    	        ip = optarg;
-	        break;
-
-        /*  Set port  */
-	    case 'p':
-	            port = atoi (optarg);
-	        break;
-
-        /*  Set TTL value  */
-	    case 't':
-    	        ttl = atoi (optarg);
-	        break;
-
-        /* Unknown option  */
-	    case '?':
-	            fprintf (stderr, "\n||  Unknown option `-%c'.\n", optopt);
-	        return 1;
-        }
-    }
-
-/*===========================================================================*/
-/*  Init RTP socket                                                          */
-/*===========================================================================*/
-
-    rtpsocket = createsocket (&RTPHeaders, &rtpsock, ip, port, ttl);
-
-/*===========================================================================*/
-/*  Print network details                                                    */
-/*===========================================================================*/
-
-    fprintf (stdout, "||---------------------------------------------------------------------------||\n");
-    fprintf (stdout, "||  Network setup\n");	  
-    fprintf (stdout, "||  IP Address= %s\n", ip);
-    fprintf (stdout, "||  Port = %d\n", port);
-    fprintf (stdout, "||  TTL = %d\n", ttl);
-    fprintf (stdout, "||\n");
-    fprintf (stdout, "||---------------------------------------------------------------------------||\n");
-
-/*===========================================================================*/
-/*  Open Vorbis file                                                         */
-/*===========================================================================*/
-
-    filename = argv [argc - 1];
-    file = fopen (filename, "rb");
-
-    if (file == NULL) {
-        fprintf (stderr, "||  Could not open file %s\n", filename);
-        exit (1);
-    }
-
-    fprintf (stdout, "||  Vorbis setup\n");
-    fprintf (stdout, "||  Filename: %s\n", filename);
-
-    int eos = 0;
-
-    buffer = ogg_sync_buffer (&oy, 4096);
-
-    bytes = fread (buffer, 1, 4096, file);
-
-    ogg_sync_wrote (&oy, bytes);
-    
-    if (ogg_sync_pageout (&oy, &og) != 1) {
-        if (bytes < 4096) {
-            fprintf (stdout, "||  Done\n");
-            exit (0);
-        }
-      
-        fprintf (stderr, "\n||  Input does not appear to be an Ogg bitstream.\n");
-        exit (1);
-    }
-  
-    ogg_stream_init (&os, ogg_page_serialno (&og));
-    
-    vorbis_info_init (&vi);
-    vorbis_comment_init (&vc);
-
-    if (ogg_stream_pagein (&os, &og) < 0) { 
-        fprintf (stderr, "||  Error reading first page of Ogg bitstream data.\n");
-        exit (1);
-    }
-    
-    if (ogg_stream_packetout (&os, &op) != 1) { 
-        fprintf (stderr, "||  Error reading initial header packet.\n");
-        exit (1);
-    }
-    
-    if (vorbis_synthesis_headerin (&vi, &vc, &op) < 0) { 
-        fprintf (stderr, "||  This Ogg bitstream does not contain Vorbis audio data.\n");
-        exit (1);
-    }
-
-    ogg_copy_packet(&(header[i]), &op);
-
-/*===========================================================================*/
-/*  Process comment and codebook headers                                     */
-/*===========================================================================*/
-
-    while (i < 2) {
-        while (i < 2) {
-            int result = ogg_sync_pageout (&oy, &og);
-
-        	if (result == 0) break; /* Need more data  */
-
-        	if (result == 1) {
-        	    ogg_stream_pagein (&os, &og); 
-
-                while(i < 2) {
-            	    result = ogg_stream_packetout (&os, &op);
-
-                    if (result == 0) break;
-                    
-                    if (result < 0) {
-                        fprintf (stderr, "||  Corrupt secondary header.  Exiting.\n");
-                        exit (1);
-    	            }
-
-
-                    vorbis_synthesis_headerin (&vi, &vc, &op);
-                    i++;
-
-                    ogg_copy_packet(&(header[i]), &op);
-                }
-            }
-        }
-
-        buffer = ogg_sync_buffer (&oy, 4096);
-        bytes = fread (buffer, 1, 4096, file);
-
-        if (bytes == 0 && i < 2) {
-            fprintf (stderr, "||  End of file before finding all Vorbis headers!\n");
-            exit (1);
-        }
-
-        ogg_sync_wrote (&oy, bytes);
-    }
-
-    VorbisBitfields.cbident = rand ();
-    
-    vorbis_synthesis_init (&vd, &vi);
-    vorbis_block_init (&vd, &vb);
-
-/*===========================================================================*/
-/*  Print details                                                            */
-/*===========================================================================*/
-
-    fprintf (stdout, "||  Bitstream is %d channel, %ldHz\n", vi.channels, vi.rate);
-    fprintf (stdout, "||  Encoded by: %s\n", vc.vendor);
-    fprintf (stdout, "||  Bitrates: min=%ld - nom=%ld - max=%ld\n", vi.bitrate_lower, vi.bitrate_nominal, vi.bitrate_upper);
-    fprintf (stdout, "||  Decode setup ident is 0x%06x\n", VorbisBitfields.cbident);
-    fprintf (stdout, "||\n");
-    fprintf (stdout, "||---------------------------------------------------------------------------||\n");
-    fprintf (stdout, "||  Processing\n");
-
-/*===========================================================================*/
-/*  Send the three headers inline                                            */
-/*===========================================================================*/
-{
-int conf_bytes = header[0].bytes+header[2].bytes;
-unsigned char *conf_packet=malloc(conf_bytes);
-
-    memcpy (conf_packet,header[0].packet,header[0].bytes);
-    memcpy (conf_packet+header[0].bytes,header[2].packet,header[2].bytes);
-    creatertp(conf_packet, conf_bytes, 0, &VorbisBitfields, 1);
-    progressmarker (6);
-
-free(conf_packet);
-}
-
-/*===========================================================================*/
-/*  Read raw Vorbis data and send RTP packet                                 */
-/*===========================================================================*/
-
-    while (!eos) {
-        while (!eos) {
-            int result = ogg_sync_pageout (&oy, &og);
-
-            if (result == 0) break; /* need more data  */
-
-            if (result < 0) {
-                fprintf (stderr, "\n||  Corrupt or missing data in bitstream; continuing....\n||  ");
-            } else {
-                ogg_stream_pagein (&os, &og); 
-
-                while (1) {
-                    result = ogg_stream_packetout (&os, &op);
-
-                    if (result == 0) break; /* need more data  */
-
-                    if (result < 0) {
-                        /* no reason to complain; already complained above  */
-            	    } else {
-#ifdef DEBUG
-			printf("||  bytes %ld bos %ld eos %ld gp %lld pno %lld\n", op.bytes, op.b_o_s, op.e_o_s, op.granulepos, op.packetno);
-#endif
-			creatertp ( op.packet, op.bytes, 
-					timestamp, &VorbisBitfields, 0);
-			timestamp = (vorbis_packet_blocksize(&vi,&op)+prev)/4*1000000L/vi.rate;
-			prev = vorbis_packet_blocksize(&vi,&op);
-            	    }
-                }
-
-                if (ogg_page_eos (&og)) eos = 1;
-            }
-        }
-
-        if (!eos) {
-            buffer = ogg_sync_buffer (&oy, 4096);
-            bytes = fread (buffer, 1, 4096, file);
-
-            ogg_sync_wrote (&oy, bytes);
-    
-            if (bytes == 0) eos = 1;
-        }
-    }
-
-    ogg_packet_clear (&(header[0]));
-    ogg_packet_clear (&(header[1]));
-    ogg_packet_clear (&(header[2]));
-
-    ogg_stream_clear (&os);
-  
-    vorbis_block_clear (&vb);
-    vorbis_dsp_clear (&vd);
-    vorbis_comment_clear (&vc);
-    vorbis_info_clear (&vi);
-
-    ogg_sync_clear (&oy);
-    fclose (file);
-
-    fprintf (stdout, "\n||---------------------------------------------------------------------------||\n");
-    fprintf (stdout, "||  Done.\n");
-    return (0);
-}
-
-/*****************************************************************************/
-/*  End                                                                      */
-/*****************************************************************************/



More information about the commits mailing list