📄 rtp.c
字号:
RTP packets need to get the correct src IP address */static char *SDPGenerate( const sout_stream_t *p_stream, const char *psz_destination, vlc_bool_t b_rtsp ){ sout_stream_sys_t *p_sys = p_stream->p_sys; int i_size; char *psz_sdp, *p, ipv; int i; /* FIXME: breaks IP version check on unknown destination */ if( psz_destination == NULL ) psz_destination = "0.0.0.0"; i_size = sizeof( "v=0\r\n" ) + sizeof( "o=- * * IN IP4 127.0.0.1\r\n" ) + 10 + 10 + sizeof( "s=*\r\n" ) + strlen( p_sys->psz_session_name ) + sizeof( "i=*\r\n" ) + strlen( p_sys->psz_session_description ) + sizeof( "u=*\r\n" ) + strlen( p_sys->psz_session_url ) + sizeof( "e=*\r\n" ) + strlen( p_sys->psz_session_email ) + sizeof( "t=0 0\r\n" ) + /* permanent stream */ /* when scheduled from vlm, we should set this info correctly */ sizeof( "a=tool:"PACKAGE_STRING"\r\n" ) + sizeof( "c=IN IP4 */*\r\n" ) + 20 + 10 + strlen( psz_destination ) ; for( i = 0; i < p_sys->i_es; i++ ) { sout_stream_id_t *id = p_sys->es[i]; i_size += strlen( "m=**d*o * RTP/AVP *\r\n" ) + 10 + 10; if ( id->i_bitrate ) { i_size += strlen( "b=AS: *\r\n") + 10; } if( id->psz_rtpmap ) { i_size += strlen( "a=rtpmap:* *\r\n" ) + strlen( id->psz_rtpmap )+10; } if( id->psz_fmtp ) { i_size += strlen( "a=fmtp:* *\r\n" ) + strlen( id->psz_fmtp ) + 10; } if( b_rtsp ) { i_size += strlen( "a=control:*/trackID=*\r\n" ) + strlen( p_sys->psz_rtsp_control ) + 10; } } if( p_sys->p_mux ) { i_size += strlen( "m=video %d RTP/AVP %d\r\n" ) +10 +10; } ipv = ( strchr( psz_destination, ':' ) != NULL ) ? '6' : '4'; p = psz_sdp = malloc( i_size ); p += sprintf( p, "v=0\r\n" ); p += sprintf( p, "o=- "I64Fd" %d IN IP%c %s\r\n", p_sys->i_sdp_id, p_sys->i_sdp_version, ipv, ipv == '6' ? "::1" : "127.0.0.1" ); if( *p_sys->psz_session_name ) p += sprintf( p, "s=%s\r\n", p_sys->psz_session_name ); if( *p_sys->psz_session_description ) p += sprintf( p, "i=%s\r\n", p_sys->psz_session_description ); if( *p_sys->psz_session_url ) p += sprintf( p, "u=%s\r\n", p_sys->psz_session_url ); if( *p_sys->psz_session_email ) p += sprintf( p, "e=%s\r\n", p_sys->psz_session_email ); p += sprintf( p, "t=0 0\r\n" ); /* permanent stream */ /* when scheduled from vlm, we should set this info correctly */ p += sprintf( p, "a=tool:"PACKAGE_STRING"\r\n" ); p += sprintf( p, "c=IN IP%c %s", ipv, psz_destination ); if( ( ipv == 4 ) && net_AddressIsMulticast( (vlc_object_t *)p_stream, psz_destination ) ) { /* Add the deprecated TTL field if it is an IPv4 multicast address */ p += sprintf( p, "/%d", p_sys->i_ttl ?: 1 ); } p += sprintf( p, "\r\n" ); for( i = 0; i < p_sys->i_es; i++ ) { sout_stream_id_t *id = p_sys->es[i]; if( id->i_cat == AUDIO_ES ) { p += sprintf( p, "m=audio %d RTP/AVP %d\r\n", id->i_port, id->i_payload_type ); } else if( id->i_cat == VIDEO_ES ) { p += sprintf( p, "m=video %d RTP/AVP %d\r\n", id->i_port, id->i_payload_type ); } else { continue; } if ( id->i_bitrate ) { p += sprintf(p,"b=AS:%d\r\n",id->i_bitrate); } if( id->psz_rtpmap ) { p += sprintf( p, "a=rtpmap:%d %s\r\n", id->i_payload_type, id->psz_rtpmap ); } if( id->psz_fmtp ) { p += sprintf( p, "a=fmtp:%d %s\r\n", id->i_payload_type, id->psz_fmtp ); } if( b_rtsp ) { p += sprintf( p, "a=control:trackID=%d\r\n", i ); } } if( p_sys->p_mux ) { p += sprintf( p, "m=video %d RTP/AVP %d\r\n", p_sys->i_port, p_sys->i_payload_type ); } return psz_sdp;}/***************************************************************************** * *****************************************************************************/static int rtp_packetize_l16 ( sout_stream_t *, sout_stream_id_t *, block_t * );static int rtp_packetize_l8 ( sout_stream_t *, sout_stream_id_t *, block_t * );static int rtp_packetize_mpa ( sout_stream_t *, sout_stream_id_t *, block_t * );static int rtp_packetize_mpv ( sout_stream_t *, sout_stream_id_t *, block_t * );static int rtp_packetize_ac3 ( sout_stream_t *, sout_stream_id_t *, block_t * );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 ){ static const char hex[16] = "0123456789abcdef"; int i; for( i = 0; i < i_data; i++ ) { s[2*i+0] = hex[(p_data[i]>>4)&0xf]; s[2*i+1] = hex[(p_data[i] )&0xf]; } s[2*i_data] = '\0';}static const char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";int ap_base64encode_len(int len){ return ((len + 2) / 3 * 4) + 1;}int ap_base64encode_binary(char *encoded, const unsigned char *string, int len){ int i; char *p; p = encoded; for (i = 0; i < len - 2; i += 3) { *p++ = basis_64[(string[i] >> 2) & 0x3F]; *p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)]; *p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((int) (string[i + 2] & 0xC0) >> 6)]; *p++ = basis_64[string[i + 2] & 0x3F]; } if (i < len) { *p++ = basis_64[(string[i] >> 2) & 0x3F]; if (i == (len - 1)) { *p++ = basis_64[((string[i] & 0x3) << 4)]; *p++ = '='; } else { *p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)]; *p++ = basis_64[((string[i + 1] & 0xF) << 2)]; } *p++ = '='; } *p++ = '\0'; return p - encoded;}int ap_base64encode(char *encoded, const char *string, int len){ return ap_base64encode_binary(encoded, (const unsigned char *) string, len);}char *b64_encode(char *buf, int len){ int elen; char *out; if(len == 0) len = strlen(buf); elen = ap_base64encode_len(len); out = (char *) malloc(sizeof(char) * (elen + 1)); ap_base64encode(out, buf, len); return out;}static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt ){ sout_instance_t *p_sout = p_stream->p_sout; sout_stream_sys_t *p_sys = p_stream->p_sys; sout_stream_id_t *id; sout_access_out_t *p_access = NULL; int i_port; char *psz_sdp; if( p_sys->p_mux != NULL ) { sout_input_t *p_input = NULL; if( ( p_input = sout_MuxAddStream( p_sys->p_mux, p_fmt ) ) == NULL ) { msg_Err( p_stream, "cannot add this stream to the muxer" ); return NULL; } id = malloc( sizeof( sout_stream_id_t ) ); memset( id, 0, sizeof( sout_stream_id_t ) ); id->p_access = NULL; id->p_input = p_input; id->pf_packetize= NULL; id->p_rtsp_url = NULL; id->i_port = 0; return id; } /* Choose the port */ i_port = 0; if( p_fmt->i_cat == AUDIO_ES && p_sys->i_port_audio > 0 ) { i_port = p_sys->i_port_audio; p_sys->i_port_audio = 0; } else if( p_fmt->i_cat == VIDEO_ES && p_sys->i_port_video > 0 ) { i_port = p_sys->i_port_video; p_sys->i_port_video = 0; } while( i_port == 0 ) { if( p_sys->i_port != p_sys->i_port_audio && p_sys->i_port != p_sys->i_port_video ) { i_port = p_sys->i_port; p_sys->i_port += 2; break; } p_sys->i_port += 2; } if( p_sys->psz_destination ) { char access[17]; char url[NI_MAXHOST + 8]; /* first try to create the access out */ if( p_sys->i_ttl ) { snprintf( access, sizeof( access ), "udp{raw,ttl=%d}", p_sys->i_ttl ); access[sizeof( access ) - 1] = '\0'; } else strcpy( access, "udp{raw}" ); snprintf( url, sizeof( url ), (( p_sys->psz_destination[0] != '[' ) && strchr( p_sys->psz_destination, ':' )) ? "[%s]:%d" : "%s:%d", p_sys->psz_destination, i_port ); url[sizeof( url ) - 1] = '\0'; if( ( p_access = sout_AccessOutNew( p_sout, access, url ) ) == NULL ) { msg_Err( p_stream, "cannot create the access out for %s://%s", access, url ); return NULL; } msg_Dbg( p_stream, "access out %s:%s", access, url ); } /* not create the rtp specific stuff */ id = malloc( sizeof( sout_stream_id_t ) ); memset( id, 0, sizeof( sout_stream_id_t ) ); id->p_stream = p_stream; id->p_access = p_access; id->p_input = NULL; id->psz_rtpmap = NULL; id->psz_fmtp = NULL; id->psz_destination = p_sys->psz_destination ? strdup( p_sys->psz_destination ) : NULL; id->i_port = i_port; id->p_rtsp_url = NULL; vlc_mutex_init( p_stream, &id->lock_rtsp ); id->i_rtsp_access = 0; id->rtsp_access = NULL; switch( p_fmt->i_codec ) { case VLC_FOURCC( 's', '1', '6', 'b' ): if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 44100 ) { id->i_payload_type = 11; } else if( p_fmt->audio.i_channels == 2 && p_fmt->audio.i_rate == 44100 ) { id->i_payload_type = 10; } else { id->i_payload_type = p_sys->i_payload_type++; } id->psz_rtpmap = malloc( strlen( "L16/*/*" ) + 20+1 ); sprintf( id->psz_rtpmap, "L16/%d/%d", p_fmt->audio.i_rate, p_fmt->audio.i_channels ); id->i_clock_rate = p_fmt->audio.i_rate; id->pf_packetize = rtp_packetize_l16; break; case VLC_FOURCC( 'u', '8', ' ', ' ' ): id->i_payload_type = p_sys->i_payload_type++; id->psz_rtpmap = malloc( strlen( "L8/*/*" ) + 20+1 ); sprintf( id->psz_rtpmap, "L8/%d/%d", p_fmt->audio.i_rate, p_fmt->audio.i_channels ); id->i_clock_rate = p_fmt->audio.i_rate; id->pf_packetize = rtp_packetize_l8; break; case VLC_FOURCC( 'm', 'p', 'g', 'a' ): id->i_payload_type = 14; id->i_clock_rate = 90000; id->psz_rtpmap = strdup( "MPA/90000" ); id->pf_packetize = rtp_packetize_mpa; break; case VLC_FOURCC( 'm', 'p', 'g', 'v' ): id->i_payload_type = 32; id->i_clock_rate = 90000; id->psz_rtpmap = strdup( "MPV/90000" ); id->pf_packetize = rtp_packetize_mpv; break; case VLC_FOURCC( 'a', '5', '2', ' ' ): id->i_payload_type = p_sys->i_payload_type++; id->i_clock_rate = 90000; id->psz_rtpmap = strdup( "ac3/90000" ); id->pf_packetize = rtp_packetize_ac3; break; case VLC_FOURCC( 'H', '2', '6', '3' ): id->i_payload_type = p_sys->i_payload_type++; id->i_clock_rate = 90000; 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; if( p_fmt->i_extra > 0 ) { uint8_t *p_buffer = p_fmt->p_extra; int i_buffer = p_fmt->i_extra; char *p_64_sps = NULL; char *p_64_pps = NULL; char hexa[6]; while( i_buffer > 4 && p_buffer[0] == 0 && p_buffer[1] == 0 && p_buffer[2] == 0 && p_buffer[3] == 1 ) { const int i_nal_type = p_buffer[4]&0x1f; int i_offset = 1; int i_size = 0; int i_startcode = 0; int i_encoded = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -