[xiph-commits] r10416 - trunk/xiph-rtp
lu_zero at svn.xiph.org
lu_zero at svn.xiph.org
Sun Nov 20 11:22:05 PST 2005
Author: lu_zero
Date: 2005-11-20 11:22:02 -0800 (Sun, 20 Nov 2005)
New Revision: 10416
Added:
trunk/xiph-rtp/theorartp.c
Modified:
trunk/xiph-rtp/Makefile
Log:
theorartp ported to xiph_rtp infrastructure
Modified: trunk/xiph-rtp/Makefile
===================================================================
--- trunk/xiph-rtp/Makefile 2005-11-20 16:18:03 UTC (rev 10415)
+++ trunk/xiph-rtp/Makefile 2005-11-20 19:22:02 UTC (rev 10416)
@@ -1,11 +1,14 @@
# GNU Makefile for xiph rtp example code
-CC = gcc -g -O2 -Wall -DCHECK #-DDEBUG
-PROGS = vorbisrtp vorbisrtp-client theorartp-client
+CC = gcc -g -O2 -Wall -DCHECK -DDEBUG
+PROGS = vorbisrtp theorartp vorbisrtp-client theorartp-client
vorbisrtp_SRCS = vorbisrtp.c
vorbisrtp_PKGS = ogg vorbis
+theorartp_SRCS = vorbisrtp.c
+theorartp_PKGS = ogg theora
+
vorbisrtp-client_SRCS = vorbisrtp-client.c
vorbisrtp-client_PKGS = ogg vorbis
@@ -22,6 +25,10 @@
$(CC) -o $@ `pkg-config --cflags $($@_PKGS)` \
$^ `pkg-config --libs $($@_PKGS)`
+theorartp : theorartp.c xiph_rtp.c
+ $(CC) -o $@ `pkg-config --cflags $($@_PKGS)` \
+ $^ `pkg-config --libs $($@_PKGS)`
+
vorbisrtp-client : vorbisrtp-client.c
$(CC) -o $@ `pkg-config --cflags $($@_PKGS)` \
$< `pkg-config --libs $($@_PKGS)`
Added: trunk/xiph-rtp/theorartp.c
===================================================================
--- trunk/xiph-rtp/theorartp.c 2005-11-20 16:18:03 UTC (rev 10415)
+++ trunk/xiph-rtp/theorartp.c 2005-11-20 19:22:02 UTC (rev 10416)
@@ -0,0 +1,328 @@
+/*
+ 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.
+
+*/
+
+/* System includes */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+
+/* Codec includes */
+
+#include <theora/theora.h>
+
+/* Network includes */
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+/* Common include */
+
+#define HAVE_THEORA
+
+#include "xiph_rtp.h"
+
+#define BUFFER_SIZE 4096
+
+
+int main (int argc, char **argv)
+{
+ xiph_rtp_t xr;
+
+ char *buffer;
+ int bytes;
+
+ char *filename;
+ FILE *file;
+
+ ogg_sync_init (&xr.oy);
+
+ int i = 0;
+ int opt;
+ long int acc=0;
+
+ char *ip = "227.0.0.1";
+ unsigned int port = 4044;
+ unsigned int ttl = 1;
+ long timestamp = 0, prev = 0;
+
+ fprintf (stderr, "Theora RTP Server (draft-barbato-avt-rtp-theora-01)\n");
+ memset (&xr,0,sizeof(xiph_rtp_t));
+
+/* Command-line args processing */
+
+ if (argc < 2) {
+ fprintf (stderr, "\n\tNo Theora file specified.\n");
+ fprintf (stderr, "\tUsage: %s [-i ip address] [-p port] [-t ttl] filename\n\n",argv[0]);
+ 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);
+ fprintf (stderr, "\tUsage: %s [-i ip address] [-p port] [-t ttl] filename\n\n",argv[0]);
+ return 1;
+ }
+ }
+
+/* Init RTP socket */
+
+ if ( createsocket (&xr, ip, port, ttl)<0) return 1;
+
+/* Print network details */
+
+ fprintf (stdout, "\n 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");
+
+/* Open Theora 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, " Theora setup\n");
+ fprintf (stdout, " Filename: %s\n", filename);
+
+ int eos = 0;
+
+ buffer = ogg_sync_buffer (&xr.oy, BUFFER_SIZE);
+
+ bytes = fread (buffer, 1, BUFFER_SIZE, file);
+
+ ogg_sync_wrote (&xr.oy, bytes);
+
+ if (ogg_sync_pageout (&xr.oy, &xr.og) != 1) {
+ if (bytes < BUFFER_SIZE) {
+ fprintf (stdout, " Done\n");
+ exit (0);
+ }
+
+ fprintf (stderr, "\n Input does not appear to be an Ogg bitstream.\n");
+ exit (1);
+ }
+
+ ogg_stream_init (&xr.os, ogg_page_serialno (&xr.og));
+
+ theora_info_init (&xr.ti);
+ theora_comment_init (&xr.tc);
+
+ if (ogg_stream_pagein (&xr.os, &xr.og) < 0) {
+ fprintf (stderr, " Error reading first page of Ogg bitstream data.\n");
+ exit (1);
+ }
+
+ if (ogg_stream_packetout (&xr.os, &xr.op) != 1) {
+ fprintf (stderr, " Error reading initial header packet.\n");
+ exit (1);
+ }
+
+ if (theora_decode_header (&xr.ti, &xr.tc, &xr.op) < 0) {
+ fprintf (stderr, " This Ogg bitstream does not contain Theora video data.\n");
+ exit (1);
+ }
+
+ ogg_copy_packet(&(xr.header[i]), &xr.op); //FIXME change it?
+
+/*===========================================================================*/
+/* Process comment and codebook headers */
+/*===========================================================================*/
+
+ while (i < 2) {
+ while (i < 2) {
+ int result = ogg_sync_pageout (&xr.oy, &xr.og);
+
+ if (result == 0) break; /* Need more data */
+
+ if (result == 1) {
+ ogg_stream_pagein (&xr.os, &xr.og);
+
+ while(i < 2) {
+ result = ogg_stream_packetout (&xr.os, &xr.op);
+
+ if (result == 0) break;
+
+ if (result < 0) {
+ fprintf (stderr, " Corrupt secondary header. Exiting.\n");
+ exit (1);
+ }
+
+ theora_decode_header (&xr.ti, &xr.tc, &xr.op);
+ i++;
+
+ ogg_copy_packet(&(xr.header[i]), &xr.op);
+ }
+ }
+ }
+
+ buffer = ogg_sync_buffer (&xr.oy, BUFFER_SIZE);
+ bytes = fread (buffer, 1, BUFFER_SIZE, file);
+
+ if (bytes == 0 && i < 2) {
+ fprintf (stderr, "|| End of file before finding all Vorbis headers!\n");
+ exit (1);
+ }
+
+ ogg_sync_wrote (&xr.oy, bytes);
+ }
+
+ xr.bitfield.cbident = rand ();
+
+ theora_decode_init (&xr.td, &xr.ti);
+
+/*===========================================================================*/
+/* Print details */
+/*===========================================================================*/
+ fprintf(stdout," Theora %dx%d %.02f fps video\n"
+ "Encoded frame content is %dx%d with %dx%d offset\n",
+ xr.ti.width,xr.ti.height,
+ (double)xr.ti.fps_numerator/xr.ti.fps_denominator,
+ xr.ti.frame_width, xr.ti.frame_height,
+ xr.ti.offset_x, xr.ti.offset_y);
+
+ fprintf (stdout, " Decode setup ident is 0x%06x\n", xr.bitfield.cbident);
+ fprintf (stdout, "\n");
+ fprintf (stdout, " Processing\n");
+
+/*===========================================================================*/
+/* Send the three headers inline */
+/*===========================================================================*/
+{
+int conf_bytes = xr.header[0].bytes + xr.header[2].bytes;
+unsigned char *conf_packet = malloc(conf_bytes);
+
+ memcpy (conf_packet, xr.header[0].packet, xr.header[0].bytes);
+ memcpy (conf_packet + xr.header[0].bytes,
+ xr.header[2].packet,
+ xr.header[2].bytes);
+ creatertp(&xr, conf_packet, conf_bytes, 0, 1);
+
+ free(conf_packet);
+}
+
+
+/* Read raw data and send RTP packet */
+
+ while (!eos) {
+ while (!eos) {
+ int result = ogg_sync_pageout (&xr.oy, &xr.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 (&xr.os, &xr.og);
+
+ while (1) {
+ result = ogg_stream_packetout (&xr.os, &xr.op);
+
+ if (result == 0) break; /* need more data */
+
+ if (result < 0) {
+ /* no reason to complain; already complained above */
+ } else {
+ theora_decode_packetin(&xr.td,&xr.op);
+#ifdef DEBUG
+ printf(" bytes %ld bos %ld eos %ld gp %lld pno %lld\n", xr.op.bytes, xr.op.b_o_s, xr.op.e_o_s, xr.op.granulepos, xr.op.packetno);
+#endif
+ timestamp =
+ theora_granule_time(&xr.td,xr.op.granulepos);
+ creatertp ( &xr, xr.op.packet, xr.op.bytes,
+ timestamp, 0);
+ }
+ }
+
+ if (ogg_page_eos (&xr.og)) eos = 1;
+ }
+ }
+
+ if (!eos) {
+ buffer = ogg_sync_buffer (&xr.oy, BUFFER_SIZE);
+ bytes = fread (buffer, 1, BUFFER_SIZE, file);
+
+ ogg_sync_wrote (&xr.oy, bytes);
+
+ if (bytes == 0) eos = 1;
+ }
+ }
+//FIXME make it a cleanup function!
+ ogg_packet_clear (&(xr.header[0]));
+ ogg_packet_clear (&(xr.header[1]));
+ ogg_packet_clear (&(xr.header[2]));
+
+ ogg_stream_clear (&xr.os);
+
+ theora_clear(&xr.td);
+ theora_comment_clear(&xr.tc);
+ theora_info_clear(&xr.ti);
+
+ ogg_sync_clear (&xr.oy);
+ fclose (file);
+
+ fprintf (stdout, "Done.\n");
+ return (0);
+}
More information about the commits
mailing list