winlin

convert format to unix

要显示太多修改。

为保证性能只显示 9 of 9+ 个文件。

1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#include <srs_core.hpp>  
25 -  
26 -#include <sys/time.h>  
27 -  
28 -static int64_t _srs_system_time_us_cache = 0;  
29 -  
30 -int64_t srs_get_system_time_ms()  
31 -{  
32 - return _srs_system_time_us_cache / 1000;  
33 -}  
34 -  
35 -void srs_update_system_time_ms()  
36 -{  
37 - timeval now;  
38 -  
39 - gettimeofday(&now, NULL);  
40 -  
41 - // we must convert the tv_sec/tv_usec to int64_t.  
42 - _srs_system_time_us_cache = now.tv_sec * 1000 * 1000 + now.tv_usec;  
43 -  
44 - _srs_system_time_us_cache = srs_max(0, _srs_system_time_us_cache);  
45 -} 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core.hpp>
  25 +
  26 +#include <sys/time.h>
  27 +
  28 +static int64_t _srs_system_time_us_cache = 0;
  29 +
  30 +int64_t srs_get_system_time_ms()
  31 +{
  32 + return _srs_system_time_us_cache / 1000;
  33 +}
  34 +
  35 +void srs_update_system_time_ms()
  36 +{
  37 + timeval now;
  38 +
  39 + gettimeofday(&now, NULL);
  40 +
  41 + // we must convert the tv_sec/tv_usec to int64_t.
  42 + _srs_system_time_us_cache = now.tv_sec * 1000 * 1000 + now.tv_usec;
  43 +
  44 + _srs_system_time_us_cache = srs_max(0, _srs_system_time_us_cache);
  45 +}
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#ifndef SRS_CORE_HPP  
25 -#define SRS_CORE_HPP  
26 -  
27 -/*  
28 -#include <srs_core.hpp>  
29 -*/  
30 -  
31 -/**  
32 -* the core provides the common defined macros, utilities,  
33 -* user must include the srs_core.hpp before any header, or maybe  
34 -* build failed.  
35 -*/  
36 -  
37 -// for int64_t print using PRId64 format.  
38 -#ifndef __STDC_FORMAT_MACROS  
39 - #define __STDC_FORMAT_MACROS  
40 -#endif  
41 -#include <inttypes.h>  
42 -  
43 -#include <assert.h>  
44 -#define srs_assert(expression) assert(expression)  
45 -  
46 -#include <stddef.h>  
47 -#include <sys/types.h>  
48 -  
49 -// free the p and set to NULL.  
50 -// p must be a T*.  
51 -#define srs_freep(p) \  
52 - if (p) { \  
53 - delete p; \  
54 - p = NULL; \  
55 - } \  
56 - (void)0  
57 -// free the p which represents a array  
58 -#define srs_freepa(p) \  
59 - if (p) { \  
60 - delete[] p; \  
61 - p = NULL; \  
62 - } \  
63 - (void)0  
64 -  
65 -// current release version  
66 -#define RTMP_SIG_SRS_VERSION "0.4.0"  
67 -// server info.  
68 -#define RTMP_SIG_SRS_KEY "srs"  
69 -#define RTMP_SIG_SRS_ROLE "origin server"  
70 -#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(simple rtmp server)"  
71 -#define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT  
72 -#define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server"  
73 -#define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin"  
74 -#define RTMP_SIG_SRS_EMAIL "winterserver@126.com"  
75 -#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)"  
76 -#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013 winlin"  
77 -  
78 -// compare  
79 -#define srs_min(a, b) (((a) < (b))? (a) : (b))  
80 -#define srs_max(a, b) (((a) < (b))? (b) : (a))  
81 -  
82 -// get current system time in ms, use cache to avoid performance problem  
83 -extern int64_t srs_get_system_time_ms();  
84 -// the deamon st-thread will update it.  
85 -extern void srs_update_system_time_ms();  
86 -  
87 -// signal defines.  
88 -#define SIGNAL_RELOAD SIGHUP  
89 - 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#ifndef SRS_CORE_HPP
  25 +#define SRS_CORE_HPP
  26 +
  27 +/*
  28 +#include <srs_core.hpp>
  29 +*/
  30 +
  31 +/**
  32 +* the core provides the common defined macros, utilities,
  33 +* user must include the srs_core.hpp before any header, or maybe
  34 +* build failed.
  35 +*/
  36 +
  37 +// for int64_t print using PRId64 format.
  38 +#ifndef __STDC_FORMAT_MACROS
  39 + #define __STDC_FORMAT_MACROS
  40 +#endif
  41 +#include <inttypes.h>
  42 +
  43 +#include <assert.h>
  44 +#define srs_assert(expression) assert(expression)
  45 +
  46 +#include <stddef.h>
  47 +#include <sys/types.h>
  48 +
  49 +// free the p and set to NULL.
  50 +// p must be a T*.
  51 +#define srs_freep(p) \
  52 + if (p) { \
  53 + delete p; \
  54 + p = NULL; \
  55 + } \
  56 + (void)0
  57 +// free the p which represents a array
  58 +#define srs_freepa(p) \
  59 + if (p) { \
  60 + delete[] p; \
  61 + p = NULL; \
  62 + } \
  63 + (void)0
  64 +
  65 +// current release version
  66 +#define RTMP_SIG_SRS_VERSION "0.4.0"
  67 +// server info.
  68 +#define RTMP_SIG_SRS_KEY "srs"
  69 +#define RTMP_SIG_SRS_ROLE "origin server"
  70 +#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(simple rtmp server)"
  71 +#define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT
  72 +#define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server"
  73 +#define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin"
  74 +#define RTMP_SIG_SRS_EMAIL "winterserver@126.com"
  75 +#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)"
  76 +#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013 winlin"
  77 +
  78 +// compare
  79 +#define srs_min(a, b) (((a) < (b))? (a) : (b))
  80 +#define srs_max(a, b) (((a) < (b))? (b) : (a))
  81 +
  82 +// get current system time in ms, use cache to avoid performance problem
  83 +extern int64_t srs_get_system_time_ms();
  84 +// the deamon st-thread will update it.
  85 +extern void srs_update_system_time_ms();
  86 +
  87 +// signal defines.
  88 +#define SIGNAL_RELOAD SIGHUP
  89 +
90 #endif 90 #endif
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#include <srs_core_amf0.hpp>  
25 -  
26 -#include <utility>  
27 -  
28 -#include <srs_core_log.hpp>  
29 -#include <srs_core_error.hpp>  
30 -#include <srs_core_stream.hpp>  
31 -  
32 -// AMF0 marker  
33 -#define RTMP_AMF0_Number 0x00  
34 -#define RTMP_AMF0_Boolean 0x01  
35 -#define RTMP_AMF0_String 0x02  
36 -#define RTMP_AMF0_Object 0x03  
37 -#define RTMP_AMF0_MovieClip 0x04 // reserved, not supported  
38 -#define RTMP_AMF0_Null 0x05  
39 -#define RTMP_AMF0_Undefined 0x06  
40 -#define RTMP_AMF0_Reference 0x07  
41 -#define RTMP_AMF0_EcmaArray 0x08  
42 -#define RTMP_AMF0_ObjectEnd 0x09  
43 -#define RTMP_AMF0_StrictArray 0x0A  
44 -#define RTMP_AMF0_Date 0x0B  
45 -#define RTMP_AMF0_LongString 0x0C  
46 -#define RTMP_AMF0_UnSupported 0x0D  
47 -#define RTMP_AMF0_RecordSet 0x0E // reserved, not supported  
48 -#define RTMP_AMF0_XmlDocument 0x0F  
49 -#define RTMP_AMF0_TypedObject 0x10  
50 -// AVM+ object is the AMF3 object.  
51 -#define RTMP_AMF0_AVMplusObject 0x11  
52 -// origin array whos data takes the same form as LengthValueBytes  
53 -#define RTMP_AMF0_OriginStrictArray 0x20  
54 -  
55 -// User defined  
56 -#define RTMP_AMF0_Invalid 0x3F  
57 -  
58 -int srs_amf0_get_object_eof_size();  
59 -int srs_amf0_get_any_size(SrsAmf0Any* value);  
60 -int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&);  
61 -int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*);  
62 -int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value);  
63 -int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value);  
64 -  
65 -SrsAmf0Any::SrsAmf0Any()  
66 -{  
67 - marker = RTMP_AMF0_Invalid;  
68 -}  
69 -  
70 -SrsAmf0Any::~SrsAmf0Any()  
71 -{  
72 -}  
73 -  
74 -bool SrsAmf0Any::is_string()  
75 -{  
76 - return marker == RTMP_AMF0_String;  
77 -}  
78 -  
79 -bool SrsAmf0Any::is_boolean()  
80 -{  
81 - return marker == RTMP_AMF0_Boolean;  
82 -}  
83 -  
84 -bool SrsAmf0Any::is_number()  
85 -{  
86 - return marker == RTMP_AMF0_Number;  
87 -}  
88 -  
89 -bool SrsAmf0Any::is_null()  
90 -{  
91 - return marker == RTMP_AMF0_Null;  
92 -}  
93 -  
94 -bool SrsAmf0Any::is_undefined()  
95 -{  
96 - return marker == RTMP_AMF0_Undefined;  
97 -}  
98 -  
99 -bool SrsAmf0Any::is_object()  
100 -{  
101 - return marker == RTMP_AMF0_Object;  
102 -}  
103 -  
104 -bool SrsAmf0Any::is_ecma_array()  
105 -{  
106 - return marker == RTMP_AMF0_EcmaArray;  
107 -}  
108 -  
109 -bool SrsAmf0Any::is_object_eof()  
110 -{  
111 - return marker == RTMP_AMF0_ObjectEnd;  
112 -}  
113 -  
114 -SrsAmf0String::SrsAmf0String(const char* _value)  
115 -{  
116 - marker = RTMP_AMF0_String;  
117 - if (_value) {  
118 - value = _value;  
119 - }  
120 -}  
121 -  
122 -SrsAmf0String::~SrsAmf0String()  
123 -{  
124 -}  
125 -  
126 -SrsAmf0Boolean::SrsAmf0Boolean(bool _value)  
127 -{  
128 - marker = RTMP_AMF0_Boolean;  
129 - value = _value;  
130 -}  
131 -  
132 -SrsAmf0Boolean::~SrsAmf0Boolean()  
133 -{  
134 -}  
135 -  
136 -SrsAmf0Number::SrsAmf0Number(double _value)  
137 -{  
138 - marker = RTMP_AMF0_Number;  
139 - value = _value;  
140 -}  
141 -  
142 -SrsAmf0Number::~SrsAmf0Number()  
143 -{  
144 -}  
145 -  
146 -SrsAmf0Null::SrsAmf0Null()  
147 -{  
148 - marker = RTMP_AMF0_Null;  
149 -}  
150 -  
151 -SrsAmf0Null::~SrsAmf0Null()  
152 -{  
153 -}  
154 -  
155 -SrsAmf0Undefined::SrsAmf0Undefined()  
156 -{  
157 - marker = RTMP_AMF0_Undefined;  
158 -}  
159 -  
160 -SrsAmf0Undefined::~SrsAmf0Undefined()  
161 -{  
162 -}  
163 -  
164 -SrsAmf0ObjectEOF::SrsAmf0ObjectEOF()  
165 -{  
166 - marker = RTMP_AMF0_ObjectEnd;  
167 - utf8_empty = 0x00;  
168 -}  
169 -  
170 -SrsAmf0ObjectEOF::~SrsAmf0ObjectEOF()  
171 -{  
172 -}  
173 -  
174 -SrsUnSortedHashtable::SrsUnSortedHashtable()  
175 -{  
176 -}  
177 -  
178 -SrsUnSortedHashtable::~SrsUnSortedHashtable()  
179 -{  
180 - std::vector<SrsObjectPropertyType>::iterator it;  
181 - for (it = properties.begin(); it != properties.end(); ++it) {  
182 - SrsObjectPropertyType& elem = *it;  
183 - SrsAmf0Any* any = elem.second;  
184 - srs_freep(any);  
185 - }  
186 - properties.clear();  
187 -}  
188 -  
189 -int SrsUnSortedHashtable::size()  
190 -{  
191 - return (int)properties.size();  
192 -}  
193 -  
194 -void SrsUnSortedHashtable::clear()  
195 -{  
196 - properties.clear();  
197 -}  
198 -  
199 -std::string SrsUnSortedHashtable::key_at(int index)  
200 -{  
201 - srs_assert(index < size());  
202 - SrsObjectPropertyType& elem = properties[index];  
203 - return elem.first;  
204 -}  
205 -  
206 -SrsAmf0Any* SrsUnSortedHashtable::value_at(int index)  
207 -{  
208 - srs_assert(index < size());  
209 - SrsObjectPropertyType& elem = properties[index];  
210 - return elem.second;  
211 -}  
212 -  
213 -void SrsUnSortedHashtable::set(std::string key, SrsAmf0Any* value)  
214 -{  
215 - std::vector<SrsObjectPropertyType>::iterator it;  
216 -  
217 - for (it = properties.begin(); it != properties.end(); ++it) {  
218 - SrsObjectPropertyType& elem = *it;  
219 - std::string name = elem.first;  
220 - SrsAmf0Any* any = elem.second;  
221 -  
222 - if (key == name) {  
223 - srs_freep(any);  
224 - properties.erase(it);  
225 - break;  
226 - }  
227 - }  
228 -  
229 - properties.push_back(std::make_pair(key, value));  
230 -}  
231 -  
232 -SrsAmf0Any* SrsUnSortedHashtable::get_property(std::string name)  
233 -{  
234 - std::vector<SrsObjectPropertyType>::iterator it;  
235 -  
236 - for (it = properties.begin(); it != properties.end(); ++it) {  
237 - SrsObjectPropertyType& elem = *it;  
238 - std::string key = elem.first;  
239 - SrsAmf0Any* any = elem.second;  
240 - if (key == name) {  
241 - return any;  
242 - }  
243 - }  
244 -  
245 - return NULL;  
246 -}  
247 -  
248 -SrsAmf0Any* SrsUnSortedHashtable::ensure_property_string(std::string name)  
249 -{  
250 - SrsAmf0Any* prop = get_property(name);  
251 -  
252 - if (!prop) {  
253 - return NULL;  
254 - }  
255 -  
256 - if (!prop->is_string()) {  
257 - return NULL;  
258 - }  
259 -  
260 - return prop;  
261 -}  
262 -  
263 -SrsAmf0Any* SrsUnSortedHashtable::ensure_property_number(std::string name)  
264 -{  
265 - SrsAmf0Any* prop = get_property(name);  
266 -  
267 - if (!prop) {  
268 - return NULL;  
269 - }  
270 -  
271 - if (!prop->is_number()) {  
272 - return NULL;  
273 - }  
274 -  
275 - return prop;  
276 -}  
277 -  
278 -SrsAmf0Object::SrsAmf0Object()  
279 -{  
280 - marker = RTMP_AMF0_Object;  
281 -}  
282 -  
283 -SrsAmf0Object::~SrsAmf0Object()  
284 -{  
285 -}  
286 -  
287 -int SrsAmf0Object::size()  
288 -{  
289 - return properties.size();  
290 -}  
291 -  
292 -std::string SrsAmf0Object::key_at(int index)  
293 -{  
294 - return properties.key_at(index);  
295 -}  
296 -  
297 -SrsAmf0Any* SrsAmf0Object::value_at(int index)  
298 -{  
299 - return properties.value_at(index);  
300 -}  
301 -  
302 -void SrsAmf0Object::set(std::string key, SrsAmf0Any* value)  
303 -{  
304 - properties.set(key, value);  
305 -}  
306 -  
307 -SrsAmf0Any* SrsAmf0Object::get_property(std::string name)  
308 -{  
309 - return properties.get_property(name);  
310 -}  
311 -  
312 -SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name)  
313 -{  
314 - return properties.ensure_property_string(name);  
315 -}  
316 -  
317 -SrsAmf0Any* SrsAmf0Object::ensure_property_number(std::string name)  
318 -{  
319 - return properties.ensure_property_number(name);  
320 -}  
321 -  
322 -SrsASrsAmf0EcmaArray::SrsASrsAmf0EcmaArray()  
323 -{  
324 - marker = RTMP_AMF0_EcmaArray;  
325 -}  
326 -  
327 -SrsASrsAmf0EcmaArray::~SrsASrsAmf0EcmaArray()  
328 -{  
329 -}  
330 -  
331 -int SrsASrsAmf0EcmaArray::size()  
332 -{  
333 - return properties.size();  
334 -}  
335 -  
336 -void SrsASrsAmf0EcmaArray::clear()  
337 -{  
338 - properties.clear();  
339 -}  
340 -  
341 -std::string SrsASrsAmf0EcmaArray::key_at(int index)  
342 -{  
343 - return properties.key_at(index);  
344 -}  
345 -  
346 -SrsAmf0Any* SrsASrsAmf0EcmaArray::value_at(int index)  
347 -{  
348 - return properties.value_at(index);  
349 -}  
350 -  
351 -void SrsASrsAmf0EcmaArray::set(std::string key, SrsAmf0Any* value)  
352 -{  
353 - properties.set(key, value);  
354 -}  
355 -  
356 -SrsAmf0Any* SrsASrsAmf0EcmaArray::get_property(std::string name)  
357 -{  
358 - return properties.get_property(name);  
359 -}  
360 -  
361 -SrsAmf0Any* SrsASrsAmf0EcmaArray::ensure_property_string(std::string name)  
362 -{  
363 - return properties.ensure_property_string(name);  
364 -}  
365 -  
366 -int srs_amf0_read_utf8(SrsStream* stream, std::string& value)  
367 -{  
368 - int ret = ERROR_SUCCESS;  
369 -  
370 - // len  
371 - if (!stream->require(2)) {  
372 - ret = ERROR_RTMP_AMF0_DECODE;  
373 - srs_error("amf0 read string length failed. ret=%d", ret);  
374 - return ret;  
375 - }  
376 - int16_t len = stream->read_2bytes();  
377 - srs_verbose("amf0 read string length success. len=%d", len);  
378 -  
379 - // empty string  
380 - if (len <= 0) {  
381 - srs_verbose("amf0 read empty string. ret=%d", ret);  
382 - return ret;  
383 - }  
384 -  
385 - // data  
386 - if (!stream->require(len)) {  
387 - ret = ERROR_RTMP_AMF0_DECODE;  
388 - srs_error("amf0 read string data failed. ret=%d", ret);  
389 - return ret;  
390 - }  
391 - std::string str = stream->read_string(len);  
392 -  
393 - // support utf8-1 only  
394 - // 1.3.1 Strings and UTF-8  
395 - // UTF8-1 = %x00-7F  
396 - for (int i = 0; i < len; i++) {  
397 - char ch = *(str.data() + i);  
398 - if ((ch & 0x80) != 0) {  
399 - ret = ERROR_RTMP_AMF0_DECODE;  
400 - srs_error("ignored. only support utf8-1, 0x00-0x7F, actual is %#x. ret=%d", (int)ch, ret);  
401 - ret = ERROR_SUCCESS;  
402 - }  
403 - }  
404 -  
405 - value = str;  
406 - srs_verbose("amf0 read string data success. str=%s", str.c_str());  
407 -  
408 - return ret;  
409 -}  
410 -int srs_amf0_write_utf8(SrsStream* stream, std::string value)  
411 -{  
412 - int ret = ERROR_SUCCESS;  
413 -  
414 - // len  
415 - if (!stream->require(2)) {  
416 - ret = ERROR_RTMP_AMF0_ENCODE;  
417 - srs_error("amf0 write string length failed. ret=%d", ret);  
418 - return ret;  
419 - }  
420 - stream->write_2bytes(value.length());  
421 - srs_verbose("amf0 write string length success. len=%d", (int)value.length());  
422 -  
423 - // empty string  
424 - if (value.length() <= 0) {  
425 - srs_verbose("amf0 write empty string. ret=%d", ret);  
426 - return ret;  
427 - }  
428 -  
429 - // data  
430 - if (!stream->require(value.length())) {  
431 - ret = ERROR_RTMP_AMF0_ENCODE;  
432 - srs_error("amf0 write string data failed. ret=%d", ret);  
433 - return ret;  
434 - }  
435 - stream->write_string(value);  
436 - srs_verbose("amf0 write string data success. str=%s", value.c_str());  
437 -  
438 - return ret;  
439 -}  
440 -  
441 -int srs_amf0_read_string(SrsStream* stream, std::string& value)  
442 -{  
443 - int ret = ERROR_SUCCESS;  
444 -  
445 - // marker  
446 - if (!stream->require(1)) {  
447 - ret = ERROR_RTMP_AMF0_DECODE;  
448 - srs_error("amf0 read string marker failed. ret=%d", ret);  
449 - return ret;  
450 - }  
451 -  
452 - char marker = stream->read_1bytes();  
453 - if (marker != RTMP_AMF0_String) {  
454 - ret = ERROR_RTMP_AMF0_DECODE;  
455 - srs_error("amf0 check string marker failed. "  
456 - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_String, ret);  
457 - return ret;  
458 - }  
459 - srs_verbose("amf0 read string marker success");  
460 -  
461 - return srs_amf0_read_utf8(stream, value);  
462 -}  
463 -  
464 -int srs_amf0_write_string(SrsStream* stream, std::string value)  
465 -{  
466 - int ret = ERROR_SUCCESS;  
467 -  
468 - // marker  
469 - if (!stream->require(1)) {  
470 - ret = ERROR_RTMP_AMF0_ENCODE;  
471 - srs_error("amf0 write string marker failed. ret=%d", ret);  
472 - return ret;  
473 - }  
474 -  
475 - stream->write_1bytes(RTMP_AMF0_String);  
476 - srs_verbose("amf0 write string marker success");  
477 -  
478 - return srs_amf0_write_utf8(stream, value);  
479 -}  
480 -  
481 -int srs_amf0_read_boolean(SrsStream* stream, bool& value)  
482 -{  
483 - int ret = ERROR_SUCCESS;  
484 -  
485 - // marker  
486 - if (!stream->require(1)) {  
487 - ret = ERROR_RTMP_AMF0_DECODE;  
488 - srs_error("amf0 read bool marker failed. ret=%d", ret);  
489 - return ret;  
490 - }  
491 -  
492 - char marker = stream->read_1bytes();  
493 - if (marker != RTMP_AMF0_Boolean) {  
494 - ret = ERROR_RTMP_AMF0_DECODE;  
495 - srs_error("amf0 check bool marker failed. "  
496 - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Boolean, ret);  
497 - return ret;  
498 - }  
499 - srs_verbose("amf0 read bool marker success");  
500 -  
501 - // value  
502 - if (!stream->require(1)) {  
503 - ret = ERROR_RTMP_AMF0_DECODE;  
504 - srs_error("amf0 read bool value failed. ret=%d", ret);  
505 - return ret;  
506 - }  
507 -  
508 - if (stream->read_1bytes() == 0) {  
509 - value = false;  
510 - } else {  
511 - value = true;  
512 - }  
513 -  
514 - srs_verbose("amf0 read bool value success. value=%d", value);  
515 -  
516 - return ret;  
517 -}  
518 -int srs_amf0_write_boolean(SrsStream* stream, bool value)  
519 -{  
520 - int ret = ERROR_SUCCESS;  
521 -  
522 - // marker  
523 - if (!stream->require(1)) {  
524 - ret = ERROR_RTMP_AMF0_ENCODE;  
525 - srs_error("amf0 write bool marker failed. ret=%d", ret);  
526 - return ret;  
527 - }  
528 - stream->write_1bytes(RTMP_AMF0_Boolean);  
529 - srs_verbose("amf0 write bool marker success");  
530 -  
531 - // value  
532 - if (!stream->require(1)) {  
533 - ret = ERROR_RTMP_AMF0_ENCODE;  
534 - srs_error("amf0 write bool value failed. ret=%d", ret);  
535 - return ret;  
536 - }  
537 -  
538 - if (value) {  
539 - stream->write_1bytes(0x01);  
540 - } else {  
541 - stream->write_1bytes(0x00);  
542 - }  
543 -  
544 - srs_verbose("amf0 write bool value success. value=%d", value);  
545 -  
546 - return ret;  
547 -}  
548 -  
549 -int srs_amf0_read_number(SrsStream* stream, double& value)  
550 -{  
551 - int ret = ERROR_SUCCESS;  
552 -  
553 - // marker  
554 - if (!stream->require(1)) {  
555 - ret = ERROR_RTMP_AMF0_DECODE;  
556 - srs_error("amf0 read number marker failed. ret=%d", ret);  
557 - return ret;  
558 - }  
559 -  
560 - char marker = stream->read_1bytes();  
561 - if (marker != RTMP_AMF0_Number) {  
562 - ret = ERROR_RTMP_AMF0_DECODE;  
563 - srs_error("amf0 check number marker failed. "  
564 - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Number, ret);  
565 - return ret;  
566 - }  
567 - srs_verbose("amf0 read number marker success");  
568 -  
569 - // value  
570 - if (!stream->require(8)) {  
571 - ret = ERROR_RTMP_AMF0_DECODE;  
572 - srs_error("amf0 read number value failed. ret=%d", ret);  
573 - return ret;  
574 - }  
575 -  
576 - int64_t temp = stream->read_8bytes();  
577 - memcpy(&value, &temp, 8);  
578 -  
579 - srs_verbose("amf0 read number value success. value=%.2f", value);  
580 -  
581 - return ret;  
582 -}  
583 -int srs_amf0_write_number(SrsStream* stream, double value)  
584 -{  
585 - int ret = ERROR_SUCCESS;  
586 -  
587 - // marker  
588 - if (!stream->require(1)) {  
589 - ret = ERROR_RTMP_AMF0_ENCODE;  
590 - srs_error("amf0 write number marker failed. ret=%d", ret);  
591 - return ret;  
592 - }  
593 -  
594 - stream->write_1bytes(RTMP_AMF0_Number);  
595 - srs_verbose("amf0 write number marker success");  
596 -  
597 - // value  
598 - if (!stream->require(8)) {  
599 - ret = ERROR_RTMP_AMF0_ENCODE;  
600 - srs_error("amf0 write number value failed. ret=%d", ret);  
601 - return ret;  
602 - }  
603 -  
604 - int64_t temp = 0x00;  
605 - memcpy(&temp, &value, 8);  
606 - stream->write_8bytes(temp);  
607 -  
608 - srs_verbose("amf0 write number value success. value=%.2f", value);  
609 -  
610 - return ret;  
611 -}  
612 -  
613 -int srs_amf0_read_null(SrsStream* stream)  
614 -{  
615 - int ret = ERROR_SUCCESS;  
616 -  
617 - // marker  
618 - if (!stream->require(1)) {  
619 - ret = ERROR_RTMP_AMF0_DECODE;  
620 - srs_error("amf0 read null marker failed. ret=%d", ret);  
621 - return ret;  
622 - }  
623 -  
624 - char marker = stream->read_1bytes();  
625 - if (marker != RTMP_AMF0_Null) {  
626 - ret = ERROR_RTMP_AMF0_DECODE;  
627 - srs_error("amf0 check null marker failed. "  
628 - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Null, ret);  
629 - return ret;  
630 - }  
631 - srs_verbose("amf0 read null success");  
632 -  
633 - return ret;  
634 -}  
635 -int srs_amf0_write_null(SrsStream* stream)  
636 -{  
637 - int ret = ERROR_SUCCESS;  
638 -  
639 - // marker  
640 - if (!stream->require(1)) {  
641 - ret = ERROR_RTMP_AMF0_ENCODE;  
642 - srs_error("amf0 write null marker failed. ret=%d", ret);  
643 - return ret;  
644 - }  
645 -  
646 - stream->write_1bytes(RTMP_AMF0_Null);  
647 - srs_verbose("amf0 write null marker success");  
648 -  
649 - return ret;  
650 -}  
651 -  
652 -int srs_amf0_read_undefined(SrsStream* stream)  
653 -{  
654 - int ret = ERROR_SUCCESS;  
655 -  
656 - // marker  
657 - if (!stream->require(1)) {  
658 - ret = ERROR_RTMP_AMF0_DECODE;  
659 - srs_error("amf0 read undefined marker failed. ret=%d", ret);  
660 - return ret;  
661 - }  
662 -  
663 - char marker = stream->read_1bytes();  
664 - if (marker != RTMP_AMF0_Undefined) {  
665 - ret = ERROR_RTMP_AMF0_DECODE;  
666 - srs_error("amf0 check undefined marker failed. "  
667 - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Undefined, ret);  
668 - return ret;  
669 - }  
670 - srs_verbose("amf0 read undefined success");  
671 -  
672 - return ret;  
673 -}  
674 -int srs_amf0_write_undefined(SrsStream* stream)  
675 -{  
676 - int ret = ERROR_SUCCESS;  
677 -  
678 - // marker  
679 - if (!stream->require(1)) {  
680 - ret = ERROR_RTMP_AMF0_ENCODE;  
681 - srs_error("amf0 write undefined marker failed. ret=%d", ret);  
682 - return ret;  
683 - }  
684 -  
685 - stream->write_1bytes(RTMP_AMF0_Undefined);  
686 - srs_verbose("amf0 write undefined marker success");  
687 -  
688 - return ret;  
689 -}  
690 -  
691 -int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)  
692 -{  
693 - int ret = ERROR_SUCCESS;  
694 -  
695 - // marker  
696 - if (!stream->require(1)) {  
697 - ret = ERROR_RTMP_AMF0_DECODE;  
698 - srs_error("amf0 read any marker failed. ret=%d", ret);  
699 - return ret;  
700 - }  
701 -  
702 - char marker = stream->read_1bytes();  
703 - srs_verbose("amf0 any marker success");  
704 -  
705 - // backward the 1byte marker.  
706 - stream->skip(-1);  
707 -  
708 - switch (marker) {  
709 - case RTMP_AMF0_String: {  
710 - std::string data;  
711 - if ((ret = srs_amf0_read_string(stream, data)) != ERROR_SUCCESS) {  
712 - return ret;  
713 - }  
714 - value = new SrsAmf0String();  
715 - srs_amf0_convert<SrsAmf0String>(value)->value = data;  
716 - return ret;  
717 - }  
718 - case RTMP_AMF0_Boolean: {  
719 - bool data;  
720 - if ((ret = srs_amf0_read_boolean(stream, data)) != ERROR_SUCCESS) {  
721 - return ret;  
722 - }  
723 - value = new SrsAmf0Boolean();  
724 - srs_amf0_convert<SrsAmf0Boolean>(value)->value = data;  
725 - return ret;  
726 - }  
727 - case RTMP_AMF0_Number: {  
728 - double data;  
729 - if ((ret = srs_amf0_read_number(stream, data)) != ERROR_SUCCESS) {  
730 - return ret;  
731 - }  
732 - value = new SrsAmf0Number();  
733 - srs_amf0_convert<SrsAmf0Number>(value)->value = data;  
734 - return ret;  
735 - }  
736 - case RTMP_AMF0_Null: {  
737 - stream->skip(1);  
738 - value = new SrsAmf0Null();  
739 - return ret;  
740 - }  
741 - case RTMP_AMF0_Undefined: {  
742 - stream->skip(1);  
743 - value = new SrsAmf0Undefined();  
744 - return ret;  
745 - }  
746 - case RTMP_AMF0_ObjectEnd: {  
747 - SrsAmf0ObjectEOF* p = NULL;  
748 - if ((ret = srs_amf0_read_object_eof(stream, p)) != ERROR_SUCCESS) {  
749 - return ret;  
750 - }  
751 - value = p;  
752 - return ret;  
753 - }  
754 - case RTMP_AMF0_Object: {  
755 - SrsAmf0Object* p = NULL;  
756 - if ((ret = srs_amf0_read_object(stream, p)) != ERROR_SUCCESS) {  
757 - return ret;  
758 - }  
759 - value = p;  
760 - return ret;  
761 - }  
762 - case RTMP_AMF0_EcmaArray: {  
763 - SrsASrsAmf0EcmaArray* p = NULL;  
764 - if ((ret = srs_amf0_read_ecma_array(stream, p)) != ERROR_SUCCESS) {  
765 - return ret;  
766 - }  
767 - value = p;  
768 - return ret;  
769 - }  
770 - case RTMP_AMF0_Invalid:  
771 - default: {  
772 - ret = ERROR_RTMP_AMF0_INVALID;  
773 - srs_error("invalid amf0 message type. marker=%#x, ret=%d", marker, ret);  
774 - return ret;  
775 - }  
776 - }  
777 -  
778 - return ret;  
779 -}  
780 -int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)  
781 -{  
782 - int ret = ERROR_SUCCESS;  
783 -  
784 - srs_assert(value != NULL);  
785 -  
786 - switch (value->marker) {  
787 - case RTMP_AMF0_String: {  
788 - std::string data = srs_amf0_convert<SrsAmf0String>(value)->value;  
789 - return srs_amf0_write_string(stream, data);  
790 - }  
791 - case RTMP_AMF0_Boolean: {  
792 - bool data = srs_amf0_convert<SrsAmf0Boolean>(value)->value;  
793 - return srs_amf0_write_boolean(stream, data);  
794 - }  
795 - case RTMP_AMF0_Number: {  
796 - double data = srs_amf0_convert<SrsAmf0Number>(value)->value;  
797 - return srs_amf0_write_number(stream, data);  
798 - }  
799 - case RTMP_AMF0_Null: {  
800 - return srs_amf0_write_null(stream);  
801 - }  
802 - case RTMP_AMF0_Undefined: {  
803 - return srs_amf0_write_undefined(stream);  
804 - }  
805 - case RTMP_AMF0_ObjectEnd: {  
806 - SrsAmf0ObjectEOF* p = srs_amf0_convert<SrsAmf0ObjectEOF>(value);  
807 - return srs_amf0_write_object_eof(stream, p);  
808 - }  
809 - case RTMP_AMF0_Object: {  
810 - SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);  
811 - return srs_amf0_write_object(stream, p);  
812 - }  
813 - case RTMP_AMF0_EcmaArray: {  
814 - SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value);  
815 - return srs_amf0_write_ecma_array(stream, p);  
816 - }  
817 - case RTMP_AMF0_Invalid:  
818 - default: {  
819 - ret = ERROR_RTMP_AMF0_INVALID;  
820 - srs_error("invalid amf0 message type. marker=%#x, ret=%d", value->marker, ret);  
821 - return ret;  
822 - }  
823 - }  
824 -  
825 - return ret;  
826 -}  
827 -int srs_amf0_get_any_size(SrsAmf0Any* value)  
828 -{  
829 - if (!value) {  
830 - return 0;  
831 - }  
832 -  
833 - int size = 0;  
834 -  
835 - switch (value->marker) {  
836 - case RTMP_AMF0_String: {  
837 - SrsAmf0String* p = srs_amf0_convert<SrsAmf0String>(value);  
838 - size += srs_amf0_get_string_size(p->value);  
839 - break;  
840 - }  
841 - case RTMP_AMF0_Boolean: {  
842 - size += srs_amf0_get_boolean_size();  
843 - break;  
844 - }  
845 - case RTMP_AMF0_Number: {  
846 - size += srs_amf0_get_number_size();  
847 - break;  
848 - }  
849 - case RTMP_AMF0_Null: {  
850 - size += srs_amf0_get_null_size();  
851 - break;  
852 - }  
853 - case RTMP_AMF0_Undefined: {  
854 - size += srs_amf0_get_undefined_size();  
855 - break;  
856 - }  
857 - case RTMP_AMF0_ObjectEnd: {  
858 - size += srs_amf0_get_object_eof_size();  
859 - break;  
860 - }  
861 - case RTMP_AMF0_Object: {  
862 - SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);  
863 - size += srs_amf0_get_object_size(p);  
864 - break;  
865 - }  
866 - case RTMP_AMF0_EcmaArray: {  
867 - SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value);  
868 - size += srs_amf0_get_ecma_array_size(p);  
869 - break;  
870 - }  
871 - default: {  
872 - // TOOD: other AMF0 types.  
873 - srs_warn("ignore unkown AMF0 type size.");  
874 - break;  
875 - }  
876 - }  
877 -  
878 - return size;  
879 -}  
880 -  
881 -int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value)  
882 -{  
883 - int ret = ERROR_SUCCESS;  
884 -  
885 - // auto skip -2 to read the object eof.  
886 - srs_assert(stream->pos() >= 2);  
887 - stream->skip(-2);  
888 -  
889 - // value  
890 - if (!stream->require(2)) {  
891 - ret = ERROR_RTMP_AMF0_DECODE;  
892 - srs_error("amf0 read object eof value failed. ret=%d", ret);  
893 - return ret;  
894 - }  
895 - int16_t temp = stream->read_2bytes();  
896 - if (temp != 0x00) {  
897 - ret = ERROR_RTMP_AMF0_DECODE;  
898 - srs_error("amf0 read object eof value check failed. "  
899 - "must be 0x00, actual is %#x, ret=%d", temp, ret);  
900 - return ret;  
901 - }  
902 -  
903 - // marker  
904 - if (!stream->require(1)) {  
905 - ret = ERROR_RTMP_AMF0_DECODE;  
906 - srs_error("amf0 read object eof marker failed. ret=%d", ret);  
907 - return ret;  
908 - }  
909 -  
910 - char marker = stream->read_1bytes();  
911 - if (marker != RTMP_AMF0_ObjectEnd) {  
912 - ret = ERROR_RTMP_AMF0_DECODE;  
913 - srs_error("amf0 check object eof marker failed. "  
914 - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_ObjectEnd, ret);  
915 - return ret;  
916 - }  
917 - srs_verbose("amf0 read object eof marker success");  
918 -  
919 - value = new SrsAmf0ObjectEOF();  
920 - srs_verbose("amf0 read object eof success");  
921 -  
922 - return ret;  
923 -}  
924 -int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF* value)  
925 -{  
926 - int ret = ERROR_SUCCESS;  
927 -  
928 - srs_assert(value != NULL);  
929 -  
930 - // value  
931 - if (!stream->require(2)) {  
932 - ret = ERROR_RTMP_AMF0_ENCODE;  
933 - srs_error("amf0 write object eof value failed. ret=%d", ret);  
934 - return ret;  
935 - }  
936 - stream->write_2bytes(0x00);  
937 - srs_verbose("amf0 write object eof value success");  
938 -  
939 - // marker  
940 - if (!stream->require(1)) {  
941 - ret = ERROR_RTMP_AMF0_ENCODE;  
942 - srs_error("amf0 write object eof marker failed. ret=%d", ret);  
943 - return ret;  
944 - }  
945 -  
946 - stream->write_1bytes(RTMP_AMF0_ObjectEnd);  
947 -  
948 - srs_verbose("amf0 read object eof success");  
949 -  
950 - return ret;  
951 -}  
952 -  
953 -int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value)  
954 -{  
955 - int ret = ERROR_SUCCESS;  
956 -  
957 - // marker  
958 - if (!stream->require(1)) {  
959 - ret = ERROR_RTMP_AMF0_DECODE;  
960 - srs_error("amf0 read object marker failed. ret=%d", ret);  
961 - return ret;  
962 - }  
963 -  
964 - char marker = stream->read_1bytes();  
965 - if (marker != RTMP_AMF0_Object) {  
966 - ret = ERROR_RTMP_AMF0_DECODE;  
967 - srs_error("amf0 check object marker failed. "  
968 - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);  
969 - return ret;  
970 - }  
971 - srs_verbose("amf0 read object marker success");  
972 -  
973 - // value  
974 - value = new SrsAmf0Object();  
975 -  
976 - while (!stream->empty()) {  
977 - // property-name: utf8 string  
978 - std::string property_name;  
979 - if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {  
980 - srs_error("amf0 object read property name failed. ret=%d", ret);  
981 - return ret;  
982 - }  
983 - // property-value: any  
984 - SrsAmf0Any* property_value = NULL;  
985 - if ((ret = srs_amf0_read_any(stream, property_value)) != ERROR_SUCCESS) {  
986 - srs_error("amf0 object read property_value failed. "  
987 - "name=%s, ret=%d", property_name.c_str(), ret);  
988 - return ret;  
989 - }  
990 -  
991 - // AMF0 Object EOF.  
992 - if (property_name.empty() || !property_value || property_value->is_object_eof()) {  
993 - if (property_value) {  
994 - srs_freep(property_value);  
995 - }  
996 - srs_info("amf0 read object EOF.");  
997 - break;  
998 - }  
999 -  
1000 - // add property  
1001 - value->set(property_name, property_value);  
1002 - }  
1003 -  
1004 - return ret;  
1005 -}  
1006 -int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value)  
1007 -{  
1008 - int ret = ERROR_SUCCESS;  
1009 -  
1010 - srs_assert(value != NULL);  
1011 -  
1012 - // marker  
1013 - if (!stream->require(1)) {  
1014 - ret = ERROR_RTMP_AMF0_ENCODE;  
1015 - srs_error("amf0 write object marker failed. ret=%d", ret);  
1016 - return ret;  
1017 - }  
1018 -  
1019 - stream->write_1bytes(RTMP_AMF0_Object);  
1020 - srs_verbose("amf0 write object marker success");  
1021 -  
1022 - // value  
1023 - for (int i = 0; i < value->size(); i++) {  
1024 - std::string name = value->key_at(i);  
1025 - SrsAmf0Any* any = value->value_at(i);  
1026 -  
1027 - if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) {  
1028 - srs_error("write object property name failed. ret=%d", ret);  
1029 - return ret;  
1030 - }  
1031 -  
1032 - if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {  
1033 - srs_error("write object property value failed. ret=%d", ret);  
1034 - return ret;  
1035 - }  
1036 -  
1037 - srs_verbose("write amf0 property success. name=%s", name.c_str());  
1038 - }  
1039 -  
1040 - if ((ret = srs_amf0_write_object_eof(stream, &value->eof)) != ERROR_SUCCESS) {  
1041 - srs_error("write object eof failed. ret=%d", ret);  
1042 - return ret;  
1043 - }  
1044 -  
1045 - srs_verbose("write amf0 object success.");  
1046 -  
1047 - return ret;  
1048 -}  
1049 -  
1050 -int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value)  
1051 -{  
1052 - int ret = ERROR_SUCCESS;  
1053 -  
1054 - // marker  
1055 - if (!stream->require(1)) {  
1056 - ret = ERROR_RTMP_AMF0_DECODE;  
1057 - srs_error("amf0 read ecma_array marker failed. ret=%d", ret);  
1058 - return ret;  
1059 - }  
1060 -  
1061 - char marker = stream->read_1bytes();  
1062 - if (marker != RTMP_AMF0_EcmaArray) {  
1063 - ret = ERROR_RTMP_AMF0_DECODE;  
1064 - srs_error("amf0 check ecma_array marker failed. "  
1065 - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);  
1066 - return ret;  
1067 - }  
1068 - srs_verbose("amf0 read ecma_array marker success");  
1069 -  
1070 - // count  
1071 - if (!stream->require(4)) {  
1072 - ret = ERROR_RTMP_AMF0_DECODE;  
1073 - srs_error("amf0 read ecma_array count failed. ret=%d", ret);  
1074 - return ret;  
1075 - }  
1076 -  
1077 - int32_t count = stream->read_4bytes();  
1078 - srs_verbose("amf0 read ecma_array count success. count=%d", count);  
1079 -  
1080 - // value  
1081 - value = new SrsASrsAmf0EcmaArray();  
1082 - value->count = count;  
1083 -  
1084 - while (!stream->empty()) {  
1085 - // property-name: utf8 string  
1086 - std::string property_name;  
1087 - if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {  
1088 - srs_error("amf0 ecma_array read property name failed. ret=%d", ret);  
1089 - return ret;  
1090 - }  
1091 - // property-value: any  
1092 - SrsAmf0Any* property_value = NULL;  
1093 - if ((ret = srs_amf0_read_any(stream, property_value)) != ERROR_SUCCESS) {  
1094 - srs_error("amf0 ecma_array read property_value failed. "  
1095 - "name=%s, ret=%d", property_name.c_str(), ret);  
1096 - return ret;  
1097 - }  
1098 -  
1099 - // AMF0 Object EOF.  
1100 - if (property_name.empty() || !property_value || property_value->is_object_eof()) {  
1101 - if (property_value) {  
1102 - srs_freep(property_value);  
1103 - }  
1104 - srs_info("amf0 read ecma_array EOF.");  
1105 - break;  
1106 - }  
1107 -  
1108 - // add property  
1109 - value->set(property_name, property_value);  
1110 - }  
1111 -  
1112 - return ret;  
1113 -}  
1114 -int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value)  
1115 -{  
1116 - int ret = ERROR_SUCCESS;  
1117 -  
1118 - srs_assert(value != NULL);  
1119 -  
1120 - // marker  
1121 - if (!stream->require(1)) {  
1122 - ret = ERROR_RTMP_AMF0_ENCODE;  
1123 - srs_error("amf0 write ecma_array marker failed. ret=%d", ret);  
1124 - return ret;  
1125 - }  
1126 -  
1127 - stream->write_1bytes(RTMP_AMF0_EcmaArray);  
1128 - srs_verbose("amf0 write ecma_array marker success");  
1129 -  
1130 - // count  
1131 - if (!stream->require(4)) {  
1132 - ret = ERROR_RTMP_AMF0_ENCODE;  
1133 - srs_error("amf0 write ecma_array count failed. ret=%d", ret);  
1134 - return ret;  
1135 - }  
1136 -  
1137 - stream->write_4bytes(value->count);  
1138 - srs_verbose("amf0 write ecma_array count success. count=%d", value->count);  
1139 -  
1140 - // value  
1141 - for (int i = 0; i < value->size(); i++) {  
1142 - std::string name = value->key_at(i);  
1143 - SrsAmf0Any* any = value->value_at(i);  
1144 -  
1145 - if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) {  
1146 - srs_error("write ecma_array property name failed. ret=%d", ret);  
1147 - return ret;  
1148 - }  
1149 -  
1150 - if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {  
1151 - srs_error("write ecma_array property value failed. ret=%d", ret);  
1152 - return ret;  
1153 - }  
1154 -  
1155 - srs_verbose("write amf0 property success. name=%s", name.c_str());  
1156 - }  
1157 -  
1158 - if ((ret = srs_amf0_write_object_eof(stream, &value->eof)) != ERROR_SUCCESS) {  
1159 - srs_error("write ecma_array eof failed. ret=%d", ret);  
1160 - return ret;  
1161 - }  
1162 -  
1163 - srs_verbose("write ecma_array object success.");  
1164 -  
1165 - return ret;  
1166 -}  
1167 -  
1168 -int srs_amf0_get_utf8_size(std::string value)  
1169 -{  
1170 - return 2 + value.length();  
1171 -}  
1172 -  
1173 -int srs_amf0_get_string_size(std::string value)  
1174 -{  
1175 - return 1 + srs_amf0_get_utf8_size(value);  
1176 -}  
1177 -  
1178 -int srs_amf0_get_number_size()  
1179 -{  
1180 - return 1 + 8;  
1181 -}  
1182 -  
1183 -int srs_amf0_get_null_size()  
1184 -{  
1185 - return 1;  
1186 -}  
1187 -  
1188 -int srs_amf0_get_undefined_size()  
1189 -{  
1190 - return 1;  
1191 -}  
1192 -  
1193 -int srs_amf0_get_boolean_size()  
1194 -{  
1195 - return 1 + 1;  
1196 -}  
1197 -  
1198 -int srs_amf0_get_object_size(SrsAmf0Object* obj)  
1199 -{  
1200 - if (!obj) {  
1201 - return 0;  
1202 - }  
1203 -  
1204 - int size = 1;  
1205 -  
1206 - for (int i = 0; i < obj->size(); i++){  
1207 - std::string name = obj->key_at(i);  
1208 - SrsAmf0Any* value = obj->value_at(i);  
1209 -  
1210 - size += srs_amf0_get_utf8_size(name);  
1211 - size += srs_amf0_get_any_size(value);  
1212 - }  
1213 -  
1214 - size += srs_amf0_get_object_eof_size();  
1215 -  
1216 - return size;  
1217 -}  
1218 -  
1219 -int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr)  
1220 -{  
1221 - if (!arr) {  
1222 - return 0;  
1223 - }  
1224 -  
1225 - int size = 1 + 4;  
1226 -  
1227 - for (int i = 0; i < arr->size(); i++){  
1228 - std::string name = arr->key_at(i);  
1229 - SrsAmf0Any* value = arr->value_at(i);  
1230 -  
1231 - size += srs_amf0_get_utf8_size(name);  
1232 - size += srs_amf0_get_any_size(value);  
1233 - }  
1234 -  
1235 - size += srs_amf0_get_object_eof_size();  
1236 -  
1237 - return size;  
1238 -}  
1239 -  
1240 -int srs_amf0_get_object_eof_size()  
1241 -{  
1242 - return 2 + 1;  
1243 -} 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_amf0.hpp>
  25 +
  26 +#include <utility>
  27 +
  28 +#include <srs_core_log.hpp>
  29 +#include <srs_core_error.hpp>
  30 +#include <srs_core_stream.hpp>
  31 +
  32 +// AMF0 marker
  33 +#define RTMP_AMF0_Number 0x00
  34 +#define RTMP_AMF0_Boolean 0x01
  35 +#define RTMP_AMF0_String 0x02
  36 +#define RTMP_AMF0_Object 0x03
  37 +#define RTMP_AMF0_MovieClip 0x04 // reserved, not supported
  38 +#define RTMP_AMF0_Null 0x05
  39 +#define RTMP_AMF0_Undefined 0x06
  40 +#define RTMP_AMF0_Reference 0x07
  41 +#define RTMP_AMF0_EcmaArray 0x08
  42 +#define RTMP_AMF0_ObjectEnd 0x09
  43 +#define RTMP_AMF0_StrictArray 0x0A
  44 +#define RTMP_AMF0_Date 0x0B
  45 +#define RTMP_AMF0_LongString 0x0C
  46 +#define RTMP_AMF0_UnSupported 0x0D
  47 +#define RTMP_AMF0_RecordSet 0x0E // reserved, not supported
  48 +#define RTMP_AMF0_XmlDocument 0x0F
  49 +#define RTMP_AMF0_TypedObject 0x10
  50 +// AVM+ object is the AMF3 object.
  51 +#define RTMP_AMF0_AVMplusObject 0x11
  52 +// origin array whos data takes the same form as LengthValueBytes
  53 +#define RTMP_AMF0_OriginStrictArray 0x20
  54 +
  55 +// User defined
  56 +#define RTMP_AMF0_Invalid 0x3F
  57 +
  58 +int srs_amf0_get_object_eof_size();
  59 +int srs_amf0_get_any_size(SrsAmf0Any* value);
  60 +int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&);
  61 +int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*);
  62 +int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value);
  63 +int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value);
  64 +
  65 +SrsAmf0Any::SrsAmf0Any()
  66 +{
  67 + marker = RTMP_AMF0_Invalid;
  68 +}
  69 +
  70 +SrsAmf0Any::~SrsAmf0Any()
  71 +{
  72 +}
  73 +
  74 +bool SrsAmf0Any::is_string()
  75 +{
  76 + return marker == RTMP_AMF0_String;
  77 +}
  78 +
  79 +bool SrsAmf0Any::is_boolean()
  80 +{
  81 + return marker == RTMP_AMF0_Boolean;
  82 +}
  83 +
  84 +bool SrsAmf0Any::is_number()
  85 +{
  86 + return marker == RTMP_AMF0_Number;
  87 +}
  88 +
  89 +bool SrsAmf0Any::is_null()
  90 +{
  91 + return marker == RTMP_AMF0_Null;
  92 +}
  93 +
  94 +bool SrsAmf0Any::is_undefined()
  95 +{
  96 + return marker == RTMP_AMF0_Undefined;
  97 +}
  98 +
  99 +bool SrsAmf0Any::is_object()
  100 +{
  101 + return marker == RTMP_AMF0_Object;
  102 +}
  103 +
  104 +bool SrsAmf0Any::is_ecma_array()
  105 +{
  106 + return marker == RTMP_AMF0_EcmaArray;
  107 +}
  108 +
  109 +bool SrsAmf0Any::is_object_eof()
  110 +{
  111 + return marker == RTMP_AMF0_ObjectEnd;
  112 +}
  113 +
  114 +SrsAmf0String::SrsAmf0String(const char* _value)
  115 +{
  116 + marker = RTMP_AMF0_String;
  117 + if (_value) {
  118 + value = _value;
  119 + }
  120 +}
  121 +
  122 +SrsAmf0String::~SrsAmf0String()
  123 +{
  124 +}
  125 +
  126 +SrsAmf0Boolean::SrsAmf0Boolean(bool _value)
  127 +{
  128 + marker = RTMP_AMF0_Boolean;
  129 + value = _value;
  130 +}
  131 +
  132 +SrsAmf0Boolean::~SrsAmf0Boolean()
  133 +{
  134 +}
  135 +
  136 +SrsAmf0Number::SrsAmf0Number(double _value)
  137 +{
  138 + marker = RTMP_AMF0_Number;
  139 + value = _value;
  140 +}
  141 +
  142 +SrsAmf0Number::~SrsAmf0Number()
  143 +{
  144 +}
  145 +
  146 +SrsAmf0Null::SrsAmf0Null()
  147 +{
  148 + marker = RTMP_AMF0_Null;
  149 +}
  150 +
  151 +SrsAmf0Null::~SrsAmf0Null()
  152 +{
  153 +}
  154 +
  155 +SrsAmf0Undefined::SrsAmf0Undefined()
  156 +{
  157 + marker = RTMP_AMF0_Undefined;
  158 +}
  159 +
  160 +SrsAmf0Undefined::~SrsAmf0Undefined()
  161 +{
  162 +}
  163 +
  164 +SrsAmf0ObjectEOF::SrsAmf0ObjectEOF()
  165 +{
  166 + marker = RTMP_AMF0_ObjectEnd;
  167 + utf8_empty = 0x00;
  168 +}
  169 +
  170 +SrsAmf0ObjectEOF::~SrsAmf0ObjectEOF()
  171 +{
  172 +}
  173 +
  174 +SrsUnSortedHashtable::SrsUnSortedHashtable()
  175 +{
  176 +}
  177 +
  178 +SrsUnSortedHashtable::~SrsUnSortedHashtable()
  179 +{
  180 + std::vector<SrsObjectPropertyType>::iterator it;
  181 + for (it = properties.begin(); it != properties.end(); ++it) {
  182 + SrsObjectPropertyType& elem = *it;
  183 + SrsAmf0Any* any = elem.second;
  184 + srs_freep(any);
  185 + }
  186 + properties.clear();
  187 +}
  188 +
  189 +int SrsUnSortedHashtable::size()
  190 +{
  191 + return (int)properties.size();
  192 +}
  193 +
  194 +void SrsUnSortedHashtable::clear()
  195 +{
  196 + properties.clear();
  197 +}
  198 +
  199 +std::string SrsUnSortedHashtable::key_at(int index)
  200 +{
  201 + srs_assert(index < size());
  202 + SrsObjectPropertyType& elem = properties[index];
  203 + return elem.first;
  204 +}
  205 +
  206 +SrsAmf0Any* SrsUnSortedHashtable::value_at(int index)
  207 +{
  208 + srs_assert(index < size());
  209 + SrsObjectPropertyType& elem = properties[index];
  210 + return elem.second;
  211 +}
  212 +
  213 +void SrsUnSortedHashtable::set(std::string key, SrsAmf0Any* value)
  214 +{
  215 + std::vector<SrsObjectPropertyType>::iterator it;
  216 +
  217 + for (it = properties.begin(); it != properties.end(); ++it) {
  218 + SrsObjectPropertyType& elem = *it;
  219 + std::string name = elem.first;
  220 + SrsAmf0Any* any = elem.second;
  221 +
  222 + if (key == name) {
  223 + srs_freep(any);
  224 + properties.erase(it);
  225 + break;
  226 + }
  227 + }
  228 +
  229 + properties.push_back(std::make_pair(key, value));
  230 +}
  231 +
  232 +SrsAmf0Any* SrsUnSortedHashtable::get_property(std::string name)
  233 +{
  234 + std::vector<SrsObjectPropertyType>::iterator it;
  235 +
  236 + for (it = properties.begin(); it != properties.end(); ++it) {
  237 + SrsObjectPropertyType& elem = *it;
  238 + std::string key = elem.first;
  239 + SrsAmf0Any* any = elem.second;
  240 + if (key == name) {
  241 + return any;
  242 + }
  243 + }
  244 +
  245 + return NULL;
  246 +}
  247 +
  248 +SrsAmf0Any* SrsUnSortedHashtable::ensure_property_string(std::string name)
  249 +{
  250 + SrsAmf0Any* prop = get_property(name);
  251 +
  252 + if (!prop) {
  253 + return NULL;
  254 + }
  255 +
  256 + if (!prop->is_string()) {
  257 + return NULL;
  258 + }
  259 +
  260 + return prop;
  261 +}
  262 +
  263 +SrsAmf0Any* SrsUnSortedHashtable::ensure_property_number(std::string name)
  264 +{
  265 + SrsAmf0Any* prop = get_property(name);
  266 +
  267 + if (!prop) {
  268 + return NULL;
  269 + }
  270 +
  271 + if (!prop->is_number()) {
  272 + return NULL;
  273 + }
  274 +
  275 + return prop;
  276 +}
  277 +
  278 +SrsAmf0Object::SrsAmf0Object()
  279 +{
  280 + marker = RTMP_AMF0_Object;
  281 +}
  282 +
  283 +SrsAmf0Object::~SrsAmf0Object()
  284 +{
  285 +}
  286 +
  287 +int SrsAmf0Object::size()
  288 +{
  289 + return properties.size();
  290 +}
  291 +
  292 +std::string SrsAmf0Object::key_at(int index)
  293 +{
  294 + return properties.key_at(index);
  295 +}
  296 +
  297 +SrsAmf0Any* SrsAmf0Object::value_at(int index)
  298 +{
  299 + return properties.value_at(index);
  300 +}
  301 +
  302 +void SrsAmf0Object::set(std::string key, SrsAmf0Any* value)
  303 +{
  304 + properties.set(key, value);
  305 +}
  306 +
  307 +SrsAmf0Any* SrsAmf0Object::get_property(std::string name)
  308 +{
  309 + return properties.get_property(name);
  310 +}
  311 +
  312 +SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name)
  313 +{
  314 + return properties.ensure_property_string(name);
  315 +}
  316 +
  317 +SrsAmf0Any* SrsAmf0Object::ensure_property_number(std::string name)
  318 +{
  319 + return properties.ensure_property_number(name);
  320 +}
  321 +
  322 +SrsASrsAmf0EcmaArray::SrsASrsAmf0EcmaArray()
  323 +{
  324 + marker = RTMP_AMF0_EcmaArray;
  325 +}
  326 +
  327 +SrsASrsAmf0EcmaArray::~SrsASrsAmf0EcmaArray()
  328 +{
  329 +}
  330 +
  331 +int SrsASrsAmf0EcmaArray::size()
  332 +{
  333 + return properties.size();
  334 +}
  335 +
  336 +void SrsASrsAmf0EcmaArray::clear()
  337 +{
  338 + properties.clear();
  339 +}
  340 +
  341 +std::string SrsASrsAmf0EcmaArray::key_at(int index)
  342 +{
  343 + return properties.key_at(index);
  344 +}
  345 +
  346 +SrsAmf0Any* SrsASrsAmf0EcmaArray::value_at(int index)
  347 +{
  348 + return properties.value_at(index);
  349 +}
  350 +
  351 +void SrsASrsAmf0EcmaArray::set(std::string key, SrsAmf0Any* value)
  352 +{
  353 + properties.set(key, value);
  354 +}
  355 +
  356 +SrsAmf0Any* SrsASrsAmf0EcmaArray::get_property(std::string name)
  357 +{
  358 + return properties.get_property(name);
  359 +}
  360 +
  361 +SrsAmf0Any* SrsASrsAmf0EcmaArray::ensure_property_string(std::string name)
  362 +{
  363 + return properties.ensure_property_string(name);
  364 +}
  365 +
  366 +int srs_amf0_read_utf8(SrsStream* stream, std::string& value)
  367 +{
  368 + int ret = ERROR_SUCCESS;
  369 +
  370 + // len
  371 + if (!stream->require(2)) {
  372 + ret = ERROR_RTMP_AMF0_DECODE;
  373 + srs_error("amf0 read string length failed. ret=%d", ret);
  374 + return ret;
  375 + }
  376 + int16_t len = stream->read_2bytes();
  377 + srs_verbose("amf0 read string length success. len=%d", len);
  378 +
  379 + // empty string
  380 + if (len <= 0) {
  381 + srs_verbose("amf0 read empty string. ret=%d", ret);
  382 + return ret;
  383 + }
  384 +
  385 + // data
  386 + if (!stream->require(len)) {
  387 + ret = ERROR_RTMP_AMF0_DECODE;
  388 + srs_error("amf0 read string data failed. ret=%d", ret);
  389 + return ret;
  390 + }
  391 + std::string str = stream->read_string(len);
  392 +
  393 + // support utf8-1 only
  394 + // 1.3.1 Strings and UTF-8
  395 + // UTF8-1 = %x00-7F
  396 + for (int i = 0; i < len; i++) {
  397 + char ch = *(str.data() + i);
  398 + if ((ch & 0x80) != 0) {
  399 + ret = ERROR_RTMP_AMF0_DECODE;
  400 + srs_error("ignored. only support utf8-1, 0x00-0x7F, actual is %#x. ret=%d", (int)ch, ret);
  401 + ret = ERROR_SUCCESS;
  402 + }
  403 + }
  404 +
  405 + value = str;
  406 + srs_verbose("amf0 read string data success. str=%s", str.c_str());
  407 +
  408 + return ret;
  409 +}
  410 +int srs_amf0_write_utf8(SrsStream* stream, std::string value)
  411 +{
  412 + int ret = ERROR_SUCCESS;
  413 +
  414 + // len
  415 + if (!stream->require(2)) {
  416 + ret = ERROR_RTMP_AMF0_ENCODE;
  417 + srs_error("amf0 write string length failed. ret=%d", ret);
  418 + return ret;
  419 + }
  420 + stream->write_2bytes(value.length());
  421 + srs_verbose("amf0 write string length success. len=%d", (int)value.length());
  422 +
  423 + // empty string
  424 + if (value.length() <= 0) {
  425 + srs_verbose("amf0 write empty string. ret=%d", ret);
  426 + return ret;
  427 + }
  428 +
  429 + // data
  430 + if (!stream->require(value.length())) {
  431 + ret = ERROR_RTMP_AMF0_ENCODE;
  432 + srs_error("amf0 write string data failed. ret=%d", ret);
  433 + return ret;
  434 + }
  435 + stream->write_string(value);
  436 + srs_verbose("amf0 write string data success. str=%s", value.c_str());
  437 +
  438 + return ret;
  439 +}
  440 +
  441 +int srs_amf0_read_string(SrsStream* stream, std::string& value)
  442 +{
  443 + int ret = ERROR_SUCCESS;
  444 +
  445 + // marker
  446 + if (!stream->require(1)) {
  447 + ret = ERROR_RTMP_AMF0_DECODE;
  448 + srs_error("amf0 read string marker failed. ret=%d", ret);
  449 + return ret;
  450 + }
  451 +
  452 + char marker = stream->read_1bytes();
  453 + if (marker != RTMP_AMF0_String) {
  454 + ret = ERROR_RTMP_AMF0_DECODE;
  455 + srs_error("amf0 check string marker failed. "
  456 + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_String, ret);
  457 + return ret;
  458 + }
  459 + srs_verbose("amf0 read string marker success");
  460 +
  461 + return srs_amf0_read_utf8(stream, value);
  462 +}
  463 +
  464 +int srs_amf0_write_string(SrsStream* stream, std::string value)
  465 +{
  466 + int ret = ERROR_SUCCESS;
  467 +
  468 + // marker
  469 + if (!stream->require(1)) {
  470 + ret = ERROR_RTMP_AMF0_ENCODE;
  471 + srs_error("amf0 write string marker failed. ret=%d", ret);
  472 + return ret;
  473 + }
  474 +
  475 + stream->write_1bytes(RTMP_AMF0_String);
  476 + srs_verbose("amf0 write string marker success");
  477 +
  478 + return srs_amf0_write_utf8(stream, value);
  479 +}
  480 +
  481 +int srs_amf0_read_boolean(SrsStream* stream, bool& value)
  482 +{
  483 + int ret = ERROR_SUCCESS;
  484 +
  485 + // marker
  486 + if (!stream->require(1)) {
  487 + ret = ERROR_RTMP_AMF0_DECODE;
  488 + srs_error("amf0 read bool marker failed. ret=%d", ret);
  489 + return ret;
  490 + }
  491 +
  492 + char marker = stream->read_1bytes();
  493 + if (marker != RTMP_AMF0_Boolean) {
  494 + ret = ERROR_RTMP_AMF0_DECODE;
  495 + srs_error("amf0 check bool marker failed. "
  496 + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Boolean, ret);
  497 + return ret;
  498 + }
  499 + srs_verbose("amf0 read bool marker success");
  500 +
  501 + // value
  502 + if (!stream->require(1)) {
  503 + ret = ERROR_RTMP_AMF0_DECODE;
  504 + srs_error("amf0 read bool value failed. ret=%d", ret);
  505 + return ret;
  506 + }
  507 +
  508 + if (stream->read_1bytes() == 0) {
  509 + value = false;
  510 + } else {
  511 + value = true;
  512 + }
  513 +
  514 + srs_verbose("amf0 read bool value success. value=%d", value);
  515 +
  516 + return ret;
  517 +}
  518 +int srs_amf0_write_boolean(SrsStream* stream, bool value)
  519 +{
  520 + int ret = ERROR_SUCCESS;
  521 +
  522 + // marker
  523 + if (!stream->require(1)) {
  524 + ret = ERROR_RTMP_AMF0_ENCODE;
  525 + srs_error("amf0 write bool marker failed. ret=%d", ret);
  526 + return ret;
  527 + }
  528 + stream->write_1bytes(RTMP_AMF0_Boolean);
  529 + srs_verbose("amf0 write bool marker success");
  530 +
  531 + // value
  532 + if (!stream->require(1)) {
  533 + ret = ERROR_RTMP_AMF0_ENCODE;
  534 + srs_error("amf0 write bool value failed. ret=%d", ret);
  535 + return ret;
  536 + }
  537 +
  538 + if (value) {
  539 + stream->write_1bytes(0x01);
  540 + } else {
  541 + stream->write_1bytes(0x00);
  542 + }
  543 +
  544 + srs_verbose("amf0 write bool value success. value=%d", value);
  545 +
  546 + return ret;
  547 +}
  548 +
  549 +int srs_amf0_read_number(SrsStream* stream, double& value)
  550 +{
  551 + int ret = ERROR_SUCCESS;
  552 +
  553 + // marker
  554 + if (!stream->require(1)) {
  555 + ret = ERROR_RTMP_AMF0_DECODE;
  556 + srs_error("amf0 read number marker failed. ret=%d", ret);
  557 + return ret;
  558 + }
  559 +
  560 + char marker = stream->read_1bytes();
  561 + if (marker != RTMP_AMF0_Number) {
  562 + ret = ERROR_RTMP_AMF0_DECODE;
  563 + srs_error("amf0 check number marker failed. "
  564 + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Number, ret);
  565 + return ret;
  566 + }
  567 + srs_verbose("amf0 read number marker success");
  568 +
  569 + // value
  570 + if (!stream->require(8)) {
  571 + ret = ERROR_RTMP_AMF0_DECODE;
  572 + srs_error("amf0 read number value failed. ret=%d", ret);
  573 + return ret;
  574 + }
  575 +
  576 + int64_t temp = stream->read_8bytes();
  577 + memcpy(&value, &temp, 8);
  578 +
  579 + srs_verbose("amf0 read number value success. value=%.2f", value);
  580 +
  581 + return ret;
  582 +}
  583 +int srs_amf0_write_number(SrsStream* stream, double value)
  584 +{
  585 + int ret = ERROR_SUCCESS;
  586 +
  587 + // marker
  588 + if (!stream->require(1)) {
  589 + ret = ERROR_RTMP_AMF0_ENCODE;
  590 + srs_error("amf0 write number marker failed. ret=%d", ret);
  591 + return ret;
  592 + }
  593 +
  594 + stream->write_1bytes(RTMP_AMF0_Number);
  595 + srs_verbose("amf0 write number marker success");
  596 +
  597 + // value
  598 + if (!stream->require(8)) {
  599 + ret = ERROR_RTMP_AMF0_ENCODE;
  600 + srs_error("amf0 write number value failed. ret=%d", ret);
  601 + return ret;
  602 + }
  603 +
  604 + int64_t temp = 0x00;
  605 + memcpy(&temp, &value, 8);
  606 + stream->write_8bytes(temp);
  607 +
  608 + srs_verbose("amf0 write number value success. value=%.2f", value);
  609 +
  610 + return ret;
  611 +}
  612 +
  613 +int srs_amf0_read_null(SrsStream* stream)
  614 +{
  615 + int ret = ERROR_SUCCESS;
  616 +
  617 + // marker
  618 + if (!stream->require(1)) {
  619 + ret = ERROR_RTMP_AMF0_DECODE;
  620 + srs_error("amf0 read null marker failed. ret=%d", ret);
  621 + return ret;
  622 + }
  623 +
  624 + char marker = stream->read_1bytes();
  625 + if (marker != RTMP_AMF0_Null) {
  626 + ret = ERROR_RTMP_AMF0_DECODE;
  627 + srs_error("amf0 check null marker failed. "
  628 + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Null, ret);
  629 + return ret;
  630 + }
  631 + srs_verbose("amf0 read null success");
  632 +
  633 + return ret;
  634 +}
  635 +int srs_amf0_write_null(SrsStream* stream)
  636 +{
  637 + int ret = ERROR_SUCCESS;
  638 +
  639 + // marker
  640 + if (!stream->require(1)) {
  641 + ret = ERROR_RTMP_AMF0_ENCODE;
  642 + srs_error("amf0 write null marker failed. ret=%d", ret);
  643 + return ret;
  644 + }
  645 +
  646 + stream->write_1bytes(RTMP_AMF0_Null);
  647 + srs_verbose("amf0 write null marker success");
  648 +
  649 + return ret;
  650 +}
  651 +
  652 +int srs_amf0_read_undefined(SrsStream* stream)
  653 +{
  654 + int ret = ERROR_SUCCESS;
  655 +
  656 + // marker
  657 + if (!stream->require(1)) {
  658 + ret = ERROR_RTMP_AMF0_DECODE;
  659 + srs_error("amf0 read undefined marker failed. ret=%d", ret);
  660 + return ret;
  661 + }
  662 +
  663 + char marker = stream->read_1bytes();
  664 + if (marker != RTMP_AMF0_Undefined) {
  665 + ret = ERROR_RTMP_AMF0_DECODE;
  666 + srs_error("amf0 check undefined marker failed. "
  667 + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Undefined, ret);
  668 + return ret;
  669 + }
  670 + srs_verbose("amf0 read undefined success");
  671 +
  672 + return ret;
  673 +}
  674 +int srs_amf0_write_undefined(SrsStream* stream)
  675 +{
  676 + int ret = ERROR_SUCCESS;
  677 +
  678 + // marker
  679 + if (!stream->require(1)) {
  680 + ret = ERROR_RTMP_AMF0_ENCODE;
  681 + srs_error("amf0 write undefined marker failed. ret=%d", ret);
  682 + return ret;
  683 + }
  684 +
  685 + stream->write_1bytes(RTMP_AMF0_Undefined);
  686 + srs_verbose("amf0 write undefined marker success");
  687 +
  688 + return ret;
  689 +}
  690 +
  691 +int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
  692 +{
  693 + int ret = ERROR_SUCCESS;
  694 +
  695 + // marker
  696 + if (!stream->require(1)) {
  697 + ret = ERROR_RTMP_AMF0_DECODE;
  698 + srs_error("amf0 read any marker failed. ret=%d", ret);
  699 + return ret;
  700 + }
  701 +
  702 + char marker = stream->read_1bytes();
  703 + srs_verbose("amf0 any marker success");
  704 +
  705 + // backward the 1byte marker.
  706 + stream->skip(-1);
  707 +
  708 + switch (marker) {
  709 + case RTMP_AMF0_String: {
  710 + std::string data;
  711 + if ((ret = srs_amf0_read_string(stream, data)) != ERROR_SUCCESS) {
  712 + return ret;
  713 + }
  714 + value = new SrsAmf0String();
  715 + srs_amf0_convert<SrsAmf0String>(value)->value = data;
  716 + return ret;
  717 + }
  718 + case RTMP_AMF0_Boolean: {
  719 + bool data;
  720 + if ((ret = srs_amf0_read_boolean(stream, data)) != ERROR_SUCCESS) {
  721 + return ret;
  722 + }
  723 + value = new SrsAmf0Boolean();
  724 + srs_amf0_convert<SrsAmf0Boolean>(value)->value = data;
  725 + return ret;
  726 + }
  727 + case RTMP_AMF0_Number: {
  728 + double data;
  729 + if ((ret = srs_amf0_read_number(stream, data)) != ERROR_SUCCESS) {
  730 + return ret;
  731 + }
  732 + value = new SrsAmf0Number();
  733 + srs_amf0_convert<SrsAmf0Number>(value)->value = data;
  734 + return ret;
  735 + }
  736 + case RTMP_AMF0_Null: {
  737 + stream->skip(1);
  738 + value = new SrsAmf0Null();
  739 + return ret;
  740 + }
  741 + case RTMP_AMF0_Undefined: {
  742 + stream->skip(1);
  743 + value = new SrsAmf0Undefined();
  744 + return ret;
  745 + }
  746 + case RTMP_AMF0_ObjectEnd: {
  747 + SrsAmf0ObjectEOF* p = NULL;
  748 + if ((ret = srs_amf0_read_object_eof(stream, p)) != ERROR_SUCCESS) {
  749 + return ret;
  750 + }
  751 + value = p;
  752 + return ret;
  753 + }
  754 + case RTMP_AMF0_Object: {
  755 + SrsAmf0Object* p = NULL;
  756 + if ((ret = srs_amf0_read_object(stream, p)) != ERROR_SUCCESS) {
  757 + return ret;
  758 + }
  759 + value = p;
  760 + return ret;
  761 + }
  762 + case RTMP_AMF0_EcmaArray: {
  763 + SrsASrsAmf0EcmaArray* p = NULL;
  764 + if ((ret = srs_amf0_read_ecma_array(stream, p)) != ERROR_SUCCESS) {
  765 + return ret;
  766 + }
  767 + value = p;
  768 + return ret;
  769 + }
  770 + case RTMP_AMF0_Invalid:
  771 + default: {
  772 + ret = ERROR_RTMP_AMF0_INVALID;
  773 + srs_error("invalid amf0 message type. marker=%#x, ret=%d", marker, ret);
  774 + return ret;
  775 + }
  776 + }
  777 +
  778 + return ret;
  779 +}
  780 +int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
  781 +{
  782 + int ret = ERROR_SUCCESS;
  783 +
  784 + srs_assert(value != NULL);
  785 +
  786 + switch (value->marker) {
  787 + case RTMP_AMF0_String: {
  788 + std::string data = srs_amf0_convert<SrsAmf0String>(value)->value;
  789 + return srs_amf0_write_string(stream, data);
  790 + }
  791 + case RTMP_AMF0_Boolean: {
  792 + bool data = srs_amf0_convert<SrsAmf0Boolean>(value)->value;
  793 + return srs_amf0_write_boolean(stream, data);
  794 + }
  795 + case RTMP_AMF0_Number: {
  796 + double data = srs_amf0_convert<SrsAmf0Number>(value)->value;
  797 + return srs_amf0_write_number(stream, data);
  798 + }
  799 + case RTMP_AMF0_Null: {
  800 + return srs_amf0_write_null(stream);
  801 + }
  802 + case RTMP_AMF0_Undefined: {
  803 + return srs_amf0_write_undefined(stream);
  804 + }
  805 + case RTMP_AMF0_ObjectEnd: {
  806 + SrsAmf0ObjectEOF* p = srs_amf0_convert<SrsAmf0ObjectEOF>(value);
  807 + return srs_amf0_write_object_eof(stream, p);
  808 + }
  809 + case RTMP_AMF0_Object: {
  810 + SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);
  811 + return srs_amf0_write_object(stream, p);
  812 + }
  813 + case RTMP_AMF0_EcmaArray: {
  814 + SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value);
  815 + return srs_amf0_write_ecma_array(stream, p);
  816 + }
  817 + case RTMP_AMF0_Invalid:
  818 + default: {
  819 + ret = ERROR_RTMP_AMF0_INVALID;
  820 + srs_error("invalid amf0 message type. marker=%#x, ret=%d", value->marker, ret);
  821 + return ret;
  822 + }
  823 + }
  824 +
  825 + return ret;
  826 +}
  827 +int srs_amf0_get_any_size(SrsAmf0Any* value)
  828 +{
  829 + if (!value) {
  830 + return 0;
  831 + }
  832 +
  833 + int size = 0;
  834 +
  835 + switch (value->marker) {
  836 + case RTMP_AMF0_String: {
  837 + SrsAmf0String* p = srs_amf0_convert<SrsAmf0String>(value);
  838 + size += srs_amf0_get_string_size(p->value);
  839 + break;
  840 + }
  841 + case RTMP_AMF0_Boolean: {
  842 + size += srs_amf0_get_boolean_size();
  843 + break;
  844 + }
  845 + case RTMP_AMF0_Number: {
  846 + size += srs_amf0_get_number_size();
  847 + break;
  848 + }
  849 + case RTMP_AMF0_Null: {
  850 + size += srs_amf0_get_null_size();
  851 + break;
  852 + }
  853 + case RTMP_AMF0_Undefined: {
  854 + size += srs_amf0_get_undefined_size();
  855 + break;
  856 + }
  857 + case RTMP_AMF0_ObjectEnd: {
  858 + size += srs_amf0_get_object_eof_size();
  859 + break;
  860 + }
  861 + case RTMP_AMF0_Object: {
  862 + SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);
  863 + size += srs_amf0_get_object_size(p);
  864 + break;
  865 + }
  866 + case RTMP_AMF0_EcmaArray: {
  867 + SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value);
  868 + size += srs_amf0_get_ecma_array_size(p);
  869 + break;
  870 + }
  871 + default: {
  872 + // TOOD: other AMF0 types.
  873 + srs_warn("ignore unkown AMF0 type size.");
  874 + break;
  875 + }
  876 + }
  877 +
  878 + return size;
  879 +}
  880 +
  881 +int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value)
  882 +{
  883 + int ret = ERROR_SUCCESS;
  884 +
  885 + // auto skip -2 to read the object eof.
  886 + srs_assert(stream->pos() >= 2);
  887 + stream->skip(-2);
  888 +
  889 + // value
  890 + if (!stream->require(2)) {
  891 + ret = ERROR_RTMP_AMF0_DECODE;
  892 + srs_error("amf0 read object eof value failed. ret=%d", ret);
  893 + return ret;
  894 + }
  895 + int16_t temp = stream->read_2bytes();
  896 + if (temp != 0x00) {
  897 + ret = ERROR_RTMP_AMF0_DECODE;
  898 + srs_error("amf0 read object eof value check failed. "
  899 + "must be 0x00, actual is %#x, ret=%d", temp, ret);
  900 + return ret;
  901 + }
  902 +
  903 + // marker
  904 + if (!stream->require(1)) {
  905 + ret = ERROR_RTMP_AMF0_DECODE;
  906 + srs_error("amf0 read object eof marker failed. ret=%d", ret);
  907 + return ret;
  908 + }
  909 +
  910 + char marker = stream->read_1bytes();
  911 + if (marker != RTMP_AMF0_ObjectEnd) {
  912 + ret = ERROR_RTMP_AMF0_DECODE;
  913 + srs_error("amf0 check object eof marker failed. "
  914 + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_ObjectEnd, ret);
  915 + return ret;
  916 + }
  917 + srs_verbose("amf0 read object eof marker success");
  918 +
  919 + value = new SrsAmf0ObjectEOF();
  920 + srs_verbose("amf0 read object eof success");
  921 +
  922 + return ret;
  923 +}
  924 +int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF* value)
  925 +{
  926 + int ret = ERROR_SUCCESS;
  927 +
  928 + srs_assert(value != NULL);
  929 +
  930 + // value
  931 + if (!stream->require(2)) {
  932 + ret = ERROR_RTMP_AMF0_ENCODE;
  933 + srs_error("amf0 write object eof value failed. ret=%d", ret);
  934 + return ret;
  935 + }
  936 + stream->write_2bytes(0x00);
  937 + srs_verbose("amf0 write object eof value success");
  938 +
  939 + // marker
  940 + if (!stream->require(1)) {
  941 + ret = ERROR_RTMP_AMF0_ENCODE;
  942 + srs_error("amf0 write object eof marker failed. ret=%d", ret);
  943 + return ret;
  944 + }
  945 +
  946 + stream->write_1bytes(RTMP_AMF0_ObjectEnd);
  947 +
  948 + srs_verbose("amf0 read object eof success");
  949 +
  950 + return ret;
  951 +}
  952 +
  953 +int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value)
  954 +{
  955 + int ret = ERROR_SUCCESS;
  956 +
  957 + // marker
  958 + if (!stream->require(1)) {
  959 + ret = ERROR_RTMP_AMF0_DECODE;
  960 + srs_error("amf0 read object marker failed. ret=%d", ret);
  961 + return ret;
  962 + }
  963 +
  964 + char marker = stream->read_1bytes();
  965 + if (marker != RTMP_AMF0_Object) {
  966 + ret = ERROR_RTMP_AMF0_DECODE;
  967 + srs_error("amf0 check object marker failed. "
  968 + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
  969 + return ret;
  970 + }
  971 + srs_verbose("amf0 read object marker success");
  972 +
  973 + // value
  974 + value = new SrsAmf0Object();
  975 +
  976 + while (!stream->empty()) {
  977 + // property-name: utf8 string
  978 + std::string property_name;
  979 + if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {
  980 + srs_error("amf0 object read property name failed. ret=%d", ret);
  981 + return ret;
  982 + }
  983 + // property-value: any
  984 + SrsAmf0Any* property_value = NULL;
  985 + if ((ret = srs_amf0_read_any(stream, property_value)) != ERROR_SUCCESS) {
  986 + srs_error("amf0 object read property_value failed. "
  987 + "name=%s, ret=%d", property_name.c_str(), ret);
  988 + return ret;
  989 + }
  990 +
  991 + // AMF0 Object EOF.
  992 + if (property_name.empty() || !property_value || property_value->is_object_eof()) {
  993 + if (property_value) {
  994 + srs_freep(property_value);
  995 + }
  996 + srs_info("amf0 read object EOF.");
  997 + break;
  998 + }
  999 +
  1000 + // add property
  1001 + value->set(property_name, property_value);
  1002 + }
  1003 +
  1004 + return ret;
  1005 +}
  1006 +int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value)
  1007 +{
  1008 + int ret = ERROR_SUCCESS;
  1009 +
  1010 + srs_assert(value != NULL);
  1011 +
  1012 + // marker
  1013 + if (!stream->require(1)) {
  1014 + ret = ERROR_RTMP_AMF0_ENCODE;
  1015 + srs_error("amf0 write object marker failed. ret=%d", ret);
  1016 + return ret;
  1017 + }
  1018 +
  1019 + stream->write_1bytes(RTMP_AMF0_Object);
  1020 + srs_verbose("amf0 write object marker success");
  1021 +
  1022 + // value
  1023 + for (int i = 0; i < value->size(); i++) {
  1024 + std::string name = value->key_at(i);
  1025 + SrsAmf0Any* any = value->value_at(i);
  1026 +
  1027 + if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) {
  1028 + srs_error("write object property name failed. ret=%d", ret);
  1029 + return ret;
  1030 + }
  1031 +
  1032 + if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {
  1033 + srs_error("write object property value failed. ret=%d", ret);
  1034 + return ret;
  1035 + }
  1036 +
  1037 + srs_verbose("write amf0 property success. name=%s", name.c_str());
  1038 + }
  1039 +
  1040 + if ((ret = srs_amf0_write_object_eof(stream, &value->eof)) != ERROR_SUCCESS) {
  1041 + srs_error("write object eof failed. ret=%d", ret);
  1042 + return ret;
  1043 + }
  1044 +
  1045 + srs_verbose("write amf0 object success.");
  1046 +
  1047 + return ret;
  1048 +}
  1049 +
  1050 +int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value)
  1051 +{
  1052 + int ret = ERROR_SUCCESS;
  1053 +
  1054 + // marker
  1055 + if (!stream->require(1)) {
  1056 + ret = ERROR_RTMP_AMF0_DECODE;
  1057 + srs_error("amf0 read ecma_array marker failed. ret=%d", ret);
  1058 + return ret;
  1059 + }
  1060 +
  1061 + char marker = stream->read_1bytes();
  1062 + if (marker != RTMP_AMF0_EcmaArray) {
  1063 + ret = ERROR_RTMP_AMF0_DECODE;
  1064 + srs_error("amf0 check ecma_array marker failed. "
  1065 + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
  1066 + return ret;
  1067 + }
  1068 + srs_verbose("amf0 read ecma_array marker success");
  1069 +
  1070 + // count
  1071 + if (!stream->require(4)) {
  1072 + ret = ERROR_RTMP_AMF0_DECODE;
  1073 + srs_error("amf0 read ecma_array count failed. ret=%d", ret);
  1074 + return ret;
  1075 + }
  1076 +
  1077 + int32_t count = stream->read_4bytes();
  1078 + srs_verbose("amf0 read ecma_array count success. count=%d", count);
  1079 +
  1080 + // value
  1081 + value = new SrsASrsAmf0EcmaArray();
  1082 + value->count = count;
  1083 +
  1084 + while (!stream->empty()) {
  1085 + // property-name: utf8 string
  1086 + std::string property_name;
  1087 + if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {
  1088 + srs_error("amf0 ecma_array read property name failed. ret=%d", ret);
  1089 + return ret;
  1090 + }
  1091 + // property-value: any
  1092 + SrsAmf0Any* property_value = NULL;
  1093 + if ((ret = srs_amf0_read_any(stream, property_value)) != ERROR_SUCCESS) {
  1094 + srs_error("amf0 ecma_array read property_value failed. "
  1095 + "name=%s, ret=%d", property_name.c_str(), ret);
  1096 + return ret;
  1097 + }
  1098 +
  1099 + // AMF0 Object EOF.
  1100 + if (property_name.empty() || !property_value || property_value->is_object_eof()) {
  1101 + if (property_value) {
  1102 + srs_freep(property_value);
  1103 + }
  1104 + srs_info("amf0 read ecma_array EOF.");
  1105 + break;
  1106 + }
  1107 +
  1108 + // add property
  1109 + value->set(property_name, property_value);
  1110 + }
  1111 +
  1112 + return ret;
  1113 +}
  1114 +int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value)
  1115 +{
  1116 + int ret = ERROR_SUCCESS;
  1117 +
  1118 + srs_assert(value != NULL);
  1119 +
  1120 + // marker
  1121 + if (!stream->require(1)) {
  1122 + ret = ERROR_RTMP_AMF0_ENCODE;
  1123 + srs_error("amf0 write ecma_array marker failed. ret=%d", ret);
  1124 + return ret;
  1125 + }
  1126 +
  1127 + stream->write_1bytes(RTMP_AMF0_EcmaArray);
  1128 + srs_verbose("amf0 write ecma_array marker success");
  1129 +
  1130 + // count
  1131 + if (!stream->require(4)) {
  1132 + ret = ERROR_RTMP_AMF0_ENCODE;
  1133 + srs_error("amf0 write ecma_array count failed. ret=%d", ret);
  1134 + return ret;
  1135 + }
  1136 +
  1137 + stream->write_4bytes(value->count);
  1138 + srs_verbose("amf0 write ecma_array count success. count=%d", value->count);
  1139 +
  1140 + // value
  1141 + for (int i = 0; i < value->size(); i++) {
  1142 + std::string name = value->key_at(i);
  1143 + SrsAmf0Any* any = value->value_at(i);
  1144 +
  1145 + if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) {
  1146 + srs_error("write ecma_array property name failed. ret=%d", ret);
  1147 + return ret;
  1148 + }
  1149 +
  1150 + if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {
  1151 + srs_error("write ecma_array property value failed. ret=%d", ret);
  1152 + return ret;
  1153 + }
  1154 +
  1155 + srs_verbose("write amf0 property success. name=%s", name.c_str());
  1156 + }
  1157 +
  1158 + if ((ret = srs_amf0_write_object_eof(stream, &value->eof)) != ERROR_SUCCESS) {
  1159 + srs_error("write ecma_array eof failed. ret=%d", ret);
  1160 + return ret;
  1161 + }
  1162 +
  1163 + srs_verbose("write ecma_array object success.");
  1164 +
  1165 + return ret;
  1166 +}
  1167 +
  1168 +int srs_amf0_get_utf8_size(std::string value)
  1169 +{
  1170 + return 2 + value.length();
  1171 +}
  1172 +
  1173 +int srs_amf0_get_string_size(std::string value)
  1174 +{
  1175 + return 1 + srs_amf0_get_utf8_size(value);
  1176 +}
  1177 +
  1178 +int srs_amf0_get_number_size()
  1179 +{
  1180 + return 1 + 8;
  1181 +}
  1182 +
  1183 +int srs_amf0_get_null_size()
  1184 +{
  1185 + return 1;
  1186 +}
  1187 +
  1188 +int srs_amf0_get_undefined_size()
  1189 +{
  1190 + return 1;
  1191 +}
  1192 +
  1193 +int srs_amf0_get_boolean_size()
  1194 +{
  1195 + return 1 + 1;
  1196 +}
  1197 +
  1198 +int srs_amf0_get_object_size(SrsAmf0Object* obj)
  1199 +{
  1200 + if (!obj) {
  1201 + return 0;
  1202 + }
  1203 +
  1204 + int size = 1;
  1205 +
  1206 + for (int i = 0; i < obj->size(); i++){
  1207 + std::string name = obj->key_at(i);
  1208 + SrsAmf0Any* value = obj->value_at(i);
  1209 +
  1210 + size += srs_amf0_get_utf8_size(name);
  1211 + size += srs_amf0_get_any_size(value);
  1212 + }
  1213 +
  1214 + size += srs_amf0_get_object_eof_size();
  1215 +
  1216 + return size;
  1217 +}
  1218 +
  1219 +int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr)
  1220 +{
  1221 + if (!arr) {
  1222 + return 0;
  1223 + }
  1224 +
  1225 + int size = 1 + 4;
  1226 +
  1227 + for (int i = 0; i < arr->size(); i++){
  1228 + std::string name = arr->key_at(i);
  1229 + SrsAmf0Any* value = arr->value_at(i);
  1230 +
  1231 + size += srs_amf0_get_utf8_size(name);
  1232 + size += srs_amf0_get_any_size(value);
  1233 + }
  1234 +
  1235 + size += srs_amf0_get_object_eof_size();
  1236 +
  1237 + return size;
  1238 +}
  1239 +
  1240 +int srs_amf0_get_object_eof_size()
  1241 +{
  1242 + return 2 + 1;
  1243 +}
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#ifndef SRS_CORE_AMF0_HPP  
25 -#define SRS_CORE_AMF0_HPP  
26 -  
27 -/*  
28 -#include <srs_core_amf0.hpp>  
29 -*/  
30 -  
31 -#include <srs_core.hpp>  
32 -  
33 -#include <string>  
34 -#include <vector>  
35 -  
36 -class SrsStream;  
37 -class SrsAmf0Object;  
38 -  
39 -/**  
40 -* any amf0 value.  
41 -* 2.1 Types Overview  
42 -* value-type = number-type | boolean-type | string-type | object-type  
43 -* | null-marker | undefined-marker | reference-type | ecma-array-type  
44 -* | strict-array-type | date-type | long-string-type | xml-document-type  
45 -* | typed-object-type  
46 -*/  
47 -struct SrsAmf0Any  
48 -{  
49 - char marker;  
50 -  
51 - SrsAmf0Any();  
52 - virtual ~SrsAmf0Any();  
53 -  
54 - virtual bool is_string();  
55 - virtual bool is_boolean();  
56 - virtual bool is_number();  
57 - virtual bool is_null();  
58 - virtual bool is_undefined();  
59 - virtual bool is_object();  
60 - virtual bool is_object_eof();  
61 - virtual bool is_ecma_array();  
62 -};  
63 -  
64 -/**  
65 -* read amf0 string from stream.  
66 -* 2.4 String Type  
67 -* string-type = string-marker UTF-8  
68 -* @return default value is empty string.  
69 -*/  
70 -struct SrsAmf0String : public SrsAmf0Any  
71 -{  
72 - std::string value;  
73 -  
74 - SrsAmf0String(const char* _value = NULL);  
75 - virtual ~SrsAmf0String();  
76 -};  
77 -  
78 -/**  
79 -* read amf0 boolean from stream.  
80 -* 2.4 String Type  
81 -* boolean-type = boolean-marker U8  
82 -* 0 is false, <> 0 is true  
83 -* @return default value is false.  
84 -*/  
85 -struct SrsAmf0Boolean : public SrsAmf0Any  
86 -{  
87 - bool value;  
88 -  
89 - SrsAmf0Boolean(bool _value = false);  
90 - virtual ~SrsAmf0Boolean();  
91 -};  
92 -  
93 -/**  
94 -* read amf0 number from stream.  
95 -* 2.2 Number Type  
96 -* number-type = number-marker DOUBLE  
97 -* @return default value is 0.  
98 -*/  
99 -struct SrsAmf0Number : public SrsAmf0Any  
100 -{  
101 - double value;  
102 -  
103 - SrsAmf0Number(double _value = 0.0);  
104 - virtual ~SrsAmf0Number();  
105 -};  
106 -  
107 -/**  
108 -* read amf0 null from stream.  
109 -* 2.7 null Type  
110 -* null-type = null-marker  
111 -*/  
112 -struct SrsAmf0Null : public SrsAmf0Any  
113 -{  
114 - SrsAmf0Null();  
115 - virtual ~SrsAmf0Null();  
116 -};  
117 -  
118 -/**  
119 -* read amf0 undefined from stream.  
120 -* 2.8 undefined Type  
121 -* undefined-type = undefined-marker  
122 -*/  
123 -struct SrsAmf0Undefined : public SrsAmf0Any  
124 -{  
125 - SrsAmf0Undefined();  
126 - virtual ~SrsAmf0Undefined();  
127 -};  
128 -  
129 -/**  
130 -* 2.11 Object End Type  
131 -* object-end-type = UTF-8-empty object-end-marker  
132 -* 0x00 0x00 0x09  
133 -*/  
134 -struct SrsAmf0ObjectEOF : public SrsAmf0Any  
135 -{  
136 - int16_t utf8_empty;  
137 -  
138 - SrsAmf0ObjectEOF();  
139 - virtual ~SrsAmf0ObjectEOF();  
140 -};  
141 -  
142 -/**  
143 -* to ensure in inserted order.  
144 -* for the FMLE will crash when AMF0Object is not ordered by inserted,  
145 -* if ordered in map, the string compare order, the FMLE will creash when  
146 -* get the response of connect app.  
147 -*/  
148 -struct SrsUnSortedHashtable  
149 -{  
150 -private:  
151 - typedef std::pair<std::string, SrsAmf0Any*> SrsObjectPropertyType;  
152 - std::vector<SrsObjectPropertyType> properties;  
153 -public:  
154 - SrsUnSortedHashtable();  
155 - virtual ~SrsUnSortedHashtable();  
156 -  
157 - virtual int size();  
158 - virtual void clear();  
159 - virtual std::string key_at(int index);  
160 - virtual SrsAmf0Any* value_at(int index);  
161 - virtual void set(std::string key, SrsAmf0Any* value);  
162 -  
163 - virtual SrsAmf0Any* get_property(std::string name);  
164 - virtual SrsAmf0Any* ensure_property_string(std::string name);  
165 - virtual SrsAmf0Any* ensure_property_number(std::string name);  
166 -};  
167 -  
168 -/**  
169 -* 2.5 Object Type  
170 -* anonymous-object-type = object-marker *(object-property)  
171 -* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)  
172 -*/  
173 -struct SrsAmf0Object : public SrsAmf0Any  
174 -{  
175 -private:  
176 - SrsUnSortedHashtable properties;  
177 -public:  
178 - SrsAmf0ObjectEOF eof;  
179 -  
180 - SrsAmf0Object();  
181 - virtual ~SrsAmf0Object();  
182 -  
183 - virtual int size();  
184 - virtual std::string key_at(int index);  
185 - virtual SrsAmf0Any* value_at(int index);  
186 - virtual void set(std::string key, SrsAmf0Any* value);  
187 -  
188 - virtual SrsAmf0Any* get_property(std::string name);  
189 - virtual SrsAmf0Any* ensure_property_string(std::string name);  
190 - virtual SrsAmf0Any* ensure_property_number(std::string name);  
191 -};  
192 -  
193 -/**  
194 -* 2.10 ECMA Array Type  
195 -* ecma-array-type = associative-count *(object-property)  
196 -* associative-count = U32  
197 -* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)  
198 -*/  
199 -struct SrsASrsAmf0EcmaArray : public SrsAmf0Any  
200 -{  
201 -private:  
202 - SrsUnSortedHashtable properties;  
203 -public:  
204 - int32_t count;  
205 - SrsAmf0ObjectEOF eof;  
206 -  
207 - SrsASrsAmf0EcmaArray();  
208 - virtual ~SrsASrsAmf0EcmaArray();  
209 -  
210 - virtual int size();  
211 - virtual void clear();  
212 - virtual std::string key_at(int index);  
213 - virtual SrsAmf0Any* value_at(int index);  
214 - virtual void set(std::string key, SrsAmf0Any* value);  
215 -  
216 - virtual SrsAmf0Any* get_property(std::string name);  
217 - virtual SrsAmf0Any* ensure_property_string(std::string name);  
218 -};  
219 -  
220 -/**  
221 -* read amf0 utf8 string from stream.  
222 -* 1.3.1 Strings and UTF-8  
223 -* UTF-8 = U16 *(UTF8-char)  
224 -* UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4  
225 -* UTF8-1 = %x00-7F  
226 -* @remark only support UTF8-1 char.  
227 -*/  
228 -extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value);  
229 -extern int srs_amf0_write_utf8(SrsStream* stream, std::string value);  
230 -  
231 -/**  
232 -* read amf0 string from stream.  
233 -* 2.4 String Type  
234 -* string-type = string-marker UTF-8  
235 -*/  
236 -extern int srs_amf0_read_string(SrsStream* stream, std::string& value);  
237 -extern int srs_amf0_write_string(SrsStream* stream, std::string value);  
238 -  
239 -/**  
240 -* read amf0 boolean from stream.  
241 -* 2.4 String Type  
242 -* boolean-type = boolean-marker U8  
243 -* 0 is false, <> 0 is true  
244 -*/  
245 -extern int srs_amf0_read_boolean(SrsStream* stream, bool& value);  
246 -extern int srs_amf0_write_boolean(SrsStream* stream, bool value);  
247 -  
248 -/**  
249 -* read amf0 number from stream.  
250 -* 2.2 Number Type  
251 -* number-type = number-marker DOUBLE  
252 -*/  
253 -extern int srs_amf0_read_number(SrsStream* stream, double& value);  
254 -extern int srs_amf0_write_number(SrsStream* stream, double value);  
255 -  
256 -/**  
257 -* read amf0 null from stream.  
258 -* 2.7 null Type  
259 -* null-type = null-marker  
260 -*/  
261 -extern int srs_amf0_read_null(SrsStream* stream);  
262 -extern int srs_amf0_write_null(SrsStream* stream);  
263 -  
264 -/**  
265 -* read amf0 undefined from stream.  
266 -* 2.8 undefined Type  
267 -* undefined-type = undefined-marker  
268 -*/  
269 -extern int srs_amf0_read_undefined(SrsStream* stream);  
270 -extern int srs_amf0_write_undefined(SrsStream* stream);  
271 -  
272 -extern int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value);  
273 -  
274 -/**  
275 -* read amf0 object from stream.  
276 -* 2.5 Object Type  
277 -* anonymous-object-type = object-marker *(object-property)  
278 -* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)  
279 -*/  
280 -extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value);  
281 -extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value);  
282 -  
283 -/**  
284 -* read amf0 object from stream.  
285 -* 2.10 ECMA Array Type  
286 -* ecma-array-type = associative-count *(object-property)  
287 -* associative-count = U32  
288 -* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)  
289 -*/  
290 -extern int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value);  
291 -extern int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value);  
292 -  
293 -/**  
294 -* get amf0 objects size.  
295 -*/  
296 -extern int srs_amf0_get_utf8_size(std::string value);  
297 -extern int srs_amf0_get_string_size(std::string value);  
298 -extern int srs_amf0_get_number_size();  
299 -extern int srs_amf0_get_null_size();  
300 -extern int srs_amf0_get_undefined_size();  
301 -extern int srs_amf0_get_boolean_size();  
302 -extern int srs_amf0_get_object_size(SrsAmf0Object* obj);  
303 -extern int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr);  
304 -  
305 -/**  
306 -* convert the any to specified object.  
307 -* @return T*, the converted object. never NULL.  
308 -* @remark, user must ensure the current object type,  
309 -* or the covert will cause assert failed.  
310 -*/  
311 -template<class T>  
312 -T* srs_amf0_convert(SrsAmf0Any* any)  
313 -{  
314 - T* p = dynamic_cast<T*>(any);  
315 - srs_assert(p != NULL);  
316 - return p;  
317 -}  
318 - 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#ifndef SRS_CORE_AMF0_HPP
  25 +#define SRS_CORE_AMF0_HPP
  26 +
  27 +/*
  28 +#include <srs_core_amf0.hpp>
  29 +*/
  30 +
  31 +#include <srs_core.hpp>
  32 +
  33 +#include <string>
  34 +#include <vector>
  35 +
  36 +class SrsStream;
  37 +class SrsAmf0Object;
  38 +
  39 +/**
  40 +* any amf0 value.
  41 +* 2.1 Types Overview
  42 +* value-type = number-type | boolean-type | string-type | object-type
  43 +* | null-marker | undefined-marker | reference-type | ecma-array-type
  44 +* | strict-array-type | date-type | long-string-type | xml-document-type
  45 +* | typed-object-type
  46 +*/
  47 +struct SrsAmf0Any
  48 +{
  49 + char marker;
  50 +
  51 + SrsAmf0Any();
  52 + virtual ~SrsAmf0Any();
  53 +
  54 + virtual bool is_string();
  55 + virtual bool is_boolean();
  56 + virtual bool is_number();
  57 + virtual bool is_null();
  58 + virtual bool is_undefined();
  59 + virtual bool is_object();
  60 + virtual bool is_object_eof();
  61 + virtual bool is_ecma_array();
  62 +};
  63 +
  64 +/**
  65 +* read amf0 string from stream.
  66 +* 2.4 String Type
  67 +* string-type = string-marker UTF-8
  68 +* @return default value is empty string.
  69 +*/
  70 +struct SrsAmf0String : public SrsAmf0Any
  71 +{
  72 + std::string value;
  73 +
  74 + SrsAmf0String(const char* _value = NULL);
  75 + virtual ~SrsAmf0String();
  76 +};
  77 +
  78 +/**
  79 +* read amf0 boolean from stream.
  80 +* 2.4 String Type
  81 +* boolean-type = boolean-marker U8
  82 +* 0 is false, <> 0 is true
  83 +* @return default value is false.
  84 +*/
  85 +struct SrsAmf0Boolean : public SrsAmf0Any
  86 +{
  87 + bool value;
  88 +
  89 + SrsAmf0Boolean(bool _value = false);
  90 + virtual ~SrsAmf0Boolean();
  91 +};
  92 +
  93 +/**
  94 +* read amf0 number from stream.
  95 +* 2.2 Number Type
  96 +* number-type = number-marker DOUBLE
  97 +* @return default value is 0.
  98 +*/
  99 +struct SrsAmf0Number : public SrsAmf0Any
  100 +{
  101 + double value;
  102 +
  103 + SrsAmf0Number(double _value = 0.0);
  104 + virtual ~SrsAmf0Number();
  105 +};
  106 +
  107 +/**
  108 +* read amf0 null from stream.
  109 +* 2.7 null Type
  110 +* null-type = null-marker
  111 +*/
  112 +struct SrsAmf0Null : public SrsAmf0Any
  113 +{
  114 + SrsAmf0Null();
  115 + virtual ~SrsAmf0Null();
  116 +};
  117 +
  118 +/**
  119 +* read amf0 undefined from stream.
  120 +* 2.8 undefined Type
  121 +* undefined-type = undefined-marker
  122 +*/
  123 +struct SrsAmf0Undefined : public SrsAmf0Any
  124 +{
  125 + SrsAmf0Undefined();
  126 + virtual ~SrsAmf0Undefined();
  127 +};
  128 +
  129 +/**
  130 +* 2.11 Object End Type
  131 +* object-end-type = UTF-8-empty object-end-marker
  132 +* 0x00 0x00 0x09
  133 +*/
  134 +struct SrsAmf0ObjectEOF : public SrsAmf0Any
  135 +{
  136 + int16_t utf8_empty;
  137 +
  138 + SrsAmf0ObjectEOF();
  139 + virtual ~SrsAmf0ObjectEOF();
  140 +};
  141 +
  142 +/**
  143 +* to ensure in inserted order.
  144 +* for the FMLE will crash when AMF0Object is not ordered by inserted,
  145 +* if ordered in map, the string compare order, the FMLE will creash when
  146 +* get the response of connect app.
  147 +*/
  148 +struct SrsUnSortedHashtable
  149 +{
  150 +private:
  151 + typedef std::pair<std::string, SrsAmf0Any*> SrsObjectPropertyType;
  152 + std::vector<SrsObjectPropertyType> properties;
  153 +public:
  154 + SrsUnSortedHashtable();
  155 + virtual ~SrsUnSortedHashtable();
  156 +
  157 + virtual int size();
  158 + virtual void clear();
  159 + virtual std::string key_at(int index);
  160 + virtual SrsAmf0Any* value_at(int index);
  161 + virtual void set(std::string key, SrsAmf0Any* value);
  162 +
  163 + virtual SrsAmf0Any* get_property(std::string name);
  164 + virtual SrsAmf0Any* ensure_property_string(std::string name);
  165 + virtual SrsAmf0Any* ensure_property_number(std::string name);
  166 +};
  167 +
  168 +/**
  169 +* 2.5 Object Type
  170 +* anonymous-object-type = object-marker *(object-property)
  171 +* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
  172 +*/
  173 +struct SrsAmf0Object : public SrsAmf0Any
  174 +{
  175 +private:
  176 + SrsUnSortedHashtable properties;
  177 +public:
  178 + SrsAmf0ObjectEOF eof;
  179 +
  180 + SrsAmf0Object();
  181 + virtual ~SrsAmf0Object();
  182 +
  183 + virtual int size();
  184 + virtual std::string key_at(int index);
  185 + virtual SrsAmf0Any* value_at(int index);
  186 + virtual void set(std::string key, SrsAmf0Any* value);
  187 +
  188 + virtual SrsAmf0Any* get_property(std::string name);
  189 + virtual SrsAmf0Any* ensure_property_string(std::string name);
  190 + virtual SrsAmf0Any* ensure_property_number(std::string name);
  191 +};
  192 +
  193 +/**
  194 +* 2.10 ECMA Array Type
  195 +* ecma-array-type = associative-count *(object-property)
  196 +* associative-count = U32
  197 +* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
  198 +*/
  199 +struct SrsASrsAmf0EcmaArray : public SrsAmf0Any
  200 +{
  201 +private:
  202 + SrsUnSortedHashtable properties;
  203 +public:
  204 + int32_t count;
  205 + SrsAmf0ObjectEOF eof;
  206 +
  207 + SrsASrsAmf0EcmaArray();
  208 + virtual ~SrsASrsAmf0EcmaArray();
  209 +
  210 + virtual int size();
  211 + virtual void clear();
  212 + virtual std::string key_at(int index);
  213 + virtual SrsAmf0Any* value_at(int index);
  214 + virtual void set(std::string key, SrsAmf0Any* value);
  215 +
  216 + virtual SrsAmf0Any* get_property(std::string name);
  217 + virtual SrsAmf0Any* ensure_property_string(std::string name);
  218 +};
  219 +
  220 +/**
  221 +* read amf0 utf8 string from stream.
  222 +* 1.3.1 Strings and UTF-8
  223 +* UTF-8 = U16 *(UTF8-char)
  224 +* UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4
  225 +* UTF8-1 = %x00-7F
  226 +* @remark only support UTF8-1 char.
  227 +*/
  228 +extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value);
  229 +extern int srs_amf0_write_utf8(SrsStream* stream, std::string value);
  230 +
  231 +/**
  232 +* read amf0 string from stream.
  233 +* 2.4 String Type
  234 +* string-type = string-marker UTF-8
  235 +*/
  236 +extern int srs_amf0_read_string(SrsStream* stream, std::string& value);
  237 +extern int srs_amf0_write_string(SrsStream* stream, std::string value);
  238 +
  239 +/**
  240 +* read amf0 boolean from stream.
  241 +* 2.4 String Type
  242 +* boolean-type = boolean-marker U8
  243 +* 0 is false, <> 0 is true
  244 +*/
  245 +extern int srs_amf0_read_boolean(SrsStream* stream, bool& value);
  246 +extern int srs_amf0_write_boolean(SrsStream* stream, bool value);
  247 +
  248 +/**
  249 +* read amf0 number from stream.
  250 +* 2.2 Number Type
  251 +* number-type = number-marker DOUBLE
  252 +*/
  253 +extern int srs_amf0_read_number(SrsStream* stream, double& value);
  254 +extern int srs_amf0_write_number(SrsStream* stream, double value);
  255 +
  256 +/**
  257 +* read amf0 null from stream.
  258 +* 2.7 null Type
  259 +* null-type = null-marker
  260 +*/
  261 +extern int srs_amf0_read_null(SrsStream* stream);
  262 +extern int srs_amf0_write_null(SrsStream* stream);
  263 +
  264 +/**
  265 +* read amf0 undefined from stream.
  266 +* 2.8 undefined Type
  267 +* undefined-type = undefined-marker
  268 +*/
  269 +extern int srs_amf0_read_undefined(SrsStream* stream);
  270 +extern int srs_amf0_write_undefined(SrsStream* stream);
  271 +
  272 +extern int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value);
  273 +
  274 +/**
  275 +* read amf0 object from stream.
  276 +* 2.5 Object Type
  277 +* anonymous-object-type = object-marker *(object-property)
  278 +* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
  279 +*/
  280 +extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value);
  281 +extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value);
  282 +
  283 +/**
  284 +* read amf0 object from stream.
  285 +* 2.10 ECMA Array Type
  286 +* ecma-array-type = associative-count *(object-property)
  287 +* associative-count = U32
  288 +* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
  289 +*/
  290 +extern int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value);
  291 +extern int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value);
  292 +
  293 +/**
  294 +* get amf0 objects size.
  295 +*/
  296 +extern int srs_amf0_get_utf8_size(std::string value);
  297 +extern int srs_amf0_get_string_size(std::string value);
  298 +extern int srs_amf0_get_number_size();
  299 +extern int srs_amf0_get_null_size();
  300 +extern int srs_amf0_get_undefined_size();
  301 +extern int srs_amf0_get_boolean_size();
  302 +extern int srs_amf0_get_object_size(SrsAmf0Object* obj);
  303 +extern int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr);
  304 +
  305 +/**
  306 +* convert the any to specified object.
  307 +* @return T*, the converted object. never NULL.
  308 +* @remark, user must ensure the current object type,
  309 +* or the covert will cause assert failed.
  310 +*/
  311 +template<class T>
  312 +T* srs_amf0_convert(SrsAmf0Any* any)
  313 +{
  314 + T* p = dynamic_cast<T*>(any);
  315 + srs_assert(p != NULL);
  316 + return p;
  317 +}
  318 +
319 #endif 319 #endif
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#include <srs_core_autofree.hpp> 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_autofree.hpp>
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#ifndef SRS_CORE_AUTO_FREE_HPP  
25 -#define SRS_CORE_AUTO_FREE_HPP  
26 -  
27 -/*  
28 -#include <srs_core_autofree.hpp>  
29 -*/  
30 -  
31 -#include <srs_core.hpp>  
32 -  
33 -/**  
34 -* auto free the instance in the current scope.  
35 -*/  
36 -#define SrsAutoFree(className, instance, is_array) \  
37 - __SrsAutoFree<className> _auto_free_##instance(&instance, is_array)  
38 -  
39 -template<class T>  
40 -class __SrsAutoFree  
41 -{  
42 -private:  
43 - T** ptr;  
44 - bool is_array;  
45 -public:  
46 - /**  
47 - * auto delete the ptr.  
48 - * @is_array a bool value indicates whether the ptr is a array.  
49 - */  
50 - __SrsAutoFree(T** _ptr, bool _is_array){  
51 - ptr = _ptr;  
52 - is_array = _is_array;  
53 - }  
54 -  
55 - virtual ~__SrsAutoFree(){  
56 - if (ptr == NULL || *ptr == NULL) {  
57 - return;  
58 - }  
59 -  
60 - if (is_array) {  
61 - delete[] *ptr;  
62 - } else {  
63 - delete *ptr;  
64 - }  
65 -  
66 - *ptr = NULL;  
67 - }  
68 -};  
69 -  
70 - 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#ifndef SRS_CORE_AUTO_FREE_HPP
  25 +#define SRS_CORE_AUTO_FREE_HPP
  26 +
  27 +/*
  28 +#include <srs_core_autofree.hpp>
  29 +*/
  30 +
  31 +#include <srs_core.hpp>
  32 +
  33 +/**
  34 +* auto free the instance in the current scope.
  35 +*/
  36 +#define SrsAutoFree(className, instance, is_array) \
  37 + __SrsAutoFree<className> _auto_free_##instance(&instance, is_array)
  38 +
  39 +template<class T>
  40 +class __SrsAutoFree
  41 +{
  42 +private:
  43 + T** ptr;
  44 + bool is_array;
  45 +public:
  46 + /**
  47 + * auto delete the ptr.
  48 + * @is_array a bool value indicates whether the ptr is a array.
  49 + */
  50 + __SrsAutoFree(T** _ptr, bool _is_array){
  51 + ptr = _ptr;
  52 + is_array = _is_array;
  53 + }
  54 +
  55 + virtual ~__SrsAutoFree(){
  56 + if (ptr == NULL || *ptr == NULL) {
  57 + return;
  58 + }
  59 +
  60 + if (is_array) {
  61 + delete[] *ptr;
  62 + } else {
  63 + delete *ptr;
  64 + }
  65 +
  66 + *ptr = NULL;
  67 + }
  68 +};
  69 +
  70 +
71 #endif 71 #endif
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#include <srs_core_buffer.hpp>  
25 -  
26 -#include <srs_core_error.hpp>  
27 -#include <srs_core_socket.hpp>  
28 -#include <srs_core_log.hpp>  
29 -  
30 -#define SOCKET_READ_SIZE 4096  
31 -  
32 -SrsBuffer::SrsBuffer()  
33 -{  
34 -}  
35 -  
36 -SrsBuffer::~SrsBuffer()  
37 -{  
38 -}  
39 -  
40 -int SrsBuffer::size()  
41 -{  
42 - return (int)data.size();  
43 -}  
44 -  
45 -char* SrsBuffer::bytes()  
46 -{  
47 - return &data.at(0);  
48 -}  
49 -  
50 -void SrsBuffer::erase(int size)  
51 -{  
52 - data.erase(data.begin(), data.begin() + size);  
53 -}  
54 -  
55 -void SrsBuffer::append(char* bytes, int size)  
56 -{  
57 - data.insert(data.end(), bytes, bytes + size);  
58 -}  
59 -  
60 -int SrsBuffer::ensure_buffer_bytes(SrsSocket* skt, int required_size)  
61 -{  
62 - int ret = ERROR_SUCCESS;  
63 -  
64 - if (required_size < 0) {  
65 - ret = ERROR_SYSTEM_SIZE_NEGATIVE;  
66 - srs_error("size is negative. size=%d, ret=%d", required_size, ret);  
67 - return ret;  
68 - }  
69 -  
70 - while (size() < required_size) {  
71 - char buffer[SOCKET_READ_SIZE];  
72 -  
73 - ssize_t nread;  
74 - if ((ret = skt->read(buffer, SOCKET_READ_SIZE, &nread)) != ERROR_SUCCESS) {  
75 - return ret;  
76 - }  
77 -  
78 - srs_assert((int)nread > 0);  
79 - append(buffer, (int)nread);  
80 - }  
81 -  
82 - return ret;  
83 -}  
84 - 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_buffer.hpp>
  25 +
  26 +#include <srs_core_error.hpp>
  27 +#include <srs_core_socket.hpp>
  28 +#include <srs_core_log.hpp>
  29 +
  30 +#define SOCKET_READ_SIZE 4096
  31 +
  32 +SrsBuffer::SrsBuffer()
  33 +{
  34 +}
  35 +
  36 +SrsBuffer::~SrsBuffer()
  37 +{
  38 +}
  39 +
  40 +int SrsBuffer::size()
  41 +{
  42 + return (int)data.size();
  43 +}
  44 +
  45 +char* SrsBuffer::bytes()
  46 +{
  47 + return &data.at(0);
  48 +}
  49 +
  50 +void SrsBuffer::erase(int size)
  51 +{
  52 + data.erase(data.begin(), data.begin() + size);
  53 +}
  54 +
  55 +void SrsBuffer::append(char* bytes, int size)
  56 +{
  57 + data.insert(data.end(), bytes, bytes + size);
  58 +}
  59 +
  60 +int SrsBuffer::ensure_buffer_bytes(SrsSocket* skt, int required_size)
  61 +{
  62 + int ret = ERROR_SUCCESS;
  63 +
  64 + if (required_size < 0) {
  65 + ret = ERROR_SYSTEM_SIZE_NEGATIVE;
  66 + srs_error("size is negative. size=%d, ret=%d", required_size, ret);
  67 + return ret;
  68 + }
  69 +
  70 + while (size() < required_size) {
  71 + char buffer[SOCKET_READ_SIZE];
  72 +
  73 + ssize_t nread;
  74 + if ((ret = skt->read(buffer, SOCKET_READ_SIZE, &nread)) != ERROR_SUCCESS) {
  75 + return ret;
  76 + }
  77 +
  78 + srs_assert((int)nread > 0);
  79 + append(buffer, (int)nread);
  80 + }
  81 +
  82 + return ret;
  83 +}
  84 +
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#ifndef SRS_CORE_BUFFER_HPP  
25 -#define SRS_CORE_BUFFER_HPP  
26 -  
27 -/*  
28 -#include <srs_core_buffer.hpp>  
29 -*/  
30 -  
31 -#include <srs_core.hpp>  
32 -  
33 -#include <vector>  
34 -  
35 -class SrsSocket;  
36 -  
37 -/**  
38 -* the buffer provices bytes cache for protocol. generally,  
39 -* protocol recv data from socket, put into buffer, decode to RTMP message.  
40 -* protocol encode RTMP message to bytes, put into buffer, send to socket.  
41 -*/  
42 -class SrsBuffer  
43 -{  
44 -private:  
45 - std::vector<char> data;  
46 -public:  
47 - SrsBuffer();  
48 - virtual ~SrsBuffer();  
49 -public:  
50 - virtual int size();  
51 - virtual char* bytes();  
52 - virtual void erase(int size);  
53 -private:  
54 - virtual void append(char* bytes, int size);  
55 -public:  
56 - virtual int ensure_buffer_bytes(SrsSocket* skt, int required_size);  
57 -};  
58 - 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#ifndef SRS_CORE_BUFFER_HPP
  25 +#define SRS_CORE_BUFFER_HPP
  26 +
  27 +/*
  28 +#include <srs_core_buffer.hpp>
  29 +*/
  30 +
  31 +#include <srs_core.hpp>
  32 +
  33 +#include <vector>
  34 +
  35 +class SrsSocket;
  36 +
  37 +/**
  38 +* the buffer provices bytes cache for protocol. generally,
  39 +* protocol recv data from socket, put into buffer, decode to RTMP message.
  40 +* protocol encode RTMP message to bytes, put into buffer, send to socket.
  41 +*/
  42 +class SrsBuffer
  43 +{
  44 +private:
  45 + std::vector<char> data;
  46 +public:
  47 + SrsBuffer();
  48 + virtual ~SrsBuffer();
  49 +public:
  50 + virtual int size();
  51 + virtual char* bytes();
  52 + virtual void erase(int size);
  53 +private:
  54 + virtual void append(char* bytes, int size);
  55 +public:
  56 + virtual int ensure_buffer_bytes(SrsSocket* skt, int required_size);
  57 +};
  58 +
59 #endif 59 #endif
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#include <srs_core_client.hpp>  
25 -  
26 -#include <arpa/inet.h>  
27 -#include <stdlib.h>  
28 -  
29 -#include <srs_core_error.hpp>  
30 -#include <srs_core_log.hpp>  
31 -#include <srs_core_rtmp.hpp>  
32 -#include <srs_core_protocol.hpp>  
33 -#include <srs_core_autofree.hpp>  
34 -#include <srs_core_source.hpp>  
35 -#include <srs_core_server.hpp>  
36 -#include <srs_core_pithy_print.hpp>  
37 -#include <srs_core_config.hpp>  
38 -#include <srs_core_refer.hpp>  
39 -  
40 -#define SRS_PULSE_TIMEOUT_MS 100  
41 -#define SRS_SEND_TIMEOUT_MS 5000000L  
42 -#define SRS_RECV_TIMEOUT_MS SRS_SEND_TIMEOUT_MS  
43 -  
44 -SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd)  
45 - : SrsConnection(srs_server, client_stfd)  
46 -{  
47 - ip = NULL;  
48 - req = new SrsRequest();  
49 - res = new SrsResponse();  
50 - rtmp = new SrsRtmp(client_stfd);  
51 - refer = new SrsRefer();  
52 -}  
53 -  
54 -SrsClient::~SrsClient()  
55 -{  
56 - srs_freepa(ip);  
57 - srs_freep(req);  
58 - srs_freep(res);  
59 - srs_freep(rtmp);  
60 - srs_freep(refer);  
61 -}  
62 -  
63 -int SrsClient::do_cycle()  
64 -{  
65 - int ret = ERROR_SUCCESS;  
66 -  
67 - if ((ret = get_peer_ip()) != ERROR_SUCCESS) {  
68 - srs_error("get peer ip failed. ret=%d", ret);  
69 - return ret;  
70 - }  
71 - srs_trace("get peer ip success. ip=%s, send_to=%"PRId64", recv_to=%"PRId64"",  
72 - ip, SRS_SEND_TIMEOUT_MS, SRS_RECV_TIMEOUT_MS);  
73 -  
74 - rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_MS * 1000);  
75 - rtmp->set_send_timeout(SRS_SEND_TIMEOUT_MS * 1000);  
76 -  
77 - if ((ret = rtmp->handshake()) != ERROR_SUCCESS) {  
78 - srs_error("rtmp handshake failed. ret=%d", ret);  
79 - return ret;  
80 - }  
81 - srs_verbose("rtmp handshake success");  
82 -  
83 - if ((ret = rtmp->connect_app(req)) != ERROR_SUCCESS) {  
84 - srs_error("rtmp connect vhost/app failed. ret=%d", ret);  
85 - return ret;  
86 - }  
87 - srs_verbose("rtmp connect app success");  
88 -  
89 - if ((ret = check_vhost()) != ERROR_SUCCESS) {  
90 - srs_error("check vhost failed. ret=%d", ret);  
91 - return ret;  
92 - }  
93 - srs_verbose("check vhost success.");  
94 -  
95 - srs_trace("rtmp connect app success. "  
96 - "tcUrl=%s, pageUrl=%s, swfUrl=%s, schema=%s, vhost=%s, port=%s, app=%s",  
97 - req->tcUrl.c_str(), req->pageUrl.c_str(), req->swfUrl.c_str(),  
98 - req->schema.c_str(), req->vhost.c_str(), req->port.c_str(),  
99 - req->app.c_str());  
100 -  
101 - if ((ret = refer->check(req->pageUrl, config->get_refer(req->vhost))) != ERROR_SUCCESS) {  
102 - srs_error("check refer failed. ret=%d", ret);  
103 - return ret;  
104 - }  
105 - srs_verbose("check refer success.");  
106 -  
107 - if ((ret = rtmp->set_window_ack_size(2.5 * 1000 * 1000)) != ERROR_SUCCESS) {  
108 - srs_error("set window acknowledgement size failed. ret=%d", ret);  
109 - return ret;  
110 - }  
111 - srs_verbose("set window acknowledgement size success");  
112 -  
113 - if ((ret = rtmp->set_peer_bandwidth(2.5 * 1000 * 1000, 2)) != ERROR_SUCCESS) {  
114 - srs_error("set peer bandwidth failed. ret=%d", ret);  
115 - return ret;  
116 - }  
117 - srs_verbose("set peer bandwidth success");  
118 -  
119 - if ((ret = rtmp->response_connect_app(req)) != ERROR_SUCCESS) {  
120 - srs_error("response connect app failed. ret=%d", ret);  
121 - return ret;  
122 - }  
123 - srs_verbose("response connect app success");  
124 -  
125 - if ((ret = rtmp->on_bw_done()) != ERROR_SUCCESS) {  
126 - srs_error("on_bw_done failed. ret=%d", ret);  
127 - return ret;  
128 - }  
129 - srs_verbose("on_bw_done success");  
130 -  
131 - SrsClientType type;  
132 - if ((ret = rtmp->identify_client(res->stream_id, type, req->stream)) != ERROR_SUCCESS) {  
133 - srs_error("identify client failed. ret=%d", ret);  
134 - return ret;  
135 - }  
136 - req->strip();  
137 - srs_trace("identify client success. type=%d, stream_name=%s", type, req->stream.c_str());  
138 -  
139 - int chunk_size = 4096;  
140 - SrsConfDirective* conf = config->get_chunk_size();  
141 - if (conf && !conf->arg0().empty()) {  
142 - chunk_size = ::atoi(conf->arg0().c_str());  
143 - }  
144 - if ((ret = rtmp->set_chunk_size(chunk_size)) != ERROR_SUCCESS) {  
145 - srs_error("set chunk_size=%d failed. ret=%d", chunk_size, ret);  
146 - return ret;  
147 - }  
148 - srs_trace("set chunk_size=%d success", chunk_size);  
149 -  
150 - // find a source to publish.  
151 - SrsSource* source = SrsSource::find(req->get_stream_url());  
152 - srs_assert(source != NULL);  
153 -  
154 - bool enabled_cache = true;  
155 - conf = config->get_gop_cache(req->vhost);  
156 - if (conf && conf->arg0() == "off") {  
157 - enabled_cache = false;  
158 - }  
159 - source->set_cache(enabled_cache);  
160 -  
161 - srs_info("source found, url=%s, enabled_cache=%d", req->get_stream_url().c_str(), enabled_cache);  
162 -  
163 - switch (type) {  
164 - case SrsClientPlay: {  
165 - srs_verbose("start to play stream %s.", req->stream.c_str());  
166 -  
167 - if ((ret = rtmp->start_play(res->stream_id)) != ERROR_SUCCESS) {  
168 - srs_error("start to play stream failed. ret=%d", ret);  
169 - return ret;  
170 - }  
171 - srs_info("start to play stream %s success", req->stream.c_str());  
172 - return playing(source);  
173 - }  
174 - case SrsClientFMLEPublish: {  
175 - srs_verbose("FMLE start to publish stream %s.", req->stream.c_str());  
176 -  
177 - if ((ret = rtmp->start_fmle_publish(res->stream_id)) != ERROR_SUCCESS) {  
178 - srs_error("start to publish stream failed. ret=%d", ret);  
179 - return ret;  
180 - }  
181 - srs_info("start to publish stream %s success", req->stream.c_str());  
182 - ret = publish(source, true);  
183 - source->on_unpublish();  
184 - return ret;  
185 - }  
186 - case SrsClientFlashPublish: {  
187 - srs_verbose("flash start to publish stream %s.", req->stream.c_str());  
188 -  
189 - if ((ret = rtmp->start_flash_publish(res->stream_id)) != ERROR_SUCCESS) {  
190 - srs_error("flash start to publish stream failed. ret=%d", ret);  
191 - return ret;  
192 - }  
193 - srs_info("flash start to publish stream %s success", req->stream.c_str());  
194 - ret = publish(source, false);  
195 - source->on_unpublish();  
196 - return ret;  
197 - }  
198 - default: {  
199 - ret = ERROR_SYSTEM_CLIENT_INVALID;  
200 - srs_info("invalid client type=%d. ret=%d", type, ret);  
201 - return ret;  
202 - }  
203 - }  
204 -  
205 - return ret;  
206 -}  
207 -  
208 -int SrsClient::check_vhost()  
209 -{  
210 - int ret = ERROR_SUCCESS;  
211 -  
212 - srs_assert(req != NULL);  
213 -  
214 - SrsConfDirective* vhost = config->get_vhost(req->vhost);  
215 - if (vhost == NULL) {  
216 - ret = ERROR_RTMP_VHOST_NOT_FOUND;  
217 - srs_error("vhost %s not found. ret=%d", req->vhost.c_str(), ret);  
218 - return ret;  
219 - }  
220 -  
221 - SrsConfDirective* conf = NULL;  
222 - if ((conf = vhost->get(RTMP_VHOST_ENABLED)) != NULL && conf->arg0() != "on") {  
223 - ret = ERROR_RTMP_VHOST_NOT_FOUND;  
224 - srs_error("vhost %s disabled. ret=%d", req->vhost.c_str(), ret);  
225 - return ret;  
226 - }  
227 -  
228 - if (req->vhost != vhost->arg0()) {  
229 - srs_trace("vhost change from %s to %s", req->vhost.c_str(), vhost->arg0().c_str());  
230 - req->vhost = vhost->arg0();  
231 - }  
232 -  
233 - return ret;  
234 -}  
235 -  
236 -int SrsClient::playing(SrsSource* source)  
237 -{  
238 - int ret = ERROR_SUCCESS;  
239 -  
240 - if ((ret = refer->check(req->pageUrl, config->get_refer_play(req->vhost))) != ERROR_SUCCESS) {  
241 - srs_error("check play_refer failed. ret=%d", ret);  
242 - return ret;  
243 - }  
244 - srs_verbose("check play_refer success.");  
245 -  
246 - SrsConsumer* consumer = NULL;  
247 - if ((ret = source->create_consumer(consumer)) != ERROR_SUCCESS) {  
248 - srs_error("create consumer failed. ret=%d", ret);  
249 - return ret;  
250 - }  
251 -  
252 - srs_assert(consumer != NULL);  
253 - SrsAutoFree(SrsConsumer, consumer, false);  
254 - srs_verbose("consumer created success.");  
255 -  
256 - rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000);  
257 -  
258 - SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER);  
259 -  
260 - while (true) {  
261 - pithy_print.elapse(SRS_PULSE_TIMEOUT_MS);  
262 -  
263 - // switch to other st-threads.  
264 - st_usleep(0);  
265 -  
266 - // read from client.  
267 - int ctl_msg_ret = ERROR_SUCCESS;  
268 - if (true) {  
269 - SrsCommonMessage* msg = NULL;  
270 - ctl_msg_ret = ret = rtmp->recv_message(&msg);  
271 -  
272 - srs_verbose("play loop recv message. ret=%d", ret);  
273 - if (ret != ERROR_SUCCESS && ret != ERROR_SOCKET_TIMEOUT) {  
274 - srs_error("recv client control message failed. ret=%d", ret);  
275 - return ret;  
276 - }  
277 - if ((ret = process_play_control_msg(consumer, msg)) != ERROR_SUCCESS) {  
278 - srs_error("process play control message failed. ret=%d", ret);  
279 - return ret;  
280 - }  
281 - }  
282 -  
283 - // get messages from consumer.  
284 - SrsSharedPtrMessage** msgs = NULL;  
285 - int count = 0;  
286 - if ((ret = consumer->get_packets(0, msgs, count)) != ERROR_SUCCESS) {  
287 - srs_error("get messages from consumer failed. ret=%d", ret);  
288 - return ret;  
289 - }  
290 -  
291 - // reportable  
292 - if (pithy_print.can_print()) {  
293 - srs_trace("-> clock=%u, time=%"PRId64", cmr=%d, msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",  
294 - (int)(srs_get_system_time_ms()/1000), pithy_print.get_age(), ctl_msg_ret, count, rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());  
295 - }  
296 -  
297 - if (count <= 0) {  
298 - srs_verbose("no packets in queue.");  
299 - continue;  
300 - }  
301 - SrsAutoFree(SrsSharedPtrMessage*, msgs, true);  
302 -  
303 - // sendout messages  
304 - for (int i = 0; i < count; i++) {  
305 - SrsSharedPtrMessage* msg = msgs[i];  
306 -  
307 - // the send_message will free the msg,  
308 - // so set the msgs[i] to NULL.  
309 - msgs[i] = NULL;  
310 -  
311 - if ((ret = rtmp->send_message(msg)) != ERROR_SUCCESS) {  
312 - srs_error("send message to client failed. ret=%d", ret);  
313 - return ret;  
314 - }  
315 - }  
316 - }  
317 -  
318 - return ret;  
319 -}  
320 -  
321 -int SrsClient::publish(SrsSource* source, bool is_fmle)  
322 -{  
323 - int ret = ERROR_SUCCESS;  
324 -  
325 - if ((ret = refer->check(req->pageUrl, config->get_refer_publish(req->vhost))) != ERROR_SUCCESS) {  
326 - srs_error("check publish_refer failed. ret=%d", ret);  
327 - return ret;  
328 - }  
329 - srs_verbose("check publish_refer success.");  
330 -  
331 - SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER);  
332 -  
333 - while (true) {  
334 - // switch to other st-threads.  
335 - st_usleep(0);  
336 -  
337 - SrsCommonMessage* msg = NULL;  
338 - if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) {  
339 - srs_error("recv identify client message failed. ret=%d", ret);  
340 - return ret;  
341 - }  
342 -  
343 - SrsAutoFree(SrsCommonMessage, msg, false);  
344 -  
345 - pithy_print.set_age(msg->header.timestamp);  
346 -  
347 - // reportable  
348 - if (pithy_print.can_print()) {  
349 - srs_trace("<- clock=%u, time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",  
350 - (int)(srs_get_system_time_ms()/1000), pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());  
351 - }  
352 -  
353 - // process audio packet  
354 - if (msg->header.is_audio() && ((ret = source->on_audio(msg)) != ERROR_SUCCESS)) {  
355 - srs_error("process audio message failed. ret=%d", ret);  
356 - return ret;  
357 - }  
358 - // process video packet  
359 - if (msg->header.is_video() && ((ret = source->on_video(msg)) != ERROR_SUCCESS)) {  
360 - srs_error("process video message failed. ret=%d", ret);  
361 - return ret;  
362 - }  
363 -  
364 - // process onMetaData  
365 - if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) {  
366 - if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {  
367 - srs_error("decode onMetaData message failed. ret=%d", ret);  
368 - return ret;  
369 - }  
370 -  
371 - SrsPacket* pkt = msg->get_packet();  
372 - if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) {  
373 - SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt);  
374 - if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) {  
375 - srs_error("process onMetaData message failed. ret=%d", ret);  
376 - return ret;  
377 - }  
378 - srs_trace("process onMetaData message success.");  
379 - continue;  
380 - }  
381 -  
382 - srs_trace("ignore AMF0/AMF3 data message.");  
383 - continue;  
384 - }  
385 -  
386 - // process UnPublish event.  
387 - if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) {  
388 - if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {  
389 - srs_error("decode unpublish message failed. ret=%d", ret);  
390 - return ret;  
391 - }  
392 -  
393 - // flash unpublish.  
394 - if (!is_fmle) {  
395 - srs_trace("flash publish finished.");  
396 - return ret;  
397 - }  
398 -  
399 - SrsPacket* pkt = msg->get_packet();  
400 - if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {  
401 - SrsFMLEStartPacket* unpublish = dynamic_cast<SrsFMLEStartPacket*>(pkt);  
402 - return rtmp->fmle_unpublish(res->stream_id, unpublish->transaction_id);  
403 - }  
404 -  
405 - srs_trace("ignore AMF0/AMF3 command message.");  
406 - continue;  
407 - }  
408 - }  
409 -  
410 - return ret;  
411 -}  
412 -  
413 -int SrsClient::get_peer_ip()  
414 -{  
415 - int ret = ERROR_SUCCESS;  
416 -  
417 - int fd = st_netfd_fileno(stfd);  
418 -  
419 - // discovery client information  
420 - sockaddr_in addr;  
421 - socklen_t addrlen = sizeof(addr);  
422 - if (getpeername(fd, (sockaddr*)&addr, &addrlen) == -1) {  
423 - ret = ERROR_SOCKET_GET_PEER_NAME;  
424 - srs_error("discovery client information failed. ret=%d", ret);  
425 - return ret;  
426 - }  
427 - srs_verbose("get peer name success.");  
428 -  
429 - // ip v4 or v6  
430 - char buf[INET6_ADDRSTRLEN];  
431 - memset(buf, 0, sizeof(buf));  
432 -  
433 - if ((inet_ntop(addr.sin_family, &addr.sin_addr, buf, sizeof(buf))) == NULL) {  
434 - ret = ERROR_SOCKET_GET_PEER_IP;  
435 - srs_error("convert client information failed. ret=%d", ret);  
436 - return ret;  
437 - }  
438 - srs_verbose("get peer ip of client ip=%s, fd=%d", buf, fd);  
439 -  
440 - ip = new char[strlen(buf) + 1];  
441 - strcpy(ip, buf);  
442 -  
443 - srs_verbose("get peer ip success. ip=%s, fd=%d", ip, fd);  
444 -  
445 - return ret;  
446 -}  
447 -  
448 -int SrsClient::process_play_control_msg(SrsConsumer* consumer, SrsCommonMessage* msg)  
449 -{  
450 - int ret = ERROR_SUCCESS;  
451 -  
452 - if (!msg) {  
453 - srs_verbose("ignore all empty message.");  
454 - return ret;  
455 - }  
456 - SrsAutoFree(SrsCommonMessage, msg, false);  
457 -  
458 - if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {  
459 - srs_info("ignore all message except amf0/amf3 command.");  
460 - return ret;  
461 - }  
462 -  
463 - if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {  
464 - srs_error("decode the amf0/amf3 command packet failed. ret=%d", ret);  
465 - return ret;  
466 - }  
467 - srs_info("decode the amf0/amf3 command packet success.");  
468 -  
469 - SrsPausePacket* pause = dynamic_cast<SrsPausePacket*>(msg->get_packet());  
470 - if (!pause) {  
471 - srs_info("ignore all amf0/amf3 command except pause.");  
472 - return ret;  
473 - }  
474 -  
475 - if ((ret = rtmp->on_play_client_pause(res->stream_id, pause->is_pause)) != ERROR_SUCCESS) {  
476 - srs_error("rtmp process play client pause failed. ret=%d", ret);  
477 - return ret;  
478 - }  
479 -  
480 - if ((ret = consumer->on_play_client_pause(pause->is_pause)) != ERROR_SUCCESS) {  
481 - srs_error("consumer process play client pause failed. ret=%d", ret);  
482 - return ret;  
483 - }  
484 - srs_info("process pause success, is_pause=%d, time=%d.", pause->is_pause, pause->time_ms);  
485 -  
486 - return ret;  
487 -}  
488 - 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_client.hpp>
  25 +
  26 +#include <arpa/inet.h>
  27 +#include <stdlib.h>
  28 +
  29 +#include <srs_core_error.hpp>
  30 +#include <srs_core_log.hpp>
  31 +#include <srs_core_rtmp.hpp>
  32 +#include <srs_core_protocol.hpp>
  33 +#include <srs_core_autofree.hpp>
  34 +#include <srs_core_source.hpp>
  35 +#include <srs_core_server.hpp>
  36 +#include <srs_core_pithy_print.hpp>
  37 +#include <srs_core_config.hpp>
  38 +#include <srs_core_refer.hpp>
  39 +
  40 +#define SRS_PULSE_TIMEOUT_MS 100
  41 +#define SRS_SEND_TIMEOUT_MS 5000000L
  42 +#define SRS_RECV_TIMEOUT_MS SRS_SEND_TIMEOUT_MS
  43 +
  44 +SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd)
  45 + : SrsConnection(srs_server, client_stfd)
  46 +{
  47 + ip = NULL;
  48 + req = new SrsRequest();
  49 + res = new SrsResponse();
  50 + rtmp = new SrsRtmp(client_stfd);
  51 + refer = new SrsRefer();
  52 +}
  53 +
  54 +SrsClient::~SrsClient()
  55 +{
  56 + srs_freepa(ip);
  57 + srs_freep(req);
  58 + srs_freep(res);
  59 + srs_freep(rtmp);
  60 + srs_freep(refer);
  61 +}
  62 +
  63 +int SrsClient::do_cycle()
  64 +{
  65 + int ret = ERROR_SUCCESS;
  66 +
  67 + if ((ret = get_peer_ip()) != ERROR_SUCCESS) {
  68 + srs_error("get peer ip failed. ret=%d", ret);
  69 + return ret;
  70 + }
  71 + srs_trace("get peer ip success. ip=%s, send_to=%"PRId64", recv_to=%"PRId64"",
  72 + ip, SRS_SEND_TIMEOUT_MS, SRS_RECV_TIMEOUT_MS);
  73 +
  74 + rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_MS * 1000);
  75 + rtmp->set_send_timeout(SRS_SEND_TIMEOUT_MS * 1000);
  76 +
  77 + if ((ret = rtmp->handshake()) != ERROR_SUCCESS) {
  78 + srs_error("rtmp handshake failed. ret=%d", ret);
  79 + return ret;
  80 + }
  81 + srs_verbose("rtmp handshake success");
  82 +
  83 + if ((ret = rtmp->connect_app(req)) != ERROR_SUCCESS) {
  84 + srs_error("rtmp connect vhost/app failed. ret=%d", ret);
  85 + return ret;
  86 + }
  87 + srs_verbose("rtmp connect app success");
  88 +
  89 + if ((ret = check_vhost()) != ERROR_SUCCESS) {
  90 + srs_error("check vhost failed. ret=%d", ret);
  91 + return ret;
  92 + }
  93 + srs_verbose("check vhost success.");
  94 +
  95 + srs_trace("rtmp connect app success. "
  96 + "tcUrl=%s, pageUrl=%s, swfUrl=%s, schema=%s, vhost=%s, port=%s, app=%s",
  97 + req->tcUrl.c_str(), req->pageUrl.c_str(), req->swfUrl.c_str(),
  98 + req->schema.c_str(), req->vhost.c_str(), req->port.c_str(),
  99 + req->app.c_str());
  100 +
  101 + if ((ret = refer->check(req->pageUrl, config->get_refer(req->vhost))) != ERROR_SUCCESS) {
  102 + srs_error("check refer failed. ret=%d", ret);
  103 + return ret;
  104 + }
  105 + srs_verbose("check refer success.");
  106 +
  107 + if ((ret = rtmp->set_window_ack_size(2.5 * 1000 * 1000)) != ERROR_SUCCESS) {
  108 + srs_error("set window acknowledgement size failed. ret=%d", ret);
  109 + return ret;
  110 + }
  111 + srs_verbose("set window acknowledgement size success");
  112 +
  113 + if ((ret = rtmp->set_peer_bandwidth(2.5 * 1000 * 1000, 2)) != ERROR_SUCCESS) {
  114 + srs_error("set peer bandwidth failed. ret=%d", ret);
  115 + return ret;
  116 + }
  117 + srs_verbose("set peer bandwidth success");
  118 +
  119 + if ((ret = rtmp->response_connect_app(req)) != ERROR_SUCCESS) {
  120 + srs_error("response connect app failed. ret=%d", ret);
  121 + return ret;
  122 + }
  123 + srs_verbose("response connect app success");
  124 +
  125 + if ((ret = rtmp->on_bw_done()) != ERROR_SUCCESS) {
  126 + srs_error("on_bw_done failed. ret=%d", ret);
  127 + return ret;
  128 + }
  129 + srs_verbose("on_bw_done success");
  130 +
  131 + SrsClientType type;
  132 + if ((ret = rtmp->identify_client(res->stream_id, type, req->stream)) != ERROR_SUCCESS) {
  133 + srs_error("identify client failed. ret=%d", ret);
  134 + return ret;
  135 + }
  136 + req->strip();
  137 + srs_trace("identify client success. type=%d, stream_name=%s", type, req->stream.c_str());
  138 +
  139 + int chunk_size = 4096;
  140 + SrsConfDirective* conf = config->get_chunk_size();
  141 + if (conf && !conf->arg0().empty()) {
  142 + chunk_size = ::atoi(conf->arg0().c_str());
  143 + }
  144 + if ((ret = rtmp->set_chunk_size(chunk_size)) != ERROR_SUCCESS) {
  145 + srs_error("set chunk_size=%d failed. ret=%d", chunk_size, ret);
  146 + return ret;
  147 + }
  148 + srs_trace("set chunk_size=%d success", chunk_size);
  149 +
  150 + // find a source to publish.
  151 + SrsSource* source = SrsSource::find(req->get_stream_url());
  152 + srs_assert(source != NULL);
  153 +
  154 + bool enabled_cache = true;
  155 + conf = config->get_gop_cache(req->vhost);
  156 + if (conf && conf->arg0() == "off") {
  157 + enabled_cache = false;
  158 + }
  159 + source->set_cache(enabled_cache);
  160 +
  161 + srs_info("source found, url=%s, enabled_cache=%d", req->get_stream_url().c_str(), enabled_cache);
  162 +
  163 + switch (type) {
  164 + case SrsClientPlay: {
  165 + srs_verbose("start to play stream %s.", req->stream.c_str());
  166 +
  167 + if ((ret = rtmp->start_play(res->stream_id)) != ERROR_SUCCESS) {
  168 + srs_error("start to play stream failed. ret=%d", ret);
  169 + return ret;
  170 + }
  171 + srs_info("start to play stream %s success", req->stream.c_str());
  172 + return playing(source);
  173 + }
  174 + case SrsClientFMLEPublish: {
  175 + srs_verbose("FMLE start to publish stream %s.", req->stream.c_str());
  176 +
  177 + if ((ret = rtmp->start_fmle_publish(res->stream_id)) != ERROR_SUCCESS) {
  178 + srs_error("start to publish stream failed. ret=%d", ret);
  179 + return ret;
  180 + }
  181 + srs_info("start to publish stream %s success", req->stream.c_str());
  182 + ret = publish(source, true);
  183 + source->on_unpublish();
  184 + return ret;
  185 + }
  186 + case SrsClientFlashPublish: {
  187 + srs_verbose("flash start to publish stream %s.", req->stream.c_str());
  188 +
  189 + if ((ret = rtmp->start_flash_publish(res->stream_id)) != ERROR_SUCCESS) {
  190 + srs_error("flash start to publish stream failed. ret=%d", ret);
  191 + return ret;
  192 + }
  193 + srs_info("flash start to publish stream %s success", req->stream.c_str());
  194 + ret = publish(source, false);
  195 + source->on_unpublish();
  196 + return ret;
  197 + }
  198 + default: {
  199 + ret = ERROR_SYSTEM_CLIENT_INVALID;
  200 + srs_info("invalid client type=%d. ret=%d", type, ret);
  201 + return ret;
  202 + }
  203 + }
  204 +
  205 + return ret;
  206 +}
  207 +
  208 +int SrsClient::check_vhost()
  209 +{
  210 + int ret = ERROR_SUCCESS;
  211 +
  212 + srs_assert(req != NULL);
  213 +
  214 + SrsConfDirective* vhost = config->get_vhost(req->vhost);
  215 + if (vhost == NULL) {
  216 + ret = ERROR_RTMP_VHOST_NOT_FOUND;
  217 + srs_error("vhost %s not found. ret=%d", req->vhost.c_str(), ret);
  218 + return ret;
  219 + }
  220 +
  221 + SrsConfDirective* conf = NULL;
  222 + if ((conf = vhost->get(RTMP_VHOST_ENABLED)) != NULL && conf->arg0() != "on") {
  223 + ret = ERROR_RTMP_VHOST_NOT_FOUND;
  224 + srs_error("vhost %s disabled. ret=%d", req->vhost.c_str(), ret);
  225 + return ret;
  226 + }
  227 +
  228 + if (req->vhost != vhost->arg0()) {
  229 + srs_trace("vhost change from %s to %s", req->vhost.c_str(), vhost->arg0().c_str());
  230 + req->vhost = vhost->arg0();
  231 + }
  232 +
  233 + return ret;
  234 +}
  235 +
  236 +int SrsClient::playing(SrsSource* source)
  237 +{
  238 + int ret = ERROR_SUCCESS;
  239 +
  240 + if ((ret = refer->check(req->pageUrl, config->get_refer_play(req->vhost))) != ERROR_SUCCESS) {
  241 + srs_error("check play_refer failed. ret=%d", ret);
  242 + return ret;
  243 + }
  244 + srs_verbose("check play_refer success.");
  245 +
  246 + SrsConsumer* consumer = NULL;
  247 + if ((ret = source->create_consumer(consumer)) != ERROR_SUCCESS) {
  248 + srs_error("create consumer failed. ret=%d", ret);
  249 + return ret;
  250 + }
  251 +
  252 + srs_assert(consumer != NULL);
  253 + SrsAutoFree(SrsConsumer, consumer, false);
  254 + srs_verbose("consumer created success.");
  255 +
  256 + rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000);
  257 +
  258 + SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER);
  259 +
  260 + while (true) {
  261 + pithy_print.elapse(SRS_PULSE_TIMEOUT_MS);
  262 +
  263 + // switch to other st-threads.
  264 + st_usleep(0);
  265 +
  266 + // read from client.
  267 + int ctl_msg_ret = ERROR_SUCCESS;
  268 + if (true) {
  269 + SrsCommonMessage* msg = NULL;
  270 + ctl_msg_ret = ret = rtmp->recv_message(&msg);
  271 +
  272 + srs_verbose("play loop recv message. ret=%d", ret);
  273 + if (ret != ERROR_SUCCESS && ret != ERROR_SOCKET_TIMEOUT) {
  274 + srs_error("recv client control message failed. ret=%d", ret);
  275 + return ret;
  276 + }
  277 + if ((ret = process_play_control_msg(consumer, msg)) != ERROR_SUCCESS) {
  278 + srs_error("process play control message failed. ret=%d", ret);
  279 + return ret;
  280 + }
  281 + }
  282 +
  283 + // get messages from consumer.
  284 + SrsSharedPtrMessage** msgs = NULL;
  285 + int count = 0;
  286 + if ((ret = consumer->get_packets(0, msgs, count)) != ERROR_SUCCESS) {
  287 + srs_error("get messages from consumer failed. ret=%d", ret);
  288 + return ret;
  289 + }
  290 +
  291 + // reportable
  292 + if (pithy_print.can_print()) {
  293 + srs_trace("-> clock=%u, time=%"PRId64", cmr=%d, msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",
  294 + (int)(srs_get_system_time_ms()/1000), pithy_print.get_age(), ctl_msg_ret, count, rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());
  295 + }
  296 +
  297 + if (count <= 0) {
  298 + srs_verbose("no packets in queue.");
  299 + continue;
  300 + }
  301 + SrsAutoFree(SrsSharedPtrMessage*, msgs, true);
  302 +
  303 + // sendout messages
  304 + for (int i = 0; i < count; i++) {
  305 + SrsSharedPtrMessage* msg = msgs[i];
  306 +
  307 + // the send_message will free the msg,
  308 + // so set the msgs[i] to NULL.
  309 + msgs[i] = NULL;
  310 +
  311 + if ((ret = rtmp->send_message(msg)) != ERROR_SUCCESS) {
  312 + srs_error("send message to client failed. ret=%d", ret);
  313 + return ret;
  314 + }
  315 + }
  316 + }
  317 +
  318 + return ret;
  319 +}
  320 +
  321 +int SrsClient::publish(SrsSource* source, bool is_fmle)
  322 +{
  323 + int ret = ERROR_SUCCESS;
  324 +
  325 + if ((ret = refer->check(req->pageUrl, config->get_refer_publish(req->vhost))) != ERROR_SUCCESS) {
  326 + srs_error("check publish_refer failed. ret=%d", ret);
  327 + return ret;
  328 + }
  329 + srs_verbose("check publish_refer success.");
  330 +
  331 + SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER);
  332 +
  333 + while (true) {
  334 + // switch to other st-threads.
  335 + st_usleep(0);
  336 +
  337 + SrsCommonMessage* msg = NULL;
  338 + if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) {
  339 + srs_error("recv identify client message failed. ret=%d", ret);
  340 + return ret;
  341 + }
  342 +
  343 + SrsAutoFree(SrsCommonMessage, msg, false);
  344 +
  345 + pithy_print.set_age(msg->header.timestamp);
  346 +
  347 + // reportable
  348 + if (pithy_print.can_print()) {
  349 + srs_trace("<- clock=%u, time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",
  350 + (int)(srs_get_system_time_ms()/1000), pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());
  351 + }
  352 +
  353 + // process audio packet
  354 + if (msg->header.is_audio() && ((ret = source->on_audio(msg)) != ERROR_SUCCESS)) {
  355 + srs_error("process audio message failed. ret=%d", ret);
  356 + return ret;
  357 + }
  358 + // process video packet
  359 + if (msg->header.is_video() && ((ret = source->on_video(msg)) != ERROR_SUCCESS)) {
  360 + srs_error("process video message failed. ret=%d", ret);
  361 + return ret;
  362 + }
  363 +
  364 + // process onMetaData
  365 + if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) {
  366 + if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {
  367 + srs_error("decode onMetaData message failed. ret=%d", ret);
  368 + return ret;
  369 + }
  370 +
  371 + SrsPacket* pkt = msg->get_packet();
  372 + if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) {
  373 + SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt);
  374 + if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) {
  375 + srs_error("process onMetaData message failed. ret=%d", ret);
  376 + return ret;
  377 + }
  378 + srs_trace("process onMetaData message success.");
  379 + continue;
  380 + }
  381 +
  382 + srs_trace("ignore AMF0/AMF3 data message.");
  383 + continue;
  384 + }
  385 +
  386 + // process UnPublish event.
  387 + if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) {
  388 + if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {
  389 + srs_error("decode unpublish message failed. ret=%d", ret);
  390 + return ret;
  391 + }
  392 +
  393 + // flash unpublish.
  394 + if (!is_fmle) {
  395 + srs_trace("flash publish finished.");
  396 + return ret;
  397 + }
  398 +
  399 + SrsPacket* pkt = msg->get_packet();
  400 + if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
  401 + SrsFMLEStartPacket* unpublish = dynamic_cast<SrsFMLEStartPacket*>(pkt);
  402 + return rtmp->fmle_unpublish(res->stream_id, unpublish->transaction_id);
  403 + }
  404 +
  405 + srs_trace("ignore AMF0/AMF3 command message.");
  406 + continue;
  407 + }
  408 + }
  409 +
  410 + return ret;
  411 +}
  412 +
  413 +int SrsClient::get_peer_ip()
  414 +{
  415 + int ret = ERROR_SUCCESS;
  416 +
  417 + int fd = st_netfd_fileno(stfd);
  418 +
  419 + // discovery client information
  420 + sockaddr_in addr;
  421 + socklen_t addrlen = sizeof(addr);
  422 + if (getpeername(fd, (sockaddr*)&addr, &addrlen) == -1) {
  423 + ret = ERROR_SOCKET_GET_PEER_NAME;
  424 + srs_error("discovery client information failed. ret=%d", ret);
  425 + return ret;
  426 + }
  427 + srs_verbose("get peer name success.");
  428 +
  429 + // ip v4 or v6
  430 + char buf[INET6_ADDRSTRLEN];
  431 + memset(buf, 0, sizeof(buf));
  432 +
  433 + if ((inet_ntop(addr.sin_family, &addr.sin_addr, buf, sizeof(buf))) == NULL) {
  434 + ret = ERROR_SOCKET_GET_PEER_IP;
  435 + srs_error("convert client information failed. ret=%d", ret);
  436 + return ret;
  437 + }
  438 + srs_verbose("get peer ip of client ip=%s, fd=%d", buf, fd);
  439 +
  440 + ip = new char[strlen(buf) + 1];
  441 + strcpy(ip, buf);
  442 +
  443 + srs_verbose("get peer ip success. ip=%s, fd=%d", ip, fd);
  444 +
  445 + return ret;
  446 +}
  447 +
  448 +int SrsClient::process_play_control_msg(SrsConsumer* consumer, SrsCommonMessage* msg)
  449 +{
  450 + int ret = ERROR_SUCCESS;
  451 +
  452 + if (!msg) {
  453 + srs_verbose("ignore all empty message.");
  454 + return ret;
  455 + }
  456 + SrsAutoFree(SrsCommonMessage, msg, false);
  457 +
  458 + if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {
  459 + srs_info("ignore all message except amf0/amf3 command.");
  460 + return ret;
  461 + }
  462 +
  463 + if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {
  464 + srs_error("decode the amf0/amf3 command packet failed. ret=%d", ret);
  465 + return ret;
  466 + }
  467 + srs_info("decode the amf0/amf3 command packet success.");
  468 +
  469 + SrsPausePacket* pause = dynamic_cast<SrsPausePacket*>(msg->get_packet());
  470 + if (!pause) {
  471 + srs_info("ignore all amf0/amf3 command except pause.");
  472 + return ret;
  473 + }
  474 +
  475 + if ((ret = rtmp->on_play_client_pause(res->stream_id, pause->is_pause)) != ERROR_SUCCESS) {
  476 + srs_error("rtmp process play client pause failed. ret=%d", ret);
  477 + return ret;
  478 + }
  479 +
  480 + if ((ret = consumer->on_play_client_pause(pause->is_pause)) != ERROR_SUCCESS) {
  481 + srs_error("consumer process play client pause failed. ret=%d", ret);
  482 + return ret;
  483 + }
  484 + srs_info("process pause success, is_pause=%d, time=%d.", pause->is_pause, pause->time_ms);
  485 +
  486 + return ret;
  487 +}
  488 +