📄 rtp.c
字号:
answer->p_body = NULL; psz_session = httpd_MsgGet( query, "Session" ); if( *psz_session == 0 ) { psz_session = malloc( 100 ); sprintf( psz_session, "%d", rand() ); } httpd_MsgAdd( answer, "Transport", "RTP/AVP/UDP;destination=%s;port=%d-%d;ttl=%d", id->psz_destination, id->i_port,id->i_port+1, p_sys->i_ttl ); } else if( strstr( psz_transport, "unicast" ) && strstr( psz_transport, "client_port=" ) ) { int i_port = atoi( strstr( psz_transport, "client_port=" ) + strlen("client_port=") ); char *ip = httpd_ClientIP( cl ); char psz_access[100]; char psz_url[100]; sout_access_out_t *p_access; rtsp_client_t *rtsp = NULL; if( ip == NULL ) { answer->i_status = 400; answer->psz_status = strdup( "Internal server error" ); answer->i_body = 0; answer->p_body = NULL; break; } fprintf( stderr, "HTTPD_MSG_SETUP: unicast ip=%s port=%d\n", ip, i_port ); psz_session = httpd_MsgGet( query, "Session" ); if( *psz_session == 0 ) { psz_session = malloc( 100 ); sprintf( psz_session, "%d", rand() ); rtsp = RtspClientNew( p_stream, psz_session ); } else { rtsp = RtspClientGet( p_stream, psz_session ); if( rtsp == NULL ) { /* FIXME right error code */ answer->i_status = 400; answer->psz_status = strdup( "Unknown session id" ); answer->i_body = 0; answer->p_body = NULL; free( ip ); break; } } /* first try to create the access out */ if( p_sys->i_ttl > 0 ) sprintf( psz_access, "udp{raw,ttl=%d}", p_sys->i_ttl ); else sprintf( psz_access, "udp{raw}" ); sprintf( psz_url, "%s:%d", ip, i_port ); free( ip ); if( ( p_access = sout_AccessOutNew( p_stream->p_sout, psz_access, psz_url ) ) == NULL ) { msg_Err( p_stream, "cannot create the access out for %s://%s", psz_access, psz_url ); answer->i_status = 400; answer->psz_status = strdup( "Server internal error" ); answer->i_body = 0; answer->p_body = NULL; break; } TAB_APPEND( rtsp->i_id, rtsp->id, id ); TAB_APPEND( rtsp->i_access, rtsp->access, p_access ); answer->i_status = 200; answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; httpd_MsgAdd( answer, "Transport", "RTP/AVP/UDP;client_port=%d-%d", i_port, i_port + 1 ); } else /* TODO strstr( psz_transport, "interleaved" ) ) */ { answer->i_status = 400; answer->psz_status = strdup( "Bad Request" ); answer->i_body = 0; answer->p_body = NULL; } break; } default: return VLC_EGENERIC; } httpd_MsgAdd( answer, "Server", "VLC Server" ); httpd_MsgAdd( answer, "Content-Length", "%d", answer->i_body ); httpd_MsgAdd( answer, "Cseq", "%d", atoi( httpd_MsgGet( query, "Cseq" ) ) ); httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" ); if( psz_session ) { httpd_MsgAdd( answer, "Session", "%s"/*;timeout=5*/, psz_session ); } return VLC_SUCCESS;}/**************************************************************************** * rtp_packetize_*: ****************************************************************************/static void rtp_packetize_common( sout_stream_id_t *id, block_t *out, int b_marker, int64_t i_pts ){ uint32_t i_timestamp = i_pts * (int64_t)id->i_clock_rate / I64C(1000000); out->p_buffer[0] = 0x80; out->p_buffer[1] = (b_marker?0x80:0x00)|id->i_payload_type; out->p_buffer[2] = ( id->i_sequence >> 8)&0xff; out->p_buffer[3] = ( id->i_sequence )&0xff; out->p_buffer[4] = ( i_timestamp >> 24 )&0xff; out->p_buffer[5] = ( i_timestamp >> 16 )&0xff; out->p_buffer[6] = ( i_timestamp >> 8 )&0xff; out->p_buffer[7] = ( i_timestamp )&0xff; out->p_buffer[ 8] = id->ssrc[0]; out->p_buffer[ 9] = id->ssrc[1]; out->p_buffer[10] = id->ssrc[2]; out->p_buffer[11] = id->ssrc[3]; out->i_buffer = 12; id->i_sequence++;}static void rtp_packetize_send( sout_stream_id_t *id, block_t *out ){ int i; vlc_mutex_lock( &id->lock_rtsp ); for( i = 0; i < id->i_rtsp_access; i++ ) { sout_AccessOutWrite( id->rtsp_access[i], block_Duplicate( out ) ); } vlc_mutex_unlock( &id->lock_rtsp ); if( id->p_access ) { sout_AccessOutWrite( id->p_access, out ); } else { block_Release( out ); }}static int rtp_packetize_mpa( sout_stream_t *p_stream, sout_stream_id_t *id, block_t *in ){ int i_max = id->i_mtu - 12 - 4; /* 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; for( i = 0; i < i_count; i++ ) { int i_payload = __MIN( i_max, i_data ); block_t *out = block_New( p_stream, 16 + i_payload ); /* rtp common header */ rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts ); /* mbz set to 0 */ out->p_buffer[12] = 0; out->p_buffer[13] = 0; /* fragment offset in the current frame */ out->p_buffer[14] = ( (i*i_max) >> 8 )&0xff; out->p_buffer[15] = ( (i*i_max) )&0xff; memcpy( &out->p_buffer[16], p_data, i_payload ); out->i_buffer = 16 + 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;}/* rfc2250 */static int rtp_packetize_mpv( sout_stream_t *p_stream, sout_stream_id_t *id, block_t *in ){ int i_max = id->i_mtu - 12 - 4; /* 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; int b_sequence_start = 0; int i_temporal_ref = 0; int i_picture_coding_type = 0; int i_fbv = 0, i_bfc = 0, i_ffv = 0, i_ffc = 0; int b_start_slice = 0; /* preparse this packet to get some info */ if( in->i_buffer > 4 ) { uint8_t *p = p_data; int i_rest = in->i_buffer; for( ;; ) { while( i_rest > 4 && ( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) ) { p++; i_rest--; } if( i_rest <= 4 ) { break; } p += 3; i_rest -= 4; if( *p == 0xb3 ) { /* sequence start code */ b_sequence_start = 1; } else if( *p == 0x00 && i_rest >= 4 ) { /* picture */ i_temporal_ref = ( p[1] << 2) |((p[2]>>6)&0x03); i_picture_coding_type = (p[2] >> 3)&0x07; if( i_rest >= 4 && ( i_picture_coding_type == 2 || i_picture_coding_type == 3 ) ) { i_ffv = (p[3] >> 2)&0x01; i_ffc = ((p[3]&0x03) << 1)|((p[4]>>7)&0x01); if( i_rest > 4 && i_picture_coding_type == 3 ) { i_fbv = (p[4]>>6)&0x01; i_bfc = (p[4]>>3)&0x07; } } } else if( *p <= 0xaf ) { b_start_slice = 1; } } } for( i = 0; i < i_count; i++ ) { int i_payload = __MIN( i_max, i_data ); block_t *out = block_New( p_stream, 16 + i_payload ); uint32_t h = ( i_temporal_ref << 16 )| ( b_sequence_start << 13 )| ( b_start_slice << 12 )| ( i == i_count - 1 ? 1 << 11 : 0 )| ( i_picture_coding_type << 8 )| ( i_fbv << 7 )|( i_bfc << 4 )|( i_ffv << 3 )|i_ffc; /* rtp common header */ rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts > 0 ? in->i_pts : in->i_dts ); /* MBZ:5 T:1 TR:10 AN:1 N:1 S:1 B:1 E:1 P:3 FBV:1 BFC:3 FFV:1 FFC:3 */ out->p_buffer[12] = ( h >> 24 )&0xff; out->p_buffer[13] = ( h >> 16 )&0xff; out->p_buffer[14] = ( h >> 8 )&0xff; out->p_buffer[15] = ( h )&0xff; memcpy( &out->p_buffer[16], p_data, i_payload ); out->i_buffer = 16 + 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;}static int rtp_packetize_ac3( sout_stream_t *p_stream, sout_stream_id_t *id, block_t *in ){ int i_max = id->i_mtu - 12 - 2; /* 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; for( i = 0; i < i_count; i++ ) { int i_payload = __MIN( i_max, i_data ); block_t *out = block_New( p_stream, 14 + i_payload ); /* rtp common header */ rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts ); /* unit count */ out->p_buffer[12] = 1; /* unit header */ out->p_buffer[13] = 0x00; /* data */ memcpy( &out->p_buffer[14], p_data, i_payload ); out->i_buffer = 14 + 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;}static int rtp_packetize_split( 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; for( i = 0; i < i_count; i++ ) { int i_payload = __MIN( i_max, i_data ); block_t *out = block_New( p_stream, 12 + i_payload ); /* rtp common header */ rtp_packetize_common( id, out, ((i == i_count - 1)?1:0), (in->i_pts > 0 ? in->i_pts : in->i_dts) ); memcpy( &out->p_buffer[12], p_data, i_payload ); out->i_buffer = 12 + 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;}static int rtp_packetize_l16( 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_packet = 0; while( i_data > 0 ) { int i_payload = (__MIN( i_max, i_data )/4)*4; block_t *out = block_New( p_stream, 12 + i_payload ); /* rtp common header */ rtp_packetize_common( id, out, 0, (in->i_pts > 0 ? in->i_pts : in->i_dts) ); memcpy( &out->p_buffer[12], p_da
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -