Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2013-10-19 21:32:41 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
df400ef1c59ab306e4e194cc2c98f35696f648d0
df400ef1
1 parent
28866723
connect vhost/app packet decoded.
隐藏空白字符变更
内嵌
并排对比
正在显示
6 个修改的文件
包含
324 行增加
和
59 行删除
trunk/src/core/srs_core_amf0.cpp
trunk/src/core/srs_core_amf0.hpp
trunk/src/core/srs_core_protocol.cpp
trunk/src/core/srs_core_protocol.hpp
trunk/src/core/srs_core_stream.cpp
trunk/src/core/srs_core_stream.hpp
trunk/src/core/srs_core_amf0.cpp
查看文件 @
df400ef
...
...
@@ -24,6 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core_amf0.hpp>
#include <srs_core_log.hpp>
#include <srs_core_error.hpp>
#include <srs_core_stream.hpp>
// AMF0 marker
...
...
@@ -49,30 +50,34 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// origin array whos data takes the same form as LengthValueBytes
#define RTMP_AMF0_OriginStrictArray 0x20
std
::
string
srs_amf0_read_utf8
(
SrsStream
*
stream
)
int
srs_amf0_read_object_eof
(
SrsStream
*
stream
,
SrsAmf0ObjectEOF
*&
);
int
srs_amf0_read_utf8
(
SrsStream
*
stream
,
std
::
string
&
value
)
{
std
::
string
str
;
int
ret
=
ERROR_SUCCESS
;
// len
if
(
!
stream
->
require
(
2
))
{
srs_warn
(
"amf0 read string length failed"
);
return
str
;
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read string length failed. ret=%d"
,
ret
);
return
ret
;
}
int16_t
len
=
stream
->
read_2bytes
();
srs_verbose
(
"amf0 read string length success. len=%d"
,
len
);
// empty string
if
(
len
<=
0
)
{
srs_verbose
(
"amf0 read empty string."
);
return
str
;
srs_verbose
(
"amf0 read empty string. ret=%d"
,
ret
);
return
ret
;
}
// data
if
(
!
stream
->
require
(
len
))
{
srs_warn
(
"amf0 read string data failed"
);
return
str
;
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read string data failed. ret=%d"
,
ret
);
return
ret
;
}
str
=
stream
->
read_string
(
len
);
st
d
::
string
st
r
=
stream
->
read_string
(
len
);
// support utf8-1 only
// 1.3.1 Strings and UTF-8
...
...
@@ -80,54 +85,104 @@ std::string srs_amf0_read_utf8(SrsStream* stream)
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
char
ch
=
*
(
str
.
data
()
+
i
);
if
((
ch
&
0x80
)
!=
0
)
{
srs_warn
(
"only support utf8-1, 0x00-0x7F, actual is %#x"
,
(
int
)
ch
);
return
""
;
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"only support utf8-1, 0x00-0x7F, actual is %#x. ret=%d"
,
(
int
)
ch
,
ret
);
return
ret
;
}
}
value
=
str
;
srs_verbose
(
"amf0 read string data success. str=%s"
,
str
.
c_str
());
return
str
;
return
ret
;
}
std
::
string
srs_amf0_read_string
(
SrsStream
*
stream
)
int
srs_amf0_read_string
(
SrsStream
*
stream
,
std
::
string
&
value
)
{
int
ret
=
ERROR_SUCCESS
;
// marker
if
(
!
stream
->
require
(
1
))
{
srs_warn
(
"amf0 read string marker failed"
);
return
""
;
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read string marker failed. ret=%d"
,
ret
);
return
ret
;
}
char
marker
=
stream
->
read_char
();
if
(
marker
!=
RTMP_AMF0_String
)
{
srs_warn
(
"amf0 check string marker failed. marker=%#x, required=%#x"
,
marker
,
RTMP_AMF0_String
);
return
""
;
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 check string marker failed. "
"marker=%#x, required=%#x, ret=%d"
,
marker
,
RTMP_AMF0_String
,
ret
);
return
ret
;
}
srs_verbose
(
"amf0 read string marker success"
);
return
srs_amf0_read_utf8
(
stream
);
return
srs_amf0_read_utf8
(
stream
,
value
);
}
int
srs_amf0_read_boolean
(
SrsStream
*
stream
,
bool
&
value
)
{
int
ret
=
ERROR_SUCCESS
;
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read bool marker failed. ret=%d"
,
ret
);
return
ret
;
}
char
marker
=
stream
->
read_char
();
if
(
marker
!=
RTMP_AMF0_Boolean
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 check bool marker failed. "
"marker=%#x, required=%#x, ret=%d"
,
marker
,
RTMP_AMF0_Boolean
,
ret
);
return
ret
;
}
srs_verbose
(
"amf0 read bool marker success"
);
// value
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read bool value failed. ret=%d"
,
ret
);
return
ret
;
}
if
(
stream
->
read_char
()
==
0
)
{
value
=
false
;
}
else
{
value
=
true
;
}
srs_verbose
(
"amf0 read bool value success. value=%d"
,
value
);
return
ret
;
}
double
srs_amf0_read_number
(
SrsStream
*
stream
)
int
srs_amf0_read_number
(
SrsStream
*
stream
,
double
&
value
)
{
double
value
=
0
;
int
ret
=
ERROR_SUCCESS
;
// marker
if
(
!
stream
->
require
(
1
))
{
srs_warn
(
"amf0 read number marker failed"
);
return
value
;
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read number marker failed. ret=%d"
,
ret
);
return
ret
;
}
char
marker
=
stream
->
read_char
();
if
(
marker
!=
RTMP_AMF0_Number
)
{
srs_warn
(
"amf0 check number marker failed. marker=%#x, required=%#x"
,
marker
,
RTMP_AMF0_Number
);
return
value
;
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 check number marker failed. "
"marker=%#x, required=%#x, ret=%d"
,
marker
,
RTMP_AMF0_Number
,
ret
);
return
ret
;
}
srs_verbose
(
"amf0 read number marker success"
);
// value
if
(
!
stream
->
require
(
8
))
{
srs_warn
(
"amf0 read number value failed"
);
return
value
;
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read number value failed. ret=%d"
,
ret
);
return
ret
;
}
int64_t
temp
=
stream
->
read_8bytes
();
...
...
@@ -135,13 +190,158 @@ double srs_amf0_read_number(SrsStream* stream)
srs_verbose
(
"amf0 read number value success. value=%.2f"
,
value
);
return
value
;
return
ret
;
}
SrsAmf0Object
*
srs_amf0_read_object
(
SrsStream
*
stream
)
int
srs_amf0_read_any
(
SrsStream
*
stream
,
SrsAmf0Any
*&
value
)
{
SrsAmf0Object
*
value
=
NULL
;
return
value
;
int
ret
=
ERROR_SUCCESS
;
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read any marker failed. ret=%d"
,
ret
);
return
ret
;
}
char
marker
=
stream
->
read_char
();
srs_verbose
(
"amf0 any marker success"
);
// backward the 1byte marker.
stream
->
skip
(
-
1
);
switch
(
marker
)
{
case
RTMP_AMF0_String
:
{
std
::
string
data
;
if
((
ret
=
srs_amf0_read_string
(
stream
,
data
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
new
SrsAmf0String
();
srs_amf0_convert
<
SrsAmf0String
>
(
value
)
->
value
=
data
;
return
ret
;
}
case
RTMP_AMF0_Boolean
:
{
bool
data
;
if
((
ret
=
srs_amf0_read_boolean
(
stream
,
data
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
new
SrsAmf0Boolean
();
srs_amf0_convert
<
SrsAmf0Boolean
>
(
value
)
->
value
=
data
;
return
ret
;
}
case
RTMP_AMF0_Number
:
{
double
data
;
if
((
ret
=
srs_amf0_read_number
(
stream
,
data
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
new
SrsAmf0Number
();
srs_amf0_convert
<
SrsAmf0Number
>
(
value
)
->
value
=
data
;
return
ret
;
}
case
RTMP_AMF0_ObjectEnd
:
{
SrsAmf0ObjectEOF
*
p
=
NULL
;
if
((
ret
=
srs_amf0_read_object_eof
(
stream
,
p
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
p
;
return
ret
;
}
case
RTMP_AMF0_Object
:
{
SrsAmf0Object
*
p
=
NULL
;
if
((
ret
=
srs_amf0_read_object
(
stream
,
p
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
p
;
return
ret
;
}
default:
value
=
new
SrsAmf0Any
();
value
->
marker
=
stream
->
read_char
();
return
ret
;
}
return
ret
;
}
int
srs_amf0_read_object_eof
(
SrsStream
*
stream
,
SrsAmf0ObjectEOF
*&
value
)
{
int
ret
=
ERROR_SUCCESS
;
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read object eof marker failed. ret=%d"
,
ret
);
return
ret
;
}
char
marker
=
stream
->
read_char
();
if
(
marker
!=
RTMP_AMF0_ObjectEnd
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 check object eof marker failed. "
"marker=%#x, required=%#x, ret=%d"
,
marker
,
RTMP_AMF0_ObjectEnd
,
ret
);
return
ret
;
}
srs_verbose
(
"amf0 read object eof marker success"
);
// value
value
=
new
SrsAmf0ObjectEOF
();
srs_verbose
(
"amf0 read object eof marker success"
);
return
ret
;
}
int
srs_amf0_read_object
(
SrsStream
*
stream
,
SrsAmf0Object
*&
value
)
{
int
ret
=
ERROR_SUCCESS
;
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read object marker failed. ret=%d"
,
ret
);
return
ret
;
}
char
marker
=
stream
->
read_char
();
if
(
marker
!=
RTMP_AMF0_Object
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 check object marker failed. "
"marker=%#x, required=%#x, ret=%d"
,
marker
,
RTMP_AMF0_Object
,
ret
);
return
ret
;
}
srs_verbose
(
"amf0 read object marker success"
);
// value
value
=
new
SrsAmf0Object
();
while
(
!
stream
->
empty
())
{
// property-name: utf8 string
std
::
string
property_name
;
if
((
ret
=
srs_amf0_read_utf8
(
stream
,
property_name
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 object read property name failed. ret=%d"
,
ret
);
return
ret
;
}
// property-value: any
SrsAmf0Any
*
property_value
=
NULL
;
if
((
ret
=
srs_amf0_read_any
(
stream
,
property_value
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 object read property_value failed. "
"name=%s, ret=%d"
,
property_name
.
c_str
(),
ret
);
return
ret
;
}
// AMF0 Object EOF.
if
(
property_name
.
empty
()
||
!
property_value
||
property_value
->
is_object_eof
())
{
if
(
property_value
)
{
delete
property_value
;
}
srs_info
(
"amf0 read object EOF."
);
break
;
}
// add property
value
->
properties
[
property_name
]
=
property_value
;
}
return
ret
;
}
SrsAmf0Any
::
SrsAmf0Any
()
...
...
@@ -158,6 +358,11 @@ bool SrsAmf0Any::is_string()
return
marker
==
RTMP_AMF0_String
;
}
bool
SrsAmf0Any
::
is_boolean
()
{
return
marker
==
RTMP_AMF0_Boolean
;
}
bool
SrsAmf0Any
::
is_number
()
{
return
marker
==
RTMP_AMF0_Number
;
...
...
@@ -168,6 +373,11 @@ bool SrsAmf0Any::is_object()
return
marker
==
RTMP_AMF0_Object
;
}
bool
SrsAmf0Any
::
is_object_eof
()
{
return
marker
==
RTMP_AMF0_ObjectEnd
;
}
SrsAmf0String
::
SrsAmf0String
()
{
marker
=
RTMP_AMF0_String
;
...
...
@@ -177,6 +387,16 @@ SrsAmf0String::~SrsAmf0String()
{
}
SrsAmf0Boolean
::
SrsAmf0Boolean
()
{
marker
=
RTMP_AMF0_Boolean
;
value
=
false
;
}
SrsAmf0Boolean
::~
SrsAmf0Boolean
()
{
}
SrsAmf0Number
::
SrsAmf0Number
()
{
marker
=
RTMP_AMF0_Number
;
...
...
@@ -185,12 +405,12 @@ SrsAmf0Number::SrsAmf0Number()
SrsAmf0Number
::~
SrsAmf0Number
()
{
marker
=
RTMP_AMF0_ObjectEnd
;
}
SrsAmf0ObjectEOF
::
SrsAmf0ObjectEOF
()
{
utf8_empty
=
0x00
;
object_end_marker
=
RTMP_AMF0_ObjectEnd
;
}
SrsAmf0ObjectEOF
::~
SrsAmf0ObjectEOF
()
...
...
trunk/src/core/srs_core_amf0.hpp
查看文件 @
df400ef
...
...
@@ -43,25 +43,30 @@ class SrsAmf0Object;
* UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4
* UTF8-1 = %x00-7F
* @remark only support UTF8-1 char.
* @return default value is empty string.
*/
extern
std
::
string
srs_amf0_read_utf8
(
SrsStream
*
stream
);
extern
int
srs_amf0_read_utf8
(
SrsStream
*
stream
,
std
::
string
&
value
);
/**
* read amf0 string from stream.
* 2.4 String Type
* string-type = string-marker UTF-8
* @return default value is empty string.
*/
extern
std
::
string
srs_amf0_read_string
(
SrsStream
*
stream
);
extern
int
srs_amf0_read_string
(
SrsStream
*
stream
,
std
::
string
&
value
);
/**
* read amf0 boolean from stream.
* 2.4 String Type
* boolean-type = boolean-marker U8
* 0 is false, <> 0 is true
*/
extern
int
srs_amf0_read_boolean
(
SrsStream
*
stream
,
bool
&
value
);
/**
* read amf0 number from stream.
* 2.2 Number Type
* number-type = number-marker DOUBLE
* @return default value is 0.
*/
extern
double
srs_amf0_read_number
(
SrsStream
*
stream
);
extern
int
srs_amf0_read_number
(
SrsStream
*
stream
,
double
&
value
);
/**
* read amf0 object from stream.
...
...
@@ -69,7 +74,7 @@ extern double srs_amf0_read_number(SrsStream* stream);
* anonymous-object-type = object-marker *(object-property)
* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
*/
extern
SrsAmf0Object
*
srs_amf0_read_object
(
SrsStream
*
stream
);
extern
int
srs_amf0_read_object
(
SrsStream
*
stream
,
SrsAmf0Object
*&
value
);
/**
* any amf0 value.
...
...
@@ -87,22 +92,10 @@ struct SrsAmf0Any
virtual
~
SrsAmf0Any
();
virtual
bool
is_string
();
virtual
bool
is_boolean
();
virtual
bool
is_number
();
virtual
bool
is_object
();
/**
* convert the any to specified object.
* @return T*, the converted object. never NULL.
* @remark, user must ensure the current object type,
* or the covert will cause assert failed.
*/
template
<
class
T
>
T
*
convert
()
{
T
*
p
=
dynamic_cast
<
T
>
(
this
);
srs_assert
(
p
!=
NULL
);
return
p
;
}
virtual
bool
is_object_eof
();
};
/**
...
...
@@ -120,6 +113,21 @@ struct SrsAmf0String : public SrsAmf0Any
};
/**
* read amf0 boolean from stream.
* 2.4 String Type
* boolean-type = boolean-marker U8
* 0 is false, <> 0 is true
* @return default value is false.
*/
struct
SrsAmf0Boolean
:
public
SrsAmf0Any
{
bool
value
;
SrsAmf0Boolean
();
virtual
~
SrsAmf0Boolean
();
};
/**
* read amf0 number from stream.
* 2.2 Number Type
* number-type = number-marker DOUBLE
...
...
@@ -138,10 +146,9 @@ struct SrsAmf0Number : public SrsAmf0Any
* object-end-type = UTF-8-empty object-end-marker
* 0x00 0x00 0x09
*/
struct
SrsAmf0ObjectEOF
struct
SrsAmf0ObjectEOF
:
public
SrsAmf0Any
{
int16_t
utf8_empty
;
char
object_end_marker
;
SrsAmf0ObjectEOF
();
virtual
~
SrsAmf0ObjectEOF
();
...
...
@@ -160,5 +167,19 @@ struct SrsAmf0Object : public SrsAmf0Any
SrsAmf0Object
();
virtual
~
SrsAmf0Object
();
};
/**
* convert the any to specified object.
* @return T*, the converted object. never NULL.
* @remark, user must ensure the current object type,
* or the covert will cause assert failed.
*/
template
<
class
T
>
T
*
srs_amf0_convert
(
SrsAmf0Any
*
any
)
{
T
*
p
=
dynamic_cast
<
T
*>
(
any
);
srs_assert
(
p
!=
NULL
);
return
p
;
}
#endif
\ No newline at end of file
...
...
trunk/src/core/srs_core_protocol.cpp
查看文件 @
df400ef
...
...
@@ -281,7 +281,11 @@ int SrsMessage::decode_packet()
}
srs_verbose
(
"decode stream initialized success"
);
std
::
string
command
=
srs_amf0_read_string
(
stream
);
std
::
string
command
;
if
((
ret
=
srs_amf0_read_string
(
stream
,
command
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"decode AMF0 command name failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"AMF0 command message, command_name=%s"
,
command
.
c_str
());
stream
->
reset
();
...
...
@@ -337,7 +341,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream)
return
ret
;
}
command_name
=
srs_amf0_read_string
(
stream
);
if
((
ret
=
srs_amf0_read_string
(
stream
,
command_name
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 decode connect command_name failed. ret=%d"
,
ret
);
return
ret
;
}
if
(
command_name
.
empty
()
||
command_name
!=
RTMP_AMF0_COMMAND_CONNECT
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 decode connect command_name failed. "
...
...
@@ -345,7 +352,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream)
return
ret
;
}
transaction_id
=
srs_amf0_read_number
(
stream
);
if
((
ret
=
srs_amf0_read_number
(
stream
,
transaction_id
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 decode connect transaction_id failed. ret=%d"
,
ret
);
return
ret
;
}
if
(
transaction_id
!=
1.0
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 decode connect transaction_id failed. "
...
...
@@ -353,7 +363,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream)
return
ret
;
}
command_object
=
srs_amf0_read_object
(
stream
);
if
((
ret
=
srs_amf0_read_object
(
stream
,
command_object
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 decode connect command_object failed. ret=%d"
,
ret
);
return
ret
;
}
if
(
command_object
==
NULL
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 decode connect command_object failed. ret=%d"
,
ret
);
...
...
trunk/src/core/srs_core_protocol.hpp
查看文件 @
df400ef
...
...
@@ -238,6 +238,7 @@ public:
*
pmsg
=
msg
;
*
ppacket
=
pkt
;
break
;
}
return
ret
;
...
...
trunk/src/core/srs_core_stream.cpp
查看文件 @
df400ef
...
...
@@ -70,7 +70,12 @@ bool SrsStream::empty()
bool
SrsStream
::
require
(
int
required_size
)
{
return
!
empty
()
&&
(
required_size
<
bytes
+
size
-
p
);
return
!
empty
()
&&
(
required_size
<=
bytes
+
size
-
p
);
}
void
SrsStream
::
skip
(
int
size
)
{
p
+=
size
;
}
char
SrsStream
::
read_char
()
...
...
trunk/src/core/srs_core_stream.hpp
查看文件 @
df400ef
...
...
@@ -65,6 +65,11 @@ public:
* @return true if stream can read/write specified required_size bytes.
*/
virtual
bool
require
(
int
required_size
);
/**
* to skip some size.
* @size can be any value. positive to forward; nagetive to backward.
*/
virtual
void
skip
(
int
size
);
public
:
/**
* get 1bytes char from stream.
...
...
请
注册
或
登录
后发表评论