* H264 RTP packetization by Vitaly V. Bursov <vitalyvb at ukr dotnet> refs #132

NAL and FU-A modes of RFC 3984
  works for VLC -> VLC
  Does not work with QT yet, because QT requires the optional params profile-level-id and sprop-parameter-sets. these are usually provided in QT hinted tracks I guess. I'm not sure if we can reconstruct them manually. If someone would care to investigate..
This commit is contained in:
Derk-Jan Hartman 2006-05-25 18:34:32 +00:00
parent 8e7484b4ff
commit 05b21e9603
3 changed files with 134 additions and 0 deletions

1
THANKS
View File

@ -133,6 +133,7 @@ Valek Filippov <frob at df.ru> - Russian translation
Vicente Jimenez Aguilar <vice at v1ce.net> - Spanish translation
Vincent van den Heuvel <heuvel@mac.com> - OSX about window artwork (v0.8.4)
Vitalijus Slavinskas <Vitalijus.Slavinskas at stud.ktu dot lt> - nsv patches
Vitaly V. Bursov <vitalyvb at ukr dot net>
Vladimir Chernyshov - MMX motion optimizations
Wade Majors <guru at startrek.com> - BeOS icon integration, debugging and fixes
Wallace Wadge <wwadge at gmail.com> - multiple programs TS mux

View File

@ -448,6 +448,11 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt )
p_es->i_payload_type = p_media->i_payload_type++;
p_es->psz_rtpmap = strdup( "H263-1998/90000" );
break;
case VLC_FOURCC( 'h', '2', '6', '4' ):
p_es->i_payload_type = p_media->i_payload_type++;
p_es->psz_rtpmap = strdup( "H264/90000" );
p_es->psz_fmtp = strdup( "packetization-mode=1" );
break;
case VLC_FOURCC( 'm', 'p', '4', 'v' ):
p_es->i_payload_type = p_media->i_payload_type++;
p_es->psz_rtpmap = strdup( "MP4V-ES/90000" );

View File

@ -902,6 +902,7 @@ static int rtp_packetize_split( sout_stream_t *, sout_stream_id_t *, block_t * )
static int rtp_packetize_mp4a ( sout_stream_t *, sout_stream_id_t *, block_t * );
static int rtp_packetize_mp4a_latm ( sout_stream_t *, sout_stream_id_t *, block_t * );
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 void sprintf_hexa( char *s, uint8_t *p_data, int i_data )
@ -1067,6 +1068,13 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
id->psz_rtpmap = strdup( "H263-1998/90000" );
id->pf_packetize = rtp_packetize_h263;
break;
case VLC_FOURCC( 'h', '2', '6', '4' ):
id->i_payload_type = p_sys->i_payload_type++;
id->i_clock_rate = 90000;
id->psz_rtpmap = strdup( "H264/90000" );
id->pf_packetize = rtp_packetize_h264;
id->psz_fmtp = strdup( "packetization-mode=1" );
break;
case VLC_FOURCC( 'm', 'p', '4', 'v' ):
{
@ -2334,6 +2342,126 @@ static int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
return VLC_SUCCESS;
}
/* rfc3984 */
static int rtp_packetize_h264( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *in )
{
int i_max = id->i_mtu - 12; /* payload max in one packet */
int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
uint8_t *p_data = in->p_buffer;
int i_data = in->i_buffer;
int i;
if( i_data <= i_max )
{
/* NAL */
int i_payload;
block_t *out;
uint8_t *p = p_data;
int i_rest = in->i_buffer;
while( i_rest > 4 &&
( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) )
{
p++;
i_rest--;
}
if (i_rest < 4)
return VLC_SUCCESS;
p+=3;
i_rest-=3;
i_payload = __MIN( i_max, i_rest );
out = block_New( p_stream, 12 + i_payload );
/* rtp common header */
rtp_packetize_common( id, out, 1,
in->i_pts > 0 ? in->i_pts : in->i_dts );
memcpy( &out->p_buffer[12], p, i_payload );
out->i_buffer = 12 + i_payload;
out->i_dts = in->i_dts;
out->i_length = in->i_length;
rtp_packetize_send( id, out );
/*msg_Dbg( p_stream, "nal-out plain %d %02x", i_payload, out->p_buffer[16] );*/
}
else
{
/* FU-A */
int i_payload;
block_t *out;
uint8_t *p = p_data;
int i_rest = in->i_buffer;
int start=1, end=0, first=0, nalh=-1;
while( i_rest > 4 &&
( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) )
{
p++;
i_rest--;
}
if (i_rest < 4)
return VLC_SUCCESS;
p+=3;
i_rest-=3;
nalh = *p;
p++;
i_rest--;
i_max = id->i_mtu - 14;
i_count = ( i_rest + i_max - 1 ) / i_max;
/*msg_Dbg( p_stream, "nal-out fragmented %02x %d", nalh, i_rest);*/
i=0;
while (end==0){
i_payload = __MIN( i_max, i_rest );
out = block_New( p_stream, 14 + i_payload );
if (i_rest==i_payload)
end = 1;
/* rtp common header */
rtp_packetize_common( id, out, (end)?1:0,
in->i_pts > 0 ? in->i_pts : in->i_dts );
/* FU indicator */
out->p_buffer[12] = (nalh&0x60)|28;
/* FU header */
out->p_buffer[13] = (start<<7)|(end<<6)|(nalh&0x1f);
memcpy( &out->p_buffer[14], p+first, i_payload );
out->i_buffer = 14 + i_payload;
// not sure what of these should be used and what it does :)
out->i_dts = in->i_dts + i * in->i_length / i_count;
out->i_length = in->i_length / i_count;
//out->i_dts = in->i_dts;
//out->i_length = in->i_length;
rtp_packetize_send( id, out );
/*msg_Dbg( p_stream, "nal-out fragmented: frag %d %d %02x %02x %d", start,end,
out->p_buffer[12], out->p_buffer[13], i_payload );*/
i_rest -= i_payload;
first += i_payload;
i++;
start=0;
}
}
return VLC_SUCCESS;
}
static int rtp_packetize_amr( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *in )
{