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
2014-05-22 16:29:42 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
7f48590239dc0c8d06390c45c57072eac3c286f9
7f485902
1 parent
c8f80414
support amf0 StrictArray(0x0a). 0.9.111.
显示空白字符变更
内嵌
并排对比
正在显示
5 个修改的文件
包含
270 行增加
和
27 行删除
README.md
trunk/src/libs/srs_librtmp.cpp
trunk/src/libs/srs_librtmp.hpp
trunk/src/rtmp/srs_protocol_amf0.cpp
trunk/src/rtmp/srs_protocol_amf0.hpp
README.md
查看文件 @
7f48590
...
...
@@ -230,6 +230,7 @@ Supported operating systems and hardware:
*
2013-10-17, Created.
<br/>
## History
*
v1.0, 2014-05-22, support amf0 StrictArray(0x0a). 0.9.111.
*
v1.0, 2014-05-22, support flv parser, add amf0 to librtmp. 0.9.110
*
v1.0, 2014-05-22, fix
[
#74
](
https://github.com/winlinvip/simple-rtmp-server/issues/74
)
, add tcUrl for http callback on_connect, 0.9.109
*
v1.0, 2014-05-19, support http heartbeat, 0.9.107
...
...
trunk/src/libs/srs_librtmp.cpp
查看文件 @
7f48590
...
...
@@ -484,6 +484,12 @@ amf0_bool srs_amf0_is_ecma_array(srs_amf0_t amf0)
return
any
->
is_ecma_array
();
}
amf0_bool
srs_amf0_is_strict_array
(
srs_amf0_t
amf0
)
{
SrsAmf0Any
*
any
=
(
SrsAmf0Any
*
)
amf0
;
return
any
->
is_strict_array
();
}
const
char
*
srs_amf0_to_string
(
srs_amf0_t
amf0
)
{
SrsAmf0Any
*
any
=
(
SrsAmf0Any
*
)
amf0
;
...
...
@@ -520,32 +526,44 @@ srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index)
return
(
srs_amf0_t
)
obj
->
value_at
(
index
);
}
int
srs_amf0_array_property_count
(
srs_amf0_t
amf0
)
int
srs_amf0_
ecma_
array_property_count
(
srs_amf0_t
amf0
)
{
SrsAmf0EcmaArray
*
obj
=
(
SrsAmf0EcmaArray
*
)
amf0
;
return
obj
->
count
();
}
const
char
*
srs_amf0_array_property_name_at
(
srs_amf0_t
amf0
,
int
index
)
const
char
*
srs_amf0_
ecma_
array_property_name_at
(
srs_amf0_t
amf0
,
int
index
)
{
SrsAmf0EcmaArray
*
obj
=
(
SrsAmf0EcmaArray
*
)
amf0
;
return
obj
->
key_raw_at
(
index
);
}
srs_amf0_t
srs_amf0_array_property_value_at
(
srs_amf0_t
amf0
,
int
index
)
srs_amf0_t
srs_amf0_ecma_array_property_value_at
(
srs_amf0_t
amf0
,
int
index
)
{
SrsAmf0EcmaArray
*
obj
=
(
SrsAmf0EcmaArray
*
)
amf0
;
return
(
srs_amf0_t
)
obj
->
value_at
(
index
);
}
int
srs_amf0_strict_array_property_count
(
srs_amf0_t
amf0
)
{
SrsAmf0EcmaArray
*
obj
=
(
SrsAmf0EcmaArray
*
)
amf0
;
return
obj
->
count
();
}
srs_amf0_t
srs_amf0_strict_array_property_at
(
srs_amf0_t
amf0
,
int
index
)
{
SrsAmf0EcmaArray
*
obj
=
(
SrsAmf0EcmaArray
*
)
amf0
;
return
(
srs_amf0_t
)
obj
->
value_at
(
index
);
}
void
__srs_
amf0_do_print
(
SrsAmf0Any
*
any
,
stringstream
&
ss
,
int
&
level
)
void
__srs_
fill_level_spaces
(
stringstream
&
ss
,
int
level
)
{
if
(
true
)
{
for
(
int
i
=
0
;
i
<
level
;
i
++
)
{
ss
<<
" "
;
}
}
}
void
__srs_amf0_do_print
(
SrsAmf0Any
*
any
,
stringstream
&
ss
,
int
level
)
{
if
(
any
->
is_boolean
())
{
ss
<<
"Boolean "
<<
(
any
->
to_boolean
()
?
"true"
:
"false"
)
<<
endl
;
}
else
if
(
any
->
is_number
())
{
...
...
@@ -558,26 +576,36 @@ void __srs_amf0_do_print(SrsAmf0Any* any, stringstream& ss, int& level)
SrsAmf0EcmaArray
*
obj
=
any
->
to_ecma_array
();
ss
<<
"EcmaArray "
<<
"("
<<
obj
->
count
()
<<
" items)"
<<
endl
;
for
(
int
i
=
0
;
i
<
obj
->
count
();
i
++
)
{
ss
<<
" Property '"
<<
obj
->
key_at
(
i
)
<<
"' "
;
if
(
obj
->
value_at
(
i
)
->
is_object
()
||
obj
->
value_at
(
i
)
->
is_ecma_array
())
{
int
next_level
=
level
+
1
;
__srs_amf0_do_print
(
obj
->
value_at
(
i
),
ss
,
next_level
);
__srs_fill_level_spaces
(
ss
,
level
+
1
);
ss
<<
"Elem '"
<<
obj
->
key_at
(
i
)
<<
"' "
;
if
(
obj
->
value_at
(
i
)
->
is_complex_object
())
{
__srs_amf0_do_print
(
obj
->
value_at
(
i
),
ss
,
level
+
1
);
}
else
{
int
next_level
=
0
;
__srs_amf0_do_print
(
obj
->
value_at
(
i
),
ss
,
next_level
);
__srs_amf0_do_print
(
obj
->
value_at
(
i
),
ss
,
0
);
}
}
}
else
if
(
any
->
is_strict_array
())
{
SrsAmf0StrictArray
*
obj
=
any
->
to_strict_array
();
ss
<<
"StrictArray "
<<
"("
<<
obj
->
count
()
<<
" items)"
<<
endl
;
for
(
int
i
=
0
;
i
<
obj
->
count
();
i
++
)
{
__srs_fill_level_spaces
(
ss
,
level
+
1
);
ss
<<
"Elem "
;
if
(
obj
->
at
(
i
)
->
is_complex_object
())
{
__srs_amf0_do_print
(
obj
->
at
(
i
),
ss
,
level
+
1
);
}
else
{
__srs_amf0_do_print
(
obj
->
at
(
i
),
ss
,
0
);
}
}
}
else
if
(
any
->
is_object
())
{
SrsAmf0Object
*
obj
=
any
->
to_object
();
ss
<<
"Object "
<<
"("
<<
obj
->
count
()
<<
" items)"
<<
endl
;
for
(
int
i
=
0
;
i
<
obj
->
count
();
i
++
)
{
ss
<<
" Property '"
<<
obj
->
key_at
(
i
)
<<
"' "
;
if
(
obj
->
value_at
(
i
)
->
is_object
()
||
obj
->
value_at
(
i
)
->
is_ecma_array
())
{
int
next_level
=
level
+
1
;
__srs_amf0_do_print
(
obj
->
value_at
(
i
),
ss
,
next_level
);
__srs_fill_level_spaces
(
ss
,
level
+
1
);
ss
<<
"Property '"
<<
obj
->
key_at
(
i
)
<<
"' "
;
if
(
obj
->
value_at
(
i
)
->
is_complex_object
())
{
__srs_amf0_do_print
(
obj
->
value_at
(
i
),
ss
,
level
+
1
);
}
else
{
int
next_level
=
0
;
__srs_amf0_do_print
(
obj
->
value_at
(
i
),
ss
,
next_level
);
__srs_amf0_do_print
(
obj
->
value_at
(
i
),
ss
,
0
);
}
}
}
else
{
...
...
@@ -587,23 +615,29 @@ void __srs_amf0_do_print(SrsAmf0Any* any, stringstream& ss, int& level)
char
*
srs_amf0_human_print
(
srs_amf0_t
amf0
,
char
**
pdata
,
int
*
psize
)
{
if
(
!
amf0
)
{
return
NULL
;
}
stringstream
ss
;
ss
.
precision
(
1
);
SrsAmf0Any
*
any
=
(
SrsAmf0Any
*
)
amf0
;
int
level
=
0
;
__srs_amf0_do_print
(
any
,
ss
,
level
);
__srs_amf0_do_print
(
any
,
ss
,
0
);
string
str
=
ss
.
str
();
if
(
str
.
empty
())
{
return
NULL
;
}
*
pdata
=
new
char
[
str
.
length
()];
char
*
data
=
new
char
[
str
.
length
()
+
1
];
memcpy
(
data
,
str
.
data
(),
str
.
length
());
data
[
str
.
length
()]
=
0
;
*
pdata
=
data
;
*
psize
=
str
.
length
();
memcpy
(
*
pdata
,
str
.
data
(),
str
.
length
());
return
*
pdata
;
}
...
...
trunk/src/libs/srs_librtmp.hpp
查看文件 @
7f48590
...
...
@@ -176,6 +176,7 @@ amf0_bool srs_amf0_is_number(srs_amf0_t amf0);
amf0_bool
srs_amf0_is_null
(
srs_amf0_t
amf0
);
amf0_bool
srs_amf0_is_object
(
srs_amf0_t
amf0
);
amf0_bool
srs_amf0_is_ecma_array
(
srs_amf0_t
amf0
);
amf0_bool
srs_amf0_is_strict_array
(
srs_amf0_t
amf0
);
/* value converter */
const
char
*
srs_amf0_to_string
(
srs_amf0_t
amf0
);
amf0_bool
srs_amf0_to_boolean
(
srs_amf0_t
amf0
);
...
...
@@ -184,10 +185,13 @@ amf0_number srs_amf0_to_number(srs_amf0_t amf0);
int
srs_amf0_object_property_count
(
srs_amf0_t
amf0
);
const
char
*
srs_amf0_object_property_name_at
(
srs_amf0_t
amf0
,
int
index
);
srs_amf0_t
srs_amf0_object_property_value_at
(
srs_amf0_t
amf0
,
int
index
);
/* array value converter */
int
srs_amf0_array_property_count
(
srs_amf0_t
amf0
);
const
char
*
srs_amf0_array_property_name_at
(
srs_amf0_t
amf0
,
int
index
);
srs_amf0_t
srs_amf0_array_property_value_at
(
srs_amf0_t
amf0
,
int
index
);
/* ecma array value converter */
int
srs_amf0_ecma_array_property_count
(
srs_amf0_t
amf0
);
const
char
*
srs_amf0_ecma_array_property_name_at
(
srs_amf0_t
amf0
,
int
index
);
srs_amf0_t
srs_amf0_ecma_array_property_value_at
(
srs_amf0_t
amf0
,
int
index
);
/* strict array value converter */
int
srs_amf0_strict_array_property_count
(
srs_amf0_t
amf0
);
srs_amf0_t
srs_amf0_strict_array_property_at
(
srs_amf0_t
amf0
,
int
index
);
/* human readable print */
char
*
srs_amf0_human_print
(
srs_amf0_t
amf0
,
char
**
pdata
,
int
*
psize
);
...
...
trunk/src/rtmp/srs_protocol_amf0.cpp
查看文件 @
7f48590
...
...
@@ -251,6 +251,16 @@ bool SrsAmf0Any::is_ecma_array()
return
marker
==
RTMP_AMF0_EcmaArray
;
}
bool
SrsAmf0Any
::
is_strict_array
()
{
return
marker
==
RTMP_AMF0_StrictArray
;
}
bool
SrsAmf0Any
::
is_complex_object
()
{
return
is_object
()
||
is_object_eof
()
||
is_ecma_array
()
||
is_strict_array
();
}
string
SrsAmf0Any
::
to_str
()
{
__SrsAmf0String
*
p
=
dynamic_cast
<
__SrsAmf0String
*>
(
this
);
...
...
@@ -293,6 +303,13 @@ SrsAmf0EcmaArray* SrsAmf0Any::to_ecma_array()
return
p
;
}
SrsAmf0StrictArray
*
SrsAmf0Any
::
to_strict_array
()
{
SrsAmf0StrictArray
*
p
=
dynamic_cast
<
SrsAmf0StrictArray
*>
(
this
);
srs_assert
(
p
!=
NULL
);
return
p
;
}
bool
SrsAmf0Any
::
is_object_eof
()
{
return
marker
==
RTMP_AMF0_ObjectEnd
;
...
...
@@ -338,6 +355,11 @@ SrsAmf0EcmaArray* SrsAmf0Any::ecma_array()
return
new
SrsAmf0EcmaArray
();
}
SrsAmf0StrictArray
*
SrsAmf0Any
::
strict_array
()
{
return
new
SrsAmf0StrictArray
();
}
int
SrsAmf0Any
::
discovery
(
SrsStream
*
stream
,
SrsAmf0Any
**
ppvalue
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -390,6 +412,10 @@ int SrsAmf0Any::discovery(SrsStream* stream, SrsAmf0Any** ppvalue)
*
ppvalue
=
SrsAmf0Any
::
ecma_array
();
return
ret
;
}
case
RTMP_AMF0_StrictArray
:
{
*
ppvalue
=
SrsAmf0Any
::
strict_array
();
return
ret
;
}
case
RTMP_AMF0_Invalid
:
default
:
{
ret
=
ERROR_RTMP_AMF0_INVALID
;
...
...
@@ -956,6 +982,137 @@ SrsAmf0Any* SrsAmf0EcmaArray::ensure_property_number(string name)
return
properties
->
ensure_property_number
(
name
);
}
SrsAmf0StrictArray
::
SrsAmf0StrictArray
()
{
marker
=
RTMP_AMF0_StrictArray
;
}
SrsAmf0StrictArray
::~
SrsAmf0StrictArray
()
{
std
::
vector
<
SrsAmf0Any
*>::
iterator
it
;
for
(
it
=
properties
.
begin
();
it
!=
properties
.
end
();
++
it
)
{
SrsAmf0Any
*
any
=
*
it
;
srs_freep
(
any
);
}
properties
.
clear
();
}
int
SrsAmf0StrictArray
::
total_size
()
{
int
size
=
1
+
4
;
for
(
int
i
=
0
;
i
<
(
int
)
properties
.
size
();
i
++
){
SrsAmf0Any
*
any
=
properties
[
i
];
size
+=
any
->
total_size
();
}
return
size
;
}
int
SrsAmf0StrictArray
::
read
(
SrsStream
*
stream
)
{
int
ret
=
ERROR_SUCCESS
;
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read strict_array marker failed. ret=%d"
,
ret
);
return
ret
;
}
char
marker
=
stream
->
read_1bytes
();
if
(
marker
!=
RTMP_AMF0_StrictArray
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 check strict_array marker failed. "
"marker=%#x, required=%#x, ret=%d"
,
marker
,
RTMP_AMF0_Object
,
ret
);
return
ret
;
}
srs_verbose
(
"amf0 read strict_array marker success"
);
// count
if
(
!
stream
->
require
(
4
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read strict_array count failed. ret=%d"
,
ret
);
return
ret
;
}
int32_t
count
=
stream
->
read_4bytes
();
srs_verbose
(
"amf0 read strict_array count success. count=%d"
,
count
);
// value
this
->
_count
=
count
;
for
(
int
i
=
0
;
i
<
count
&&
!
stream
->
empty
();
i
++
)
{
// property-value: any
SrsAmf0Any
*
elem
=
NULL
;
if
((
ret
=
srs_amf0_read_any
(
stream
,
&
elem
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"amf0 strict_array read value failed. ret=%d"
,
ret
);
return
ret
;
}
// add property
properties
.
push_back
(
elem
);
}
return
ret
;
}
int
SrsAmf0StrictArray
::
write
(
SrsStream
*
stream
)
{
int
ret
=
ERROR_SUCCESS
;
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_ENCODE
;
srs_error
(
"amf0 write strict_array marker failed. ret=%d"
,
ret
);
return
ret
;
}
stream
->
write_1bytes
(
RTMP_AMF0_StrictArray
);
srs_verbose
(
"amf0 write strict_array marker success"
);
// count
if
(
!
stream
->
require
(
4
))
{
ret
=
ERROR_RTMP_AMF0_ENCODE
;
srs_error
(
"amf0 write strict_array count failed. ret=%d"
,
ret
);
return
ret
;
}
stream
->
write_4bytes
(
this
->
_count
);
srs_verbose
(
"amf0 write strict_array count success. count=%d"
,
_count
);
// value
for
(
int
i
=
0
;
i
<
(
int
)
properties
.
size
();
i
++
)
{
SrsAmf0Any
*
any
=
properties
[
i
];
if
((
ret
=
srs_amf0_write_any
(
stream
,
any
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"write strict_array property value failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"write amf0 property success. name=%s"
,
name
.
c_str
());
}
srs_verbose
(
"write strict_array object success."
);
return
ret
;
}
void
SrsAmf0StrictArray
::
clear
()
{
properties
.
clear
();
}
int
SrsAmf0StrictArray
::
count
()
{
return
properties
.
size
();
}
SrsAmf0Any
*
SrsAmf0StrictArray
::
at
(
int
index
)
{
srs_assert
(
index
<
(
int
)
properties
.
size
());
return
properties
.
at
(
index
);
}
int
SrsAmf0Size
::
utf8
(
string
value
)
{
return
2
+
value
.
length
();
...
...
@@ -1009,6 +1166,15 @@ int SrsAmf0Size::ecma_array(SrsAmf0EcmaArray* arr)
return
arr
->
total_size
();
}
int
SrsAmf0Size
::
strict_array
(
SrsAmf0StrictArray
*
arr
)
{
if
(
!
arr
)
{
return
0
;
}
return
arr
->
total_size
();
}
int
SrsAmf0Size
::
any
(
SrsAmf0Any
*
o
)
{
if
(
!
o
)
{
...
...
trunk/src/rtmp/srs_protocol_amf0.hpp
查看文件 @
7f48590
...
...
@@ -31,10 +31,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core.hpp>
#include <string>
#include <vector>
class
SrsStream
;
class
SrsAmf0Object
;
class
SrsAmf0EcmaArray
;
class
SrsAmf0StrictArray
;
class
__SrsUnSortedHashtable
;
class
__SrsAmf0ObjectEOF
;
...
...
@@ -96,6 +98,9 @@ public:
virtual
bool
is_object
();
virtual
bool
is_object_eof
();
virtual
bool
is_ecma_array
();
virtual
bool
is_strict_array
();
public
:
virtual
bool
is_complex_object
();
public
:
/**
* get the string of any when is_string() indicates true.
...
...
@@ -123,6 +128,7 @@ public:
* user must ensure the type is a ecma array, or assert failed.
*/
virtual
SrsAmf0EcmaArray
*
to_ecma_array
();
virtual
SrsAmf0StrictArray
*
to_strict_array
();
public
:
/**
* get the size of amf0 any, including the marker size.
...
...
@@ -142,6 +148,7 @@ public:
static
SrsAmf0Object
*
object
();
static
SrsAmf0Any
*
object_eof
();
static
SrsAmf0EcmaArray
*
ecma_array
();
static
SrsAmf0StrictArray
*
strict_array
();
public
:
static
int
discovery
(
SrsStream
*
stream
,
SrsAmf0Any
**
ppvalue
);
};
...
...
@@ -226,6 +233,36 @@ public:
};
/**
* 2.12 Strict Array Type
* array-count = U32
* strict-array-type = array-count *(value-type)
*/
class
SrsAmf0StrictArray
:
public
SrsAmf0Any
{
private
:
std
::
vector
<
SrsAmf0Any
*>
properties
;
int32_t
_count
;
private
:
// use SrsAmf0Any::strict_array() to create it.
friend
class
SrsAmf0Any
;
SrsAmf0StrictArray
();
public
:
virtual
~
SrsAmf0StrictArray
();
public
:
virtual
int
total_size
();
virtual
int
read
(
SrsStream
*
stream
);
virtual
int
write
(
SrsStream
*
stream
);
public
:
virtual
void
clear
();
virtual
int
count
();
// @remark: max index is count().
virtual
SrsAmf0Any
*
at
(
int
index
);
};
/**
* the class to get amf0 object size
*/
class
SrsAmf0Size
...
...
@@ -240,6 +277,7 @@ public:
static
int
object
(
SrsAmf0Object
*
obj
);
static
int
object_eof
();
static
int
ecma_array
(
SrsAmf0EcmaArray
*
arr
);
static
int
strict_array
(
SrsAmf0StrictArray
*
arr
);
static
int
any
(
SrsAmf0Any
*
o
);
};
...
...
请
注册
或
登录
后发表评论