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-20 17:55:44 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
1beee1e970ec5a709b8086d2f736107db336e9c7
1beee1e9
1 parent
8283ed46
support ecma array. connect app response.
显示空白字符变更
内嵌
并排对比
正在显示
6 个修改的文件
包含
342 行增加
和
24 行删除
trunk/src/core/srs_core_amf0.cpp
trunk/src/core/srs_core_amf0.hpp
trunk/src/core/srs_core_client.cpp
trunk/src/core/srs_core_protocol.cpp
trunk/src/core/srs_core_rtmp.cpp
trunk/src/core/srs_core_rtmp.hpp
trunk/src/core/srs_core_amf0.cpp
查看文件 @
1beee1e
...
...
@@ -54,6 +54,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define RTMP_AMF0_Invalid 0x3F
int
srs_amf0_get_object_eof_size
();
int
srs_amf0_get_any_size
(
SrsAmf0Any
*
value
);
int
srs_amf0_read_object_eof
(
SrsStream
*
stream
,
SrsAmf0ObjectEOF
*&
);
int
srs_amf0_write_object_eof
(
SrsStream
*
stream
,
SrsAmf0ObjectEOF
*
);
int
srs_amf0_read_any
(
SrsStream
*
stream
,
SrsAmf0Any
*&
value
);
...
...
@@ -88,43 +89,51 @@ bool SrsAmf0Any::is_object()
return
marker
==
RTMP_AMF0_Object
;
}
bool
SrsAmf0Any
::
is_ecma_array
()
{
return
marker
==
RTMP_AMF0_EcmaArray
;
}
bool
SrsAmf0Any
::
is_object_eof
()
{
return
marker
==
RTMP_AMF0_ObjectEnd
;
}
SrsAmf0String
::
SrsAmf0String
()
SrsAmf0String
::
SrsAmf0String
(
const
char
*
_value
)
{
marker
=
RTMP_AMF0_String
;
if
(
_value
)
{
value
=
_value
;
}
}
SrsAmf0String
::~
SrsAmf0String
()
{
}
SrsAmf0Boolean
::
SrsAmf0Boolean
()
SrsAmf0Boolean
::
SrsAmf0Boolean
(
bool
_value
)
{
marker
=
RTMP_AMF0_Boolean
;
value
=
fals
e
;
value
=
_valu
e
;
}
SrsAmf0Boolean
::~
SrsAmf0Boolean
()
{
}
SrsAmf0Number
::
SrsAmf0Number
()
SrsAmf0Number
::
SrsAmf0Number
(
double
_value
)
{
marker
=
RTMP_AMF0_Number
;
value
=
0
;
value
=
_value
;
}
SrsAmf0Number
::~
SrsAmf0Number
()
{
marker
=
RTMP_AMF0_ObjectEnd
;
}
SrsAmf0ObjectEOF
::
SrsAmf0ObjectEOF
()
{
marker
=
RTMP_AMF0_ObjectEnd
;
utf8_empty
=
0x00
;
}
...
...
@@ -173,6 +182,47 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name)
return
prop
;
}
SrsASrsAmf0EcmaArray
::
SrsASrsAmf0EcmaArray
()
{
marker
=
RTMP_AMF0_EcmaArray
;
}
SrsASrsAmf0EcmaArray
::~
SrsASrsAmf0EcmaArray
()
{
std
::
map
<
std
::
string
,
SrsAmf0Any
*>::
iterator
it
;
for
(
it
=
properties
.
begin
();
it
!=
properties
.
end
();
++
it
)
{
SrsAmf0Any
*
any
=
it
->
second
;
delete
any
;
}
properties
.
clear
();
}
SrsAmf0Any
*
SrsASrsAmf0EcmaArray
::
get_property
(
std
::
string
name
)
{
std
::
map
<
std
::
string
,
SrsAmf0Any
*>::
iterator
it
;
if
((
it
=
properties
.
find
(
name
))
==
properties
.
end
())
{
return
NULL
;
}
return
it
->
second
;
}
SrsAmf0Any
*
SrsASrsAmf0EcmaArray
::
ensure_property_string
(
std
::
string
name
)
{
SrsAmf0Any
*
prop
=
get_property
(
name
);
if
(
!
prop
)
{
return
NULL
;
}
if
(
!
prop
->
is_string
())
{
return
NULL
;
}
return
prop
;
}
int
srs_amf0_read_utf8
(
SrsStream
*
stream
,
std
::
string
&
value
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -481,6 +531,14 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
value
=
p
;
return
ret
;
}
case
RTMP_AMF0_EcmaArray
:
{
SrsASrsAmf0EcmaArray
*
p
=
NULL
;
if
((
ret
=
srs_amf0_read_ecma_array
(
stream
,
p
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
value
=
p
;
return
ret
;
}
case
RTMP_AMF0_Invalid
:
default
:
{
ret
=
ERROR_RTMP_AMF0_INVALID
;
...
...
@@ -518,6 +576,10 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
SrsAmf0Object
*
p
=
srs_amf0_convert
<
SrsAmf0Object
>
(
value
);
return
srs_amf0_write_object
(
stream
,
p
);
}
case
RTMP_AMF0_EcmaArray
:
{
SrsASrsAmf0EcmaArray
*
p
=
srs_amf0_convert
<
SrsASrsAmf0EcmaArray
>
(
value
);
return
srs_amf0_write_ecma_array
(
stream
,
p
);
}
case
RTMP_AMF0_Invalid
:
default
:
{
ret
=
ERROR_RTMP_AMF0_INVALID
;
...
...
@@ -529,6 +591,52 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
return
ret
;
}
int
srs_amf0_get_any_size
(
SrsAmf0Any
*
value
)
{
if
(
!
value
)
{
return
0
;
}
int
size
=
0
;
switch
(
value
->
marker
)
{
case
RTMP_AMF0_String
:
{
SrsAmf0String
*
p
=
srs_amf0_convert
<
SrsAmf0String
>
(
value
);
size
+=
srs_amf0_get_string_size
(
p
->
value
);
break
;
}
case
RTMP_AMF0_Boolean
:
{
size
+=
srs_amf0_get_boolean_size
();
break
;
}
case
RTMP_AMF0_Number
:
{
size
+=
srs_amf0_get_number_size
();
break
;
}
case
RTMP_AMF0_ObjectEnd
:
{
size
+=
srs_amf0_get_object_eof_size
();
break
;
}
case
RTMP_AMF0_Object
:
{
SrsAmf0Object
*
p
=
srs_amf0_convert
<
SrsAmf0Object
>
(
value
);
size
+=
srs_amf0_get_object_size
(
p
);
break
;
}
case
RTMP_AMF0_EcmaArray
:
{
SrsASrsAmf0EcmaArray
*
p
=
srs_amf0_convert
<
SrsASrsAmf0EcmaArray
>
(
value
);
size
+=
srs_amf0_get_ecma_array_size
(
p
);
break
;
}
default
:
{
// TOOD: other AMF0 types.
srs_warn
(
"ignore unkown AMF0 type size."
);
break
;
}
}
return
size
;
}
int
srs_amf0_read_object_eof
(
SrsStream
*
stream
,
SrsAmf0ObjectEOF
*&
value
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -699,6 +807,125 @@ int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value)
return
ret
;
}
int
srs_amf0_read_ecma_array
(
SrsStream
*
stream
,
SrsASrsAmf0EcmaArray
*&
value
)
{
int
ret
=
ERROR_SUCCESS
;
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read ecma_array marker failed. ret=%d"
,
ret
);
return
ret
;
}
char
marker
=
stream
->
read_1bytes
();
if
(
marker
!=
RTMP_AMF0_EcmaArray
)
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 check ecma_array marker failed. "
"marker=%#x, required=%#x, ret=%d"
,
marker
,
RTMP_AMF0_Object
,
ret
);
return
ret
;
}
srs_verbose
(
"amf0 read ecma_array marker success"
);
// count
if
(
!
stream
->
require
(
4
))
{
ret
=
ERROR_RTMP_AMF0_DECODE
;
srs_error
(
"amf0 read ecma_array count failed. ret=%d"
,
ret
);
return
ret
;
}
int32_t
count
=
stream
->
read_4bytes
();
srs_verbose
(
"amf0 read ecma_array count success. count=%d"
,
count
);
// value
value
=
new
SrsASrsAmf0EcmaArray
();
value
->
count
=
count
;
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 ecma_array 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 ecma_array 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 ecma_array EOF."
);
break
;
}
// add property
value
->
properties
[
property_name
]
=
property_value
;
}
return
ret
;
}
int
srs_amf0_write_ecma_array
(
SrsStream
*
stream
,
SrsASrsAmf0EcmaArray
*
value
)
{
int
ret
=
ERROR_SUCCESS
;
srs_assert
(
value
!=
NULL
);
// marker
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_RTMP_AMF0_ENCODE
;
srs_error
(
"amf0 write ecma_array marker failed. ret=%d"
,
ret
);
return
ret
;
}
stream
->
write_1bytes
(
RTMP_AMF0_EcmaArray
);
srs_verbose
(
"amf0 write ecma_array marker success"
);
// count
if
(
!
stream
->
require
(
4
))
{
ret
=
ERROR_RTMP_AMF0_ENCODE
;
srs_error
(
"amf0 write ecma_array count failed. ret=%d"
,
ret
);
return
ret
;
}
stream
->
write_4bytes
(
value
->
count
);
srs_verbose
(
"amf0 write ecma_array count success. count=%d"
,
value
->
count
);
// value
std
::
map
<
std
::
string
,
SrsAmf0Any
*>::
iterator
it
;
for
(
it
=
value
->
properties
.
begin
();
it
!=
value
->
properties
.
end
();
++
it
)
{
std
::
string
name
=
it
->
first
;
SrsAmf0Any
*
any
=
it
->
second
;
if
((
ret
=
srs_amf0_write_utf8
(
stream
,
name
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"write ecma_array property name failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
srs_amf0_write_any
(
stream
,
any
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"write ecma_array property value failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"write amf0 property success. name=%s"
,
name
.
c_str
());
}
if
((
ret
=
srs_amf0_write_object_eof
(
stream
,
&
value
->
eof
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"write ecma_array eof failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"write ecma_array object success."
);
return
ret
;
}
int
srs_amf0_get_utf8_size
(
std
::
string
value
)
{
return
2
+
value
.
length
();
...
...
@@ -733,21 +960,29 @@ int srs_amf0_get_object_size(SrsAmf0Object* obj)
SrsAmf0Any
*
value
=
it
->
second
;
size
+=
srs_amf0_get_utf8_size
(
name
);
size
+=
srs_amf0_get_any_size
(
value
);
}
if
(
value
->
is_boolean
())
{
size
+=
srs_amf0_get_boolean_size
();
}
else
if
(
value
->
is_number
())
{
size
+=
srs_amf0_get_number_size
();
}
else
if
(
value
->
is_string
())
{
SrsAmf0String
*
p
=
srs_amf0_convert
<
SrsAmf0String
>
(
value
);
size
+=
srs_amf0_get_string_size
(
p
->
value
);
}
else
if
(
value
->
is_object
())
{
SrsAmf0Object
*
p
=
srs_amf0_convert
<
SrsAmf0Object
>
(
value
);
size
+=
srs_amf0_get_object_size
(
p
);
}
else
{
// TOOD: other AMF0 types.
srs_warn
(
"ignore unkown AMF0 type size."
);
size
+=
srs_amf0_get_object_eof_size
();
return
size
;
}
int
srs_amf0_get_ecma_array_size
(
SrsASrsAmf0EcmaArray
*
arr
)
{
if
(
!
arr
)
{
return
0
;
}
int
size
=
1
+
4
;
std
::
map
<
std
::
string
,
SrsAmf0Any
*>::
iterator
it
;
for
(
it
=
arr
->
properties
.
begin
();
it
!=
arr
->
properties
.
end
();
++
it
)
{
std
::
string
name
=
it
->
first
;
SrsAmf0Any
*
value
=
it
->
second
;
size
+=
srs_amf0_get_utf8_size
(
name
);
size
+=
srs_amf0_get_any_size
(
value
);
}
size
+=
srs_amf0_get_object_eof_size
();
...
...
trunk/src/core/srs_core_amf0.hpp
查看文件 @
1beee1e
...
...
@@ -56,6 +56,7 @@ struct SrsAmf0Any
virtual
bool
is_number
();
virtual
bool
is_object
();
virtual
bool
is_object_eof
();
virtual
bool
is_ecma_array
();
};
/**
...
...
@@ -68,7 +69,7 @@ struct SrsAmf0String : public SrsAmf0Any
{
std
::
string
value
;
SrsAmf0String
();
SrsAmf0String
(
const
char
*
_value
=
NULL
);
virtual
~
SrsAmf0String
();
};
...
...
@@ -83,7 +84,7 @@ struct SrsAmf0Boolean : public SrsAmf0Any
{
bool
value
;
SrsAmf0Boolean
();
SrsAmf0Boolean
(
bool
_value
=
false
);
virtual
~
SrsAmf0Boolean
();
};
...
...
@@ -97,7 +98,7 @@ struct SrsAmf0Number : public SrsAmf0Any
{
double
value
;
SrsAmf0Number
();
SrsAmf0Number
(
double
_value
=
0.0
);
virtual
~
SrsAmf0Number
();
};
...
...
@@ -132,6 +133,25 @@ struct SrsAmf0Object : public SrsAmf0Any
};
/**
* 2.10 ECMA Array Type
* ecma-array-type = associative-count *(object-property)
* associative-count = U32
* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
*/
struct
SrsASrsAmf0EcmaArray
:
public
SrsAmf0Any
{
int32_t
count
;
std
::
map
<
std
::
string
,
SrsAmf0Any
*>
properties
;
SrsAmf0ObjectEOF
eof
;
SrsASrsAmf0EcmaArray
();
virtual
~
SrsASrsAmf0EcmaArray
();
virtual
SrsAmf0Any
*
get_property
(
std
::
string
name
);
virtual
SrsAmf0Any
*
ensure_property_string
(
std
::
string
name
);
};
/**
* read amf0 utf8 string from stream.
* 1.3.1 Strings and UTF-8
* UTF-8 = U16 *(UTF8-char)
...
...
@@ -177,6 +197,16 @@ extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value);
extern
int
srs_amf0_write_object
(
SrsStream
*
stream
,
SrsAmf0Object
*
value
);
/**
* read amf0 object from stream.
* 2.10 ECMA Array Type
* ecma-array-type = associative-count *(object-property)
* associative-count = U32
* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
*/
extern
int
srs_amf0_read_ecma_array
(
SrsStream
*
stream
,
SrsASrsAmf0EcmaArray
*&
value
);
extern
int
srs_amf0_write_ecma_array
(
SrsStream
*
stream
,
SrsASrsAmf0EcmaArray
*
value
);
/**
* get amf0 objects size.
*/
extern
int
srs_amf0_get_utf8_size
(
std
::
string
value
);
...
...
@@ -184,6 +214,7 @@ extern int srs_amf0_get_string_size(std::string value);
extern
int
srs_amf0_get_number_size
();
extern
int
srs_amf0_get_boolean_size
();
extern
int
srs_amf0_get_object_size
(
SrsAmf0Object
*
obj
);
extern
int
srs_amf0_get_ecma_array_size
(
SrsASrsAmf0EcmaArray
*
arr
);
/**
* convert the any to specified object.
...
...
trunk/src/core/srs_core_client.cpp
查看文件 @
1beee1e
...
...
@@ -93,6 +93,12 @@ int SrsClient::do_cycle()
}
srs_verbose
(
"set peer bandwidth success"
);
if
((
ret
=
rtmp
->
response_connect_app
())
!=
ERROR_SUCCESS
)
{
srs_error
(
"response connect app failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"response connect app success"
);
return
ret
;
}
...
...
trunk/src/core/srs_core_protocol.cpp
查看文件 @
1beee1e
...
...
@@ -1061,8 +1061,8 @@ SrsConnectAppResPacket::SrsConnectAppResPacket()
{
command_name
=
RTMP_AMF0_COMMAND_CONNECT
;
transaction_id
=
1
;
props
=
NULL
;
info
=
NULL
;
props
=
new
SrsAmf0Object
();
info
=
new
SrsAmf0Object
();
}
SrsConnectAppResPacket
::~
SrsConnectAppResPacket
()
...
...
trunk/src/core/srs_core_rtmp.cpp
查看文件 @
1beee1e
...
...
@@ -30,6 +30,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core_auto_free.hpp>
#include <srs_core_amf0.hpp>
/**
* the signature for packets to client.
*/
#define RTMP_SIG_FMS_VER "3,5,3,888"
#define RTMP_SIG_AMF0_VER 3
#define RTMP_SIG_SRS_NAME "srs(simple rtmp server)"
#define RTMP_SIG_SRS_URL "https://github.com/winlinvip/simple-rtmp-server"
#define RTMP_SIG_SRS_VERSION "0.1"
int
SrsRequest
::
discovery_app
()
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -205,3 +214,39 @@ int SrsRtmp::set_peer_bandwidth(int bandwidth, int type)
return
ret
;
}
int
SrsRtmp
::
response_connect_app
()
{
int
ret
=
ERROR_SUCCESS
;
SrsMessage
*
msg
=
new
SrsMessage
();
SrsConnectAppResPacket
*
pkt
=
new
SrsConnectAppResPacket
();
pkt
->
command_name
=
"_result"
;
pkt
->
props
->
properties
[
"fmsVer"
]
=
new
SrsAmf0String
(
"FMS/"
RTMP_SIG_FMS_VER
);
pkt
->
props
->
properties
[
"capabilities"
]
=
new
SrsAmf0Number
(
123
);
pkt
->
props
->
properties
[
"mode"
]
=
new
SrsAmf0Number
(
1
);
pkt
->
info
->
properties
[
"level"
]
=
new
SrsAmf0String
(
"status"
);
pkt
->
info
->
properties
[
"code"
]
=
new
SrsAmf0String
(
"NetConnection.Connect.Success"
);
pkt
->
info
->
properties
[
"description"
]
=
new
SrsAmf0String
(
"Connection succeeded"
);
pkt
->
info
->
properties
[
"objectEncoding"
]
=
new
SrsAmf0Number
(
RTMP_SIG_AMF0_VER
);
SrsASrsAmf0EcmaArray
*
data
=
new
SrsASrsAmf0EcmaArray
();
pkt
->
info
->
properties
[
"data"
]
=
data
;
data
->
properties
[
"version"
]
=
new
SrsAmf0String
(
RTMP_SIG_FMS_VER
);
data
->
properties
[
"server"
]
=
new
SrsAmf0String
(
RTMP_SIG_SRS_NAME
);
data
->
properties
[
"srs_url"
]
=
new
SrsAmf0String
(
RTMP_SIG_SRS_URL
);
data
->
properties
[
"srs_version"
]
=
new
SrsAmf0String
(
RTMP_SIG_SRS_VERSION
);
msg
->
set_packet
(
pkt
);
if
((
ret
=
protocol
->
send_message
(
msg
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"send connect app response message failed. ret=%d"
,
ret
);
return
ret
;
}
srs_info
(
"send connect app response message success."
);
return
ret
;
}
...
...
trunk/src/core/srs_core_rtmp.hpp
查看文件 @
1beee1e
...
...
@@ -79,6 +79,7 @@ public:
* using the Limit type field.
*/
virtual
int
set_peer_bandwidth
(
int
bandwidth
,
int
type
);
virtual
int
response_connect_app
();
};
#endif
\ No newline at end of file
...
...
请
注册
或
登录
后发表评论