@ -2970,7 +2970,6 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
}
}
if ( rt - > flv_header_bytes < RTMP_HEADER ) {
if ( rt - > flv_header_bytes < RTMP_HEADER ) {
int set_data_frame = 0 ;
const uint8_t * header = rt - > flv_header ;
const uint8_t * header = rt - > flv_header ;
int channel = RTMP_AUDIO_CHANNEL ;
int channel = RTMP_AUDIO_CHANNEL ;
@ -2991,32 +2990,8 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
if ( pkttype = = RTMP_PT_VIDEO )
if ( pkttype = = RTMP_PT_VIDEO )
channel = RTMP_VIDEO_CHANNEL ;
channel = RTMP_VIDEO_CHANNEL ;
if ( pkttype = = RTMP_PT_NOTIFY ) {
// For onMetaData and |RtmpSampleAccess packets, we want
// @setDataFrame prepended to the packet before it gets sent.
// However, definitely not *all* RTMP_PT_NOTIFY packets (e.g.,
// onTextData and onCuePoint).
uint8_t commandbuffer [ 64 ] ;
int stringlen = 0 , commandsize = size - rt - > flv_header_bytes ;
GetByteContext gbc ;
// buf_temp at this point should be pointing to the RTMP command
bytestream2_init ( & gbc , buf_temp , commandsize ) ;
if ( ff_amf_read_string ( & gbc , commandbuffer , sizeof ( commandbuffer ) ,
& stringlen ) )
return AVERROR_INVALIDDATA ;
if ( ! strcmp ( commandbuffer , " onMetaData " ) | |
! strcmp ( commandbuffer , " |RtmpSampleAccess " ) ) {
set_data_frame = 1 ;
}
}
if ( ( ( pkttype = = RTMP_PT_VIDEO | | pkttype = = RTMP_PT_AUDIO ) & & ts = = 0 ) | |
if ( ( ( pkttype = = RTMP_PT_VIDEO | | pkttype = = RTMP_PT_AUDIO ) & & ts = = 0 ) | |
pkttype = = RTMP_PT_NOTIFY ) {
pkttype = = RTMP_PT_NOTIFY ) {
// add 12 bytes header if passing @setDataFrame
if ( set_data_frame )
pktsize + = 16 ;
if ( ( ret = ff_rtmp_check_alloc_array ( & rt - > prev_pkt [ 1 ] ,
if ( ( ret = ff_rtmp_check_alloc_array ( & rt - > prev_pkt [ 1 ] ,
& rt - > nb_prev_pkt [ 1 ] ,
& rt - > nb_prev_pkt [ 1 ] ,
channel ) ) < 0 )
channel ) ) < 0 )
@ -3034,10 +3009,6 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
rt - > out_pkt . extra = rt - > stream_id ;
rt - > out_pkt . extra = rt - > stream_id ;
rt - > flv_data = rt - > out_pkt . data ;
rt - > flv_data = rt - > out_pkt . data ;
if ( set_data_frame ) {
ff_amf_write_string ( & rt - > flv_data , " @setDataFrame " ) ;
}
}
}
copy = FFMIN ( rt - > flv_size - rt - > flv_off , size_temp ) ;
copy = FFMIN ( rt - > flv_size - rt - > flv_off , size_temp ) ;
@ -3048,6 +3019,33 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
if ( rt - > flv_off = = rt - > flv_size ) {
if ( rt - > flv_off = = rt - > flv_size ) {
rt - > skip_bytes = 4 ;
rt - > skip_bytes = 4 ;
if ( rt - > out_pkt . type = = RTMP_PT_NOTIFY ) {
// For onMetaData and |RtmpSampleAccess packets, we want
// @setDataFrame prepended to the packet before it gets sent.
// However, not all RTMP_PT_NOTIFY packets (e.g., onTextData
// and onCuePoint).
uint8_t commandbuffer [ 64 ] ;
int stringlen = 0 ;
GetByteContext gbc ;
bytestream2_init ( & gbc , rt - > flv_data , rt - > flv_size ) ;
if ( ! ff_amf_read_string ( & gbc , commandbuffer , sizeof ( commandbuffer ) ,
& stringlen ) ) {
if ( ! strcmp ( commandbuffer , " onMetaData " ) | |
! strcmp ( commandbuffer , " |RtmpSampleAccess " ) ) {
uint8_t * ptr ;
if ( ( ret = av_reallocp ( & rt - > out_pkt . data , rt - > out_pkt . size + 16 ) ) < 0 ) {
rt - > flv_size = rt - > flv_off = rt - > flv_header_bytes = 0 ;
return ret ;
}
memmove ( rt - > out_pkt . data + 16 , rt - > out_pkt . data , rt - > out_pkt . size ) ;
rt - > out_pkt . size + = 16 ;
ptr = rt - > out_pkt . data ;
ff_amf_write_string ( & ptr , " @setDataFrame " ) ;
}
}
}
if ( ( ret = rtmp_send_packet ( rt , & rt - > out_pkt , 0 ) ) < 0 )
if ( ( ret = rtmp_send_packet ( rt , & rt - > out_pkt , 0 ) ) < 0 )
return ret ;
return ret ;
rt - > flv_size = 0 ;
rt - > flv_size = 0 ;