/*****************************************************************************
* rtpfmt.c: RTP payload formats
*****************************************************************************
- * Copyright (C) 2003-2004 the VideoLAN team
+ * Copyright (C) 2003-2004 VLC authors and VideoLAN
* Copyright © 2007 Rémi Denis-Courmont
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
static int rtp_packetize_g726_32 (sout_stream_id_t *, block_t *);
static int rtp_packetize_g726_40 (sout_stream_id_t *, block_t *);
static int rtp_packetize_xiph (sout_stream_id_t *, block_t *);
+static int rtp_packetize_vp8 (sout_stream_id_t *, block_t *);
#define XIPH_IDENT (0)
unsigned packet_size[XIPH_MAX_HEADER_COUNT];
void *packet[XIPH_MAX_HEADER_COUNT];
unsigned packet_count;
- int val = xiph_SplitHeaders(packet_size, packet, &packet_count,
- i_extra, p_extra);
- if (val != VLC_SUCCESS)
- return val;
+ if (xiph_SplitHeaders(packet_size, packet, &packet_count,
+ i_extra, p_extra))
+ return VLC_EGENERIC;;
if (packet_count < 3)
- {
- val = VLC_EGENERIC;
- goto free;
- }
+ return VLC_EGENERIC;;
if (theora_pixel_fmt != NULL)
{
if (packet_size[0] < 42)
- {
- val = VLC_EGENERIC;
- goto free;
- }
+ return VLC_EGENERIC;
*theora_pixel_fmt = (((uint8_t *)packet[0])[41] >> 3) & 0x03;
}
+ packet_size[0] + packet_size[1] + packet_size[2];
*p_buffer = malloc(*i_buffer);
if (*p_buffer == NULL)
- {
- val = VLC_ENOMEM;
- goto free;
- }
+ return VLC_ENOMEM;
uint8_t *p = *p_buffer + room;
/* Number of headers */
p += packet_size[i];
}
- val = VLC_SUCCESS;
-free:
- for (unsigned i = 0; i < packet_count; i++)
- free(packet[i]);
-
- return val;
+ return VLC_SUCCESS;
}
static char *rtp_xiph_b64_oob_config(void *p_extra, size_t i_extra,
rtp_fmt->clock_rate = 1000;
rtp_fmt->pf_packetize = rtp_packetize_t140;
break;
+ case VLC_CODEC_GSM:
+ rtp_fmt->payload_type = 3;
+ rtp_fmt->ptname = "GSM";
+ rtp_fmt->pf_packetize = rtp_packetize_split;
+ break;
+ case VLC_CODEC_OPUS:
+ if (p_fmt->audio.i_channels > 2)
+ {
+ msg_Err( obj, "Multistream opus not supported in RTP"
+ " (having %d channels input)",
+ p_fmt->audio.i_channels );
+ return VLC_EGENERIC;
+ }
+ rtp_fmt->ptname = "opus";
+ rtp_fmt->pf_packetize = rtp_packetize_split;
+ rtp_fmt->clock_rate = 48000;
+ rtp_fmt->channels = 2;
+ if (p_fmt->audio.i_channels == 2)
+ rtp_fmt->fmtp = strdup( "sprop-stereo=1" );
+ break;
+ case VLC_CODEC_VP8:
+ rtp_fmt->ptname = "VP8";
+ rtp_fmt->pf_packetize = rtp_packetize_vp8;
+ break;
default:
msg_Err( obj, "cannot add this stream (unsupported "
{
return rtp_packetize_g726( id, in, 8 );
}
+
+#define RTP_VP8_HEADER_SIZE 1
+#define RTP_VP8_PAYLOAD_START (12 + RTP_VP8_HEADER_SIZE)
+
+static int rtp_packetize_vp8( sout_stream_id_t *id, block_t *in )
+{
+ int i_max = rtp_mtu (id) - RTP_VP8_HEADER_SIZE;
+ int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
+
+ uint8_t *p_data = in->p_buffer;
+ int i_data = in->i_buffer;
+
+ if ( i_max <= 0 )
+ return VLC_EGENERIC;
+
+ for( int i = 0; i < i_count; i++ )
+ {
+ int i_payload = __MIN( i_max, i_data );
+ block_t *out = block_Alloc( RTP_VP8_PAYLOAD_START + i_payload );
+ if ( out == NULL )
+ return VLC_ENOMEM;
+
+ /* VP8 payload header */
+ /* All frames are marked as reference ones */
+ if (i == 0)
+ out->p_buffer[12] = 0x10; // partition start
+ else
+ out->p_buffer[12] = 0;
+
+ /* rtp common header */
+ rtp_packetize_common( id, out, (i == i_count - 1),
+ (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
+ memcpy( &out->p_buffer[RTP_VP8_PAYLOAD_START], p_data, i_payload );
+
+ out->i_buffer = RTP_VP8_PAYLOAD_START + i_payload;
+ out->i_dts = in->i_dts + i * in->i_length / i_count;
+ out->i_length = in->i_length / i_count;
+
+ rtp_packetize_send( id, out );
+
+ p_data += i_payload;
+ i_data -= i_payload;
+ }
+
+ return VLC_SUCCESS;
+}