Commit feac01be authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Speex RTP payload format output - refs #1291

parent a5170e02
......@@ -782,6 +782,7 @@ static int rtp_packetize_mp4a_latm ( sout_stream_t *, sout_stream_id_t *, block_
static int rtp_packetize_h263 ( sout_stream_t *, sout_stream_id_t *, block_t * );
static int rtp_packetize_h264 ( sout_stream_t *, sout_stream_id_t *, block_t * );
static int rtp_packetize_amr ( sout_stream_t *, sout_stream_id_t *, block_t * );
static int rtp_packetize_spx ( sout_stream_t *, sout_stream_id_t *, block_t * );
static int rtp_packetize_t140 ( sout_stream_t *, sout_stream_id_t *, block_t * );
static void sprintf_hexa( char *s, uint8_t *p_data, int i_data )
......@@ -1114,6 +1115,14 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
id->i_clock_rate = p_fmt->audio.i_rate;
id->pf_packetize = rtp_packetize_amr;
break;
case VLC_FOURCC( 's', 'p', 'x', ' ' ):
id->i_payload_type = p_sys->i_payload_type++;
if( asprintf( &id->psz_rtpmap, "SPEEX/%d",
p_fmt->audio.i_rate ) == -1)
id->psz_rtpmap = NULL;
id->i_clock_rate = p_fmt->audio.i_rate;
id->pf_packetize = rtp_packetize_spx;
break;
case VLC_FOURCC( 't', '1', '4', '0' ):
id->psz_rtpmap = strdup( "t140/1000" );
id->i_clock_rate = 1000;
......@@ -2257,3 +2266,80 @@ static sout_access_out_t *GrabberCreate( sout_stream_t *p_stream )
p_grab->pf_write = AccessOutGrabberWrite;
return p_grab;
}
static int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *in )
{
uint8_t *p_buffer = in->p_buffer;
int i_data_size, i_payload_size, i_payload_padding;
i_data_size = i_payload_size = in->i_buffer;
i_payload_padding = 0;
block_t *p_out;
if ( in->i_buffer + 12 > id->i_mtu )
{
msg_Warn( p_stream, "Cannot send packet larger than output MTU" );
return VLC_SUCCESS;
}
/*
RFC for Speex in RTP says that each packet must end on an octet
boundary. So, we check to see if the number of bytes % 4 is zero.
If not, we have to add some padding.
This MAY be overkill since packetization is handled elsewhere and
appears to ensure the octet boundary. However, better safe than
sorry.
*/
if ( i_payload_size % 4 )
{
i_payload_padding = 4 - ( i_payload_size % 4 );
i_payload_size += i_payload_padding;
}
/*
Allocate a new RTP p_output block of the appropriate size.
Allow for 12 extra bytes of RTP header.
*/
p_out = block_New( p_stream, 12 + i_payload_size );
if ( i_payload_padding )
{
/*
The padding is required to be a zero followed by all 1s.
*/
char c_first_pad, c_remaining_pad;
c_first_pad = 0x7F;
c_remaining_pad = 0xFF;
/*
Allow for 12 bytes before the i_data_size because
of the expected RTP header added during
rtp_packetize_common.
*/
p_out->p_buffer[12 + i_data_size] = c_first_pad;
switch (i_payload_padding)
{
case 2:
p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;
break;
case 3:
p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;
p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad;
break;
}
}
/* Add the RTP header to our p_output buffer. */
rtp_packetize_common( id, p_out, 0, (in->i_pts > 0 ? in->i_pts : in->i_dts) );
/* Copy the Speex payload to the p_output buffer */
memcpy( &p_out->p_buffer[12], p_buffer, i_data_size );
p_out->i_buffer = 12 + i_payload_size;
p_out->i_dts = in->i_dts;
p_out->i_length = in->i_length;
/* Queue the buffer for actual transmission. */
rtp_packetize_send( id, p_out );
return VLC_SUCCESS;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment