正在显示
7 个修改的文件
包含
482 行增加
和
10 行删除
| @@ -53,6 +53,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -53,6 +53,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 53 | // User defined | 53 | // User defined |
| 54 | #define RTMP_AMF0_Invalid 0x3F | 54 | #define RTMP_AMF0_Invalid 0x3F |
| 55 | 55 | ||
| 56 | +int srs_amf0_get_object_eof_size(); | ||
| 57 | +int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&); | ||
| 58 | +int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*); | ||
| 59 | +int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value); | ||
| 60 | +int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value); | ||
| 61 | + | ||
| 56 | SrsAmf0Any::SrsAmf0Any() | 62 | SrsAmf0Any::SrsAmf0Any() |
| 57 | { | 63 | { |
| 58 | marker = RTMP_AMF0_Invalid; | 64 | marker = RTMP_AMF0_Invalid; |
| @@ -167,8 +173,6 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name) | @@ -167,8 +173,6 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name) | ||
| 167 | return prop; | 173 | return prop; |
| 168 | } | 174 | } |
| 169 | 175 | ||
| 170 | -int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&); | ||
| 171 | - | ||
| 172 | int srs_amf0_read_utf8(SrsStream* stream, std::string& value) | 176 | int srs_amf0_read_utf8(SrsStream* stream, std::string& value) |
| 173 | { | 177 | { |
| 174 | int ret = ERROR_SUCCESS; | 178 | int ret = ERROR_SUCCESS; |
| @@ -213,6 +217,36 @@ int srs_amf0_read_utf8(SrsStream* stream, std::string& value) | @@ -213,6 +217,36 @@ int srs_amf0_read_utf8(SrsStream* stream, std::string& value) | ||
| 213 | 217 | ||
| 214 | return ret; | 218 | return ret; |
| 215 | } | 219 | } |
| 220 | +int srs_amf0_write_utf8(SrsStream* stream, std::string value) | ||
| 221 | +{ | ||
| 222 | + int ret = ERROR_SUCCESS; | ||
| 223 | + | ||
| 224 | + // len | ||
| 225 | + if (!stream->require(2)) { | ||
| 226 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
| 227 | + srs_error("amf0 write string length failed. ret=%d", ret); | ||
| 228 | + return ret; | ||
| 229 | + } | ||
| 230 | + stream->write_2bytes(value.length()); | ||
| 231 | + srs_verbose("amf0 write string length success. len=%d", (int)value.length()); | ||
| 232 | + | ||
| 233 | + // empty string | ||
| 234 | + if (value.length() <= 0) { | ||
| 235 | + srs_verbose("amf0 write empty string. ret=%d", ret); | ||
| 236 | + return ret; | ||
| 237 | + } | ||
| 238 | + | ||
| 239 | + // data | ||
| 240 | + if (!stream->require(value.length())) { | ||
| 241 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
| 242 | + srs_error("amf0 write string data failed. ret=%d", ret); | ||
| 243 | + return ret; | ||
| 244 | + } | ||
| 245 | + stream->write_string(value); | ||
| 246 | + srs_verbose("amf0 write string data success. str=%s", value.c_str()); | ||
| 247 | + | ||
| 248 | + return ret; | ||
| 249 | +} | ||
| 216 | 250 | ||
| 217 | int srs_amf0_read_string(SrsStream* stream, std::string& value) | 251 | int srs_amf0_read_string(SrsStream* stream, std::string& value) |
| 218 | { | 252 | { |
| @@ -237,6 +271,23 @@ int srs_amf0_read_string(SrsStream* stream, std::string& value) | @@ -237,6 +271,23 @@ int srs_amf0_read_string(SrsStream* stream, std::string& value) | ||
| 237 | return srs_amf0_read_utf8(stream, value); | 271 | return srs_amf0_read_utf8(stream, value); |
| 238 | } | 272 | } |
| 239 | 273 | ||
| 274 | +int srs_amf0_write_string(SrsStream* stream, std::string value) | ||
| 275 | +{ | ||
| 276 | + int ret = ERROR_SUCCESS; | ||
| 277 | + | ||
| 278 | + // marker | ||
| 279 | + if (!stream->require(1)) { | ||
| 280 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
| 281 | + srs_error("amf0 write string marker failed. ret=%d", ret); | ||
| 282 | + return ret; | ||
| 283 | + } | ||
| 284 | + | ||
| 285 | + stream->write_1bytes(RTMP_AMF0_String); | ||
| 286 | + srs_verbose("amf0 write string marker success"); | ||
| 287 | + | ||
| 288 | + return srs_amf0_write_utf8(stream, value); | ||
| 289 | +} | ||
| 290 | + | ||
| 240 | int srs_amf0_read_boolean(SrsStream* stream, bool& value) | 291 | int srs_amf0_read_boolean(SrsStream* stream, bool& value) |
| 241 | { | 292 | { |
| 242 | int ret = ERROR_SUCCESS; | 293 | int ret = ERROR_SUCCESS; |
| @@ -274,6 +325,36 @@ int srs_amf0_read_boolean(SrsStream* stream, bool& value) | @@ -274,6 +325,36 @@ int srs_amf0_read_boolean(SrsStream* stream, bool& value) | ||
| 274 | 325 | ||
| 275 | return ret; | 326 | return ret; |
| 276 | } | 327 | } |
| 328 | +int srs_amf0_write_boolean(SrsStream* stream, bool value) | ||
| 329 | +{ | ||
| 330 | + int ret = ERROR_SUCCESS; | ||
| 331 | + | ||
| 332 | + // marker | ||
| 333 | + if (!stream->require(1)) { | ||
| 334 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
| 335 | + srs_error("amf0 write bool marker failed. ret=%d", ret); | ||
| 336 | + return ret; | ||
| 337 | + } | ||
| 338 | + stream->write_1bytes(RTMP_AMF0_Boolean); | ||
| 339 | + srs_verbose("amf0 write bool marker success"); | ||
| 340 | + | ||
| 341 | + // value | ||
| 342 | + if (!stream->require(1)) { | ||
| 343 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
| 344 | + srs_error("amf0 write bool value failed. ret=%d", ret); | ||
| 345 | + return ret; | ||
| 346 | + } | ||
| 347 | + | ||
| 348 | + if (value) { | ||
| 349 | + stream->write_1bytes(0x01); | ||
| 350 | + } else { | ||
| 351 | + stream->write_1bytes(0x00); | ||
| 352 | + } | ||
| 353 | + | ||
| 354 | + srs_verbose("amf0 write bool value success. value=%d", value); | ||
| 355 | + | ||
| 356 | + return ret; | ||
| 357 | +} | ||
| 277 | 358 | ||
| 278 | int srs_amf0_read_number(SrsStream* stream, double& value) | 359 | int srs_amf0_read_number(SrsStream* stream, double& value) |
| 279 | { | 360 | { |
| @@ -309,6 +390,35 @@ int srs_amf0_read_number(SrsStream* stream, double& value) | @@ -309,6 +390,35 @@ int srs_amf0_read_number(SrsStream* stream, double& value) | ||
| 309 | 390 | ||
| 310 | return ret; | 391 | return ret; |
| 311 | } | 392 | } |
| 393 | +int srs_amf0_write_number(SrsStream* stream, double value) | ||
| 394 | +{ | ||
| 395 | + int ret = ERROR_SUCCESS; | ||
| 396 | + | ||
| 397 | + // marker | ||
| 398 | + if (!stream->require(1)) { | ||
| 399 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
| 400 | + srs_error("amf0 write number marker failed. ret=%d", ret); | ||
| 401 | + return ret; | ||
| 402 | + } | ||
| 403 | + | ||
| 404 | + stream->write_1bytes(RTMP_AMF0_Number); | ||
| 405 | + srs_verbose("amf0 write number marker success"); | ||
| 406 | + | ||
| 407 | + // value | ||
| 408 | + if (!stream->require(8)) { | ||
| 409 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
| 410 | + srs_error("amf0 write number value failed. ret=%d", ret); | ||
| 411 | + return ret; | ||
| 412 | + } | ||
| 413 | + | ||
| 414 | + int64_t temp = 0x00; | ||
| 415 | + memcpy(&temp, &value, 8); | ||
| 416 | + stream->write_8bytes(temp); | ||
| 417 | + | ||
| 418 | + srs_verbose("amf0 write number value success. value=%.2f", value); | ||
| 419 | + | ||
| 420 | + return ret; | ||
| 421 | +} | ||
| 312 | 422 | ||
| 313 | int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) | 423 | int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) |
| 314 | { | 424 | { |
| @@ -381,11 +491,66 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) | @@ -381,11 +491,66 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) | ||
| 381 | 491 | ||
| 382 | return ret; | 492 | return ret; |
| 383 | } | 493 | } |
| 494 | +int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value) | ||
| 495 | +{ | ||
| 496 | + int ret = ERROR_SUCCESS; | ||
| 497 | + | ||
| 498 | + srs_assert(value != NULL); | ||
| 499 | + | ||
| 500 | + switch (value->marker) { | ||
| 501 | + case RTMP_AMF0_String: { | ||
| 502 | + std::string data = srs_amf0_convert<SrsAmf0String>(value)->value; | ||
| 503 | + return srs_amf0_write_string(stream, data); | ||
| 504 | + } | ||
| 505 | + case RTMP_AMF0_Boolean: { | ||
| 506 | + bool data = srs_amf0_convert<SrsAmf0Boolean>(value)->value; | ||
| 507 | + return srs_amf0_write_boolean(stream, data); | ||
| 508 | + } | ||
| 509 | + case RTMP_AMF0_Number: { | ||
| 510 | + double data = srs_amf0_convert<SrsAmf0Number>(value)->value; | ||
| 511 | + return srs_amf0_write_number(stream, data); | ||
| 512 | + } | ||
| 513 | + case RTMP_AMF0_ObjectEnd: { | ||
| 514 | + SrsAmf0ObjectEOF* p = srs_amf0_convert<SrsAmf0ObjectEOF>(value); | ||
| 515 | + return srs_amf0_write_object_eof(stream, p); | ||
| 516 | + } | ||
| 517 | + case RTMP_AMF0_Object: { | ||
| 518 | + SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value); | ||
| 519 | + return srs_amf0_write_object(stream, p); | ||
| 520 | + } | ||
| 521 | + case RTMP_AMF0_Invalid: | ||
| 522 | + default: { | ||
| 523 | + ret = ERROR_RTMP_AMF0_INVALID; | ||
| 524 | + srs_error("invalid amf0 message type. marker=%#x, ret=%d", value->marker, ret); | ||
| 525 | + return ret; | ||
| 526 | + } | ||
| 527 | + } | ||
| 528 | + | ||
| 529 | + return ret; | ||
| 530 | +} | ||
| 384 | 531 | ||
| 385 | int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) | 532 | int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) |
| 386 | { | 533 | { |
| 387 | int ret = ERROR_SUCCESS; | 534 | int ret = ERROR_SUCCESS; |
| 388 | 535 | ||
| 536 | + // auto skip -2 to read the object eof. | ||
| 537 | + srs_assert(stream->pos() >= 2); | ||
| 538 | + stream->skip(-2); | ||
| 539 | + | ||
| 540 | + // value | ||
| 541 | + if (!stream->require(2)) { | ||
| 542 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 543 | + srs_error("amf0 read object eof value failed. ret=%d", ret); | ||
| 544 | + return ret; | ||
| 545 | + } | ||
| 546 | + int16_t temp = stream->read_2bytes(); | ||
| 547 | + if (temp != 0x00) { | ||
| 548 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 549 | + srs_error("amf0 read object eof value check failed. " | ||
| 550 | + "must be 0x00, actual is %#x, ret=%d", temp, ret); | ||
| 551 | + return ret; | ||
| 552 | + } | ||
| 553 | + | ||
| 389 | // marker | 554 | // marker |
| 390 | if (!stream->require(1)) { | 555 | if (!stream->require(1)) { |
| 391 | ret = ERROR_RTMP_AMF0_DECODE; | 556 | ret = ERROR_RTMP_AMF0_DECODE; |
| @@ -402,9 +567,36 @@ int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) | @@ -402,9 +567,36 @@ int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) | ||
| 402 | } | 567 | } |
| 403 | srs_verbose("amf0 read object eof marker success"); | 568 | srs_verbose("amf0 read object eof marker success"); |
| 404 | 569 | ||
| 405 | - // value | ||
| 406 | value = new SrsAmf0ObjectEOF(); | 570 | value = new SrsAmf0ObjectEOF(); |
| 407 | - srs_verbose("amf0 read object eof marker success"); | 571 | + srs_verbose("amf0 read object eof success"); |
| 572 | + | ||
| 573 | + return ret; | ||
| 574 | +} | ||
| 575 | +int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF* value) | ||
| 576 | +{ | ||
| 577 | + int ret = ERROR_SUCCESS; | ||
| 578 | + | ||
| 579 | + srs_assert(value != NULL); | ||
| 580 | + | ||
| 581 | + // value | ||
| 582 | + if (!stream->require(2)) { | ||
| 583 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
| 584 | + srs_error("amf0 write object eof value failed. ret=%d", ret); | ||
| 585 | + return ret; | ||
| 586 | + } | ||
| 587 | + stream->write_2bytes(0x00); | ||
| 588 | + srs_verbose("amf0 write object eof value success"); | ||
| 589 | + | ||
| 590 | + // marker | ||
| 591 | + if (!stream->require(1)) { | ||
| 592 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
| 593 | + srs_error("amf0 write object eof marker failed. ret=%d", ret); | ||
| 594 | + return ret; | ||
| 595 | + } | ||
| 596 | + | ||
| 597 | + stream->write_1bytes(RTMP_AMF0_ObjectEnd); | ||
| 598 | + | ||
| 599 | + srs_verbose("amf0 read object eof success"); | ||
| 408 | 600 | ||
| 409 | return ret; | 601 | return ret; |
| 410 | } | 602 | } |
| @@ -462,3 +654,108 @@ int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value) | @@ -462,3 +654,108 @@ int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value) | ||
| 462 | 654 | ||
| 463 | return ret; | 655 | return ret; |
| 464 | } | 656 | } |
| 657 | +int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value) | ||
| 658 | +{ | ||
| 659 | + int ret = ERROR_SUCCESS; | ||
| 660 | + | ||
| 661 | + srs_assert(value != NULL); | ||
| 662 | + | ||
| 663 | + // marker | ||
| 664 | + if (!stream->require(1)) { | ||
| 665 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
| 666 | + srs_error("amf0 write object marker failed. ret=%d", ret); | ||
| 667 | + return ret; | ||
| 668 | + } | ||
| 669 | + | ||
| 670 | + stream->write_1bytes(RTMP_AMF0_Object); | ||
| 671 | + srs_verbose("amf0 write object marker success"); | ||
| 672 | + | ||
| 673 | + // value | ||
| 674 | + std::map<std::string, SrsAmf0Any*>::iterator it; | ||
| 675 | + for (it = value->properties.begin(); it != value->properties.end(); ++it) { | ||
| 676 | + std::string name = it->first; | ||
| 677 | + SrsAmf0Any* any = it->second; | ||
| 678 | + | ||
| 679 | + if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) { | ||
| 680 | + srs_error("write object property name failed. ret=%d", ret); | ||
| 681 | + return ret; | ||
| 682 | + } | ||
| 683 | + | ||
| 684 | + if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) { | ||
| 685 | + srs_error("write object property value failed. ret=%d", ret); | ||
| 686 | + return ret; | ||
| 687 | + } | ||
| 688 | + | ||
| 689 | + srs_verbose("write amf0 property success. name=%s", name.c_str()); | ||
| 690 | + } | ||
| 691 | + | ||
| 692 | + if ((ret = srs_amf0_write_object_eof(stream, &value->eof)) != ERROR_SUCCESS) { | ||
| 693 | + srs_error("write object eof failed. ret=%d", ret); | ||
| 694 | + return ret; | ||
| 695 | + } | ||
| 696 | + | ||
| 697 | + srs_verbose("write amf0 object success."); | ||
| 698 | + | ||
| 699 | + return ret; | ||
| 700 | +} | ||
| 701 | + | ||
| 702 | +int srs_amf0_get_utf8_size(std::string value) | ||
| 703 | +{ | ||
| 704 | + return 2 + value.length(); | ||
| 705 | +} | ||
| 706 | + | ||
| 707 | +int srs_amf0_get_string_size(std::string value) | ||
| 708 | +{ | ||
| 709 | + return 1 + srs_amf0_get_utf8_size(value); | ||
| 710 | +} | ||
| 711 | + | ||
| 712 | +int srs_amf0_get_number_size() | ||
| 713 | +{ | ||
| 714 | + return 1 + 8; | ||
| 715 | +} | ||
| 716 | + | ||
| 717 | +int srs_amf0_get_boolean_size() | ||
| 718 | +{ | ||
| 719 | + return 1 + 1; | ||
| 720 | +} | ||
| 721 | + | ||
| 722 | +int srs_amf0_get_object_size(SrsAmf0Object* obj) | ||
| 723 | +{ | ||
| 724 | + if (!obj) { | ||
| 725 | + return 0; | ||
| 726 | + } | ||
| 727 | + | ||
| 728 | + int size = 1; | ||
| 729 | + | ||
| 730 | + std::map<std::string, SrsAmf0Any*>::iterator it; | ||
| 731 | + for (it = obj->properties.begin(); it != obj->properties.end(); ++it) { | ||
| 732 | + std::string name = it->first; | ||
| 733 | + SrsAmf0Any* value = it->second; | ||
| 734 | + | ||
| 735 | + size += srs_amf0_get_utf8_size(name); | ||
| 736 | + | ||
| 737 | + if (value->is_boolean()) { | ||
| 738 | + size += srs_amf0_get_boolean_size(); | ||
| 739 | + } else if (value->is_number()) { | ||
| 740 | + size += srs_amf0_get_number_size(); | ||
| 741 | + } else if (value->is_string()) { | ||
| 742 | + SrsAmf0String* p = srs_amf0_convert<SrsAmf0String>(value); | ||
| 743 | + size += srs_amf0_get_string_size(p->value); | ||
| 744 | + } else if (value->is_object()) { | ||
| 745 | + SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value); | ||
| 746 | + size += srs_amf0_get_object_size(p); | ||
| 747 | + } else { | ||
| 748 | + // TOOD: other AMF0 types. | ||
| 749 | + srs_warn("ignore unkown AMF0 type size."); | ||
| 750 | + } | ||
| 751 | + } | ||
| 752 | + | ||
| 753 | + size += srs_amf0_get_object_eof_size(); | ||
| 754 | + | ||
| 755 | + return size; | ||
| 756 | +} | ||
| 757 | + | ||
| 758 | +int srs_amf0_get_object_eof_size() | ||
| 759 | +{ | ||
| 760 | + return 2 + 1; | ||
| 761 | +} |
| @@ -140,6 +140,7 @@ struct SrsAmf0Object : public SrsAmf0Any | @@ -140,6 +140,7 @@ struct SrsAmf0Object : public SrsAmf0Any | ||
| 140 | * @remark only support UTF8-1 char. | 140 | * @remark only support UTF8-1 char. |
| 141 | */ | 141 | */ |
| 142 | extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value); | 142 | extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value); |
| 143 | +extern int srs_amf0_write_utf8(SrsStream* stream, std::string value); | ||
| 143 | 144 | ||
| 144 | /** | 145 | /** |
| 145 | * read amf0 string from stream. | 146 | * read amf0 string from stream. |
| @@ -147,6 +148,7 @@ extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value); | @@ -147,6 +148,7 @@ extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value); | ||
| 147 | * string-type = string-marker UTF-8 | 148 | * string-type = string-marker UTF-8 |
| 148 | */ | 149 | */ |
| 149 | extern int srs_amf0_read_string(SrsStream* stream, std::string& value); | 150 | extern int srs_amf0_read_string(SrsStream* stream, std::string& value); |
| 151 | +extern int srs_amf0_write_string(SrsStream* stream, std::string value); | ||
| 150 | 152 | ||
| 151 | /** | 153 | /** |
| 152 | * read amf0 boolean from stream. | 154 | * read amf0 boolean from stream. |
| @@ -155,6 +157,7 @@ extern int srs_amf0_read_string(SrsStream* stream, std::string& value); | @@ -155,6 +157,7 @@ extern int srs_amf0_read_string(SrsStream* stream, std::string& value); | ||
| 155 | * 0 is false, <> 0 is true | 157 | * 0 is false, <> 0 is true |
| 156 | */ | 158 | */ |
| 157 | extern int srs_amf0_read_boolean(SrsStream* stream, bool& value); | 159 | extern int srs_amf0_read_boolean(SrsStream* stream, bool& value); |
| 160 | +extern int srs_amf0_write_boolean(SrsStream* stream, bool value); | ||
| 158 | 161 | ||
| 159 | /** | 162 | /** |
| 160 | * read amf0 number from stream. | 163 | * read amf0 number from stream. |
| @@ -162,6 +165,7 @@ extern int srs_amf0_read_boolean(SrsStream* stream, bool& value); | @@ -162,6 +165,7 @@ extern int srs_amf0_read_boolean(SrsStream* stream, bool& value); | ||
| 162 | * number-type = number-marker DOUBLE | 165 | * number-type = number-marker DOUBLE |
| 163 | */ | 166 | */ |
| 164 | extern int srs_amf0_read_number(SrsStream* stream, double& value); | 167 | extern int srs_amf0_read_number(SrsStream* stream, double& value); |
| 168 | +extern int srs_amf0_write_number(SrsStream* stream, double value); | ||
| 165 | 169 | ||
| 166 | /** | 170 | /** |
| 167 | * read amf0 object from stream. | 171 | * read amf0 object from stream. |
| @@ -170,6 +174,16 @@ extern int srs_amf0_read_number(SrsStream* stream, double& value); | @@ -170,6 +174,16 @@ extern int srs_amf0_read_number(SrsStream* stream, double& value); | ||
| 170 | * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) | 174 | * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) |
| 171 | */ | 175 | */ |
| 172 | extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value); | 176 | extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value); |
| 177 | +extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value); | ||
| 178 | + | ||
| 179 | +/** | ||
| 180 | +* get amf0 objects size. | ||
| 181 | +*/ | ||
| 182 | +extern int srs_amf0_get_utf8_size(std::string value); | ||
| 183 | +extern int srs_amf0_get_string_size(std::string value); | ||
| 184 | +extern int srs_amf0_get_number_size(); | ||
| 185 | +extern int srs_amf0_get_boolean_size(); | ||
| 186 | +extern int srs_amf0_get_object_size(SrsAmf0Object* obj); | ||
| 173 | 187 | ||
| 174 | /** | 188 | /** |
| 175 | * convert the any to specified object. | 189 | * convert the any to specified object. |
| @@ -58,6 +58,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -58,6 +58,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 58 | #define ERROR_RTMP_REQ_TCURL 306 | 58 | #define ERROR_RTMP_REQ_TCURL 306 |
| 59 | #define ERROR_RTMP_MESSAGE_DECODE 307 | 59 | #define ERROR_RTMP_MESSAGE_DECODE 307 |
| 60 | #define ERROR_RTMP_MESSAGE_ENCODE 308 | 60 | #define ERROR_RTMP_MESSAGE_ENCODE 308 |
| 61 | +#define ERROR_RTMP_AMF0_ENCODE 309 | ||
| 61 | 62 | ||
| 62 | #define ERROR_SYSTEM_STREAM_INIT 400 | 63 | #define ERROR_SYSTEM_STREAM_INIT 400 |
| 63 | #define ERROR_SYSTEM_PACKET_INVALID 401 | 64 | #define ERROR_SYSTEM_PACKET_INVALID 401 |
| @@ -1010,6 +1010,10 @@ SrsConnectAppPacket::SrsConnectAppPacket() | @@ -1010,6 +1010,10 @@ SrsConnectAppPacket::SrsConnectAppPacket() | ||
| 1010 | 1010 | ||
| 1011 | SrsConnectAppPacket::~SrsConnectAppPacket() | 1011 | SrsConnectAppPacket::~SrsConnectAppPacket() |
| 1012 | { | 1012 | { |
| 1013 | + if (command_object) { | ||
| 1014 | + delete command_object; | ||
| 1015 | + command_object = NULL; | ||
| 1016 | + } | ||
| 1013 | } | 1017 | } |
| 1014 | 1018 | ||
| 1015 | int SrsConnectAppPacket::decode(SrsStream* stream) | 1019 | int SrsConnectAppPacket::decode(SrsStream* stream) |
| @@ -1053,6 +1057,77 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | @@ -1053,6 +1057,77 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | ||
| 1053 | return ret; | 1057 | return ret; |
| 1054 | } | 1058 | } |
| 1055 | 1059 | ||
| 1060 | +SrsConnectAppResPacket::SrsConnectAppResPacket() | ||
| 1061 | +{ | ||
| 1062 | + command_name = RTMP_AMF0_COMMAND_CONNECT; | ||
| 1063 | + transaction_id = 1; | ||
| 1064 | + props = NULL; | ||
| 1065 | + info = NULL; | ||
| 1066 | +} | ||
| 1067 | + | ||
| 1068 | +SrsConnectAppResPacket::~SrsConnectAppResPacket() | ||
| 1069 | +{ | ||
| 1070 | + if (props) { | ||
| 1071 | + delete props; | ||
| 1072 | + props = NULL; | ||
| 1073 | + } | ||
| 1074 | + | ||
| 1075 | + if (info) { | ||
| 1076 | + delete info; | ||
| 1077 | + info = NULL; | ||
| 1078 | + } | ||
| 1079 | +} | ||
| 1080 | + | ||
| 1081 | +int SrsConnectAppResPacket::get_perfer_cid() | ||
| 1082 | +{ | ||
| 1083 | + return RTMP_CID_OverConnection; | ||
| 1084 | +} | ||
| 1085 | + | ||
| 1086 | +int SrsConnectAppResPacket::get_message_type() | ||
| 1087 | +{ | ||
| 1088 | + return RTMP_MSG_AMF0CommandMessage; | ||
| 1089 | +} | ||
| 1090 | + | ||
| 1091 | +int SrsConnectAppResPacket::get_size() | ||
| 1092 | +{ | ||
| 1093 | + return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size() | ||
| 1094 | + + srs_amf0_get_object_size(props)+ srs_amf0_get_object_size(info); | ||
| 1095 | +} | ||
| 1096 | + | ||
| 1097 | +int SrsConnectAppResPacket::encode_packet(SrsStream* stream) | ||
| 1098 | +{ | ||
| 1099 | + int ret = ERROR_SUCCESS; | ||
| 1100 | + | ||
| 1101 | + if ((ret = srs_amf0_write_string(stream, command_name)) != ERROR_SUCCESS) { | ||
| 1102 | + srs_error("encode command_name failed. ret=%d", ret); | ||
| 1103 | + return ret; | ||
| 1104 | + } | ||
| 1105 | + srs_verbose("encode command_name success."); | ||
| 1106 | + | ||
| 1107 | + if ((ret = srs_amf0_write_number(stream, transaction_id)) != ERROR_SUCCESS) { | ||
| 1108 | + srs_error("encode transaction_id failed. ret=%d", ret); | ||
| 1109 | + return ret; | ||
| 1110 | + } | ||
| 1111 | + srs_verbose("encode transaction_id success."); | ||
| 1112 | + | ||
| 1113 | + if ((ret = srs_amf0_write_object(stream, props)) != ERROR_SUCCESS) { | ||
| 1114 | + srs_error("encode props failed. ret=%d", ret); | ||
| 1115 | + return ret; | ||
| 1116 | + } | ||
| 1117 | + srs_verbose("encode props success."); | ||
| 1118 | + | ||
| 1119 | + if ((ret = srs_amf0_write_object(stream, info)) != ERROR_SUCCESS) { | ||
| 1120 | + srs_error("encode info failed. ret=%d", ret); | ||
| 1121 | + return ret; | ||
| 1122 | + } | ||
| 1123 | + srs_verbose("encode info success."); | ||
| 1124 | + | ||
| 1125 | + | ||
| 1126 | + srs_info("encode connect app response packet success."); | ||
| 1127 | + | ||
| 1128 | + return ret; | ||
| 1129 | +} | ||
| 1130 | + | ||
| 1056 | SrsSetWindowAckSizePacket::SrsSetWindowAckSizePacket() | 1131 | SrsSetWindowAckSizePacket::SrsSetWindowAckSizePacket() |
| 1057 | { | 1132 | { |
| 1058 | ackowledgement_window_size = 0; | 1133 | ackowledgement_window_size = 0; |
| @@ -324,6 +324,34 @@ public: | @@ -324,6 +324,34 @@ public: | ||
| 324 | public: | 324 | public: |
| 325 | virtual int decode(SrsStream* stream); | 325 | virtual int decode(SrsStream* stream); |
| 326 | }; | 326 | }; |
| 327 | +/** | ||
| 328 | +* response for SrsConnectAppPacket. | ||
| 329 | +*/ | ||
| 330 | +class SrsConnectAppResPacket : public SrsPacket | ||
| 331 | +{ | ||
| 332 | +private: | ||
| 333 | + typedef SrsPacket super; | ||
| 334 | +protected: | ||
| 335 | + virtual const char* get_class_name() | ||
| 336 | + { | ||
| 337 | + return CLASS_NAME_STRING(SrsConnectAppResPacket); | ||
| 338 | + } | ||
| 339 | +public: | ||
| 340 | + std::string command_name; | ||
| 341 | + double transaction_id; | ||
| 342 | + SrsAmf0Object* props; | ||
| 343 | + SrsAmf0Object* info; | ||
| 344 | +public: | ||
| 345 | + SrsConnectAppResPacket(); | ||
| 346 | + virtual ~SrsConnectAppResPacket(); | ||
| 347 | +public: | ||
| 348 | + virtual int get_perfer_cid(); | ||
| 349 | +public: | ||
| 350 | + virtual int get_message_type(); | ||
| 351 | +protected: | ||
| 352 | + virtual int get_size(); | ||
| 353 | + virtual int encode_packet(SrsStream* stream); | ||
| 354 | +}; | ||
| 327 | 355 | ||
| 328 | /** | 356 | /** |
| 329 | * 5.5. Window Acknowledgement Size (5) | 357 | * 5.5. Window Acknowledgement Size (5) |
| @@ -78,6 +78,15 @@ void SrsStream::skip(int size) | @@ -78,6 +78,15 @@ void SrsStream::skip(int size) | ||
| 78 | p += size; | 78 | p += size; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | +int SrsStream::pos() | ||
| 82 | +{ | ||
| 83 | + if (empty()) { | ||
| 84 | + return 0; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + return p - bytes; | ||
| 88 | +} | ||
| 89 | + | ||
| 81 | int8_t SrsStream::read_1bytes() | 90 | int8_t SrsStream::read_1bytes() |
| 82 | { | 91 | { |
| 83 | srs_assert(require(1)); | 92 | srs_assert(require(1)); |
| @@ -141,6 +150,22 @@ std::string SrsStream::read_string(int len) | @@ -141,6 +150,22 @@ std::string SrsStream::read_string(int len) | ||
| 141 | return value; | 150 | return value; |
| 142 | } | 151 | } |
| 143 | 152 | ||
| 153 | +void SrsStream::write_1bytes(int8_t value) | ||
| 154 | +{ | ||
| 155 | + srs_assert(require(1)); | ||
| 156 | + | ||
| 157 | + *p++ = value; | ||
| 158 | +} | ||
| 159 | + | ||
| 160 | +void SrsStream::write_2bytes(int16_t value) | ||
| 161 | +{ | ||
| 162 | + srs_assert(require(2)); | ||
| 163 | + | ||
| 164 | + pp = (char*)&value; | ||
| 165 | + *p++ = pp[1]; | ||
| 166 | + *p++ = pp[0]; | ||
| 167 | +} | ||
| 168 | + | ||
| 144 | void SrsStream::write_4bytes(int32_t value) | 169 | void SrsStream::write_4bytes(int32_t value) |
| 145 | { | 170 | { |
| 146 | srs_assert(require(4)); | 171 | srs_assert(require(4)); |
| @@ -152,10 +177,26 @@ void SrsStream::write_4bytes(int32_t value) | @@ -152,10 +177,26 @@ void SrsStream::write_4bytes(int32_t value) | ||
| 152 | *p++ = pp[0]; | 177 | *p++ = pp[0]; |
| 153 | } | 178 | } |
| 154 | 179 | ||
| 155 | -void SrsStream::write_1bytes(int8_t value) | 180 | +void SrsStream::write_8bytes(int64_t value) |
| 156 | { | 181 | { |
| 157 | - srs_assert(require(1)); | 182 | + srs_assert(require(8)); |
| 158 | 183 | ||
| 159 | - *p++ = value; | 184 | + pp = (char*)&value; |
| 185 | + *p++ = pp[7]; | ||
| 186 | + *p++ = pp[6]; | ||
| 187 | + *p++ = pp[5]; | ||
| 188 | + *p++ = pp[4]; | ||
| 189 | + *p++ = pp[3]; | ||
| 190 | + *p++ = pp[2]; | ||
| 191 | + *p++ = pp[1]; | ||
| 192 | + *p++ = pp[0]; | ||
| 193 | +} | ||
| 194 | + | ||
| 195 | +void SrsStream::write_string(std::string value) | ||
| 196 | +{ | ||
| 197 | + srs_assert(require(value.length())); | ||
| 198 | + | ||
| 199 | + memcpy(p, value.data(), value.length()); | ||
| 200 | + p += value.length(); | ||
| 160 | } | 201 | } |
| 161 | 202 |
| @@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 35 | 35 | ||
| 36 | class SrsStream | 36 | class SrsStream |
| 37 | { | 37 | { |
| 38 | -protected: | 38 | +private: |
| 39 | char* p; | 39 | char* p; |
| 40 | char* pp; | 40 | char* pp; |
| 41 | char* bytes; | 41 | char* bytes; |
| @@ -70,6 +70,10 @@ public: | @@ -70,6 +70,10 @@ public: | ||
| 70 | * @size can be any value. positive to forward; nagetive to backward. | 70 | * @size can be any value. positive to forward; nagetive to backward. |
| 71 | */ | 71 | */ |
| 72 | virtual void skip(int size); | 72 | virtual void skip(int size); |
| 73 | + /** | ||
| 74 | + * tell the current pos. | ||
| 75 | + */ | ||
| 76 | + virtual int pos(); | ||
| 73 | public: | 77 | public: |
| 74 | /** | 78 | /** |
| 75 | * get 1bytes char from stream. | 79 | * get 1bytes char from stream. |
| @@ -93,13 +97,25 @@ public: | @@ -93,13 +97,25 @@ public: | ||
| 93 | virtual std::string read_string(int len); | 97 | virtual std::string read_string(int len); |
| 94 | public: | 98 | public: |
| 95 | /** | 99 | /** |
| 100 | + * write 1bytes char to stream. | ||
| 101 | + */ | ||
| 102 | + virtual void write_1bytes(int8_t value); | ||
| 103 | + /** | ||
| 104 | + * write 2bytes int to stream. | ||
| 105 | + */ | ||
| 106 | + virtual void write_2bytes(int16_t value); | ||
| 107 | + /** | ||
| 96 | * write 4bytes int to stream. | 108 | * write 4bytes int to stream. |
| 97 | */ | 109 | */ |
| 98 | virtual void write_4bytes(int32_t value); | 110 | virtual void write_4bytes(int32_t value); |
| 99 | /** | 111 | /** |
| 100 | - * write 1bytes char to stream. | 112 | + * write 8bytes int to stream. |
| 101 | */ | 113 | */ |
| 102 | - virtual void write_1bytes(int8_t value); | 114 | + virtual void write_8bytes(int64_t value); |
| 115 | + /** | ||
| 116 | + * write string to stream | ||
| 117 | + */ | ||
| 118 | + virtual void write_string(std::string value); | ||
| 103 | }; | 119 | }; |
| 104 | 120 | ||
| 105 | #endif | 121 | #endif |
-
请 注册 或 登录 后发表评论