正在显示
6 个修改的文件
包含
324 行增加
和
59 行删除
| @@ -24,6 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -24,6 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | #include <srs_core_amf0.hpp> | 24 | #include <srs_core_amf0.hpp> |
| 25 | 25 | ||
| 26 | #include <srs_core_log.hpp> | 26 | #include <srs_core_log.hpp> |
| 27 | +#include <srs_core_error.hpp> | ||
| 27 | #include <srs_core_stream.hpp> | 28 | #include <srs_core_stream.hpp> |
| 28 | 29 | ||
| 29 | // AMF0 marker | 30 | // AMF0 marker |
| @@ -49,30 +50,34 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -49,30 +50,34 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 49 | // origin array whos data takes the same form as LengthValueBytes | 50 | // origin array whos data takes the same form as LengthValueBytes |
| 50 | #define RTMP_AMF0_OriginStrictArray 0x20 | 51 | #define RTMP_AMF0_OriginStrictArray 0x20 |
| 51 | 52 | ||
| 52 | -std::string srs_amf0_read_utf8(SrsStream* stream) | 53 | +int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&); |
| 54 | + | ||
| 55 | +int srs_amf0_read_utf8(SrsStream* stream, std::string& value) | ||
| 53 | { | 56 | { |
| 54 | - std::string str; | 57 | + int ret = ERROR_SUCCESS; |
| 55 | 58 | ||
| 56 | // len | 59 | // len |
| 57 | if (!stream->require(2)) { | 60 | if (!stream->require(2)) { |
| 58 | - srs_warn("amf0 read string length failed"); | ||
| 59 | - return str; | 61 | + ret = ERROR_RTMP_AMF0_DECODE; |
| 62 | + srs_error("amf0 read string length failed. ret=%d", ret); | ||
| 63 | + return ret; | ||
| 60 | } | 64 | } |
| 61 | int16_t len = stream->read_2bytes(); | 65 | int16_t len = stream->read_2bytes(); |
| 62 | srs_verbose("amf0 read string length success. len=%d", len); | 66 | srs_verbose("amf0 read string length success. len=%d", len); |
| 63 | 67 | ||
| 64 | // empty string | 68 | // empty string |
| 65 | if (len <= 0) { | 69 | if (len <= 0) { |
| 66 | - srs_verbose("amf0 read empty string."); | ||
| 67 | - return str; | 70 | + srs_verbose("amf0 read empty string. ret=%d", ret); |
| 71 | + return ret; | ||
| 68 | } | 72 | } |
| 69 | 73 | ||
| 70 | // data | 74 | // data |
| 71 | if (!stream->require(len)) { | 75 | if (!stream->require(len)) { |
| 72 | - srs_warn("amf0 read string data failed"); | ||
| 73 | - return str; | 76 | + ret = ERROR_RTMP_AMF0_DECODE; |
| 77 | + srs_error("amf0 read string data failed. ret=%d", ret); | ||
| 78 | + return ret; | ||
| 74 | } | 79 | } |
| 75 | - str = stream->read_string(len); | 80 | + std::string str = stream->read_string(len); |
| 76 | 81 | ||
| 77 | // support utf8-1 only | 82 | // support utf8-1 only |
| 78 | // 1.3.1 Strings and UTF-8 | 83 | // 1.3.1 Strings and UTF-8 |
| @@ -80,54 +85,104 @@ std::string srs_amf0_read_utf8(SrsStream* stream) | @@ -80,54 +85,104 @@ std::string srs_amf0_read_utf8(SrsStream* stream) | ||
| 80 | for (int i = 0; i < len; i++) { | 85 | for (int i = 0; i < len; i++) { |
| 81 | char ch = *(str.data() + i); | 86 | char ch = *(str.data() + i); |
| 82 | if ((ch & 0x80) != 0) { | 87 | if ((ch & 0x80) != 0) { |
| 83 | - srs_warn("only support utf8-1, 0x00-0x7F, actual is %#x", (int)ch); | ||
| 84 | - return ""; | 88 | + ret = ERROR_RTMP_AMF0_DECODE; |
| 89 | + srs_error("only support utf8-1, 0x00-0x7F, actual is %#x. ret=%d", (int)ch, ret); | ||
| 90 | + return ret; | ||
| 85 | } | 91 | } |
| 86 | } | 92 | } |
| 93 | + | ||
| 94 | + value = str; | ||
| 87 | srs_verbose("amf0 read string data success. str=%s", str.c_str()); | 95 | srs_verbose("amf0 read string data success. str=%s", str.c_str()); |
| 88 | 96 | ||
| 89 | - return str; | 97 | + return ret; |
| 90 | } | 98 | } |
| 91 | 99 | ||
| 92 | -std::string srs_amf0_read_string(SrsStream* stream) | 100 | +int srs_amf0_read_string(SrsStream* stream, std::string& value) |
| 93 | { | 101 | { |
| 102 | + int ret = ERROR_SUCCESS; | ||
| 103 | + | ||
| 94 | // marker | 104 | // marker |
| 95 | if (!stream->require(1)) { | 105 | if (!stream->require(1)) { |
| 96 | - srs_warn("amf0 read string marker failed"); | ||
| 97 | - return ""; | 106 | + ret = ERROR_RTMP_AMF0_DECODE; |
| 107 | + srs_error("amf0 read string marker failed. ret=%d", ret); | ||
| 108 | + return ret; | ||
| 98 | } | 109 | } |
| 99 | 110 | ||
| 100 | char marker = stream->read_char(); | 111 | char marker = stream->read_char(); |
| 101 | if (marker != RTMP_AMF0_String) { | 112 | if (marker != RTMP_AMF0_String) { |
| 102 | - srs_warn("amf0 check string marker failed. marker=%#x, required=%#x", marker, RTMP_AMF0_String); | ||
| 103 | - return ""; | 113 | + ret = ERROR_RTMP_AMF0_DECODE; |
| 114 | + srs_error("amf0 check string marker failed. " | ||
| 115 | + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_String, ret); | ||
| 116 | + return ret; | ||
| 104 | } | 117 | } |
| 105 | srs_verbose("amf0 read string marker success"); | 118 | srs_verbose("amf0 read string marker success"); |
| 106 | 119 | ||
| 107 | - return srs_amf0_read_utf8(stream); | 120 | + return srs_amf0_read_utf8(stream, value); |
| 121 | +} | ||
| 122 | + | ||
| 123 | +int srs_amf0_read_boolean(SrsStream* stream, bool& value) | ||
| 124 | +{ | ||
| 125 | + int ret = ERROR_SUCCESS; | ||
| 126 | + | ||
| 127 | + // marker | ||
| 128 | + if (!stream->require(1)) { | ||
| 129 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 130 | + srs_error("amf0 read bool marker failed. ret=%d", ret); | ||
| 131 | + return ret; | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + char marker = stream->read_char(); | ||
| 135 | + if (marker != RTMP_AMF0_Boolean) { | ||
| 136 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 137 | + srs_error("amf0 check bool marker failed. " | ||
| 138 | + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Boolean, ret); | ||
| 139 | + return ret; | ||
| 140 | + } | ||
| 141 | + srs_verbose("amf0 read bool marker success"); | ||
| 142 | + | ||
| 143 | + // value | ||
| 144 | + if (!stream->require(1)) { | ||
| 145 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 146 | + srs_error("amf0 read bool value failed. ret=%d", ret); | ||
| 147 | + return ret; | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + if (stream->read_char() == 0) { | ||
| 151 | + value = false; | ||
| 152 | + } else { | ||
| 153 | + value = true; | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + srs_verbose("amf0 read bool value success. value=%d", value); | ||
| 157 | + | ||
| 158 | + return ret; | ||
| 108 | } | 159 | } |
| 109 | 160 | ||
| 110 | -double srs_amf0_read_number(SrsStream* stream) | 161 | +int srs_amf0_read_number(SrsStream* stream, double& value) |
| 111 | { | 162 | { |
| 112 | - double value = 0; | 163 | + int ret = ERROR_SUCCESS; |
| 113 | 164 | ||
| 114 | // marker | 165 | // marker |
| 115 | if (!stream->require(1)) { | 166 | if (!stream->require(1)) { |
| 116 | - srs_warn("amf0 read number marker failed"); | ||
| 117 | - return value; | 167 | + ret = ERROR_RTMP_AMF0_DECODE; |
| 168 | + srs_error("amf0 read number marker failed. ret=%d", ret); | ||
| 169 | + return ret; | ||
| 118 | } | 170 | } |
| 119 | 171 | ||
| 120 | char marker = stream->read_char(); | 172 | char marker = stream->read_char(); |
| 121 | if (marker != RTMP_AMF0_Number) { | 173 | if (marker != RTMP_AMF0_Number) { |
| 122 | - srs_warn("amf0 check number marker failed. marker=%#x, required=%#x", marker, RTMP_AMF0_Number); | ||
| 123 | - return value; | 174 | + ret = ERROR_RTMP_AMF0_DECODE; |
| 175 | + srs_error("amf0 check number marker failed. " | ||
| 176 | + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Number, ret); | ||
| 177 | + return ret; | ||
| 124 | } | 178 | } |
| 125 | srs_verbose("amf0 read number marker success"); | 179 | srs_verbose("amf0 read number marker success"); |
| 126 | 180 | ||
| 127 | // value | 181 | // value |
| 128 | if (!stream->require(8)) { | 182 | if (!stream->require(8)) { |
| 129 | - srs_warn("amf0 read number value failed"); | ||
| 130 | - return value; | 183 | + ret = ERROR_RTMP_AMF0_DECODE; |
| 184 | + srs_error("amf0 read number value failed. ret=%d", ret); | ||
| 185 | + return ret; | ||
| 131 | } | 186 | } |
| 132 | 187 | ||
| 133 | int64_t temp = stream->read_8bytes(); | 188 | int64_t temp = stream->read_8bytes(); |
| @@ -135,13 +190,158 @@ double srs_amf0_read_number(SrsStream* stream) | @@ -135,13 +190,158 @@ double srs_amf0_read_number(SrsStream* stream) | ||
| 135 | 190 | ||
| 136 | srs_verbose("amf0 read number value success. value=%.2f", value); | 191 | srs_verbose("amf0 read number value success. value=%.2f", value); |
| 137 | 192 | ||
| 138 | - return value; | 193 | + return ret; |
| 139 | } | 194 | } |
| 140 | 195 | ||
| 141 | -SrsAmf0Object* srs_amf0_read_object(SrsStream* stream) | 196 | +int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) |
| 142 | { | 197 | { |
| 143 | - SrsAmf0Object* value = NULL; | ||
| 144 | - return value; | 198 | + int ret = ERROR_SUCCESS; |
| 199 | + | ||
| 200 | + // marker | ||
| 201 | + if (!stream->require(1)) { | ||
| 202 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 203 | + srs_error("amf0 read any marker failed. ret=%d", ret); | ||
| 204 | + return ret; | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + char marker = stream->read_char(); | ||
| 208 | + srs_verbose("amf0 any marker success"); | ||
| 209 | + | ||
| 210 | + // backward the 1byte marker. | ||
| 211 | + stream->skip(-1); | ||
| 212 | + | ||
| 213 | + switch (marker) { | ||
| 214 | + case RTMP_AMF0_String: { | ||
| 215 | + std::string data; | ||
| 216 | + if ((ret = srs_amf0_read_string(stream, data)) != ERROR_SUCCESS) { | ||
| 217 | + return ret; | ||
| 218 | + } | ||
| 219 | + value = new SrsAmf0String(); | ||
| 220 | + srs_amf0_convert<SrsAmf0String>(value)->value = data; | ||
| 221 | + return ret; | ||
| 222 | + } | ||
| 223 | + case RTMP_AMF0_Boolean: { | ||
| 224 | + bool data; | ||
| 225 | + if ((ret = srs_amf0_read_boolean(stream, data)) != ERROR_SUCCESS) { | ||
| 226 | + return ret; | ||
| 227 | + } | ||
| 228 | + value = new SrsAmf0Boolean(); | ||
| 229 | + srs_amf0_convert<SrsAmf0Boolean>(value)->value = data; | ||
| 230 | + return ret; | ||
| 231 | + } | ||
| 232 | + case RTMP_AMF0_Number: { | ||
| 233 | + double data; | ||
| 234 | + if ((ret = srs_amf0_read_number(stream, data)) != ERROR_SUCCESS) { | ||
| 235 | + return ret; | ||
| 236 | + } | ||
| 237 | + value = new SrsAmf0Number(); | ||
| 238 | + srs_amf0_convert<SrsAmf0Number>(value)->value = data; | ||
| 239 | + return ret; | ||
| 240 | + } | ||
| 241 | + case RTMP_AMF0_ObjectEnd: { | ||
| 242 | + SrsAmf0ObjectEOF* p = NULL; | ||
| 243 | + if ((ret = srs_amf0_read_object_eof(stream, p)) != ERROR_SUCCESS) { | ||
| 244 | + return ret; | ||
| 245 | + } | ||
| 246 | + value = p; | ||
| 247 | + return ret; | ||
| 248 | + } | ||
| 249 | + case RTMP_AMF0_Object: { | ||
| 250 | + SrsAmf0Object* p = NULL; | ||
| 251 | + if ((ret = srs_amf0_read_object(stream, p)) != ERROR_SUCCESS) { | ||
| 252 | + return ret; | ||
| 253 | + } | ||
| 254 | + value = p; | ||
| 255 | + return ret; | ||
| 256 | + } | ||
| 257 | + default: | ||
| 258 | + value = new SrsAmf0Any(); | ||
| 259 | + value->marker = stream->read_char(); | ||
| 260 | + return ret; | ||
| 261 | + } | ||
| 262 | + | ||
| 263 | + return ret; | ||
| 264 | +} | ||
| 265 | + | ||
| 266 | +int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) | ||
| 267 | +{ | ||
| 268 | + int ret = ERROR_SUCCESS; | ||
| 269 | + | ||
| 270 | + // marker | ||
| 271 | + if (!stream->require(1)) { | ||
| 272 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 273 | + srs_error("amf0 read object eof marker failed. ret=%d", ret); | ||
| 274 | + return ret; | ||
| 275 | + } | ||
| 276 | + | ||
| 277 | + char marker = stream->read_char(); | ||
| 278 | + if (marker != RTMP_AMF0_ObjectEnd) { | ||
| 279 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 280 | + srs_error("amf0 check object eof marker failed. " | ||
| 281 | + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_ObjectEnd, ret); | ||
| 282 | + return ret; | ||
| 283 | + } | ||
| 284 | + srs_verbose("amf0 read object eof marker success"); | ||
| 285 | + | ||
| 286 | + // value | ||
| 287 | + value = new SrsAmf0ObjectEOF(); | ||
| 288 | + srs_verbose("amf0 read object eof marker success"); | ||
| 289 | + | ||
| 290 | + return ret; | ||
| 291 | +} | ||
| 292 | + | ||
| 293 | +int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value) | ||
| 294 | +{ | ||
| 295 | + int ret = ERROR_SUCCESS; | ||
| 296 | + | ||
| 297 | + // marker | ||
| 298 | + if (!stream->require(1)) { | ||
| 299 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 300 | + srs_error("amf0 read object marker failed. ret=%d", ret); | ||
| 301 | + return ret; | ||
| 302 | + } | ||
| 303 | + | ||
| 304 | + char marker = stream->read_char(); | ||
| 305 | + if (marker != RTMP_AMF0_Object) { | ||
| 306 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 307 | + srs_error("amf0 check object marker failed. " | ||
| 308 | + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret); | ||
| 309 | + return ret; | ||
| 310 | + } | ||
| 311 | + srs_verbose("amf0 read object marker success"); | ||
| 312 | + | ||
| 313 | + // value | ||
| 314 | + value = new SrsAmf0Object(); | ||
| 315 | + | ||
| 316 | + while (!stream->empty()) { | ||
| 317 | + // property-name: utf8 string | ||
| 318 | + std::string property_name; | ||
| 319 | + if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) { | ||
| 320 | + srs_error("amf0 object read property name failed. ret=%d", ret); | ||
| 321 | + return ret; | ||
| 322 | + } | ||
| 323 | + // property-value: any | ||
| 324 | + SrsAmf0Any* property_value = NULL; | ||
| 325 | + if ((ret = srs_amf0_read_any(stream, property_value)) != ERROR_SUCCESS) { | ||
| 326 | + srs_error("amf0 object read property_value failed. " | ||
| 327 | + "name=%s, ret=%d", property_name.c_str(), ret); | ||
| 328 | + return ret; | ||
| 329 | + } | ||
| 330 | + | ||
| 331 | + // AMF0 Object EOF. | ||
| 332 | + if (property_name.empty() || !property_value || property_value->is_object_eof()) { | ||
| 333 | + if (property_value) { | ||
| 334 | + delete property_value; | ||
| 335 | + } | ||
| 336 | + srs_info("amf0 read object EOF."); | ||
| 337 | + break; | ||
| 338 | + } | ||
| 339 | + | ||
| 340 | + // add property | ||
| 341 | + value->properties[property_name] = property_value; | ||
| 342 | + } | ||
| 343 | + | ||
| 344 | + return ret; | ||
| 145 | } | 345 | } |
| 146 | 346 | ||
| 147 | SrsAmf0Any::SrsAmf0Any() | 347 | SrsAmf0Any::SrsAmf0Any() |
| @@ -158,6 +358,11 @@ bool SrsAmf0Any::is_string() | @@ -158,6 +358,11 @@ bool SrsAmf0Any::is_string() | ||
| 158 | return marker == RTMP_AMF0_String; | 358 | return marker == RTMP_AMF0_String; |
| 159 | } | 359 | } |
| 160 | 360 | ||
| 361 | +bool SrsAmf0Any::is_boolean() | ||
| 362 | +{ | ||
| 363 | + return marker == RTMP_AMF0_Boolean; | ||
| 364 | +} | ||
| 365 | + | ||
| 161 | bool SrsAmf0Any::is_number() | 366 | bool SrsAmf0Any::is_number() |
| 162 | { | 367 | { |
| 163 | return marker == RTMP_AMF0_Number; | 368 | return marker == RTMP_AMF0_Number; |
| @@ -168,6 +373,11 @@ bool SrsAmf0Any::is_object() | @@ -168,6 +373,11 @@ bool SrsAmf0Any::is_object() | ||
| 168 | return marker == RTMP_AMF0_Object; | 373 | return marker == RTMP_AMF0_Object; |
| 169 | } | 374 | } |
| 170 | 375 | ||
| 376 | +bool SrsAmf0Any::is_object_eof() | ||
| 377 | +{ | ||
| 378 | + return marker == RTMP_AMF0_ObjectEnd; | ||
| 379 | +} | ||
| 380 | + | ||
| 171 | SrsAmf0String::SrsAmf0String() | 381 | SrsAmf0String::SrsAmf0String() |
| 172 | { | 382 | { |
| 173 | marker = RTMP_AMF0_String; | 383 | marker = RTMP_AMF0_String; |
| @@ -177,6 +387,16 @@ SrsAmf0String::~SrsAmf0String() | @@ -177,6 +387,16 @@ SrsAmf0String::~SrsAmf0String() | ||
| 177 | { | 387 | { |
| 178 | } | 388 | } |
| 179 | 389 | ||
| 390 | +SrsAmf0Boolean::SrsAmf0Boolean() | ||
| 391 | +{ | ||
| 392 | + marker = RTMP_AMF0_Boolean; | ||
| 393 | + value = false; | ||
| 394 | +} | ||
| 395 | + | ||
| 396 | +SrsAmf0Boolean::~SrsAmf0Boolean() | ||
| 397 | +{ | ||
| 398 | +} | ||
| 399 | + | ||
| 180 | SrsAmf0Number::SrsAmf0Number() | 400 | SrsAmf0Number::SrsAmf0Number() |
| 181 | { | 401 | { |
| 182 | marker = RTMP_AMF0_Number; | 402 | marker = RTMP_AMF0_Number; |
| @@ -185,12 +405,12 @@ SrsAmf0Number::SrsAmf0Number() | @@ -185,12 +405,12 @@ SrsAmf0Number::SrsAmf0Number() | ||
| 185 | 405 | ||
| 186 | SrsAmf0Number::~SrsAmf0Number() | 406 | SrsAmf0Number::~SrsAmf0Number() |
| 187 | { | 407 | { |
| 408 | + marker = RTMP_AMF0_ObjectEnd; | ||
| 188 | } | 409 | } |
| 189 | 410 | ||
| 190 | SrsAmf0ObjectEOF::SrsAmf0ObjectEOF() | 411 | SrsAmf0ObjectEOF::SrsAmf0ObjectEOF() |
| 191 | { | 412 | { |
| 192 | utf8_empty = 0x00; | 413 | utf8_empty = 0x00; |
| 193 | - object_end_marker = RTMP_AMF0_ObjectEnd; | ||
| 194 | } | 414 | } |
| 195 | 415 | ||
| 196 | SrsAmf0ObjectEOF::~SrsAmf0ObjectEOF() | 416 | SrsAmf0ObjectEOF::~SrsAmf0ObjectEOF() |
| @@ -43,25 +43,30 @@ class SrsAmf0Object; | @@ -43,25 +43,30 @@ class SrsAmf0Object; | ||
| 43 | * UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4 | 43 | * UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4 |
| 44 | * UTF8-1 = %x00-7F | 44 | * UTF8-1 = %x00-7F |
| 45 | * @remark only support UTF8-1 char. | 45 | * @remark only support UTF8-1 char. |
| 46 | -* @return default value is empty string. | ||
| 47 | */ | 46 | */ |
| 48 | -extern std::string srs_amf0_read_utf8(SrsStream* stream); | 47 | +extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value); |
| 49 | 48 | ||
| 50 | /** | 49 | /** |
| 51 | * read amf0 string from stream. | 50 | * read amf0 string from stream. |
| 52 | * 2.4 String Type | 51 | * 2.4 String Type |
| 53 | * string-type = string-marker UTF-8 | 52 | * string-type = string-marker UTF-8 |
| 54 | -* @return default value is empty string. | ||
| 55 | */ | 53 | */ |
| 56 | -extern std::string srs_amf0_read_string(SrsStream* stream); | 54 | +extern int srs_amf0_read_string(SrsStream* stream, std::string& value); |
| 55 | + | ||
| 56 | +/** | ||
| 57 | +* read amf0 boolean from stream. | ||
| 58 | +* 2.4 String Type | ||
| 59 | +* boolean-type = boolean-marker U8 | ||
| 60 | +* 0 is false, <> 0 is true | ||
| 61 | +*/ | ||
| 62 | +extern int srs_amf0_read_boolean(SrsStream* stream, bool& value); | ||
| 57 | 63 | ||
| 58 | /** | 64 | /** |
| 59 | * read amf0 number from stream. | 65 | * read amf0 number from stream. |
| 60 | * 2.2 Number Type | 66 | * 2.2 Number Type |
| 61 | * number-type = number-marker DOUBLE | 67 | * number-type = number-marker DOUBLE |
| 62 | -* @return default value is 0. | ||
| 63 | */ | 68 | */ |
| 64 | -extern double srs_amf0_read_number(SrsStream* stream); | 69 | +extern int srs_amf0_read_number(SrsStream* stream, double& value); |
| 65 | 70 | ||
| 66 | /** | 71 | /** |
| 67 | * read amf0 object from stream. | 72 | * read amf0 object from stream. |
| @@ -69,7 +74,7 @@ extern double srs_amf0_read_number(SrsStream* stream); | @@ -69,7 +74,7 @@ extern double srs_amf0_read_number(SrsStream* stream); | ||
| 69 | * anonymous-object-type = object-marker *(object-property) | 74 | * anonymous-object-type = object-marker *(object-property) |
| 70 | * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) | 75 | * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) |
| 71 | */ | 76 | */ |
| 72 | -extern SrsAmf0Object* srs_amf0_read_object(SrsStream* stream); | 77 | +extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value); |
| 73 | 78 | ||
| 74 | /** | 79 | /** |
| 75 | * any amf0 value. | 80 | * any amf0 value. |
| @@ -87,22 +92,10 @@ struct SrsAmf0Any | @@ -87,22 +92,10 @@ struct SrsAmf0Any | ||
| 87 | virtual ~SrsAmf0Any(); | 92 | virtual ~SrsAmf0Any(); |
| 88 | 93 | ||
| 89 | virtual bool is_string(); | 94 | virtual bool is_string(); |
| 95 | + virtual bool is_boolean(); | ||
| 90 | virtual bool is_number(); | 96 | virtual bool is_number(); |
| 91 | virtual bool is_object(); | 97 | virtual bool is_object(); |
| 92 | - | ||
| 93 | - /** | ||
| 94 | - * convert the any to specified object. | ||
| 95 | - * @return T*, the converted object. never NULL. | ||
| 96 | - * @remark, user must ensure the current object type, | ||
| 97 | - * or the covert will cause assert failed. | ||
| 98 | - */ | ||
| 99 | - template<class T> | ||
| 100 | - T* convert() | ||
| 101 | - { | ||
| 102 | - T* p = dynamic_cast<T>(this); | ||
| 103 | - srs_assert(p != NULL); | ||
| 104 | - return p; | ||
| 105 | - } | 98 | + virtual bool is_object_eof(); |
| 106 | }; | 99 | }; |
| 107 | 100 | ||
| 108 | /** | 101 | /** |
| @@ -120,6 +113,21 @@ struct SrsAmf0String : public SrsAmf0Any | @@ -120,6 +113,21 @@ struct SrsAmf0String : public SrsAmf0Any | ||
| 120 | }; | 113 | }; |
| 121 | 114 | ||
| 122 | /** | 115 | /** |
| 116 | +* read amf0 boolean from stream. | ||
| 117 | +* 2.4 String Type | ||
| 118 | +* boolean-type = boolean-marker U8 | ||
| 119 | +* 0 is false, <> 0 is true | ||
| 120 | +* @return default value is false. | ||
| 121 | +*/ | ||
| 122 | +struct SrsAmf0Boolean : public SrsAmf0Any | ||
| 123 | +{ | ||
| 124 | + bool value; | ||
| 125 | + | ||
| 126 | + SrsAmf0Boolean(); | ||
| 127 | + virtual ~SrsAmf0Boolean(); | ||
| 128 | +}; | ||
| 129 | + | ||
| 130 | +/** | ||
| 123 | * read amf0 number from stream. | 131 | * read amf0 number from stream. |
| 124 | * 2.2 Number Type | 132 | * 2.2 Number Type |
| 125 | * number-type = number-marker DOUBLE | 133 | * number-type = number-marker DOUBLE |
| @@ -138,10 +146,9 @@ struct SrsAmf0Number : public SrsAmf0Any | @@ -138,10 +146,9 @@ struct SrsAmf0Number : public SrsAmf0Any | ||
| 138 | * object-end-type = UTF-8-empty object-end-marker | 146 | * object-end-type = UTF-8-empty object-end-marker |
| 139 | * 0x00 0x00 0x09 | 147 | * 0x00 0x00 0x09 |
| 140 | */ | 148 | */ |
| 141 | -struct SrsAmf0ObjectEOF | 149 | +struct SrsAmf0ObjectEOF : public SrsAmf0Any |
| 142 | { | 150 | { |
| 143 | int16_t utf8_empty; | 151 | int16_t utf8_empty; |
| 144 | - char object_end_marker; | ||
| 145 | 152 | ||
| 146 | SrsAmf0ObjectEOF(); | 153 | SrsAmf0ObjectEOF(); |
| 147 | virtual ~SrsAmf0ObjectEOF(); | 154 | virtual ~SrsAmf0ObjectEOF(); |
| @@ -160,5 +167,19 @@ struct SrsAmf0Object : public SrsAmf0Any | @@ -160,5 +167,19 @@ struct SrsAmf0Object : public SrsAmf0Any | ||
| 160 | SrsAmf0Object(); | 167 | SrsAmf0Object(); |
| 161 | virtual ~SrsAmf0Object(); | 168 | virtual ~SrsAmf0Object(); |
| 162 | }; | 169 | }; |
| 170 | + | ||
| 171 | +/** | ||
| 172 | +* convert the any to specified object. | ||
| 173 | +* @return T*, the converted object. never NULL. | ||
| 174 | +* @remark, user must ensure the current object type, | ||
| 175 | +* or the covert will cause assert failed. | ||
| 176 | +*/ | ||
| 177 | +template<class T> | ||
| 178 | +T* srs_amf0_convert(SrsAmf0Any* any) | ||
| 179 | +{ | ||
| 180 | + T* p = dynamic_cast<T*>(any); | ||
| 181 | + srs_assert(p != NULL); | ||
| 182 | + return p; | ||
| 183 | +} | ||
| 163 | 184 | ||
| 164 | #endif | 185 | #endif |
| @@ -281,7 +281,11 @@ int SrsMessage::decode_packet() | @@ -281,7 +281,11 @@ int SrsMessage::decode_packet() | ||
| 281 | } | 281 | } |
| 282 | srs_verbose("decode stream initialized success"); | 282 | srs_verbose("decode stream initialized success"); |
| 283 | 283 | ||
| 284 | - std::string command = srs_amf0_read_string(stream); | 284 | + std::string command; |
| 285 | + if ((ret = srs_amf0_read_string(stream, command)) != ERROR_SUCCESS) { | ||
| 286 | + srs_error("decode AMF0 command name failed. ret=%d", ret); | ||
| 287 | + return ret; | ||
| 288 | + } | ||
| 285 | srs_verbose("AMF0 command message, command_name=%s", command.c_str()); | 289 | srs_verbose("AMF0 command message, command_name=%s", command.c_str()); |
| 286 | 290 | ||
| 287 | stream->reset(); | 291 | stream->reset(); |
| @@ -337,7 +341,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | @@ -337,7 +341,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | ||
| 337 | return ret; | 341 | return ret; |
| 338 | } | 342 | } |
| 339 | 343 | ||
| 340 | - command_name = srs_amf0_read_string(stream); | 344 | + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { |
| 345 | + srs_error("amf0 decode connect command_name failed. ret=%d", ret); | ||
| 346 | + return ret; | ||
| 347 | + } | ||
| 341 | if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_CONNECT) { | 348 | if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_CONNECT) { |
| 342 | ret = ERROR_RTMP_AMF0_DECODE; | 349 | ret = ERROR_RTMP_AMF0_DECODE; |
| 343 | srs_error("amf0 decode connect command_name failed. " | 350 | srs_error("amf0 decode connect command_name failed. " |
| @@ -345,7 +352,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | @@ -345,7 +352,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | ||
| 345 | return ret; | 352 | return ret; |
| 346 | } | 353 | } |
| 347 | 354 | ||
| 348 | - transaction_id = srs_amf0_read_number(stream); | 355 | + if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) { |
| 356 | + srs_error("amf0 decode connect transaction_id failed. ret=%d", ret); | ||
| 357 | + return ret; | ||
| 358 | + } | ||
| 349 | if (transaction_id != 1.0) { | 359 | if (transaction_id != 1.0) { |
| 350 | ret = ERROR_RTMP_AMF0_DECODE; | 360 | ret = ERROR_RTMP_AMF0_DECODE; |
| 351 | srs_error("amf0 decode connect transaction_id failed. " | 361 | srs_error("amf0 decode connect transaction_id failed. " |
| @@ -353,7 +363,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | @@ -353,7 +363,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | ||
| 353 | return ret; | 363 | return ret; |
| 354 | } | 364 | } |
| 355 | 365 | ||
| 356 | - command_object = srs_amf0_read_object(stream); | 366 | + if ((ret = srs_amf0_read_object(stream, command_object)) != ERROR_SUCCESS) { |
| 367 | + srs_error("amf0 decode connect command_object failed. ret=%d", ret); | ||
| 368 | + return ret; | ||
| 369 | + } | ||
| 357 | if (command_object == NULL) { | 370 | if (command_object == NULL) { |
| 358 | ret = ERROR_RTMP_AMF0_DECODE; | 371 | ret = ERROR_RTMP_AMF0_DECODE; |
| 359 | srs_error("amf0 decode connect command_object failed. ret=%d", ret); | 372 | srs_error("amf0 decode connect command_object failed. ret=%d", ret); |
| @@ -70,7 +70,12 @@ bool SrsStream::empty() | @@ -70,7 +70,12 @@ bool SrsStream::empty() | ||
| 70 | 70 | ||
| 71 | bool SrsStream::require(int required_size) | 71 | bool SrsStream::require(int required_size) |
| 72 | { | 72 | { |
| 73 | - return !empty() && (required_size < bytes + size - p); | 73 | + return !empty() && (required_size <= bytes + size - p); |
| 74 | +} | ||
| 75 | + | ||
| 76 | +void SrsStream::skip(int size) | ||
| 77 | +{ | ||
| 78 | + p += size; | ||
| 74 | } | 79 | } |
| 75 | 80 | ||
| 76 | char SrsStream::read_char() | 81 | char SrsStream::read_char() |
| @@ -65,6 +65,11 @@ public: | @@ -65,6 +65,11 @@ public: | ||
| 65 | * @return true if stream can read/write specified required_size bytes. | 65 | * @return true if stream can read/write specified required_size bytes. |
| 66 | */ | 66 | */ |
| 67 | virtual bool require(int required_size); | 67 | virtual bool require(int required_size); |
| 68 | + /** | ||
| 69 | + * to skip some size. | ||
| 70 | + * @size can be any value. positive to forward; nagetive to backward. | ||
| 71 | + */ | ||
| 72 | + virtual void skip(int size); | ||
| 68 | public: | 73 | public: |
| 69 | /** | 74 | /** |
| 70 | * get 1bytes char from stream. | 75 | * get 1bytes char from stream. |
-
请 注册 或 登录 后发表评论