winlin

support amf0 StrictArray(0x0a). 0.9.111.

@@ -230,6 +230,7 @@ Supported operating systems and hardware: @@ -230,6 +230,7 @@ Supported operating systems and hardware:
230 * 2013-10-17, Created.<br/> 230 * 2013-10-17, Created.<br/>
231 231
232 ## History 232 ## History
  233 +* v1.0, 2014-05-22, support amf0 StrictArray(0x0a). 0.9.111.
233 * v1.0, 2014-05-22, support flv parser, add amf0 to librtmp. 0.9.110 234 * v1.0, 2014-05-22, support flv parser, add amf0 to librtmp. 0.9.110
234 * v1.0, 2014-05-22, fix [#74](https://github.com/winlinvip/simple-rtmp-server/issues/74), add tcUrl for http callback on_connect, 0.9.109 235 * v1.0, 2014-05-22, fix [#74](https://github.com/winlinvip/simple-rtmp-server/issues/74), add tcUrl for http callback on_connect, 0.9.109
235 * v1.0, 2014-05-19, support http heartbeat, 0.9.107 236 * v1.0, 2014-05-19, support http heartbeat, 0.9.107
@@ -484,6 +484,12 @@ amf0_bool srs_amf0_is_ecma_array(srs_amf0_t amf0) @@ -484,6 +484,12 @@ amf0_bool srs_amf0_is_ecma_array(srs_amf0_t amf0)
484 return any->is_ecma_array(); 484 return any->is_ecma_array();
485 } 485 }
486 486
  487 +amf0_bool srs_amf0_is_strict_array(srs_amf0_t amf0)
  488 +{
  489 + SrsAmf0Any* any = (SrsAmf0Any*)amf0;
  490 + return any->is_strict_array();
  491 +}
  492 +
487 const char* srs_amf0_to_string(srs_amf0_t amf0) 493 const char* srs_amf0_to_string(srs_amf0_t amf0)
488 { 494 {
489 SrsAmf0Any* any = (SrsAmf0Any*)amf0; 495 SrsAmf0Any* any = (SrsAmf0Any*)amf0;
@@ -520,32 +526,44 @@ srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index) @@ -520,32 +526,44 @@ srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index)
520 return (srs_amf0_t)obj->value_at(index); 526 return (srs_amf0_t)obj->value_at(index);
521 } 527 }
522 528
523 -int srs_amf0_array_property_count(srs_amf0_t amf0) 529 +int srs_amf0_ecma_array_property_count(srs_amf0_t amf0)
524 { 530 {
525 SrsAmf0EcmaArray * obj = (SrsAmf0EcmaArray*)amf0; 531 SrsAmf0EcmaArray * obj = (SrsAmf0EcmaArray*)amf0;
526 return obj->count(); 532 return obj->count();
527 } 533 }
528 534
529 -const char* srs_amf0_array_property_name_at(srs_amf0_t amf0, int index) 535 +const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index)
530 { 536 {
531 SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; 537 SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0;
532 return obj->key_raw_at(index); 538 return obj->key_raw_at(index);
533 } 539 }
534 540
535 -srs_amf0_t srs_amf0_array_property_value_at(srs_amf0_t amf0, int index) 541 +srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index)
536 { 542 {
537 SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; 543 SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0;
538 return (srs_amf0_t)obj->value_at(index); 544 return (srs_amf0_t)obj->value_at(index);
539 } 545 }
540 546
541 -void __srs_amf0_do_print(SrsAmf0Any* any, stringstream& ss, int& level) 547 +int srs_amf0_strict_array_property_count(srs_amf0_t amf0)
542 { 548 {
543 - if (true) {  
544 - for (int i = 0; i < level; i++) {  
545 - ss << " ";  
546 - } 549 + SrsAmf0EcmaArray * obj = (SrsAmf0EcmaArray*)amf0;
  550 + return obj->count();
  551 +}
  552 +
  553 +srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index)
  554 +{
  555 + SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0;
  556 + return (srs_amf0_t)obj->value_at(index);
  557 +}
  558 +
  559 +void __srs_fill_level_spaces(stringstream& ss, int level)
  560 +{
  561 + for (int i = 0; i < level; i++) {
  562 + ss << " ";
547 } 563 }
548 - 564 +}
  565 +void __srs_amf0_do_print(SrsAmf0Any* any, stringstream& ss, int level)
  566 +{
549 if (any->is_boolean()) { 567 if (any->is_boolean()) {
550 ss << "Boolean " << (any->to_boolean()? "true":"false") << endl; 568 ss << "Boolean " << (any->to_boolean()? "true":"false") << endl;
551 } else if (any->is_number()) { 569 } else if (any->is_number()) {
@@ -558,26 +576,36 @@ void __srs_amf0_do_print(SrsAmf0Any* any, stringstream& ss, int& level) @@ -558,26 +576,36 @@ void __srs_amf0_do_print(SrsAmf0Any* any, stringstream& ss, int& level)
558 SrsAmf0EcmaArray* obj = any->to_ecma_array(); 576 SrsAmf0EcmaArray* obj = any->to_ecma_array();
559 ss << "EcmaArray " << "(" << obj->count() << " items)" << endl; 577 ss << "EcmaArray " << "(" << obj->count() << " items)" << endl;
560 for (int i = 0; i < obj->count(); i++) { 578 for (int i = 0; i < obj->count(); i++) {
561 - ss << " Property '" << obj->key_at(i) << "' ";  
562 - if (obj->value_at(i)->is_object() || obj->value_at(i)->is_ecma_array()) {  
563 - int next_level = level + 1;  
564 - __srs_amf0_do_print(obj->value_at(i), ss, next_level); 579 + __srs_fill_level_spaces(ss, level + 1);
  580 + ss << "Elem '" << obj->key_at(i) << "' ";
  581 + if (obj->value_at(i)->is_complex_object()) {
  582 + __srs_amf0_do_print(obj->value_at(i), ss, level + 1);
565 } else { 583 } else {
566 - int next_level = 0;  
567 - __srs_amf0_do_print(obj->value_at(i), ss, next_level); 584 + __srs_amf0_do_print(obj->value_at(i), ss, 0);
  585 + }
  586 + }
  587 + } else if (any->is_strict_array()) {
  588 + SrsAmf0StrictArray* obj = any->to_strict_array();
  589 + ss << "StrictArray " << "(" << obj->count() << " items)" << endl;
  590 + for (int i = 0; i < obj->count(); i++) {
  591 + __srs_fill_level_spaces(ss, level + 1);
  592 + ss << "Elem ";
  593 + if (obj->at(i)->is_complex_object()) {
  594 + __srs_amf0_do_print(obj->at(i), ss, level + 1);
  595 + } else {
  596 + __srs_amf0_do_print(obj->at(i), ss, 0);
568 } 597 }
569 } 598 }
570 } else if (any->is_object()) { 599 } else if (any->is_object()) {
571 SrsAmf0Object* obj = any->to_object(); 600 SrsAmf0Object* obj = any->to_object();
572 ss << "Object " << "(" << obj->count() << " items)" << endl; 601 ss << "Object " << "(" << obj->count() << " items)" << endl;
573 for (int i = 0; i < obj->count(); i++) { 602 for (int i = 0; i < obj->count(); i++) {
574 - ss << " Property '" << obj->key_at(i) << "' ";  
575 - if (obj->value_at(i)->is_object() || obj->value_at(i)->is_ecma_array()) {  
576 - int next_level = level + 1;  
577 - __srs_amf0_do_print(obj->value_at(i), ss, next_level); 603 + __srs_fill_level_spaces(ss, level + 1);
  604 + ss << "Property '" << obj->key_at(i) << "' ";
  605 + if (obj->value_at(i)->is_complex_object()) {
  606 + __srs_amf0_do_print(obj->value_at(i), ss, level + 1);
578 } else { 607 } else {
579 - int next_level = 0;  
580 - __srs_amf0_do_print(obj->value_at(i), ss, next_level); 608 + __srs_amf0_do_print(obj->value_at(i), ss, 0);
581 } 609 }
582 } 610 }
583 } else { 611 } else {
@@ -587,23 +615,29 @@ void __srs_amf0_do_print(SrsAmf0Any* any, stringstream& ss, int& level) @@ -587,23 +615,29 @@ void __srs_amf0_do_print(SrsAmf0Any* any, stringstream& ss, int& level)
587 615
588 char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize) 616 char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize)
589 { 617 {
  618 + if (!amf0) {
  619 + return NULL;
  620 + }
  621 +
590 stringstream ss; 622 stringstream ss;
591 623
592 ss.precision(1); 624 ss.precision(1);
593 625
594 SrsAmf0Any* any = (SrsAmf0Any*)amf0; 626 SrsAmf0Any* any = (SrsAmf0Any*)amf0;
595 627
596 - int level = 0;  
597 - __srs_amf0_do_print(any, ss, level); 628 + __srs_amf0_do_print(any, ss, 0);
598 629
599 string str = ss.str(); 630 string str = ss.str();
600 if (str.empty()) { 631 if (str.empty()) {
601 return NULL; 632 return NULL;
602 } 633 }
603 634
604 - *pdata = new char[str.length()]; 635 + char* data = new char[str.length() + 1];
  636 + memcpy(data, str.data(), str.length());
  637 + data[str.length()] = 0;
  638 +
  639 + *pdata = data;
605 *psize = str.length(); 640 *psize = str.length();
606 - memcpy(*pdata, str.data(), str.length());  
607 641
608 return *pdata; 642 return *pdata;
609 } 643 }
@@ -176,6 +176,7 @@ amf0_bool srs_amf0_is_number(srs_amf0_t amf0); @@ -176,6 +176,7 @@ amf0_bool srs_amf0_is_number(srs_amf0_t amf0);
176 amf0_bool srs_amf0_is_null(srs_amf0_t amf0); 176 amf0_bool srs_amf0_is_null(srs_amf0_t amf0);
177 amf0_bool srs_amf0_is_object(srs_amf0_t amf0); 177 amf0_bool srs_amf0_is_object(srs_amf0_t amf0);
178 amf0_bool srs_amf0_is_ecma_array(srs_amf0_t amf0); 178 amf0_bool srs_amf0_is_ecma_array(srs_amf0_t amf0);
  179 +amf0_bool srs_amf0_is_strict_array(srs_amf0_t amf0);
179 /* value converter */ 180 /* value converter */
180 const char* srs_amf0_to_string(srs_amf0_t amf0); 181 const char* srs_amf0_to_string(srs_amf0_t amf0);
181 amf0_bool srs_amf0_to_boolean(srs_amf0_t amf0); 182 amf0_bool srs_amf0_to_boolean(srs_amf0_t amf0);
@@ -184,10 +185,13 @@ amf0_number srs_amf0_to_number(srs_amf0_t amf0); @@ -184,10 +185,13 @@ amf0_number srs_amf0_to_number(srs_amf0_t amf0);
184 int srs_amf0_object_property_count(srs_amf0_t amf0); 185 int srs_amf0_object_property_count(srs_amf0_t amf0);
185 const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index); 186 const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index);
186 srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index); 187 srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index);
187 -/* array value converter */  
188 -int srs_amf0_array_property_count(srs_amf0_t amf0);  
189 -const char* srs_amf0_array_property_name_at(srs_amf0_t amf0, int index);  
190 -srs_amf0_t srs_amf0_array_property_value_at(srs_amf0_t amf0, int index); 188 +/* ecma array value converter */
  189 +int srs_amf0_ecma_array_property_count(srs_amf0_t amf0);
  190 +const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index);
  191 +srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index);
  192 +/* strict array value converter */
  193 +int srs_amf0_strict_array_property_count(srs_amf0_t amf0);
  194 +srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index);
191 /* human readable print */ 195 /* human readable print */
192 char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); 196 char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize);
193 197
@@ -251,6 +251,16 @@ bool SrsAmf0Any::is_ecma_array() @@ -251,6 +251,16 @@ bool SrsAmf0Any::is_ecma_array()
251 return marker == RTMP_AMF0_EcmaArray; 251 return marker == RTMP_AMF0_EcmaArray;
252 } 252 }
253 253
  254 +bool SrsAmf0Any::is_strict_array()
  255 +{
  256 + return marker == RTMP_AMF0_StrictArray;
  257 +}
  258 +
  259 +bool SrsAmf0Any::is_complex_object()
  260 +{
  261 + return is_object() || is_object_eof() || is_ecma_array() || is_strict_array();
  262 +}
  263 +
254 string SrsAmf0Any::to_str() 264 string SrsAmf0Any::to_str()
255 { 265 {
256 __SrsAmf0String* p = dynamic_cast<__SrsAmf0String*>(this); 266 __SrsAmf0String* p = dynamic_cast<__SrsAmf0String*>(this);
@@ -293,6 +303,13 @@ SrsAmf0EcmaArray* SrsAmf0Any::to_ecma_array() @@ -293,6 +303,13 @@ SrsAmf0EcmaArray* SrsAmf0Any::to_ecma_array()
293 return p; 303 return p;
294 } 304 }
295 305
  306 +SrsAmf0StrictArray* SrsAmf0Any::to_strict_array()
  307 +{
  308 + SrsAmf0StrictArray* p = dynamic_cast<SrsAmf0StrictArray*>(this);
  309 + srs_assert(p != NULL);
  310 + return p;
  311 +}
  312 +
296 bool SrsAmf0Any::is_object_eof() 313 bool SrsAmf0Any::is_object_eof()
297 { 314 {
298 return marker == RTMP_AMF0_ObjectEnd; 315 return marker == RTMP_AMF0_ObjectEnd;
@@ -338,6 +355,11 @@ SrsAmf0EcmaArray* SrsAmf0Any::ecma_array() @@ -338,6 +355,11 @@ SrsAmf0EcmaArray* SrsAmf0Any::ecma_array()
338 return new SrsAmf0EcmaArray(); 355 return new SrsAmf0EcmaArray();
339 } 356 }
340 357
  358 +SrsAmf0StrictArray* SrsAmf0Any::strict_array()
  359 +{
  360 + return new SrsAmf0StrictArray();
  361 +}
  362 +
341 int SrsAmf0Any::discovery(SrsStream* stream, SrsAmf0Any** ppvalue) 363 int SrsAmf0Any::discovery(SrsStream* stream, SrsAmf0Any** ppvalue)
342 { 364 {
343 int ret = ERROR_SUCCESS; 365 int ret = ERROR_SUCCESS;
@@ -390,6 +412,10 @@ int SrsAmf0Any::discovery(SrsStream* stream, SrsAmf0Any** ppvalue) @@ -390,6 +412,10 @@ int SrsAmf0Any::discovery(SrsStream* stream, SrsAmf0Any** ppvalue)
390 *ppvalue = SrsAmf0Any::ecma_array(); 412 *ppvalue = SrsAmf0Any::ecma_array();
391 return ret; 413 return ret;
392 } 414 }
  415 + case RTMP_AMF0_StrictArray: {
  416 + *ppvalue = SrsAmf0Any::strict_array();
  417 + return ret;
  418 + }
393 case RTMP_AMF0_Invalid: 419 case RTMP_AMF0_Invalid:
394 default: { 420 default: {
395 ret = ERROR_RTMP_AMF0_INVALID; 421 ret = ERROR_RTMP_AMF0_INVALID;
@@ -956,6 +982,137 @@ SrsAmf0Any* SrsAmf0EcmaArray::ensure_property_number(string name) @@ -956,6 +982,137 @@ SrsAmf0Any* SrsAmf0EcmaArray::ensure_property_number(string name)
956 return properties->ensure_property_number(name); 982 return properties->ensure_property_number(name);
957 } 983 }
958 984
  985 +SrsAmf0StrictArray::SrsAmf0StrictArray()
  986 +{
  987 + marker = RTMP_AMF0_StrictArray;
  988 +}
  989 +
  990 +SrsAmf0StrictArray::~SrsAmf0StrictArray()
  991 +{
  992 + std::vector<SrsAmf0Any*>::iterator it;
  993 + for (it = properties.begin(); it != properties.end(); ++it) {
  994 + SrsAmf0Any* any = *it;
  995 + srs_freep(any);
  996 + }
  997 + properties.clear();
  998 +}
  999 +
  1000 +int SrsAmf0StrictArray::total_size()
  1001 +{
  1002 + int size = 1 + 4;
  1003 +
  1004 + for (int i = 0; i < (int)properties.size(); i++){
  1005 + SrsAmf0Any* any = properties[i];
  1006 + size += any->total_size();
  1007 + }
  1008 +
  1009 + return size;
  1010 +}
  1011 +
  1012 +int SrsAmf0StrictArray::read(SrsStream* stream)
  1013 +{
  1014 + int ret = ERROR_SUCCESS;
  1015 +
  1016 + // marker
  1017 + if (!stream->require(1)) {
  1018 + ret = ERROR_RTMP_AMF0_DECODE;
  1019 + srs_error("amf0 read strict_array marker failed. ret=%d", ret);
  1020 + return ret;
  1021 + }
  1022 +
  1023 + char marker = stream->read_1bytes();
  1024 + if (marker != RTMP_AMF0_StrictArray) {
  1025 + ret = ERROR_RTMP_AMF0_DECODE;
  1026 + srs_error("amf0 check strict_array marker failed. "
  1027 + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
  1028 + return ret;
  1029 + }
  1030 + srs_verbose("amf0 read strict_array marker success");
  1031 +
  1032 + // count
  1033 + if (!stream->require(4)) {
  1034 + ret = ERROR_RTMP_AMF0_DECODE;
  1035 + srs_error("amf0 read strict_array count failed. ret=%d", ret);
  1036 + return ret;
  1037 + }
  1038 +
  1039 + int32_t count = stream->read_4bytes();
  1040 + srs_verbose("amf0 read strict_array count success. count=%d", count);
  1041 +
  1042 + // value
  1043 + this->_count = count;
  1044 +
  1045 + for (int i = 0; i < count && !stream->empty(); i++) {
  1046 + // property-value: any
  1047 + SrsAmf0Any* elem = NULL;
  1048 + if ((ret = srs_amf0_read_any(stream, &elem)) != ERROR_SUCCESS) {
  1049 + srs_error("amf0 strict_array read value failed. ret=%d", ret);
  1050 + return ret;
  1051 + }
  1052 +
  1053 + // add property
  1054 + properties.push_back(elem);
  1055 + }
  1056 +
  1057 + return ret;
  1058 +}
  1059 +int SrsAmf0StrictArray::write(SrsStream* stream)
  1060 +{
  1061 + int ret = ERROR_SUCCESS;
  1062 +
  1063 + // marker
  1064 + if (!stream->require(1)) {
  1065 + ret = ERROR_RTMP_AMF0_ENCODE;
  1066 + srs_error("amf0 write strict_array marker failed. ret=%d", ret);
  1067 + return ret;
  1068 + }
  1069 +
  1070 + stream->write_1bytes(RTMP_AMF0_StrictArray);
  1071 + srs_verbose("amf0 write strict_array marker success");
  1072 +
  1073 + // count
  1074 + if (!stream->require(4)) {
  1075 + ret = ERROR_RTMP_AMF0_ENCODE;
  1076 + srs_error("amf0 write strict_array count failed. ret=%d", ret);
  1077 + return ret;
  1078 + }
  1079 +
  1080 + stream->write_4bytes(this->_count);
  1081 + srs_verbose("amf0 write strict_array count success. count=%d", _count);
  1082 +
  1083 + // value
  1084 + for (int i = 0; i < (int)properties.size(); i++) {
  1085 + SrsAmf0Any* any = properties[i];
  1086 +
  1087 + if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {
  1088 + srs_error("write strict_array property value failed. ret=%d", ret);
  1089 + return ret;
  1090 + }
  1091 +
  1092 + srs_verbose("write amf0 property success. name=%s", name.c_str());
  1093 + }
  1094 +
  1095 + srs_verbose("write strict_array object success.");
  1096 +
  1097 + return ret;
  1098 +}
  1099 +
  1100 +void SrsAmf0StrictArray::clear()
  1101 +{
  1102 + properties.clear();
  1103 +}
  1104 +
  1105 +int SrsAmf0StrictArray::count()
  1106 +{
  1107 + return properties.size();
  1108 +}
  1109 +
  1110 +SrsAmf0Any* SrsAmf0StrictArray::at(int index)
  1111 +{
  1112 + srs_assert(index < (int)properties.size());
  1113 + return properties.at(index);
  1114 +}
  1115 +
959 int SrsAmf0Size::utf8(string value) 1116 int SrsAmf0Size::utf8(string value)
960 { 1117 {
961 return 2 + value.length(); 1118 return 2 + value.length();
@@ -1009,6 +1166,15 @@ int SrsAmf0Size::ecma_array(SrsAmf0EcmaArray* arr) @@ -1009,6 +1166,15 @@ int SrsAmf0Size::ecma_array(SrsAmf0EcmaArray* arr)
1009 return arr->total_size(); 1166 return arr->total_size();
1010 } 1167 }
1011 1168
  1169 +int SrsAmf0Size::strict_array(SrsAmf0StrictArray* arr)
  1170 +{
  1171 + if (!arr) {
  1172 + return 0;
  1173 + }
  1174 +
  1175 + return arr->total_size();
  1176 +}
  1177 +
1012 int SrsAmf0Size::any(SrsAmf0Any* o) 1178 int SrsAmf0Size::any(SrsAmf0Any* o)
1013 { 1179 {
1014 if (!o) { 1180 if (!o) {
@@ -31,10 +31,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,10 +31,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
33 #include <string> 33 #include <string>
  34 +#include <vector>
34 35
35 class SrsStream; 36 class SrsStream;
36 class SrsAmf0Object; 37 class SrsAmf0Object;
37 class SrsAmf0EcmaArray; 38 class SrsAmf0EcmaArray;
  39 +class SrsAmf0StrictArray;
38 class __SrsUnSortedHashtable; 40 class __SrsUnSortedHashtable;
39 class __SrsAmf0ObjectEOF; 41 class __SrsAmf0ObjectEOF;
40 42
@@ -96,6 +98,9 @@ public: @@ -96,6 +98,9 @@ public:
96 virtual bool is_object(); 98 virtual bool is_object();
97 virtual bool is_object_eof(); 99 virtual bool is_object_eof();
98 virtual bool is_ecma_array(); 100 virtual bool is_ecma_array();
  101 + virtual bool is_strict_array();
  102 +public:
  103 + virtual bool is_complex_object();
99 public: 104 public:
100 /** 105 /**
101 * get the string of any when is_string() indicates true. 106 * get the string of any when is_string() indicates true.
@@ -123,6 +128,7 @@ public: @@ -123,6 +128,7 @@ public:
123 * user must ensure the type is a ecma array, or assert failed. 128 * user must ensure the type is a ecma array, or assert failed.
124 */ 129 */
125 virtual SrsAmf0EcmaArray* to_ecma_array(); 130 virtual SrsAmf0EcmaArray* to_ecma_array();
  131 + virtual SrsAmf0StrictArray* to_strict_array();
126 public: 132 public:
127 /** 133 /**
128 * get the size of amf0 any, including the marker size. 134 * get the size of amf0 any, including the marker size.
@@ -142,6 +148,7 @@ public: @@ -142,6 +148,7 @@ public:
142 static SrsAmf0Object* object(); 148 static SrsAmf0Object* object();
143 static SrsAmf0Any* object_eof(); 149 static SrsAmf0Any* object_eof();
144 static SrsAmf0EcmaArray* ecma_array(); 150 static SrsAmf0EcmaArray* ecma_array();
  151 + static SrsAmf0StrictArray* strict_array();
145 public: 152 public:
146 static int discovery(SrsStream* stream, SrsAmf0Any** ppvalue); 153 static int discovery(SrsStream* stream, SrsAmf0Any** ppvalue);
147 }; 154 };
@@ -226,6 +233,36 @@ public: @@ -226,6 +233,36 @@ public:
226 }; 233 };
227 234
228 /** 235 /**
  236 +* 2.12 Strict Array Type
  237 +* array-count = U32
  238 +* strict-array-type = array-count *(value-type)
  239 +*/
  240 +class SrsAmf0StrictArray : public SrsAmf0Any
  241 +{
  242 +private:
  243 + std::vector<SrsAmf0Any*> properties;
  244 + int32_t _count;
  245 +
  246 +private:
  247 + // use SrsAmf0Any::strict_array() to create it.
  248 + friend class SrsAmf0Any;
  249 + SrsAmf0StrictArray();
  250 +public:
  251 + virtual ~SrsAmf0StrictArray();
  252 +
  253 +public:
  254 + virtual int total_size();
  255 + virtual int read(SrsStream* stream);
  256 + virtual int write(SrsStream* stream);
  257 +
  258 +public:
  259 + virtual void clear();
  260 + virtual int count();
  261 + // @remark: max index is count().
  262 + virtual SrsAmf0Any* at(int index);
  263 +};
  264 +
  265 +/**
229 * the class to get amf0 object size 266 * the class to get amf0 object size
230 */ 267 */
231 class SrsAmf0Size 268 class SrsAmf0Size
@@ -240,6 +277,7 @@ public: @@ -240,6 +277,7 @@ public:
240 static int object(SrsAmf0Object* obj); 277 static int object(SrsAmf0Object* obj);
241 static int object_eof(); 278 static int object_eof();
242 static int ecma_array(SrsAmf0EcmaArray* arr); 279 static int ecma_array(SrsAmf0EcmaArray* arr);
  280 + static int strict_array(SrsAmf0StrictArray* arr);
243 static int any(SrsAmf0Any* o); 281 static int any(SrsAmf0Any* o);
244 }; 282 };
245 283