正在显示
6 个修改的文件
包含
344 行增加
和
26 行删除
@@ -54,6 +54,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -54,6 +54,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
54 | #define RTMP_AMF0_Invalid 0x3F | 54 | #define RTMP_AMF0_Invalid 0x3F |
55 | 55 | ||
56 | int srs_amf0_get_object_eof_size(); | 56 | int srs_amf0_get_object_eof_size(); |
57 | +int srs_amf0_get_any_size(SrsAmf0Any* value); | ||
57 | int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&); | 58 | int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&); |
58 | int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*); | 59 | int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*); |
59 | int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value); | 60 | int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value); |
@@ -88,43 +89,51 @@ bool SrsAmf0Any::is_object() | @@ -88,43 +89,51 @@ bool SrsAmf0Any::is_object() | ||
88 | return marker == RTMP_AMF0_Object; | 89 | return marker == RTMP_AMF0_Object; |
89 | } | 90 | } |
90 | 91 | ||
92 | +bool SrsAmf0Any::is_ecma_array() | ||
93 | +{ | ||
94 | + return marker == RTMP_AMF0_EcmaArray; | ||
95 | +} | ||
96 | + | ||
91 | bool SrsAmf0Any::is_object_eof() | 97 | bool SrsAmf0Any::is_object_eof() |
92 | { | 98 | { |
93 | return marker == RTMP_AMF0_ObjectEnd; | 99 | return marker == RTMP_AMF0_ObjectEnd; |
94 | } | 100 | } |
95 | 101 | ||
96 | -SrsAmf0String::SrsAmf0String() | 102 | +SrsAmf0String::SrsAmf0String(const char* _value) |
97 | { | 103 | { |
98 | marker = RTMP_AMF0_String; | 104 | marker = RTMP_AMF0_String; |
105 | + if (_value) { | ||
106 | + value = _value; | ||
107 | + } | ||
99 | } | 108 | } |
100 | 109 | ||
101 | SrsAmf0String::~SrsAmf0String() | 110 | SrsAmf0String::~SrsAmf0String() |
102 | { | 111 | { |
103 | } | 112 | } |
104 | 113 | ||
105 | -SrsAmf0Boolean::SrsAmf0Boolean() | 114 | +SrsAmf0Boolean::SrsAmf0Boolean(bool _value) |
106 | { | 115 | { |
107 | marker = RTMP_AMF0_Boolean; | 116 | marker = RTMP_AMF0_Boolean; |
108 | - value = false; | 117 | + value = _value; |
109 | } | 118 | } |
110 | 119 | ||
111 | SrsAmf0Boolean::~SrsAmf0Boolean() | 120 | SrsAmf0Boolean::~SrsAmf0Boolean() |
112 | { | 121 | { |
113 | } | 122 | } |
114 | 123 | ||
115 | -SrsAmf0Number::SrsAmf0Number() | 124 | +SrsAmf0Number::SrsAmf0Number(double _value) |
116 | { | 125 | { |
117 | marker = RTMP_AMF0_Number; | 126 | marker = RTMP_AMF0_Number; |
118 | - value = 0; | 127 | + value = _value; |
119 | } | 128 | } |
120 | 129 | ||
121 | SrsAmf0Number::~SrsAmf0Number() | 130 | SrsAmf0Number::~SrsAmf0Number() |
122 | { | 131 | { |
123 | - marker = RTMP_AMF0_ObjectEnd; | ||
124 | } | 132 | } |
125 | 133 | ||
126 | SrsAmf0ObjectEOF::SrsAmf0ObjectEOF() | 134 | SrsAmf0ObjectEOF::SrsAmf0ObjectEOF() |
127 | { | 135 | { |
136 | + marker = RTMP_AMF0_ObjectEnd; | ||
128 | utf8_empty = 0x00; | 137 | utf8_empty = 0x00; |
129 | } | 138 | } |
130 | 139 | ||
@@ -173,6 +182,47 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name) | @@ -173,6 +182,47 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name) | ||
173 | return prop; | 182 | return prop; |
174 | } | 183 | } |
175 | 184 | ||
185 | +SrsASrsAmf0EcmaArray::SrsASrsAmf0EcmaArray() | ||
186 | +{ | ||
187 | + marker = RTMP_AMF0_EcmaArray; | ||
188 | +} | ||
189 | + | ||
190 | +SrsASrsAmf0EcmaArray::~SrsASrsAmf0EcmaArray() | ||
191 | +{ | ||
192 | + std::map<std::string, SrsAmf0Any*>::iterator it; | ||
193 | + for (it = properties.begin(); it != properties.end(); ++it) { | ||
194 | + SrsAmf0Any* any = it->second; | ||
195 | + delete any; | ||
196 | + } | ||
197 | + properties.clear(); | ||
198 | +} | ||
199 | + | ||
200 | +SrsAmf0Any* SrsASrsAmf0EcmaArray::get_property(std::string name) | ||
201 | +{ | ||
202 | + std::map<std::string, SrsAmf0Any*>::iterator it; | ||
203 | + | ||
204 | + if ((it = properties.find(name)) == properties.end()) { | ||
205 | + return NULL; | ||
206 | + } | ||
207 | + | ||
208 | + return it->second; | ||
209 | +} | ||
210 | + | ||
211 | +SrsAmf0Any* SrsASrsAmf0EcmaArray::ensure_property_string(std::string name) | ||
212 | +{ | ||
213 | + SrsAmf0Any* prop = get_property(name); | ||
214 | + | ||
215 | + if (!prop) { | ||
216 | + return NULL; | ||
217 | + } | ||
218 | + | ||
219 | + if (!prop->is_string()) { | ||
220 | + return NULL; | ||
221 | + } | ||
222 | + | ||
223 | + return prop; | ||
224 | +} | ||
225 | + | ||
176 | int srs_amf0_read_utf8(SrsStream* stream, std::string& value) | 226 | int srs_amf0_read_utf8(SrsStream* stream, std::string& value) |
177 | { | 227 | { |
178 | int ret = ERROR_SUCCESS; | 228 | int ret = ERROR_SUCCESS; |
@@ -481,6 +531,14 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) | @@ -481,6 +531,14 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) | ||
481 | value = p; | 531 | value = p; |
482 | return ret; | 532 | return ret; |
483 | } | 533 | } |
534 | + case RTMP_AMF0_EcmaArray: { | ||
535 | + SrsASrsAmf0EcmaArray* p = NULL; | ||
536 | + if ((ret = srs_amf0_read_ecma_array(stream, p)) != ERROR_SUCCESS) { | ||
537 | + return ret; | ||
538 | + } | ||
539 | + value = p; | ||
540 | + return ret; | ||
541 | + } | ||
484 | case RTMP_AMF0_Invalid: | 542 | case RTMP_AMF0_Invalid: |
485 | default: { | 543 | default: { |
486 | ret = ERROR_RTMP_AMF0_INVALID; | 544 | ret = ERROR_RTMP_AMF0_INVALID; |
@@ -518,6 +576,10 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value) | @@ -518,6 +576,10 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value) | ||
518 | SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value); | 576 | SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value); |
519 | return srs_amf0_write_object(stream, p); | 577 | return srs_amf0_write_object(stream, p); |
520 | } | 578 | } |
579 | + case RTMP_AMF0_EcmaArray: { | ||
580 | + SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value); | ||
581 | + return srs_amf0_write_ecma_array(stream, p); | ||
582 | + } | ||
521 | case RTMP_AMF0_Invalid: | 583 | case RTMP_AMF0_Invalid: |
522 | default: { | 584 | default: { |
523 | ret = ERROR_RTMP_AMF0_INVALID; | 585 | ret = ERROR_RTMP_AMF0_INVALID; |
@@ -529,6 +591,52 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value) | @@ -529,6 +591,52 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value) | ||
529 | return ret; | 591 | return ret; |
530 | } | 592 | } |
531 | 593 | ||
594 | +int srs_amf0_get_any_size(SrsAmf0Any* value) | ||
595 | +{ | ||
596 | + if (!value) { | ||
597 | + return 0; | ||
598 | + } | ||
599 | + | ||
600 | + int size = 0; | ||
601 | + | ||
602 | + switch (value->marker) { | ||
603 | + case RTMP_AMF0_String: { | ||
604 | + SrsAmf0String* p = srs_amf0_convert<SrsAmf0String>(value); | ||
605 | + size += srs_amf0_get_string_size(p->value); | ||
606 | + break; | ||
607 | + } | ||
608 | + case RTMP_AMF0_Boolean: { | ||
609 | + size += srs_amf0_get_boolean_size(); | ||
610 | + break; | ||
611 | + } | ||
612 | + case RTMP_AMF0_Number: { | ||
613 | + size += srs_amf0_get_number_size(); | ||
614 | + break; | ||
615 | + } | ||
616 | + case RTMP_AMF0_ObjectEnd: { | ||
617 | + size += srs_amf0_get_object_eof_size(); | ||
618 | + break; | ||
619 | + } | ||
620 | + case RTMP_AMF0_Object: { | ||
621 | + SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value); | ||
622 | + size += srs_amf0_get_object_size(p); | ||
623 | + break; | ||
624 | + } | ||
625 | + case RTMP_AMF0_EcmaArray: { | ||
626 | + SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value); | ||
627 | + size += srs_amf0_get_ecma_array_size(p); | ||
628 | + break; | ||
629 | + } | ||
630 | + default: { | ||
631 | + // TOOD: other AMF0 types. | ||
632 | + srs_warn("ignore unkown AMF0 type size."); | ||
633 | + break; | ||
634 | + } | ||
635 | + } | ||
636 | + | ||
637 | + return size; | ||
638 | +} | ||
639 | + | ||
532 | int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) | 640 | int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) |
533 | { | 641 | { |
534 | int ret = ERROR_SUCCESS; | 642 | int ret = ERROR_SUCCESS; |
@@ -699,6 +807,125 @@ int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value) | @@ -699,6 +807,125 @@ int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value) | ||
699 | return ret; | 807 | return ret; |
700 | } | 808 | } |
701 | 809 | ||
810 | +int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value) | ||
811 | +{ | ||
812 | + int ret = ERROR_SUCCESS; | ||
813 | + | ||
814 | + // marker | ||
815 | + if (!stream->require(1)) { | ||
816 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
817 | + srs_error("amf0 read ecma_array marker failed. ret=%d", ret); | ||
818 | + return ret; | ||
819 | + } | ||
820 | + | ||
821 | + char marker = stream->read_1bytes(); | ||
822 | + if (marker != RTMP_AMF0_EcmaArray) { | ||
823 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
824 | + srs_error("amf0 check ecma_array marker failed. " | ||
825 | + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret); | ||
826 | + return ret; | ||
827 | + } | ||
828 | + srs_verbose("amf0 read ecma_array marker success"); | ||
829 | + | ||
830 | + // count | ||
831 | + if (!stream->require(4)) { | ||
832 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
833 | + srs_error("amf0 read ecma_array count failed. ret=%d", ret); | ||
834 | + return ret; | ||
835 | + } | ||
836 | + | ||
837 | + int32_t count = stream->read_4bytes(); | ||
838 | + srs_verbose("amf0 read ecma_array count success. count=%d", count); | ||
839 | + | ||
840 | + // value | ||
841 | + value = new SrsASrsAmf0EcmaArray(); | ||
842 | + value->count = count; | ||
843 | + | ||
844 | + while (!stream->empty()) { | ||
845 | + // property-name: utf8 string | ||
846 | + std::string property_name; | ||
847 | + if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) { | ||
848 | + srs_error("amf0 ecma_array read property name failed. ret=%d", ret); | ||
849 | + return ret; | ||
850 | + } | ||
851 | + // property-value: any | ||
852 | + SrsAmf0Any* property_value = NULL; | ||
853 | + if ((ret = srs_amf0_read_any(stream, property_value)) != ERROR_SUCCESS) { | ||
854 | + srs_error("amf0 ecma_array read property_value failed. " | ||
855 | + "name=%s, ret=%d", property_name.c_str(), ret); | ||
856 | + return ret; | ||
857 | + } | ||
858 | + | ||
859 | + // AMF0 Object EOF. | ||
860 | + if (property_name.empty() || !property_value || property_value->is_object_eof()) { | ||
861 | + if (property_value) { | ||
862 | + delete property_value; | ||
863 | + } | ||
864 | + srs_info("amf0 read ecma_array EOF."); | ||
865 | + break; | ||
866 | + } | ||
867 | + | ||
868 | + // add property | ||
869 | + value->properties[property_name] = property_value; | ||
870 | + } | ||
871 | + | ||
872 | + return ret; | ||
873 | +} | ||
874 | +int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value) | ||
875 | +{ | ||
876 | + int ret = ERROR_SUCCESS; | ||
877 | + | ||
878 | + srs_assert(value != NULL); | ||
879 | + | ||
880 | + // marker | ||
881 | + if (!stream->require(1)) { | ||
882 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
883 | + srs_error("amf0 write ecma_array marker failed. ret=%d", ret); | ||
884 | + return ret; | ||
885 | + } | ||
886 | + | ||
887 | + stream->write_1bytes(RTMP_AMF0_EcmaArray); | ||
888 | + srs_verbose("amf0 write ecma_array marker success"); | ||
889 | + | ||
890 | + // count | ||
891 | + if (!stream->require(4)) { | ||
892 | + ret = ERROR_RTMP_AMF0_ENCODE; | ||
893 | + srs_error("amf0 write ecma_array count failed. ret=%d", ret); | ||
894 | + return ret; | ||
895 | + } | ||
896 | + | ||
897 | + stream->write_4bytes(value->count); | ||
898 | + srs_verbose("amf0 write ecma_array count success. count=%d", value->count); | ||
899 | + | ||
900 | + // value | ||
901 | + std::map<std::string, SrsAmf0Any*>::iterator it; | ||
902 | + for (it = value->properties.begin(); it != value->properties.end(); ++it) { | ||
903 | + std::string name = it->first; | ||
904 | + SrsAmf0Any* any = it->second; | ||
905 | + | ||
906 | + if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) { | ||
907 | + srs_error("write ecma_array property name failed. ret=%d", ret); | ||
908 | + return ret; | ||
909 | + } | ||
910 | + | ||
911 | + if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) { | ||
912 | + srs_error("write ecma_array property value failed. ret=%d", ret); | ||
913 | + return ret; | ||
914 | + } | ||
915 | + | ||
916 | + srs_verbose("write amf0 property success. name=%s", name.c_str()); | ||
917 | + } | ||
918 | + | ||
919 | + if ((ret = srs_amf0_write_object_eof(stream, &value->eof)) != ERROR_SUCCESS) { | ||
920 | + srs_error("write ecma_array eof failed. ret=%d", ret); | ||
921 | + return ret; | ||
922 | + } | ||
923 | + | ||
924 | + srs_verbose("write ecma_array object success."); | ||
925 | + | ||
926 | + return ret; | ||
927 | +} | ||
928 | + | ||
702 | int srs_amf0_get_utf8_size(std::string value) | 929 | int srs_amf0_get_utf8_size(std::string value) |
703 | { | 930 | { |
704 | return 2 + value.length(); | 931 | return 2 + value.length(); |
@@ -733,21 +960,29 @@ int srs_amf0_get_object_size(SrsAmf0Object* obj) | @@ -733,21 +960,29 @@ int srs_amf0_get_object_size(SrsAmf0Object* obj) | ||
733 | SrsAmf0Any* value = it->second; | 960 | SrsAmf0Any* value = it->second; |
734 | 961 | ||
735 | size += srs_amf0_get_utf8_size(name); | 962 | size += srs_amf0_get_utf8_size(name); |
963 | + size += srs_amf0_get_any_size(value); | ||
964 | + } | ||
965 | + | ||
966 | + size += srs_amf0_get_object_eof_size(); | ||
967 | + | ||
968 | + return size; | ||
969 | +} | ||
970 | + | ||
971 | +int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr) | ||
972 | +{ | ||
973 | + if (!arr) { | ||
974 | + return 0; | ||
975 | + } | ||
976 | + | ||
977 | + int size = 1 + 4; | ||
978 | + | ||
979 | + std::map<std::string, SrsAmf0Any*>::iterator it; | ||
980 | + for (it = arr->properties.begin(); it != arr->properties.end(); ++it) { | ||
981 | + std::string name = it->first; | ||
982 | + SrsAmf0Any* value = it->second; | ||
736 | 983 | ||
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 | - } | 984 | + size += srs_amf0_get_utf8_size(name); |
985 | + size += srs_amf0_get_any_size(value); | ||
751 | } | 986 | } |
752 | 987 | ||
753 | size += srs_amf0_get_object_eof_size(); | 988 | size += srs_amf0_get_object_eof_size(); |
@@ -56,6 +56,7 @@ struct SrsAmf0Any | @@ -56,6 +56,7 @@ struct SrsAmf0Any | ||
56 | virtual bool is_number(); | 56 | virtual bool is_number(); |
57 | virtual bool is_object(); | 57 | virtual bool is_object(); |
58 | virtual bool is_object_eof(); | 58 | virtual bool is_object_eof(); |
59 | + virtual bool is_ecma_array(); | ||
59 | }; | 60 | }; |
60 | 61 | ||
61 | /** | 62 | /** |
@@ -68,7 +69,7 @@ struct SrsAmf0String : public SrsAmf0Any | @@ -68,7 +69,7 @@ struct SrsAmf0String : public SrsAmf0Any | ||
68 | { | 69 | { |
69 | std::string value; | 70 | std::string value; |
70 | 71 | ||
71 | - SrsAmf0String(); | 72 | + SrsAmf0String(const char* _value = NULL); |
72 | virtual ~SrsAmf0String(); | 73 | virtual ~SrsAmf0String(); |
73 | }; | 74 | }; |
74 | 75 | ||
@@ -83,7 +84,7 @@ struct SrsAmf0Boolean : public SrsAmf0Any | @@ -83,7 +84,7 @@ struct SrsAmf0Boolean : public SrsAmf0Any | ||
83 | { | 84 | { |
84 | bool value; | 85 | bool value; |
85 | 86 | ||
86 | - SrsAmf0Boolean(); | 87 | + SrsAmf0Boolean(bool _value = false); |
87 | virtual ~SrsAmf0Boolean(); | 88 | virtual ~SrsAmf0Boolean(); |
88 | }; | 89 | }; |
89 | 90 | ||
@@ -97,7 +98,7 @@ struct SrsAmf0Number : public SrsAmf0Any | @@ -97,7 +98,7 @@ struct SrsAmf0Number : public SrsAmf0Any | ||
97 | { | 98 | { |
98 | double value; | 99 | double value; |
99 | 100 | ||
100 | - SrsAmf0Number(); | 101 | + SrsAmf0Number(double _value = 0.0); |
101 | virtual ~SrsAmf0Number(); | 102 | virtual ~SrsAmf0Number(); |
102 | }; | 103 | }; |
103 | 104 | ||
@@ -132,6 +133,25 @@ struct SrsAmf0Object : public SrsAmf0Any | @@ -132,6 +133,25 @@ struct SrsAmf0Object : public SrsAmf0Any | ||
132 | }; | 133 | }; |
133 | 134 | ||
134 | /** | 135 | /** |
136 | +* 2.10 ECMA Array Type | ||
137 | +* ecma-array-type = associative-count *(object-property) | ||
138 | +* associative-count = U32 | ||
139 | +* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) | ||
140 | +*/ | ||
141 | +struct SrsASrsAmf0EcmaArray : public SrsAmf0Any | ||
142 | +{ | ||
143 | + int32_t count; | ||
144 | + std::map<std::string, SrsAmf0Any*> properties; | ||
145 | + SrsAmf0ObjectEOF eof; | ||
146 | + | ||
147 | + SrsASrsAmf0EcmaArray(); | ||
148 | + virtual ~SrsASrsAmf0EcmaArray(); | ||
149 | + | ||
150 | + virtual SrsAmf0Any* get_property(std::string name); | ||
151 | + virtual SrsAmf0Any* ensure_property_string(std::string name); | ||
152 | +}; | ||
153 | + | ||
154 | +/** | ||
135 | * read amf0 utf8 string from stream. | 155 | * read amf0 utf8 string from stream. |
136 | * 1.3.1 Strings and UTF-8 | 156 | * 1.3.1 Strings and UTF-8 |
137 | * UTF-8 = U16 *(UTF8-char) | 157 | * UTF-8 = U16 *(UTF8-char) |
@@ -177,6 +197,16 @@ extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value); | @@ -177,6 +197,16 @@ extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value); | ||
177 | extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value); | 197 | extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value); |
178 | 198 | ||
179 | /** | 199 | /** |
200 | +* read amf0 object from stream. | ||
201 | +* 2.10 ECMA Array Type | ||
202 | +* ecma-array-type = associative-count *(object-property) | ||
203 | +* associative-count = U32 | ||
204 | +* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) | ||
205 | +*/ | ||
206 | +extern int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value); | ||
207 | +extern int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value); | ||
208 | + | ||
209 | +/** | ||
180 | * get amf0 objects size. | 210 | * get amf0 objects size. |
181 | */ | 211 | */ |
182 | extern int srs_amf0_get_utf8_size(std::string value); | 212 | extern int srs_amf0_get_utf8_size(std::string value); |
@@ -184,7 +214,8 @@ extern int srs_amf0_get_string_size(std::string value); | @@ -184,7 +214,8 @@ extern int srs_amf0_get_string_size(std::string value); | ||
184 | extern int srs_amf0_get_number_size(); | 214 | extern int srs_amf0_get_number_size(); |
185 | extern int srs_amf0_get_boolean_size(); | 215 | extern int srs_amf0_get_boolean_size(); |
186 | extern int srs_amf0_get_object_size(SrsAmf0Object* obj); | 216 | extern int srs_amf0_get_object_size(SrsAmf0Object* obj); |
187 | - | 217 | +extern int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr); |
218 | + | ||
188 | /** | 219 | /** |
189 | * convert the any to specified object. | 220 | * convert the any to specified object. |
190 | * @return T*, the converted object. never NULL. | 221 | * @return T*, the converted object. never NULL. |
@@ -92,6 +92,12 @@ int SrsClient::do_cycle() | @@ -92,6 +92,12 @@ int SrsClient::do_cycle() | ||
92 | return ret; | 92 | return ret; |
93 | } | 93 | } |
94 | srs_verbose("set peer bandwidth success"); | 94 | srs_verbose("set peer bandwidth success"); |
95 | + | ||
96 | + if ((ret = rtmp->response_connect_app()) != ERROR_SUCCESS) { | ||
97 | + srs_error("response connect app failed. ret=%d", ret); | ||
98 | + return ret; | ||
99 | + } | ||
100 | + srs_verbose("response connect app success"); | ||
95 | 101 | ||
96 | return ret; | 102 | return ret; |
97 | } | 103 | } |
@@ -1061,8 +1061,8 @@ SrsConnectAppResPacket::SrsConnectAppResPacket() | @@ -1061,8 +1061,8 @@ SrsConnectAppResPacket::SrsConnectAppResPacket() | ||
1061 | { | 1061 | { |
1062 | command_name = RTMP_AMF0_COMMAND_CONNECT; | 1062 | command_name = RTMP_AMF0_COMMAND_CONNECT; |
1063 | transaction_id = 1; | 1063 | transaction_id = 1; |
1064 | - props = NULL; | ||
1065 | - info = NULL; | 1064 | + props = new SrsAmf0Object(); |
1065 | + info = new SrsAmf0Object(); | ||
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | SrsConnectAppResPacket::~SrsConnectAppResPacket() | 1068 | SrsConnectAppResPacket::~SrsConnectAppResPacket() |
@@ -30,6 +30,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -30,6 +30,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
30 | #include <srs_core_auto_free.hpp> | 30 | #include <srs_core_auto_free.hpp> |
31 | #include <srs_core_amf0.hpp> | 31 | #include <srs_core_amf0.hpp> |
32 | 32 | ||
33 | +/** | ||
34 | +* the signature for packets to client. | ||
35 | +*/ | ||
36 | +#define RTMP_SIG_FMS_VER "3,5,3,888" | ||
37 | +#define RTMP_SIG_AMF0_VER 3 | ||
38 | +#define RTMP_SIG_SRS_NAME "srs(simple rtmp server)" | ||
39 | +#define RTMP_SIG_SRS_URL "https://github.com/winlinvip/simple-rtmp-server" | ||
40 | +#define RTMP_SIG_SRS_VERSION "0.1" | ||
41 | + | ||
33 | int SrsRequest::discovery_app() | 42 | int SrsRequest::discovery_app() |
34 | { | 43 | { |
35 | int ret = ERROR_SUCCESS; | 44 | int ret = ERROR_SUCCESS; |
@@ -205,3 +214,39 @@ int SrsRtmp::set_peer_bandwidth(int bandwidth, int type) | @@ -205,3 +214,39 @@ int SrsRtmp::set_peer_bandwidth(int bandwidth, int type) | ||
205 | return ret; | 214 | return ret; |
206 | } | 215 | } |
207 | 216 | ||
217 | +int SrsRtmp::response_connect_app() | ||
218 | +{ | ||
219 | + int ret = ERROR_SUCCESS; | ||
220 | + | ||
221 | + SrsMessage* msg = new SrsMessage(); | ||
222 | + SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket(); | ||
223 | + | ||
224 | + pkt->command_name = "_result"; | ||
225 | + | ||
226 | + pkt->props->properties["fmsVer"] = new SrsAmf0String("FMS/"RTMP_SIG_FMS_VER); | ||
227 | + pkt->props->properties["capabilities"] = new SrsAmf0Number(123); | ||
228 | + pkt->props->properties["mode"] = new SrsAmf0Number(1); | ||
229 | + | ||
230 | + pkt->info->properties["level"] = new SrsAmf0String("status"); | ||
231 | + pkt->info->properties["code"] = new SrsAmf0String("NetConnection.Connect.Success"); | ||
232 | + pkt->info->properties["description"] = new SrsAmf0String("Connection succeeded"); | ||
233 | + pkt->info->properties["objectEncoding"] = new SrsAmf0Number(RTMP_SIG_AMF0_VER); | ||
234 | + SrsASrsAmf0EcmaArray* data = new SrsASrsAmf0EcmaArray(); | ||
235 | + pkt->info->properties["data"] = data; | ||
236 | + | ||
237 | + data->properties["version"] = new SrsAmf0String(RTMP_SIG_FMS_VER); | ||
238 | + data->properties["server"] = new SrsAmf0String(RTMP_SIG_SRS_NAME); | ||
239 | + data->properties["srs_url"] = new SrsAmf0String(RTMP_SIG_SRS_URL); | ||
240 | + data->properties["srs_version"] = new SrsAmf0String(RTMP_SIG_SRS_VERSION); | ||
241 | + | ||
242 | + msg->set_packet(pkt); | ||
243 | + | ||
244 | + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
245 | + srs_error("send connect app response message failed. ret=%d", ret); | ||
246 | + return ret; | ||
247 | + } | ||
248 | + srs_info("send connect app response message success."); | ||
249 | + | ||
250 | + return ret; | ||
251 | +} | ||
252 | + |
@@ -79,6 +79,7 @@ public: | @@ -79,6 +79,7 @@ public: | ||
79 | * using the Limit type field. | 79 | * using the Limit type field. |
80 | */ | 80 | */ |
81 | virtual int set_peer_bandwidth(int bandwidth, int type); | 81 | virtual int set_peer_bandwidth(int bandwidth, int type); |
82 | + virtual int response_connect_app(); | ||
82 | }; | 83 | }; |
83 | 84 | ||
84 | #endif | 85 | #endif |
-
请 注册 或 登录 后发表评论