📄 rtpfmt.c
字号:
/***************************************************************************** * rtpfmt.c: RTP payload formats ***************************************************************************** * Copyright (C) 2003-2004 the VideoLAN team * Copyright © 2007 Rémi Denis-Courmont * $Id: a9d0aee6df0b1b9c78afc8a731fed57b9df2cc96 $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_sout.h>#include <vlc_block.h>#include "rtp.h"intrtp_packetize_h264_nal( sout_stream_id_t *id, const uint8_t *p_data, int i_data, int64_t i_pts, int64_t i_dts, bool b_last, int64_t i_length );int rtp_packetize_mpa( sout_stream_id_t *id, block_t *in ){ int i_max = rtp_mtu (id) - 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_Alloc( 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 */int rtp_packetize_mpv( sout_stream_id_t *id, block_t *in ){ int i_max = rtp_mtu (id) - 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_Alloc( 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;}int rtp_packetize_ac3( sout_stream_id_t *id, block_t *in ){ int i_max = rtp_mtu (id) - 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_Alloc( 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;}int rtp_packetize_split( sout_stream_id_t *id, block_t *in ){ int i_max = rtp_mtu (id); /* 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_Alloc( 12 + i_payload ); /* rtp common header */ rtp_packetize_common( id, out, (i == i_count - 1), (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;}/* rfc3016 */int rtp_packetize_mp4a_latm( sout_stream_id_t *id, block_t *in ){ int i_max = rtp_mtu (id) - 2; /* payload max in one packet */ int latmhdrsize = in->i_buffer / 0xff + 1; int i_count = ( in->i_buffer + i_max - 1 ) / i_max; uint8_t *p_data = in->p_buffer, *p_header = NULL; 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; if( i != 0 ) latmhdrsize = 0; out = block_Alloc( 12 + latmhdrsize + 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) ); if( i == 0 ) { int tmp = in->i_buffer; p_header=out->p_buffer+12; while( tmp > 0xfe ) { *p_header = 0xff; p_header++; tmp -= 0xff; } *p_header = tmp; } memcpy( &out->p_buffer[12+latmhdrsize], p_data, i_payload ); out->i_buffer = 12 + latmhdrsize + 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;}int rtp_packetize_mp4a( sout_stream_id_t *id, block_t *in ){ int i_max = rtp_mtu (id) - 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_Alloc( 16 + 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) ); /* AU headers */ /* AU headers length (bits) */ out->p_buffer[12] = 0; out->p_buffer[13] = 2*8; /* for each AU length 13 bits + idx 3bits, */ out->p_buffer[14] = ( in->i_buffer >> 5 )&0xff; out->p_buffer[15] = ( (in->i_buffer&0xff)<<3 )|0; 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -