[vlc-devel] H.263 over RTP (RFC 2429)
Callan, Wilson
wcallan at starentnetworks.com
Fri May 28 16:53:43 CEST 2004
I have implemented enough of RFC 2429 "RTP Payload Format for the 1998 Version of H.263 Video" for it to work with live.com and quicktime. in other words, i have a function in rtp.c for VLC to send H.263 in RTP to another VLC or to a quicktime client. i first did it in 0.7.1. i've integrated it in to 0.7.2 but cant get 0.7.2 to run at all without a segmentation fault so i havent tested it there.
should i give it to the current owner of rtp.c (Laurent Aimar <fenrir at via.ecp.fr>?) or should i somehow check it in myself?
here's the code...
in Add():
case VLC_FOURCC( 'H', '2', '6', '3' ):
id->i_payload_type = 34; // from live.com MediaSession.cpp
id->i_clock_rate = 90000;
id->psz_rtpmap = strdup( "H263-1998/90000" );
id->pf_packetize = rtp_packetize_h263;
break;
and the new function in 0.7.2 format:
/* rfc2429 */
static int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *in )
{
uint8_t *p_data = in->p_buffer;
int i_data = in->i_buffer;
int i;
#define RTP_H263_HEADER_SIZE (2) // plen = 0
int i_max = id->i_mtu - 12 - RTP_H263_HEADER_SIZE; /* payload max in one packet */
int i_count;
int b_p_bit;
int b_v_bit = 0; // no pesky error resilience
int i_plen = 0; // normally plen=0 for PSC packet
int i_pebit = 0; // because plen=0
uint16_t h;
if (i_data < 2) {
return VLC_EGENERIC;
}
if (p_data[0] || p_data[1]) {
return VLC_EGENERIC;
}
// remove 2 leading 0 bytes
p_data += 2;
i_data -= 2;
i_count = ( i_data + i_max - 1 ) / i_max;
#define RTP_H263_PAYLOAD_START (14) // plen = 0
for( i = 0; i < i_count; i++ )
{
int i_payload = __MIN( i_max, i_data );
block_t *out = block_New( p_stream,
RTP_H263_PAYLOAD_START + i_payload );
b_p_bit = (i == 0) ? 1 : 0;
h = ( b_p_bit << 10 )|
( b_v_bit << 9 )|
( i_plen << 3 )|
i_pebit;
/* rtp common header */
//b_m_bit = 1; // always contains end of frame
rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
in->i_pts > 0 ? in->i_pts : in->i_dts );
/* h263 header */
out->p_buffer[12] = ( h >> 8 )&0xff;
out->p_buffer[13] = ( h )&0xff;
memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );
out->i_buffer = RTP_H263_PAYLOAD_START + i_payload;
out->i_dts = in->i_dts + i * in->i_length / i_count;
out->i_length = in->i_length / i_count;
sout_AccessOutWrite( id->p_access, out );
p_data += i_payload;
i_data -= i_payload;
}
return VLC_SUCCESS;
}
for reference, the function in 0.7.1 format:
/* rfc2429 */
static int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
sout_buffer_t *in )
{
uint8_t *p_data = in->p_buffer;
int i_data = in->i_size;
int i;
#define WCAL_H263_HEADER_SIZE (2) // plen = 0
int i_max = id->i_mtu - 12 - WCAL_H263_HEADER_SIZE; /* payload max in one packet */
int i_count;
// int b_m_bit;
int b_p_bit;
int b_v_bit = 0; // no pesky error resilience
int i_plen = 0; // normally plen=0 for PSC packet
int i_pebit = 0; // because plen=0
uint16_t h;
if (i_data < 2) {
printf("WCAL not enough H263 data!\n");
return VLC_EGENERIC;
}
if (p_data[0] || p_data[1]) {
printf("WCAL not a PSC!\n");
return VLC_EGENERIC;
}
// remove 2 leading 0 bytes
p_data += 2;
i_data -= 2;
i_count = ( i_data + i_max - 1 ) / i_max;
#define WCAL_H263_PAYLOAD_START (14) // plen = 0
for( i = 0; i < i_count; i++ )
{
int i_payload = __MIN( i_max, i_data );
sout_buffer_t *out = sout_BufferNew( p_stream->p_sout,
WCAL_H263_PAYLOAD_START + i_payload );
b_p_bit = (i == 0) ? 1 : 0;
h = ( b_p_bit << 10 )|
( b_v_bit << 9 )|
( i_plen << 3 )|
i_pebit;
//if (i_data > i_max) {
// printf("wcal h263 %d dont fit in pkt %d!\n", i_data, i_max);
//}
/* rtp common header */
//b_m_bit = 1; // always contains end of frame
rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
in->i_pts > 0 ? in->i_pts : in->i_dts );
/* h263 header */
out->p_buffer[12] = ( h >> 8 )&0xff;
out->p_buffer[13] = ( h )&0xff;
memcpy( &out->p_buffer[WCAL_H263_PAYLOAD_START], p_data, i_payload );
out->i_size = WCAL_H263_PAYLOAD_START + i_payload;
out->i_dts = in->i_dts + i * in->i_length / i_count;
out->i_length = in->i_length / i_count;
sout_AccessOutWrite( id->p_access, out );
p_data += i_payload;
i_data -= i_payload;
}
return VLC_SUCCESS;
}
--
This is the vlc-devel mailing-list, see http://www.videolan.org/vlc/
To unsubscribe, please read http://developers.videolan.org/lists.html
If you are in trouble, please contact <postmaster at videolan.org>
More information about the vlc-devel
mailing list