@ -433,50 +433,78 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt)
pkt - > size = 0 ;
}
int ff_amf_tag_size ( const uint8_t * data , const uint8_t * data_end )
static int amf_tag_skip ( GetByteContext * gb )
{
const uint8_t * base = data ;
AMFDataType type ;
unsigned nb = - 1 ;
int parse_key = 1 ;
if ( data > = data_end )
if ( bytestream2_get_bytes_left ( gb ) < 1 )
return - 1 ;
switch ( ( type = * data + + ) ) {
case AMF_DATA_TYPE_NUMBER : return 9 ;
case AMF_DATA_TYPE_BOOL : return 2 ;
case AMF_DATA_TYPE_STRING : return 3 + AV_RB16 ( data ) ;
case AMF_DATA_TYPE_LONG_STRING : return 5 + AV_RB32 ( data ) ;
case AMF_DATA_TYPE_NULL : return 1 ;
case AMF_DATA_TYPE_DATE : return 11 ;
type = bytestream2_get_byte ( gb ) ;
switch ( type ) {
case AMF_DATA_TYPE_NUMBER :
bytestream2_get_be64 ( gb ) ;
return 0 ;
case AMF_DATA_TYPE_BOOL :
bytestream2_get_byte ( gb ) ;
return 0 ;
case AMF_DATA_TYPE_STRING :
bytestream2_skip ( gb , bytestream2_get_be16 ( gb ) ) ;
return 0 ;
case AMF_DATA_TYPE_LONG_STRING :
bytestream2_skip ( gb , bytestream2_get_be32 ( gb ) ) ;
return 0 ;
case AMF_DATA_TYPE_NULL :
return 0 ;
case AMF_DATA_TYPE_DATE :
bytestream2_skip ( gb , 10 ) ;
return 0 ;
case AMF_DATA_TYPE_ARRAY :
parse_key = 0 ;
case AMF_DATA_TYPE_MIXEDARRAY :
nb = bytestream_get_be32 ( & data ) ;
nb = bytestream2 _get_be32 ( gb ) ;
case AMF_DATA_TYPE_OBJECT :
while ( nb - - > 0 | | type ! = AMF_DATA_TYPE_ARRAY ) {
int t ;
if ( parse_key ) {
int size = bytestream_get_be16 ( & data ) ;
int size = bytestream2 _get_be16 ( gb ) ;
if ( ! size ) {
data + + ;
bytestream2_get_byte ( gb ) ;
break ;
}
if ( size < 0 | | size > = data_end - data )
if ( size < 0 | | size > = bytestream2_get_bytes_left ( gb ) )
return - 1 ;
data + = size ;
bytestream2_skip ( gb , size ) ;
}
t = ff_amf_tag_size ( data , data_end ) ;
if ( t < 0 | | t > = data_end - data )
t = amf_tag_skip ( gb ) ;
if ( t < 0 | | bytestream2_get_bytes_left ( gb ) < = 0 )
return - 1 ;
data + = t ;
}
return data - base ;
case AMF_DATA_TYPE_OBJECT_END : return 1 ;
return 0 ;
case AMF_DATA_TYPE_OBJECT_END : return 0 ;
default : return - 1 ;
}
}
int ff_amf_tag_size ( const uint8_t * data , const uint8_t * data_end )
{
GetByteContext gb ;
int ret ;
if ( data > = data_end )
return - 1 ;
bytestream2_init ( & gb , data , data_end - data ) ;
ret = amf_tag_skip ( & gb ) ;
if ( ret < 0 | | bytestream2_get_bytes_left ( & gb ) < = 0 )
return - 1 ;
av_assert0 ( bytestream2_tell ( & gb ) > = 0 & & bytestream2_tell ( & gb ) < = data_end - data ) ;
return bytestream2_tell ( & gb ) ;
}
int ff_amf_get_field_value ( const uint8_t * data , const uint8_t * data_end ,
const uint8_t * name , uint8_t * dst , int dst_size )
{