正在显示
9 个修改的文件
包含
494 行增加
和
246 行删除
| @@ -45,4 +45,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -45,4 +45,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 45 | #include <stddef.h> | 45 | #include <stddef.h> |
| 46 | #include <sys/types.h> | 46 | #include <sys/types.h> |
| 47 | 47 | ||
| 48 | +// free the p and set to NULL. | ||
| 49 | +// p must be a T*. | ||
| 50 | +#define srs_freep(p) \ | ||
| 51 | + if (p) { \ | ||
| 52 | + delete p; \ | ||
| 53 | + p = NULL; \ | ||
| 54 | + } \ | ||
| 55 | + (void)0 | ||
| 56 | +// free the p which represents a array | ||
| 57 | +#define srs_freepa(p) \ | ||
| 58 | + if (p) { \ | ||
| 59 | + delete[] p; \ | ||
| 60 | + p = NULL; \ | ||
| 61 | + } \ | ||
| 62 | + (void)0 | ||
| 63 | + | ||
| 48 | #endif | 64 | #endif |
| @@ -23,6 +23,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -23,6 +23,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 23 | 23 | ||
| 24 | #include <srs_core_amf0.hpp> | 24 | #include <srs_core_amf0.hpp> |
| 25 | 25 | ||
| 26 | +#include <utility> | ||
| 27 | + | ||
| 26 | #include <srs_core_log.hpp> | 28 | #include <srs_core_log.hpp> |
| 27 | #include <srs_core_error.hpp> | 29 | #include <srs_core_error.hpp> |
| 28 | #include <srs_core_stream.hpp> | 30 | #include <srs_core_stream.hpp> |
| @@ -169,33 +171,76 @@ SrsAmf0ObjectEOF::~SrsAmf0ObjectEOF() | @@ -169,33 +171,76 @@ SrsAmf0ObjectEOF::~SrsAmf0ObjectEOF() | ||
| 169 | { | 171 | { |
| 170 | } | 172 | } |
| 171 | 173 | ||
| 172 | -SrsAmf0Object::SrsAmf0Object() | 174 | +SrsUnSortedHashtable::SrsUnSortedHashtable() |
| 173 | { | 175 | { |
| 174 | - marker = RTMP_AMF0_Object; | ||
| 175 | } | 176 | } |
| 176 | 177 | ||
| 177 | -SrsAmf0Object::~SrsAmf0Object() | 178 | +SrsUnSortedHashtable::~SrsUnSortedHashtable() |
| 178 | { | 179 | { |
| 179 | - std::map<std::string, SrsAmf0Any*>::iterator it; | 180 | + std::vector<SrsObjectPropertyType>::iterator it; |
| 180 | for (it = properties.begin(); it != properties.end(); ++it) { | 181 | for (it = properties.begin(); it != properties.end(); ++it) { |
| 181 | - SrsAmf0Any* any = it->second; | ||
| 182 | - delete any; | 182 | + SrsObjectPropertyType& elem = *it; |
| 183 | + SrsAmf0Any* any = elem.second; | ||
| 184 | + srs_freep(any); | ||
| 183 | } | 185 | } |
| 184 | properties.clear(); | 186 | properties.clear(); |
| 185 | } | 187 | } |
| 186 | 188 | ||
| 187 | -SrsAmf0Any* SrsAmf0Object::get_property(std::string name) | 189 | +int SrsUnSortedHashtable::size() |
| 190 | +{ | ||
| 191 | + return (int)properties.size(); | ||
| 192 | +} | ||
| 193 | + | ||
| 194 | +std::string SrsUnSortedHashtable::key_at(int index) | ||
| 195 | +{ | ||
| 196 | + srs_assert(index < size()); | ||
| 197 | + SrsObjectPropertyType& elem = properties[index]; | ||
| 198 | + return elem.first; | ||
| 199 | +} | ||
| 200 | + | ||
| 201 | +SrsAmf0Any* SrsUnSortedHashtable::value_at(int index) | ||
| 188 | { | 202 | { |
| 189 | - std::map<std::string, SrsAmf0Any*>::iterator it; | 203 | + srs_assert(index < size()); |
| 204 | + SrsObjectPropertyType& elem = properties[index]; | ||
| 205 | + return elem.second; | ||
| 206 | +} | ||
| 207 | + | ||
| 208 | +void SrsUnSortedHashtable::set(std::string key, SrsAmf0Any* value) | ||
| 209 | +{ | ||
| 210 | + std::vector<SrsObjectPropertyType>::iterator it; | ||
| 190 | 211 | ||
| 191 | - if ((it = properties.find(name)) == properties.end()) { | ||
| 192 | - return NULL; | 212 | + for (it = properties.begin(); it != properties.end(); ++it) { |
| 213 | + SrsObjectPropertyType& elem = *it; | ||
| 214 | + std::string name = elem.first; | ||
| 215 | + SrsAmf0Any* any = elem.second; | ||
| 216 | + | ||
| 217 | + if (key == name) { | ||
| 218 | + srs_freep(any); | ||
| 219 | + properties.erase(it); | ||
| 220 | + break; | ||
| 221 | + } | ||
| 193 | } | 222 | } |
| 194 | 223 | ||
| 195 | - return it->second; | 224 | + properties.push_back(std::make_pair(key, value)); |
| 196 | } | 225 | } |
| 197 | 226 | ||
| 198 | -SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name) | 227 | +SrsAmf0Any* SrsUnSortedHashtable::get_property(std::string name) |
| 228 | +{ | ||
| 229 | + std::vector<SrsObjectPropertyType>::iterator it; | ||
| 230 | + | ||
| 231 | + for (it = properties.begin(); it != properties.end(); ++it) { | ||
| 232 | + SrsObjectPropertyType& elem = *it; | ||
| 233 | + std::string key = elem.first; | ||
| 234 | + SrsAmf0Any* any = elem.second; | ||
| 235 | + if (key == name) { | ||
| 236 | + return any; | ||
| 237 | + } | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + return NULL; | ||
| 241 | +} | ||
| 242 | + | ||
| 243 | +SrsAmf0Any* SrsUnSortedHashtable::ensure_property_string(std::string name) | ||
| 199 | { | 244 | { |
| 200 | SrsAmf0Any* prop = get_property(name); | 245 | SrsAmf0Any* prop = get_property(name); |
| 201 | 246 | ||
| @@ -210,6 +255,45 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name) | @@ -210,6 +255,45 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name) | ||
| 210 | return prop; | 255 | return prop; |
| 211 | } | 256 | } |
| 212 | 257 | ||
| 258 | +SrsAmf0Object::SrsAmf0Object() | ||
| 259 | +{ | ||
| 260 | + marker = RTMP_AMF0_Object; | ||
| 261 | +} | ||
| 262 | + | ||
| 263 | +SrsAmf0Object::~SrsAmf0Object() | ||
| 264 | +{ | ||
| 265 | +} | ||
| 266 | + | ||
| 267 | +int SrsAmf0Object::size() | ||
| 268 | +{ | ||
| 269 | + return properties.size(); | ||
| 270 | +} | ||
| 271 | + | ||
| 272 | +std::string SrsAmf0Object::key_at(int index) | ||
| 273 | +{ | ||
| 274 | + return properties.key_at(index); | ||
| 275 | +} | ||
| 276 | + | ||
| 277 | +SrsAmf0Any* SrsAmf0Object::value_at(int index) | ||
| 278 | +{ | ||
| 279 | + return properties.value_at(index); | ||
| 280 | +} | ||
| 281 | + | ||
| 282 | +void SrsAmf0Object::set(std::string key, SrsAmf0Any* value) | ||
| 283 | +{ | ||
| 284 | + properties.set(key, value); | ||
| 285 | +} | ||
| 286 | + | ||
| 287 | +SrsAmf0Any* SrsAmf0Object::get_property(std::string name) | ||
| 288 | +{ | ||
| 289 | + return properties.get_property(name); | ||
| 290 | +} | ||
| 291 | + | ||
| 292 | +SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name) | ||
| 293 | +{ | ||
| 294 | + return properties.ensure_property_string(name); | ||
| 295 | +} | ||
| 296 | + | ||
| 213 | SrsASrsAmf0EcmaArray::SrsASrsAmf0EcmaArray() | 297 | SrsASrsAmf0EcmaArray::SrsASrsAmf0EcmaArray() |
| 214 | { | 298 | { |
| 215 | marker = RTMP_AMF0_EcmaArray; | 299 | marker = RTMP_AMF0_EcmaArray; |
| @@ -217,38 +301,36 @@ SrsASrsAmf0EcmaArray::SrsASrsAmf0EcmaArray() | @@ -217,38 +301,36 @@ SrsASrsAmf0EcmaArray::SrsASrsAmf0EcmaArray() | ||
| 217 | 301 | ||
| 218 | SrsASrsAmf0EcmaArray::~SrsASrsAmf0EcmaArray() | 302 | SrsASrsAmf0EcmaArray::~SrsASrsAmf0EcmaArray() |
| 219 | { | 303 | { |
| 220 | - std::map<std::string, SrsAmf0Any*>::iterator it; | ||
| 221 | - for (it = properties.begin(); it != properties.end(); ++it) { | ||
| 222 | - SrsAmf0Any* any = it->second; | ||
| 223 | - delete any; | ||
| 224 | - } | ||
| 225 | - properties.clear(); | 304 | +} |
| 305 | + | ||
| 306 | +int SrsASrsAmf0EcmaArray::size() | ||
| 307 | +{ | ||
| 308 | + return properties.size(); | ||
| 309 | +} | ||
| 310 | + | ||
| 311 | +std::string SrsASrsAmf0EcmaArray::key_at(int index) | ||
| 312 | +{ | ||
| 313 | + return properties.key_at(index); | ||
| 314 | +} | ||
| 315 | + | ||
| 316 | +SrsAmf0Any* SrsASrsAmf0EcmaArray::value_at(int index) | ||
| 317 | +{ | ||
| 318 | + return properties.value_at(index); | ||
| 319 | +} | ||
| 320 | + | ||
| 321 | +void SrsASrsAmf0EcmaArray::set(std::string key, SrsAmf0Any* value) | ||
| 322 | +{ | ||
| 323 | + properties.set(key, value); | ||
| 226 | } | 324 | } |
| 227 | 325 | ||
| 228 | SrsAmf0Any* SrsASrsAmf0EcmaArray::get_property(std::string name) | 326 | SrsAmf0Any* SrsASrsAmf0EcmaArray::get_property(std::string name) |
| 229 | { | 327 | { |
| 230 | - std::map<std::string, SrsAmf0Any*>::iterator it; | ||
| 231 | - | ||
| 232 | - if ((it = properties.find(name)) == properties.end()) { | ||
| 233 | - return NULL; | ||
| 234 | - } | ||
| 235 | - | ||
| 236 | - return it->second; | 328 | + return properties.get_property(name); |
| 237 | } | 329 | } |
| 238 | 330 | ||
| 239 | SrsAmf0Any* SrsASrsAmf0EcmaArray::ensure_property_string(std::string name) | 331 | SrsAmf0Any* SrsASrsAmf0EcmaArray::ensure_property_string(std::string name) |
| 240 | { | 332 | { |
| 241 | - SrsAmf0Any* prop = get_property(name); | ||
| 242 | - | ||
| 243 | - if (!prop) { | ||
| 244 | - return NULL; | ||
| 245 | - } | ||
| 246 | - | ||
| 247 | - if (!prop->is_string()) { | ||
| 248 | - return NULL; | ||
| 249 | - } | ||
| 250 | - | ||
| 251 | - return prop; | 333 | + return properties.ensure_property_string(name); |
| 252 | } | 334 | } |
| 253 | 335 | ||
| 254 | int srs_amf0_read_utf8(SrsStream* stream, std::string& value) | 336 | int srs_amf0_read_utf8(SrsStream* stream, std::string& value) |
| @@ -877,14 +959,14 @@ int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value) | @@ -877,14 +959,14 @@ int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value) | ||
| 877 | // AMF0 Object EOF. | 959 | // AMF0 Object EOF. |
| 878 | if (property_name.empty() || !property_value || property_value->is_object_eof()) { | 960 | if (property_name.empty() || !property_value || property_value->is_object_eof()) { |
| 879 | if (property_value) { | 961 | if (property_value) { |
| 880 | - delete property_value; | 962 | + srs_freep(property_value); |
| 881 | } | 963 | } |
| 882 | srs_info("amf0 read object EOF."); | 964 | srs_info("amf0 read object EOF."); |
| 883 | break; | 965 | break; |
| 884 | } | 966 | } |
| 885 | 967 | ||
| 886 | // add property | 968 | // add property |
| 887 | - value->properties[property_name] = property_value; | 969 | + value->set(property_name, property_value); |
| 888 | } | 970 | } |
| 889 | 971 | ||
| 890 | return ret; | 972 | return ret; |
| @@ -906,10 +988,9 @@ int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value) | @@ -906,10 +988,9 @@ int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value) | ||
| 906 | srs_verbose("amf0 write object marker success"); | 988 | srs_verbose("amf0 write object marker success"); |
| 907 | 989 | ||
| 908 | // value | 990 | // value |
| 909 | - std::map<std::string, SrsAmf0Any*>::iterator it; | ||
| 910 | - for (it = value->properties.begin(); it != value->properties.end(); ++it) { | ||
| 911 | - std::string name = it->first; | ||
| 912 | - SrsAmf0Any* any = it->second; | 991 | + for (int i = 0; i < value->size(); i++) { |
| 992 | + std::string name = value->key_at(i); | ||
| 993 | + SrsAmf0Any* any = value->value_at(i); | ||
| 913 | 994 | ||
| 914 | if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) { | 995 | if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) { |
| 915 | srs_error("write object property name failed. ret=%d", ret); | 996 | srs_error("write object property name failed. ret=%d", ret); |
| @@ -986,14 +1067,14 @@ int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value) | @@ -986,14 +1067,14 @@ int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value) | ||
| 986 | // AMF0 Object EOF. | 1067 | // AMF0 Object EOF. |
| 987 | if (property_name.empty() || !property_value || property_value->is_object_eof()) { | 1068 | if (property_name.empty() || !property_value || property_value->is_object_eof()) { |
| 988 | if (property_value) { | 1069 | if (property_value) { |
| 989 | - delete property_value; | 1070 | + srs_freep(property_value); |
| 990 | } | 1071 | } |
| 991 | srs_info("amf0 read ecma_array EOF."); | 1072 | srs_info("amf0 read ecma_array EOF."); |
| 992 | break; | 1073 | break; |
| 993 | } | 1074 | } |
| 994 | 1075 | ||
| 995 | // add property | 1076 | // add property |
| 996 | - value->properties[property_name] = property_value; | 1077 | + value->set(property_name, property_value); |
| 997 | } | 1078 | } |
| 998 | 1079 | ||
| 999 | return ret; | 1080 | return ret; |
| @@ -1025,10 +1106,9 @@ int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value) | @@ -1025,10 +1106,9 @@ int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value) | ||
| 1025 | srs_verbose("amf0 write ecma_array count success. count=%d", value->count); | 1106 | srs_verbose("amf0 write ecma_array count success. count=%d", value->count); |
| 1026 | 1107 | ||
| 1027 | // value | 1108 | // value |
| 1028 | - std::map<std::string, SrsAmf0Any*>::iterator it; | ||
| 1029 | - for (it = value->properties.begin(); it != value->properties.end(); ++it) { | ||
| 1030 | - std::string name = it->first; | ||
| 1031 | - SrsAmf0Any* any = it->second; | 1109 | + for (int i = 0; i < value->size(); i++) { |
| 1110 | + std::string name = value->key_at(i); | ||
| 1111 | + SrsAmf0Any* any = value->value_at(i); | ||
| 1032 | 1112 | ||
| 1033 | if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) { | 1113 | if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) { |
| 1034 | srs_error("write ecma_array property name failed. ret=%d", ret); | 1114 | srs_error("write ecma_array property name failed. ret=%d", ret); |
| @@ -1091,10 +1171,9 @@ int srs_amf0_get_object_size(SrsAmf0Object* obj) | @@ -1091,10 +1171,9 @@ int srs_amf0_get_object_size(SrsAmf0Object* obj) | ||
| 1091 | 1171 | ||
| 1092 | int size = 1; | 1172 | int size = 1; |
| 1093 | 1173 | ||
| 1094 | - std::map<std::string, SrsAmf0Any*>::iterator it; | ||
| 1095 | - for (it = obj->properties.begin(); it != obj->properties.end(); ++it) { | ||
| 1096 | - std::string name = it->first; | ||
| 1097 | - SrsAmf0Any* value = it->second; | 1174 | + for (int i = 0; i < obj->size(); i++){ |
| 1175 | + std::string name = obj->key_at(i); | ||
| 1176 | + SrsAmf0Any* value = obj->value_at(i); | ||
| 1098 | 1177 | ||
| 1099 | size += srs_amf0_get_utf8_size(name); | 1178 | size += srs_amf0_get_utf8_size(name); |
| 1100 | size += srs_amf0_get_any_size(value); | 1179 | size += srs_amf0_get_any_size(value); |
| @@ -1113,10 +1192,9 @@ int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr) | @@ -1113,10 +1192,9 @@ int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr) | ||
| 1113 | 1192 | ||
| 1114 | int size = 1 + 4; | 1193 | int size = 1 + 4; |
| 1115 | 1194 | ||
| 1116 | - std::map<std::string, SrsAmf0Any*>::iterator it; | ||
| 1117 | - for (it = arr->properties.begin(); it != arr->properties.end(); ++it) { | ||
| 1118 | - std::string name = it->first; | ||
| 1119 | - SrsAmf0Any* value = it->second; | 1195 | + for (int i = 0; i < arr->size(); i++){ |
| 1196 | + std::string name = arr->key_at(i); | ||
| 1197 | + SrsAmf0Any* value = arr->value_at(i); | ||
| 1120 | 1198 | ||
| 1121 | size += srs_amf0_get_utf8_size(name); | 1199 | size += srs_amf0_get_utf8_size(name); |
| 1122 | size += srs_amf0_get_any_size(value); | 1200 | size += srs_amf0_get_any_size(value); |
| @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,7 +31,7 @@ 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 <map> | 34 | +#include <vector> |
| 35 | 35 | ||
| 36 | class SrsStream; | 36 | class SrsStream; |
| 37 | class SrsAmf0Object; | 37 | class SrsAmf0Object; |
| @@ -140,17 +140,48 @@ struct SrsAmf0ObjectEOF : public SrsAmf0Any | @@ -140,17 +140,48 @@ struct SrsAmf0ObjectEOF : public SrsAmf0Any | ||
| 140 | }; | 140 | }; |
| 141 | 141 | ||
| 142 | /** | 142 | /** |
| 143 | +* to ensure in inserted order. | ||
| 144 | +* for the FMLE will crash when AMF0Object is not ordered by inserted, | ||
| 145 | +* if ordered in map, the string compare order, the FMLE will creash when | ||
| 146 | +* get the response of connect app. | ||
| 147 | +*/ | ||
| 148 | +struct SrsUnSortedHashtable | ||
| 149 | +{ | ||
| 150 | +private: | ||
| 151 | + typedef std::pair<std::string, SrsAmf0Any*> SrsObjectPropertyType; | ||
| 152 | + std::vector<SrsObjectPropertyType> properties; | ||
| 153 | +public: | ||
| 154 | + SrsUnSortedHashtable(); | ||
| 155 | + virtual ~SrsUnSortedHashtable(); | ||
| 156 | + | ||
| 157 | + virtual int size(); | ||
| 158 | + virtual std::string key_at(int index); | ||
| 159 | + virtual SrsAmf0Any* value_at(int index); | ||
| 160 | + virtual void set(std::string key, SrsAmf0Any* value); | ||
| 161 | + | ||
| 162 | + virtual SrsAmf0Any* get_property(std::string name); | ||
| 163 | + virtual SrsAmf0Any* ensure_property_string(std::string name); | ||
| 164 | +}; | ||
| 165 | + | ||
| 166 | +/** | ||
| 143 | * 2.5 Object Type | 167 | * 2.5 Object Type |
| 144 | * anonymous-object-type = object-marker *(object-property) | 168 | * anonymous-object-type = object-marker *(object-property) |
| 145 | * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) | 169 | * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) |
| 146 | */ | 170 | */ |
| 147 | struct SrsAmf0Object : public SrsAmf0Any | 171 | struct SrsAmf0Object : public SrsAmf0Any |
| 148 | { | 172 | { |
| 149 | - std::map<std::string, SrsAmf0Any*> properties; | 173 | +private: |
| 174 | + SrsUnSortedHashtable properties; | ||
| 175 | +public: | ||
| 150 | SrsAmf0ObjectEOF eof; | 176 | SrsAmf0ObjectEOF eof; |
| 151 | 177 | ||
| 152 | SrsAmf0Object(); | 178 | SrsAmf0Object(); |
| 153 | virtual ~SrsAmf0Object(); | 179 | virtual ~SrsAmf0Object(); |
| 180 | + | ||
| 181 | + virtual int size(); | ||
| 182 | + virtual std::string key_at(int index); | ||
| 183 | + virtual SrsAmf0Any* value_at(int index); | ||
| 184 | + virtual void set(std::string key, SrsAmf0Any* value); | ||
| 154 | 185 | ||
| 155 | virtual SrsAmf0Any* get_property(std::string name); | 186 | virtual SrsAmf0Any* get_property(std::string name); |
| 156 | virtual SrsAmf0Any* ensure_property_string(std::string name); | 187 | virtual SrsAmf0Any* ensure_property_string(std::string name); |
| @@ -164,12 +195,19 @@ struct SrsAmf0Object : public SrsAmf0Any | @@ -164,12 +195,19 @@ struct SrsAmf0Object : public SrsAmf0Any | ||
| 164 | */ | 195 | */ |
| 165 | struct SrsASrsAmf0EcmaArray : public SrsAmf0Any | 196 | struct SrsASrsAmf0EcmaArray : public SrsAmf0Any |
| 166 | { | 197 | { |
| 198 | +private: | ||
| 199 | + SrsUnSortedHashtable properties; | ||
| 200 | +public: | ||
| 167 | int32_t count; | 201 | int32_t count; |
| 168 | - std::map<std::string, SrsAmf0Any*> properties; | ||
| 169 | SrsAmf0ObjectEOF eof; | 202 | SrsAmf0ObjectEOF eof; |
| 170 | 203 | ||
| 171 | SrsASrsAmf0EcmaArray(); | 204 | SrsASrsAmf0EcmaArray(); |
| 172 | virtual ~SrsASrsAmf0EcmaArray(); | 205 | virtual ~SrsASrsAmf0EcmaArray(); |
| 206 | + | ||
| 207 | + virtual int size(); | ||
| 208 | + virtual std::string key_at(int index); | ||
| 209 | + virtual SrsAmf0Any* value_at(int index); | ||
| 210 | + virtual void set(std::string key, SrsAmf0Any* value); | ||
| 173 | 211 | ||
| 174 | virtual SrsAmf0Any* get_property(std::string name); | 212 | virtual SrsAmf0Any* get_property(std::string name); |
| 175 | virtual SrsAmf0Any* ensure_property_string(std::string name); | 213 | virtual SrsAmf0Any* ensure_property_string(std::string name); |
| @@ -55,7 +55,7 @@ void SrsBuffer::append(char* bytes, int size) | @@ -55,7 +55,7 @@ void SrsBuffer::append(char* bytes, int size) | ||
| 55 | { | 55 | { |
| 56 | std::vector<char> vec(bytes, bytes + size); | 56 | std::vector<char> vec(bytes, bytes + size); |
| 57 | 57 | ||
| 58 | - data.insert(data.begin(), vec.begin(), vec.end()); | 58 | + data.insert(data.end(), vec.begin(), vec.end()); |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | int SrsBuffer::ensure_buffer_bytes(SrsSocket* skt, int required_size) | 61 | int SrsBuffer::ensure_buffer_bytes(SrsSocket* skt, int required_size) |
| @@ -42,20 +42,9 @@ SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) | @@ -42,20 +42,9 @@ SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) | ||
| 42 | 42 | ||
| 43 | SrsClient::~SrsClient() | 43 | SrsClient::~SrsClient() |
| 44 | { | 44 | { |
| 45 | - if (ip) { | ||
| 46 | - delete[] ip; | ||
| 47 | - ip = NULL; | ||
| 48 | - } | ||
| 49 | - | ||
| 50 | - if (req) { | ||
| 51 | - delete req; | ||
| 52 | - req = NULL; | ||
| 53 | - } | ||
| 54 | - | ||
| 55 | - if (rtmp) { | ||
| 56 | - delete rtmp; | ||
| 57 | - rtmp = NULL; | ||
| 58 | - } | 45 | + srs_freepa(ip); |
| 46 | + srs_freep(req); | ||
| 47 | + srs_freep(rtmp); | ||
| 59 | } | 48 | } |
| 60 | 49 | ||
| 61 | int SrsClient::do_cycle() | 50 | int SrsClient::do_cycle() |
| @@ -199,6 +199,7 @@ messages. | @@ -199,6 +199,7 @@ messages. | ||
| 199 | #define RTMP_AMF0_COMMAND_RESULT "_result" | 199 | #define RTMP_AMF0_COMMAND_RESULT "_result" |
| 200 | #define RTMP_AMF0_COMMAND_RELEASE_STREAM "releaseStream" | 200 | #define RTMP_AMF0_COMMAND_RELEASE_STREAM "releaseStream" |
| 201 | #define RTMP_AMF0_COMMAND_FC_PUBLISH "FCPublish" | 201 | #define RTMP_AMF0_COMMAND_FC_PUBLISH "FCPublish" |
| 202 | +#define RTMP_AMF0_COMMAND_PUBLISH "publish" | ||
| 202 | #define RTMP_AMF0_DATA_SAMPLE_ACCESS "|RtmpSampleAccess" | 203 | #define RTMP_AMF0_DATA_SAMPLE_ACCESS "|RtmpSampleAccess" |
| 203 | 204 | ||
| 204 | /**************************************************************************** | 205 | /**************************************************************************** |
| @@ -260,23 +261,13 @@ SrsProtocol::~SrsProtocol() | @@ -260,23 +261,13 @@ SrsProtocol::~SrsProtocol() | ||
| 260 | 261 | ||
| 261 | for (it = chunk_streams.begin(); it != chunk_streams.end(); ++it) { | 262 | for (it = chunk_streams.begin(); it != chunk_streams.end(); ++it) { |
| 262 | SrsChunkStream* stream = it->second; | 263 | SrsChunkStream* stream = it->second; |
| 263 | - | ||
| 264 | - if (stream) { | ||
| 265 | - delete stream; | ||
| 266 | - } | 264 | + srs_freep(stream); |
| 267 | } | 265 | } |
| 268 | 266 | ||
| 269 | chunk_streams.clear(); | 267 | chunk_streams.clear(); |
| 270 | 268 | ||
| 271 | - if (buffer) { | ||
| 272 | - delete buffer; | ||
| 273 | - buffer = NULL; | ||
| 274 | - } | ||
| 275 | - | ||
| 276 | - if (skt) { | ||
| 277 | - delete skt; | ||
| 278 | - skt = NULL; | ||
| 279 | - } | 269 | + srs_freep(buffer); |
| 270 | + srs_freep(skt); | ||
| 280 | } | 271 | } |
| 281 | 272 | ||
| 282 | int SrsProtocol::recv_message(SrsMessage** pmsg) | 273 | int SrsProtocol::recv_message(SrsMessage** pmsg) |
| @@ -302,13 +293,13 @@ int SrsProtocol::recv_message(SrsMessage** pmsg) | @@ -302,13 +293,13 @@ int SrsProtocol::recv_message(SrsMessage** pmsg) | ||
| 302 | srs_trace("ignore empty message(type=%d, size=%d, time=%d, sid=%d).", | 293 | srs_trace("ignore empty message(type=%d, size=%d, time=%d, sid=%d).", |
| 303 | msg->header.message_type, msg->header.payload_length, | 294 | msg->header.message_type, msg->header.payload_length, |
| 304 | msg->header.timestamp, msg->header.stream_id); | 295 | msg->header.timestamp, msg->header.stream_id); |
| 305 | - delete msg; | 296 | + srs_freep(msg); |
| 306 | continue; | 297 | continue; |
| 307 | } | 298 | } |
| 308 | 299 | ||
| 309 | if ((ret = on_recv_message(msg)) != ERROR_SUCCESS) { | 300 | if ((ret = on_recv_message(msg)) != ERROR_SUCCESS) { |
| 310 | srs_error("hook the received msg failed. ret=%d", ret); | 301 | srs_error("hook the received msg failed. ret=%d", ret); |
| 311 | - delete msg; | 302 | + srs_freep(msg); |
| 312 | return ret; | 303 | return ret; |
| 313 | } | 304 | } |
| 314 | 305 | ||
| @@ -615,13 +606,36 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | @@ -615,13 +606,36 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | ||
| 615 | { | 606 | { |
| 616 | int ret = ERROR_SUCCESS; | 607 | int ret = ERROR_SUCCESS; |
| 617 | 608 | ||
| 618 | - // when not exists cached msg, means get an new message, | ||
| 619 | - // the fmt must be type0/type1 which means new message. | ||
| 620 | - if (!chunk->msg && fmt != RTMP_FMT_TYPE0 && fmt != RTMP_FMT_TYPE1) { | 609 | + /** |
| 610 | + * we should not assert anything about fmt, for the first packet. | ||
| 611 | + * (when first packet, the chunk->msg is NULL). | ||
| 612 | + * the fmt maybe 0/1/2/3, the FMLE will send a 0xC4 for some audio packet. | ||
| 613 | + * the previous packet is: | ||
| 614 | + * 04 // fmt=0, cid=4 | ||
| 615 | + * 00 00 1a // timestamp=26 | ||
| 616 | + * 00 00 9d // payload_length=157 | ||
| 617 | + * 08 // message_type=8(audio) | ||
| 618 | + * 01 00 00 00 // stream_id=1 | ||
| 619 | + * the current packet maybe: | ||
| 620 | + * c4 // fmt=3, cid=4 | ||
| 621 | + * it's ok, for the packet is audio, and timestamp delta is 26. | ||
| 622 | + * the current packet must be parsed as: | ||
| 623 | + * fmt=0, cid=4 | ||
| 624 | + * timestamp=26+26=52 | ||
| 625 | + * payload_length=157 | ||
| 626 | + * message_type=8(audio) | ||
| 627 | + * stream_id=1 | ||
| 628 | + * so we must update the timestamp even fmt=3 for first packet. | ||
| 629 | + */ | ||
| 630 | + // fresh packet used to update the timestamp even fmt=3 for first packet. | ||
| 631 | + bool is_fresh_packet = !chunk->msg; | ||
| 632 | + | ||
| 633 | + // but, we can ensure that when a chunk stream is fresh, | ||
| 634 | + // the fmt must be 0, a new stream. | ||
| 635 | + if (chunk->msg_count == 0 && fmt != RTMP_FMT_TYPE0) { | ||
| 621 | ret = ERROR_RTMP_CHUNK_START; | 636 | ret = ERROR_RTMP_CHUNK_START; |
| 622 | - srs_error("chunk stream start, " | ||
| 623 | - "fmt must be %d or %d, actual is %d. ret=%d", | ||
| 624 | - RTMP_FMT_TYPE0, RTMP_FMT_TYPE1, fmt, ret); | 637 | + srs_error("chunk stream is fresh, " |
| 638 | + "fmt must be %d, actual is %d. ret=%d", RTMP_FMT_TYPE0, fmt, ret); | ||
| 625 | return ret; | 639 | return ret; |
| 626 | } | 640 | } |
| 627 | 641 | ||
| @@ -636,13 +650,12 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | @@ -636,13 +650,12 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | ||
| 636 | 650 | ||
| 637 | // create msg when new chunk stream start | 651 | // create msg when new chunk stream start |
| 638 | if (!chunk->msg) { | 652 | if (!chunk->msg) { |
| 639 | - srs_assert(fmt == RTMP_FMT_TYPE0 || fmt == RTMP_FMT_TYPE1); | ||
| 640 | chunk->msg = new SrsMessage(); | 653 | chunk->msg = new SrsMessage(); |
| 641 | srs_verbose("create message for new chunk, fmt=%d, cid=%d", fmt, chunk->cid); | 654 | srs_verbose("create message for new chunk, fmt=%d, cid=%d", fmt, chunk->cid); |
| 642 | } | 655 | } |
| 643 | 656 | ||
| 644 | // read message header from socket to buffer. | 657 | // read message header from socket to buffer. |
| 645 | - static char mh_sizes[] = {11, 7, 1, 0}; | 658 | + static char mh_sizes[] = {11, 7, 3, 0}; |
| 646 | mh_size = mh_sizes[(int)fmt]; | 659 | mh_size = mh_sizes[(int)fmt]; |
| 647 | srs_verbose("calc chunk message header size. fmt=%d, mh_size=%d", fmt, mh_size); | 660 | srs_verbose("calc chunk message header size. fmt=%d, mh_size=%d", fmt, mh_size); |
| 648 | 661 | ||
| @@ -656,8 +669,7 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | @@ -656,8 +669,7 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | ||
| 656 | // parse the message header. | 669 | // parse the message header. |
| 657 | // see also: ngx_rtmp_recv | 670 | // see also: ngx_rtmp_recv |
| 658 | if (fmt <= RTMP_FMT_TYPE2) { | 671 | if (fmt <= RTMP_FMT_TYPE2) { |
| 659 | - int32_t timestamp_delta; | ||
| 660 | - char* pp = (char*)×tamp_delta; | 672 | + char* pp = (char*)&chunk->header.timestamp_delta; |
| 661 | pp[2] = *p++; | 673 | pp[2] = *p++; |
| 662 | pp[1] = *p++; | 674 | pp[1] = *p++; |
| 663 | pp[0] = *p++; | 675 | pp[0] = *p++; |
| @@ -667,13 +679,13 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | @@ -667,13 +679,13 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | ||
| 667 | // 6.1.2.1. Type 0 | 679 | // 6.1.2.1. Type 0 |
| 668 | // For a type-0 chunk, the absolute timestamp of the message is sent | 680 | // For a type-0 chunk, the absolute timestamp of the message is sent |
| 669 | // here. | 681 | // here. |
| 670 | - chunk->header.timestamp = timestamp_delta; | 682 | + chunk->header.timestamp = chunk->header.timestamp_delta; |
| 671 | } else { | 683 | } else { |
| 672 | // 6.1.2.2. Type 1 | 684 | // 6.1.2.2. Type 1 |
| 673 | // 6.1.2.3. Type 2 | 685 | // 6.1.2.3. Type 2 |
| 674 | // For a type-1 or type-2 chunk, the difference between the previous | 686 | // For a type-1 or type-2 chunk, the difference between the previous |
| 675 | // chunk's timestamp and the current chunk's timestamp is sent here. | 687 | // chunk's timestamp and the current chunk's timestamp is sent here. |
| 676 | - chunk->header.timestamp += timestamp_delta; | 688 | + chunk->header.timestamp += chunk->header.timestamp_delta; |
| 677 | } | 689 | } |
| 678 | 690 | ||
| 679 | // fmt: 0 | 691 | // fmt: 0 |
| @@ -689,7 +701,7 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | @@ -689,7 +701,7 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | ||
| 689 | // 0x00ffffff), this value MUST be 16777215, and the ‘extended | 701 | // 0x00ffffff), this value MUST be 16777215, and the ‘extended |
| 690 | // timestamp header’ MUST be present. Otherwise, this value SHOULD be | 702 | // timestamp header’ MUST be present. Otherwise, this value SHOULD be |
| 691 | // the entire delta. | 703 | // the entire delta. |
| 692 | - chunk->extended_timestamp = (timestamp_delta >= RTMP_EXTENDED_TIMESTAMP); | 704 | + chunk->extended_timestamp = (chunk->header.timestamp_delta >= RTMP_EXTENDED_TIMESTAMP); |
| 693 | if (chunk->extended_timestamp) { | 705 | if (chunk->extended_timestamp) { |
| 694 | chunk->header.timestamp = RTMP_EXTENDED_TIMESTAMP; | 706 | chunk->header.timestamp = RTMP_EXTENDED_TIMESTAMP; |
| 695 | } | 707 | } |
| @@ -722,6 +734,10 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | @@ -722,6 +734,10 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | ||
| 722 | fmt, mh_size, chunk->extended_timestamp, chunk->header.timestamp); | 734 | fmt, mh_size, chunk->extended_timestamp, chunk->header.timestamp); |
| 723 | } | 735 | } |
| 724 | } else { | 736 | } else { |
| 737 | + // update the timestamp even fmt=3 for first stream | ||
| 738 | + if (is_fresh_packet && !chunk->extended_timestamp) { | ||
| 739 | + chunk->header.timestamp += chunk->header.timestamp_delta; | ||
| 740 | + } | ||
| 725 | srs_verbose("header read completed. fmt=%d, size=%d, ext_time=%d", | 741 | srs_verbose("header read completed. fmt=%d, size=%d, ext_time=%d", |
| 726 | fmt, mh_size, chunk->extended_timestamp); | 742 | fmt, mh_size, chunk->extended_timestamp); |
| 727 | } | 743 | } |
| @@ -754,6 +770,9 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | @@ -754,6 +770,9 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | ||
| 754 | // copy header to msg | 770 | // copy header to msg |
| 755 | chunk->msg->header = chunk->header; | 771 | chunk->msg->header = chunk->header; |
| 756 | 772 | ||
| 773 | + // increase the msg count, the chunk stream can accept fmt=1/2/3 message now. | ||
| 774 | + chunk->msg_count++; | ||
| 775 | + | ||
| 757 | return ret; | 776 | return ret; |
| 758 | } | 777 | } |
| 759 | 778 | ||
| @@ -802,7 +821,7 @@ int SrsProtocol::read_message_payload(SrsChunkStream* chunk, int bh_size, int mh | @@ -802,7 +821,7 @@ int SrsProtocol::read_message_payload(SrsChunkStream* chunk, int bh_size, int mh | ||
| 802 | buffer->erase(bh_size + mh_size + payload_size); | 821 | buffer->erase(bh_size + mh_size + payload_size); |
| 803 | chunk->msg->size += payload_size; | 822 | chunk->msg->size += payload_size; |
| 804 | 823 | ||
| 805 | - srs_verbose("chunk payload read complted. bh_size=%d, mh_size=%d, payload_size=%d", bh_size, mh_size, payload_size); | 824 | + srs_verbose("chunk payload read completed. bh_size=%d, mh_size=%d, payload_size=%d", bh_size, mh_size, payload_size); |
| 806 | 825 | ||
| 807 | // got entire RTMP message? | 826 | // got entire RTMP message? |
| 808 | if (chunk->header.payload_length == chunk->msg->size) { | 827 | if (chunk->header.payload_length == chunk->msg->size) { |
| @@ -826,8 +845,10 @@ SrsMessageHeader::SrsMessageHeader() | @@ -826,8 +845,10 @@ SrsMessageHeader::SrsMessageHeader() | ||
| 826 | { | 845 | { |
| 827 | message_type = 0; | 846 | message_type = 0; |
| 828 | payload_length = 0; | 847 | payload_length = 0; |
| 829 | - timestamp = 0; | 848 | + timestamp_delta = 0; |
| 830 | stream_id = 0; | 849 | stream_id = 0; |
| 850 | + | ||
| 851 | + timestamp = 0; | ||
| 831 | } | 852 | } |
| 832 | 853 | ||
| 833 | SrsMessageHeader::~SrsMessageHeader() | 854 | SrsMessageHeader::~SrsMessageHeader() |
| @@ -849,20 +870,23 @@ bool SrsMessageHeader::is_window_ackledgement_size() | @@ -849,20 +870,23 @@ bool SrsMessageHeader::is_window_ackledgement_size() | ||
| 849 | return message_type == RTMP_MSG_WindowAcknowledgementSize; | 870 | return message_type == RTMP_MSG_WindowAcknowledgementSize; |
| 850 | } | 871 | } |
| 851 | 872 | ||
| 873 | +bool SrsMessageHeader::is_set_chunk_size() | ||
| 874 | +{ | ||
| 875 | + return message_type == RTMP_MSG_SetChunkSize; | ||
| 876 | +} | ||
| 877 | + | ||
| 852 | SrsChunkStream::SrsChunkStream(int _cid) | 878 | SrsChunkStream::SrsChunkStream(int _cid) |
| 853 | { | 879 | { |
| 854 | fmt = 0; | 880 | fmt = 0; |
| 855 | cid = _cid; | 881 | cid = _cid; |
| 856 | extended_timestamp = false; | 882 | extended_timestamp = false; |
| 857 | msg = NULL; | 883 | msg = NULL; |
| 884 | + msg_count = 0; | ||
| 858 | } | 885 | } |
| 859 | 886 | ||
| 860 | SrsChunkStream::~SrsChunkStream() | 887 | SrsChunkStream::~SrsChunkStream() |
| 861 | { | 888 | { |
| 862 | - if (msg) { | ||
| 863 | - delete msg; | ||
| 864 | - msg = NULL; | ||
| 865 | - } | 889 | + srs_freep(msg); |
| 866 | } | 890 | } |
| 867 | 891 | ||
| 868 | SrsMessage::SrsMessage() | 892 | SrsMessage::SrsMessage() |
| @@ -875,20 +899,9 @@ SrsMessage::SrsMessage() | @@ -875,20 +899,9 @@ SrsMessage::SrsMessage() | ||
| 875 | 899 | ||
| 876 | SrsMessage::~SrsMessage() | 900 | SrsMessage::~SrsMessage() |
| 877 | { | 901 | { |
| 878 | - if (payload) { | ||
| 879 | - delete[] payload; | ||
| 880 | - payload = NULL; | ||
| 881 | - } | ||
| 882 | - | ||
| 883 | - if (packet) { | ||
| 884 | - delete packet; | ||
| 885 | - packet = NULL; | ||
| 886 | - } | ||
| 887 | - | ||
| 888 | - if (stream) { | ||
| 889 | - delete stream; | ||
| 890 | - stream = NULL; | ||
| 891 | - } | 902 | + srs_freep(payload); |
| 903 | + srs_freep(packet); | ||
| 904 | + srs_freep(stream); | ||
| 892 | } | 905 | } |
| 893 | 906 | ||
| 894 | int SrsMessage::decode_packet() | 907 | int SrsMessage::decode_packet() |
| @@ -962,6 +975,10 @@ int SrsMessage::decode_packet() | @@ -962,6 +975,10 @@ int SrsMessage::decode_packet() | ||
| 962 | srs_info("decode the AMF0/AMF3 command(FMLE FCPublish message)."); | 975 | srs_info("decode the AMF0/AMF3 command(FMLE FCPublish message)."); |
| 963 | packet = new SrsFMLEStartPacket(); | 976 | packet = new SrsFMLEStartPacket(); |
| 964 | return packet->decode(stream); | 977 | return packet->decode(stream); |
| 978 | + } else if(command == RTMP_AMF0_COMMAND_PUBLISH) { | ||
| 979 | + srs_info("decode the AMF0/AMF3 command(publish message)."); | ||
| 980 | + packet = new SrsPublishPacket(); | ||
| 981 | + return packet->decode(stream); | ||
| 965 | } | 982 | } |
| 966 | 983 | ||
| 967 | // default packet to drop message. | 984 | // default packet to drop message. |
| @@ -972,6 +989,10 @@ int SrsMessage::decode_packet() | @@ -972,6 +989,10 @@ int SrsMessage::decode_packet() | ||
| 972 | srs_verbose("start to decode set ack window size message."); | 989 | srs_verbose("start to decode set ack window size message."); |
| 973 | packet = new SrsSetWindowAckSizePacket(); | 990 | packet = new SrsSetWindowAckSizePacket(); |
| 974 | return packet->decode(stream); | 991 | return packet->decode(stream); |
| 992 | + } else if(header.is_set_chunk_size()) { | ||
| 993 | + srs_verbose("start to decode set chunk size message."); | ||
| 994 | + packet = new SrsSetChunkSizePacket(); | ||
| 995 | + return packet->decode(stream); | ||
| 975 | } else { | 996 | } else { |
| 976 | // default packet to drop message. | 997 | // default packet to drop message. |
| 977 | srs_trace("drop the unknown message, type=%d", header.message_type); | 998 | srs_trace("drop the unknown message, type=%d", header.message_type); |
| @@ -1008,9 +1029,7 @@ int SrsMessage::get_perfer_cid() | @@ -1008,9 +1029,7 @@ int SrsMessage::get_perfer_cid() | ||
| 1008 | 1029 | ||
| 1009 | void SrsMessage::set_packet(SrsPacket* pkt, int stream_id) | 1030 | void SrsMessage::set_packet(SrsPacket* pkt, int stream_id) |
| 1010 | { | 1031 | { |
| 1011 | - if (packet) { | ||
| 1012 | - delete packet; | ||
| 1013 | - } | 1032 | + srs_freep(packet); |
| 1014 | 1033 | ||
| 1015 | packet = pkt; | 1034 | packet = pkt; |
| 1016 | 1035 | ||
| @@ -1029,10 +1048,7 @@ int SrsMessage::encode_packet() | @@ -1029,10 +1048,7 @@ int SrsMessage::encode_packet() | ||
| 1029 | } | 1048 | } |
| 1030 | // realloc the payload. | 1049 | // realloc the payload. |
| 1031 | size = 0; | 1050 | size = 0; |
| 1032 | - if (payload) { | ||
| 1033 | - delete[] payload; | ||
| 1034 | - payload = NULL; | ||
| 1035 | - } | 1051 | + srs_freepa(payload); |
| 1036 | 1052 | ||
| 1037 | return packet->encode(size, (char*&)payload); | 1053 | return packet->encode(size, (char*&)payload); |
| 1038 | } | 1054 | } |
| @@ -1087,14 +1103,14 @@ int SrsPacket::encode(int& psize, char*& ppayload) | @@ -1087,14 +1103,14 @@ int SrsPacket::encode(int& psize, char*& ppayload) | ||
| 1087 | 1103 | ||
| 1088 | if ((ret = stream.initialize(payload, size)) != ERROR_SUCCESS) { | 1104 | if ((ret = stream.initialize(payload, size)) != ERROR_SUCCESS) { |
| 1089 | srs_error("initialize the stream failed. ret=%d", ret); | 1105 | srs_error("initialize the stream failed. ret=%d", ret); |
| 1090 | - delete[] payload; | 1106 | + srs_freepa(payload); |
| 1091 | return ret; | 1107 | return ret; |
| 1092 | } | 1108 | } |
| 1093 | } | 1109 | } |
| 1094 | 1110 | ||
| 1095 | if ((ret = encode_packet(&stream)) != ERROR_SUCCESS) { | 1111 | if ((ret = encode_packet(&stream)) != ERROR_SUCCESS) { |
| 1096 | srs_error("encode the packet failed. ret=%d", ret); | 1112 | srs_error("encode the packet failed. ret=%d", ret); |
| 1097 | - delete[] payload; | 1113 | + srs_freepa(payload); |
| 1098 | return ret; | 1114 | return ret; |
| 1099 | } | 1115 | } |
| 1100 | 1116 | ||
| @@ -1132,10 +1148,7 @@ SrsConnectAppPacket::SrsConnectAppPacket() | @@ -1132,10 +1148,7 @@ SrsConnectAppPacket::SrsConnectAppPacket() | ||
| 1132 | 1148 | ||
| 1133 | SrsConnectAppPacket::~SrsConnectAppPacket() | 1149 | SrsConnectAppPacket::~SrsConnectAppPacket() |
| 1134 | { | 1150 | { |
| 1135 | - if (command_object) { | ||
| 1136 | - delete command_object; | ||
| 1137 | - command_object = NULL; | ||
| 1138 | - } | 1151 | + srs_freep(command_object); |
| 1139 | } | 1152 | } |
| 1140 | 1153 | ||
| 1141 | int SrsConnectAppPacket::decode(SrsStream* stream) | 1154 | int SrsConnectAppPacket::decode(SrsStream* stream) |
| @@ -1189,15 +1202,8 @@ SrsConnectAppResPacket::SrsConnectAppResPacket() | @@ -1189,15 +1202,8 @@ SrsConnectAppResPacket::SrsConnectAppResPacket() | ||
| 1189 | 1202 | ||
| 1190 | SrsConnectAppResPacket::~SrsConnectAppResPacket() | 1203 | SrsConnectAppResPacket::~SrsConnectAppResPacket() |
| 1191 | { | 1204 | { |
| 1192 | - if (props) { | ||
| 1193 | - delete props; | ||
| 1194 | - props = NULL; | ||
| 1195 | - } | ||
| 1196 | - | ||
| 1197 | - if (info) { | ||
| 1198 | - delete info; | ||
| 1199 | - info = NULL; | ||
| 1200 | - } | 1205 | + srs_freep(props); |
| 1206 | + srs_freep(info); | ||
| 1201 | } | 1207 | } |
| 1202 | 1208 | ||
| 1203 | int SrsConnectAppResPacket::get_perfer_cid() | 1209 | int SrsConnectAppResPacket::get_perfer_cid() |
| @@ -1259,10 +1265,7 @@ SrsCreateStreamPacket::SrsCreateStreamPacket() | @@ -1259,10 +1265,7 @@ SrsCreateStreamPacket::SrsCreateStreamPacket() | ||
| 1259 | 1265 | ||
| 1260 | SrsCreateStreamPacket::~SrsCreateStreamPacket() | 1266 | SrsCreateStreamPacket::~SrsCreateStreamPacket() |
| 1261 | { | 1267 | { |
| 1262 | - if (command_object) { | ||
| 1263 | - delete command_object; | ||
| 1264 | - command_object = NULL; | ||
| 1265 | - } | 1268 | + srs_freep(command_object); |
| 1266 | } | 1269 | } |
| 1267 | 1270 | ||
| 1268 | int SrsCreateStreamPacket::decode(SrsStream* stream) | 1271 | int SrsCreateStreamPacket::decode(SrsStream* stream) |
| @@ -1305,10 +1308,7 @@ SrsCreateStreamResPacket::SrsCreateStreamResPacket(double _transaction_id, doubl | @@ -1305,10 +1308,7 @@ SrsCreateStreamResPacket::SrsCreateStreamResPacket(double _transaction_id, doubl | ||
| 1305 | 1308 | ||
| 1306 | SrsCreateStreamResPacket::~SrsCreateStreamResPacket() | 1309 | SrsCreateStreamResPacket::~SrsCreateStreamResPacket() |
| 1307 | { | 1310 | { |
| 1308 | - if (command_object) { | ||
| 1309 | - delete command_object; | ||
| 1310 | - command_object = NULL; | ||
| 1311 | - } | 1311 | + srs_freep(command_object); |
| 1312 | } | 1312 | } |
| 1313 | 1313 | ||
| 1314 | int SrsCreateStreamResPacket::get_perfer_cid() | 1314 | int SrsCreateStreamResPacket::get_perfer_cid() |
| @@ -1365,10 +1365,12 @@ SrsFMLEStartPacket::SrsFMLEStartPacket() | @@ -1365,10 +1365,12 @@ SrsFMLEStartPacket::SrsFMLEStartPacket() | ||
| 1365 | { | 1365 | { |
| 1366 | command_name = RTMP_AMF0_COMMAND_CREATE_STREAM; | 1366 | command_name = RTMP_AMF0_COMMAND_CREATE_STREAM; |
| 1367 | transaction_id = 0; | 1367 | transaction_id = 0; |
| 1368 | + command_object = new SrsAmf0Null(); | ||
| 1368 | } | 1369 | } |
| 1369 | 1370 | ||
| 1370 | SrsFMLEStartPacket::~SrsFMLEStartPacket() | 1371 | SrsFMLEStartPacket::~SrsFMLEStartPacket() |
| 1371 | { | 1372 | { |
| 1373 | + srs_freep(command_object); | ||
| 1372 | } | 1374 | } |
| 1373 | 1375 | ||
| 1374 | int SrsFMLEStartPacket::decode(SrsStream* stream) | 1376 | int SrsFMLEStartPacket::decode(SrsStream* stream) |
| @@ -1380,8 +1382,8 @@ int SrsFMLEStartPacket::decode(SrsStream* stream) | @@ -1380,8 +1382,8 @@ int SrsFMLEStartPacket::decode(SrsStream* stream) | ||
| 1380 | return ret; | 1382 | return ret; |
| 1381 | } | 1383 | } |
| 1382 | if (command_name.empty() | 1384 | if (command_name.empty() |
| 1383 | - || command_name != RTMP_AMF0_COMMAND_RELEASE_STREAM | ||
| 1384 | - || command_name != RTMP_AMF0_COMMAND_FC_PUBLISH | 1385 | + || (command_name != RTMP_AMF0_COMMAND_RELEASE_STREAM |
| 1386 | + && command_name != RTMP_AMF0_COMMAND_FC_PUBLISH) | ||
| 1385 | ) { | 1387 | ) { |
| 1386 | ret = ERROR_RTMP_AMF0_DECODE; | 1388 | ret = ERROR_RTMP_AMF0_DECODE; |
| 1387 | srs_error("amf0 decode FMLE start command_name failed. " | 1389 | srs_error("amf0 decode FMLE start command_name failed. " |
| @@ -1394,6 +1396,11 @@ int SrsFMLEStartPacket::decode(SrsStream* stream) | @@ -1394,6 +1396,11 @@ int SrsFMLEStartPacket::decode(SrsStream* stream) | ||
| 1394 | return ret; | 1396 | return ret; |
| 1395 | } | 1397 | } |
| 1396 | 1398 | ||
| 1399 | + if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) { | ||
| 1400 | + srs_error("amf0 decode FMLE start command_object failed. ret=%d", ret); | ||
| 1401 | + return ret; | ||
| 1402 | + } | ||
| 1403 | + | ||
| 1397 | if ((ret = srs_amf0_read_string(stream, stream_name)) != ERROR_SUCCESS) { | 1404 | if ((ret = srs_amf0_read_string(stream, stream_name)) != ERROR_SUCCESS) { |
| 1398 | srs_error("amf0 decode FMLE start stream_name failed. ret=%d", ret); | 1405 | srs_error("amf0 decode FMLE start stream_name failed. ret=%d", ret); |
| 1399 | return ret; | 1406 | return ret; |
| @@ -1414,14 +1421,8 @@ SrsFMLEStartResPacket::SrsFMLEStartResPacket(double _transaction_id) | @@ -1414,14 +1421,8 @@ SrsFMLEStartResPacket::SrsFMLEStartResPacket(double _transaction_id) | ||
| 1414 | 1421 | ||
| 1415 | SrsFMLEStartResPacket::~SrsFMLEStartResPacket() | 1422 | SrsFMLEStartResPacket::~SrsFMLEStartResPacket() |
| 1416 | { | 1423 | { |
| 1417 | - if (command_object) { | ||
| 1418 | - delete command_object; | ||
| 1419 | - command_object = NULL; | ||
| 1420 | - } | ||
| 1421 | - if (args) { | ||
| 1422 | - delete args; | ||
| 1423 | - args = NULL; | ||
| 1424 | - } | 1424 | + srs_freep(command_object); |
| 1425 | + srs_freep(args); | ||
| 1425 | } | 1426 | } |
| 1426 | 1427 | ||
| 1427 | int SrsFMLEStartResPacket::get_perfer_cid() | 1428 | int SrsFMLEStartResPacket::get_perfer_cid() |
| @@ -1474,6 +1475,59 @@ int SrsFMLEStartResPacket::encode_packet(SrsStream* stream) | @@ -1474,6 +1475,59 @@ int SrsFMLEStartResPacket::encode_packet(SrsStream* stream) | ||
| 1474 | return ret; | 1475 | return ret; |
| 1475 | } | 1476 | } |
| 1476 | 1477 | ||
| 1478 | +SrsPublishPacket::SrsPublishPacket() | ||
| 1479 | +{ | ||
| 1480 | + command_name = RTMP_AMF0_COMMAND_PUBLISH; | ||
| 1481 | + transaction_id = 0; | ||
| 1482 | + command_object = new SrsAmf0Null(); | ||
| 1483 | + type = "live"; | ||
| 1484 | +} | ||
| 1485 | + | ||
| 1486 | +SrsPublishPacket::~SrsPublishPacket() | ||
| 1487 | +{ | ||
| 1488 | + srs_freep(command_object); | ||
| 1489 | +} | ||
| 1490 | + | ||
| 1491 | +int SrsPublishPacket::decode(SrsStream* stream) | ||
| 1492 | +{ | ||
| 1493 | + int ret = ERROR_SUCCESS; | ||
| 1494 | + | ||
| 1495 | + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { | ||
| 1496 | + srs_error("amf0 decode publish command_name failed. ret=%d", ret); | ||
| 1497 | + return ret; | ||
| 1498 | + } | ||
| 1499 | + if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_PUBLISH) { | ||
| 1500 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
| 1501 | + srs_error("amf0 decode publish command_name failed. " | ||
| 1502 | + "command_name=%s, ret=%d", command_name.c_str(), ret); | ||
| 1503 | + return ret; | ||
| 1504 | + } | ||
| 1505 | + | ||
| 1506 | + if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) { | ||
| 1507 | + srs_error("amf0 decode publish transaction_id failed. ret=%d", ret); | ||
| 1508 | + return ret; | ||
| 1509 | + } | ||
| 1510 | + | ||
| 1511 | + if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) { | ||
| 1512 | + srs_error("amf0 decode publish command_object failed. ret=%d", ret); | ||
| 1513 | + return ret; | ||
| 1514 | + } | ||
| 1515 | + | ||
| 1516 | + if ((ret = srs_amf0_read_string(stream, stream_name)) != ERROR_SUCCESS) { | ||
| 1517 | + srs_error("amf0 decode publish stream_name failed. ret=%d", ret); | ||
| 1518 | + return ret; | ||
| 1519 | + } | ||
| 1520 | + | ||
| 1521 | + if ((ret = srs_amf0_read_string(stream, type)) != ERROR_SUCCESS) { | ||
| 1522 | + srs_error("amf0 decode publish type failed. ret=%d", ret); | ||
| 1523 | + return ret; | ||
| 1524 | + } | ||
| 1525 | + | ||
| 1526 | + srs_info("amf0 decode publish packet success"); | ||
| 1527 | + | ||
| 1528 | + return ret; | ||
| 1529 | +} | ||
| 1530 | + | ||
| 1477 | SrsPlayPacket::SrsPlayPacket() | 1531 | SrsPlayPacket::SrsPlayPacket() |
| 1478 | { | 1532 | { |
| 1479 | command_name = RTMP_AMF0_COMMAND_PLAY; | 1533 | command_name = RTMP_AMF0_COMMAND_PLAY; |
| @@ -1487,10 +1541,7 @@ SrsPlayPacket::SrsPlayPacket() | @@ -1487,10 +1541,7 @@ SrsPlayPacket::SrsPlayPacket() | ||
| 1487 | 1541 | ||
| 1488 | SrsPlayPacket::~SrsPlayPacket() | 1542 | SrsPlayPacket::~SrsPlayPacket() |
| 1489 | { | 1543 | { |
| 1490 | - if (command_object) { | ||
| 1491 | - delete command_object; | ||
| 1492 | - command_object = NULL; | ||
| 1493 | - } | 1544 | + srs_freep(command_object); |
| 1494 | } | 1545 | } |
| 1495 | 1546 | ||
| 1496 | int SrsPlayPacket::decode(SrsStream* stream) | 1547 | int SrsPlayPacket::decode(SrsStream* stream) |
| @@ -1551,15 +1602,8 @@ SrsPlayResPacket::SrsPlayResPacket() | @@ -1551,15 +1602,8 @@ SrsPlayResPacket::SrsPlayResPacket() | ||
| 1551 | 1602 | ||
| 1552 | SrsPlayResPacket::~SrsPlayResPacket() | 1603 | SrsPlayResPacket::~SrsPlayResPacket() |
| 1553 | { | 1604 | { |
| 1554 | - if (command_object) { | ||
| 1555 | - delete command_object; | ||
| 1556 | - command_object = NULL; | ||
| 1557 | - } | ||
| 1558 | - | ||
| 1559 | - if (desc) { | ||
| 1560 | - delete desc; | ||
| 1561 | - desc = NULL; | ||
| 1562 | - } | 1605 | + srs_freep(command_object); |
| 1606 | + srs_freep(desc); | ||
| 1563 | } | 1607 | } |
| 1564 | 1608 | ||
| 1565 | int SrsPlayResPacket::get_perfer_cid() | 1609 | int SrsPlayResPacket::get_perfer_cid() |
| @@ -1621,10 +1665,7 @@ SrsOnBWDonePacket::SrsOnBWDonePacket() | @@ -1621,10 +1665,7 @@ SrsOnBWDonePacket::SrsOnBWDonePacket() | ||
| 1621 | 1665 | ||
| 1622 | SrsOnBWDonePacket::~SrsOnBWDonePacket() | 1666 | SrsOnBWDonePacket::~SrsOnBWDonePacket() |
| 1623 | { | 1667 | { |
| 1624 | - if (args) { | ||
| 1625 | - delete args; | ||
| 1626 | - args = NULL; | ||
| 1627 | - } | 1668 | + srs_freep(args); |
| 1628 | } | 1669 | } |
| 1629 | 1670 | ||
| 1630 | int SrsOnBWDonePacket::get_perfer_cid() | 1671 | int SrsOnBWDonePacket::get_perfer_cid() |
| @@ -1680,15 +1721,8 @@ SrsOnStatusCallPacket::SrsOnStatusCallPacket() | @@ -1680,15 +1721,8 @@ SrsOnStatusCallPacket::SrsOnStatusCallPacket() | ||
| 1680 | 1721 | ||
| 1681 | SrsOnStatusCallPacket::~SrsOnStatusCallPacket() | 1722 | SrsOnStatusCallPacket::~SrsOnStatusCallPacket() |
| 1682 | { | 1723 | { |
| 1683 | - if (args) { | ||
| 1684 | - delete args; | ||
| 1685 | - args = NULL; | ||
| 1686 | - } | ||
| 1687 | - | ||
| 1688 | - if (data) { | ||
| 1689 | - delete data; | ||
| 1690 | - data = NULL; | ||
| 1691 | - } | 1724 | + srs_freep(args); |
| 1725 | + srs_freep(data); | ||
| 1692 | } | 1726 | } |
| 1693 | 1727 | ||
| 1694 | int SrsOnStatusCallPacket::get_perfer_cid() | 1728 | int SrsOnStatusCallPacket::get_perfer_cid() |
| @@ -1748,10 +1782,7 @@ SrsOnStatusDataPacket::SrsOnStatusDataPacket() | @@ -1748,10 +1782,7 @@ SrsOnStatusDataPacket::SrsOnStatusDataPacket() | ||
| 1748 | 1782 | ||
| 1749 | SrsOnStatusDataPacket::~SrsOnStatusDataPacket() | 1783 | SrsOnStatusDataPacket::~SrsOnStatusDataPacket() |
| 1750 | { | 1784 | { |
| 1751 | - if (data) { | ||
| 1752 | - delete data; | ||
| 1753 | - data = NULL; | ||
| 1754 | - } | 1785 | + srs_freep(data); |
| 1755 | } | 1786 | } |
| 1756 | 1787 | ||
| 1757 | int SrsOnStatusDataPacket::get_perfer_cid() | 1788 | int SrsOnStatusDataPacket::get_perfer_cid() |
| @@ -160,22 +160,29 @@ struct SrsMessageHeader | @@ -160,22 +160,29 @@ struct SrsMessageHeader | ||
| 160 | */ | 160 | */ |
| 161 | int32_t payload_length; | 161 | int32_t payload_length; |
| 162 | /** | 162 | /** |
| 163 | - * Four-byte field that contains a timestamp of the message. | 163 | + * Three-byte field that contains a timestamp delta of the message. |
| 164 | * The 4 bytes are packed in the big-endian order. | 164 | * The 4 bytes are packed in the big-endian order. |
| 165 | */ | 165 | */ |
| 166 | - int32_t timestamp; | 166 | + int32_t timestamp_delta; |
| 167 | /** | 167 | /** |
| 168 | * Three-byte field that identifies the stream of the message. These | 168 | * Three-byte field that identifies the stream of the message. These |
| 169 | * bytes are set in big-endian format. | 169 | * bytes are set in big-endian format. |
| 170 | */ | 170 | */ |
| 171 | int32_t stream_id; | 171 | int32_t stream_id; |
| 172 | 172 | ||
| 173 | + /** | ||
| 174 | + * Four-byte field that contains a timestamp of the message. | ||
| 175 | + * The 4 bytes are packed in the big-endian order. | ||
| 176 | + */ | ||
| 177 | + int32_t timestamp; | ||
| 178 | + | ||
| 173 | SrsMessageHeader(); | 179 | SrsMessageHeader(); |
| 174 | virtual ~SrsMessageHeader(); | 180 | virtual ~SrsMessageHeader(); |
| 175 | 181 | ||
| 176 | bool is_amf0_command(); | 182 | bool is_amf0_command(); |
| 177 | bool is_amf3_command(); | 183 | bool is_amf3_command(); |
| 178 | bool is_window_ackledgement_size(); | 184 | bool is_window_ackledgement_size(); |
| 185 | + bool is_set_chunk_size(); | ||
| 179 | }; | 186 | }; |
| 180 | 187 | ||
| 181 | /** | 188 | /** |
| @@ -207,6 +214,10 @@ public: | @@ -207,6 +214,10 @@ public: | ||
| 207 | * partially read message. | 214 | * partially read message. |
| 208 | */ | 215 | */ |
| 209 | SrsMessage* msg; | 216 | SrsMessage* msg; |
| 217 | + /** | ||
| 218 | + * decoded msg count, to identify whether the chunk stream is fresh. | ||
| 219 | + */ | ||
| 220 | + int64_t msg_count; | ||
| 210 | public: | 221 | public: |
| 211 | SrsChunkStream(int _cid); | 222 | SrsChunkStream(int _cid); |
| 212 | virtual ~SrsChunkStream(); | 223 | virtual ~SrsChunkStream(); |
| @@ -257,7 +268,7 @@ public: | @@ -257,7 +268,7 @@ public: | ||
| 257 | * @stream_id, the id of stream which is created by createStream. | 268 | * @stream_id, the id of stream which is created by createStream. |
| 258 | * @remark, user never free the pkt, the message will auto free it. | 269 | * @remark, user never free the pkt, the message will auto free it. |
| 259 | */ | 270 | */ |
| 260 | - virtual void set_packet(SrsPacket* pkt, int stream_id = 0); | 271 | + virtual void set_packet(SrsPacket* pkt, int stream_id); |
| 261 | /** | 272 | /** |
| 262 | * encode the packet to message payload bytes. | 273 | * encode the packet to message payload bytes. |
| 263 | * @remark there exists empty packet, so maybe the payload is NULL. | 274 | * @remark there exists empty packet, so maybe the payload is NULL. |
| @@ -443,6 +454,7 @@ protected: | @@ -443,6 +454,7 @@ protected: | ||
| 443 | public: | 454 | public: |
| 444 | std::string command_name; | 455 | std::string command_name; |
| 445 | double transaction_id; | 456 | double transaction_id; |
| 457 | + SrsAmf0Null* command_object; | ||
| 446 | std::string stream_name; | 458 | std::string stream_name; |
| 447 | public: | 459 | public: |
| 448 | SrsFMLEStartPacket(); | 460 | SrsFMLEStartPacket(); |
| @@ -480,6 +492,35 @@ protected: | @@ -480,6 +492,35 @@ protected: | ||
| 480 | }; | 492 | }; |
| 481 | 493 | ||
| 482 | /** | 494 | /** |
| 495 | +* FMLE/flash publish | ||
| 496 | +* 4.2.6. Publish | ||
| 497 | +* The client sends the publish command to publish a named stream to the | ||
| 498 | +* server. Using this name, any client can play this stream and receive | ||
| 499 | +* the published audio, video, and data messages. | ||
| 500 | +*/ | ||
| 501 | +class SrsPublishPacket : public SrsPacket | ||
| 502 | +{ | ||
| 503 | +private: | ||
| 504 | + typedef SrsPacket super; | ||
| 505 | +protected: | ||
| 506 | + virtual const char* get_class_name() | ||
| 507 | + { | ||
| 508 | + return CLASS_NAME_STRING(SrsPublishPacket); | ||
| 509 | + } | ||
| 510 | +public: | ||
| 511 | + std::string command_name; | ||
| 512 | + double transaction_id; | ||
| 513 | + SrsAmf0Null* command_object; | ||
| 514 | + std::string stream_name; | ||
| 515 | + std::string type; | ||
| 516 | +public: | ||
| 517 | + SrsPublishPacket(); | ||
| 518 | + virtual ~SrsPublishPacket(); | ||
| 519 | +public: | ||
| 520 | + virtual int decode(SrsStream* stream); | ||
| 521 | +}; | ||
| 522 | + | ||
| 523 | +/** | ||
| 483 | * 4.2.1. play | 524 | * 4.2.1. play |
| 484 | * The client sends this command to the server to play a stream. | 525 | * The client sends this command to the server to play a stream. |
| 485 | */ | 526 | */ |
| @@ -566,7 +607,7 @@ protected: | @@ -566,7 +607,7 @@ protected: | ||
| 566 | 607 | ||
| 567 | /** | 608 | /** |
| 568 | * onStatus command, AMF0 Call | 609 | * onStatus command, AMF0 Call |
| 569 | -* @remark, user must set the stream_id in header. | 610 | +* @remark, user must set the stream_id by SrsMessage.set_packet(). |
| 570 | */ | 611 | */ |
| 571 | class SrsOnStatusCallPacket : public SrsPacket | 612 | class SrsOnStatusCallPacket : public SrsPacket |
| 572 | { | 613 | { |
| @@ -596,7 +637,7 @@ protected: | @@ -596,7 +637,7 @@ protected: | ||
| 596 | 637 | ||
| 597 | /** | 638 | /** |
| 598 | * onStatus data, AMF0 Data | 639 | * onStatus data, AMF0 Data |
| 599 | -* @remark, user must set the stream_id in header. | 640 | +* @remark, user must set the stream_id by SrsMessage.set_packet(). |
| 600 | */ | 641 | */ |
| 601 | class SrsOnStatusDataPacket : public SrsPacket | 642 | class SrsOnStatusDataPacket : public SrsPacket |
| 602 | { | 643 | { |
| @@ -624,7 +665,7 @@ protected: | @@ -624,7 +665,7 @@ protected: | ||
| 624 | 665 | ||
| 625 | /** | 666 | /** |
| 626 | * AMF0Data RtmpSampleAccess | 667 | * AMF0Data RtmpSampleAccess |
| 627 | -* @remark, user must set the stream_id in header. | 668 | +* @remark, user must set the stream_id by SrsMessage.set_packet(). |
| 628 | */ | 669 | */ |
| 629 | class SrsSampleAccessPacket : public SrsPacket | 670 | class SrsSampleAccessPacket : public SrsPacket |
| 630 | { | 671 | { |
| @@ -51,8 +51,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -51,8 +51,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 51 | #define StatusCodeConnectSuccess "NetConnection.Connect.Success" | 51 | #define StatusCodeConnectSuccess "NetConnection.Connect.Success" |
| 52 | #define StatusCodeStreamReset "NetStream.Play.Reset" | 52 | #define StatusCodeStreamReset "NetStream.Play.Reset" |
| 53 | #define StatusCodeStreamStart "NetStream.Play.Start" | 53 | #define StatusCodeStreamStart "NetStream.Play.Start" |
| 54 | +#define StatusCodePublishStart "NetStream.Publish.Start" | ||
| 54 | #define StatusCodeDataStart "NetStream.Data.Start" | 55 | #define StatusCodeDataStart "NetStream.Data.Start" |
| 55 | 56 | ||
| 57 | +// FMLE | ||
| 58 | +#define RTMP_AMF0_COMMAND_ON_FC_PUBLISH "onFCPublish" | ||
| 59 | + | ||
| 56 | SrsRequest::SrsRequest() | 60 | SrsRequest::SrsRequest() |
| 57 | { | 61 | { |
| 58 | objectEncoding = RTMP_SIG_AMF0_VER; | 62 | objectEncoding = RTMP_SIG_AMF0_VER; |
| @@ -111,10 +115,7 @@ SrsRtmp::SrsRtmp(st_netfd_t client_stfd) | @@ -111,10 +115,7 @@ SrsRtmp::SrsRtmp(st_netfd_t client_stfd) | ||
| 111 | 115 | ||
| 112 | SrsRtmp::~SrsRtmp() | 116 | SrsRtmp::~SrsRtmp() |
| 113 | { | 117 | { |
| 114 | - if (protocol) { | ||
| 115 | - delete protocol; | ||
| 116 | - protocol = NULL; | ||
| 117 | - } | 118 | + srs_freep(protocol); |
| 118 | } | 119 | } |
| 119 | 120 | ||
| 120 | int SrsRtmp::handshake() | 121 | int SrsRtmp::handshake() |
| @@ -210,7 +211,7 @@ int SrsRtmp::set_window_ack_size(int ack_size) | @@ -210,7 +211,7 @@ int SrsRtmp::set_window_ack_size(int ack_size) | ||
| 210 | SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket(); | 211 | SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket(); |
| 211 | 212 | ||
| 212 | pkt->ackowledgement_window_size = ack_size; | 213 | pkt->ackowledgement_window_size = ack_size; |
| 213 | - msg->set_packet(pkt); | 214 | + msg->set_packet(pkt, 0); |
| 214 | 215 | ||
| 215 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 216 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 216 | srs_error("send ack size message failed. ret=%d", ret); | 217 | srs_error("send ack size message failed. ret=%d", ret); |
| @@ -230,7 +231,7 @@ int SrsRtmp::set_peer_bandwidth(int bandwidth, int type) | @@ -230,7 +231,7 @@ int SrsRtmp::set_peer_bandwidth(int bandwidth, int type) | ||
| 230 | 231 | ||
| 231 | pkt->bandwidth = bandwidth; | 232 | pkt->bandwidth = bandwidth; |
| 232 | pkt->type = type; | 233 | pkt->type = type; |
| 233 | - msg->set_packet(pkt); | 234 | + msg->set_packet(pkt, 0); |
| 234 | 235 | ||
| 235 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 236 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 236 | srs_error("send set bandwidth message failed. ret=%d", ret); | 237 | srs_error("send set bandwidth message failed. ret=%d", ret); |
| @@ -249,23 +250,23 @@ int SrsRtmp::response_connect_app(SrsRequest* req) | @@ -249,23 +250,23 @@ int SrsRtmp::response_connect_app(SrsRequest* req) | ||
| 249 | SrsMessage* msg = new SrsMessage(); | 250 | SrsMessage* msg = new SrsMessage(); |
| 250 | SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket(); | 251 | SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket(); |
| 251 | 252 | ||
| 252 | - pkt->props->properties["fmsVer"] = new SrsAmf0String("FMS/"RTMP_SIG_FMS_VER); | ||
| 253 | - pkt->props->properties["capabilities"] = new SrsAmf0Number(123); | ||
| 254 | - pkt->props->properties["mode"] = new SrsAmf0Number(1); | 253 | + pkt->props->set("fmsVer", new SrsAmf0String("FMS/"RTMP_SIG_FMS_VER)); |
| 254 | + pkt->props->set("capabilities", new SrsAmf0Number(127)); | ||
| 255 | + pkt->props->set("mode", new SrsAmf0Number(1)); | ||
| 255 | 256 | ||
| 256 | - pkt->info->properties[StatusLevel] = new SrsAmf0String(StatusLevelStatus); | ||
| 257 | - pkt->info->properties[StatusCode] = new SrsAmf0String(StatusCodeConnectSuccess); | ||
| 258 | - pkt->info->properties[StatusDescription] = new SrsAmf0String("Connection succeeded"); | ||
| 259 | - pkt->info->properties["objectEncoding"] = new SrsAmf0Number(req->objectEncoding); | 257 | + pkt->info->set(StatusLevel, new SrsAmf0String(StatusLevelStatus)); |
| 258 | + pkt->info->set(StatusCode, new SrsAmf0String(StatusCodeConnectSuccess)); | ||
| 259 | + pkt->info->set(StatusDescription, new SrsAmf0String("Connection succeeded")); | ||
| 260 | + pkt->info->set("objectEncoding", new SrsAmf0Number(req->objectEncoding)); | ||
| 260 | SrsASrsAmf0EcmaArray* data = new SrsASrsAmf0EcmaArray(); | 261 | SrsASrsAmf0EcmaArray* data = new SrsASrsAmf0EcmaArray(); |
| 261 | - pkt->info->properties["data"] = data; | 262 | + pkt->info->set("data", data); |
| 262 | 263 | ||
| 263 | - data->properties["version"] = new SrsAmf0String(RTMP_SIG_FMS_VER); | ||
| 264 | - data->properties["server"] = new SrsAmf0String(RTMP_SIG_SRS_NAME); | ||
| 265 | - data->properties["srs_url"] = new SrsAmf0String(RTMP_SIG_SRS_URL); | ||
| 266 | - data->properties["srs_version"] = new SrsAmf0String(RTMP_SIG_SRS_VERSION); | 264 | + data->set("version", new SrsAmf0String(RTMP_SIG_FMS_VER)); |
| 265 | + data->set("server", new SrsAmf0String(RTMP_SIG_SRS_NAME)); | ||
| 266 | + data->set("srs_url", new SrsAmf0String(RTMP_SIG_SRS_URL)); | ||
| 267 | + data->set("srs_version", new SrsAmf0String(RTMP_SIG_SRS_VERSION)); | ||
| 267 | 268 | ||
| 268 | - msg->set_packet(pkt); | 269 | + msg->set_packet(pkt, 0); |
| 269 | 270 | ||
| 270 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 271 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 271 | srs_error("send connect app response message failed. ret=%d", ret); | 272 | srs_error("send connect app response message failed. ret=%d", ret); |
| @@ -283,7 +284,7 @@ int SrsRtmp::on_bw_done() | @@ -283,7 +284,7 @@ int SrsRtmp::on_bw_done() | ||
| 283 | SrsMessage* msg = new SrsMessage(); | 284 | SrsMessage* msg = new SrsMessage(); |
| 284 | SrsOnBWDonePacket* pkt = new SrsOnBWDonePacket(); | 285 | SrsOnBWDonePacket* pkt = new SrsOnBWDonePacket(); |
| 285 | 286 | ||
| 286 | - msg->set_packet(pkt); | 287 | + msg->set_packet(pkt, 0); |
| 287 | 288 | ||
| 288 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 289 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 289 | srs_error("send onBWDone message failed. ret=%d", ret); | 290 | srs_error("send onBWDone message failed. ret=%d", ret); |
| @@ -345,7 +346,7 @@ int SrsRtmp::set_chunk_size(int chunk_size) | @@ -345,7 +346,7 @@ int SrsRtmp::set_chunk_size(int chunk_size) | ||
| 345 | SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket(); | 346 | SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket(); |
| 346 | 347 | ||
| 347 | pkt->chunk_size = chunk_size; | 348 | pkt->chunk_size = chunk_size; |
| 348 | - msg->set_packet(pkt); | 349 | + msg->set_packet(pkt, 0); |
| 349 | 350 | ||
| 350 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 351 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 351 | srs_error("send set chunk size message failed. ret=%d", ret); | 352 | srs_error("send set chunk size message failed. ret=%d", ret); |
| @@ -367,7 +368,7 @@ int SrsRtmp::start_play(int stream_id) | @@ -367,7 +368,7 @@ int SrsRtmp::start_play(int stream_id) | ||
| 367 | 368 | ||
| 368 | pkt->event_type = SrcPCUCStreamBegin; | 369 | pkt->event_type = SrcPCUCStreamBegin; |
| 369 | pkt->event_data = stream_id; | 370 | pkt->event_data = stream_id; |
| 370 | - msg->set_packet(pkt); | 371 | + msg->set_packet(pkt, 0); |
| 371 | 372 | ||
| 372 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 373 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 373 | srs_error("send PCUC(StreamBegin) message failed. ret=%d", ret); | 374 | srs_error("send PCUC(StreamBegin) message failed. ret=%d", ret); |
| @@ -381,14 +382,13 @@ int SrsRtmp::start_play(int stream_id) | @@ -381,14 +382,13 @@ int SrsRtmp::start_play(int stream_id) | ||
| 381 | SrsMessage* msg = new SrsMessage(); | 382 | SrsMessage* msg = new SrsMessage(); |
| 382 | SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket(); | 383 | SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket(); |
| 383 | 384 | ||
| 384 | - pkt->data->properties[StatusLevel] = new SrsAmf0String(StatusLevelStatus); | ||
| 385 | - pkt->data->properties[StatusCode] = new SrsAmf0String(StatusCodeStreamReset); | ||
| 386 | - pkt->data->properties[StatusDescription] = new SrsAmf0String("Playing and resetting stream."); | ||
| 387 | - pkt->data->properties[StatusDetails] = new SrsAmf0String("stream"); | ||
| 388 | - pkt->data->properties[StatusClientId] = new SrsAmf0String(RTMP_SIG_CLIENT_ID); | 385 | + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus)); |
| 386 | + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamReset)); | ||
| 387 | + pkt->data->set(StatusDescription, new SrsAmf0String("Playing and resetting stream.")); | ||
| 388 | + pkt->data->set(StatusDetails, new SrsAmf0String("stream")); | ||
| 389 | + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID)); | ||
| 389 | 390 | ||
| 390 | - msg->header.stream_id = stream_id; | ||
| 391 | - msg->set_packet(pkt); | 391 | + msg->set_packet(pkt, stream_id); |
| 392 | 392 | ||
| 393 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 393 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 394 | srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret); | 394 | srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret); |
| @@ -402,14 +402,13 @@ int SrsRtmp::start_play(int stream_id) | @@ -402,14 +402,13 @@ int SrsRtmp::start_play(int stream_id) | ||
| 402 | SrsMessage* msg = new SrsMessage(); | 402 | SrsMessage* msg = new SrsMessage(); |
| 403 | SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket(); | 403 | SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket(); |
| 404 | 404 | ||
| 405 | - pkt->data->properties[StatusLevel] = new SrsAmf0String(StatusLevelStatus); | ||
| 406 | - pkt->data->properties[StatusCode] = new SrsAmf0String(StatusCodeStreamStart); | ||
| 407 | - pkt->data->properties[StatusDescription] = new SrsAmf0String("Started playing stream."); | ||
| 408 | - pkt->data->properties[StatusDetails] = new SrsAmf0String("stream"); | ||
| 409 | - pkt->data->properties[StatusClientId] = new SrsAmf0String(RTMP_SIG_CLIENT_ID); | 405 | + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus)); |
| 406 | + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamStart)); | ||
| 407 | + pkt->data->set(StatusDescription, new SrsAmf0String("Started playing stream.")); | ||
| 408 | + pkt->data->set(StatusDetails, new SrsAmf0String("stream")); | ||
| 409 | + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID)); | ||
| 410 | 410 | ||
| 411 | - msg->header.stream_id = stream_id; | ||
| 412 | - msg->set_packet(pkt); | 411 | + msg->set_packet(pkt, stream_id); |
| 413 | 412 | ||
| 414 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 413 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 415 | srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret); | 414 | srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret); |
| @@ -423,8 +422,7 @@ int SrsRtmp::start_play(int stream_id) | @@ -423,8 +422,7 @@ int SrsRtmp::start_play(int stream_id) | ||
| 423 | SrsMessage* msg = new SrsMessage(); | 422 | SrsMessage* msg = new SrsMessage(); |
| 424 | SrsSampleAccessPacket* pkt = new SrsSampleAccessPacket(); | 423 | SrsSampleAccessPacket* pkt = new SrsSampleAccessPacket(); |
| 425 | 424 | ||
| 426 | - msg->header.stream_id = stream_id; | ||
| 427 | - msg->set_packet(pkt); | 425 | + msg->set_packet(pkt, stream_id); |
| 428 | 426 | ||
| 429 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 427 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 430 | srs_error("send |RtmpSampleAccess(false, false) message failed. ret=%d", ret); | 428 | srs_error("send |RtmpSampleAccess(false, false) message failed. ret=%d", ret); |
| @@ -438,10 +436,9 @@ int SrsRtmp::start_play(int stream_id) | @@ -438,10 +436,9 @@ int SrsRtmp::start_play(int stream_id) | ||
| 438 | SrsMessage* msg = new SrsMessage(); | 436 | SrsMessage* msg = new SrsMessage(); |
| 439 | SrsOnStatusDataPacket* pkt = new SrsOnStatusDataPacket(); | 437 | SrsOnStatusDataPacket* pkt = new SrsOnStatusDataPacket(); |
| 440 | 438 | ||
| 441 | - pkt->data->properties[StatusCode] = new SrsAmf0String(StatusCodeDataStart); | 439 | + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeDataStart)); |
| 442 | 440 | ||
| 443 | - msg->header.stream_id = stream_id; | ||
| 444 | - msg->set_packet(pkt); | 441 | + msg->set_packet(pkt, stream_id); |
| 445 | 442 | ||
| 446 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 443 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 447 | srs_error("send onStatus(NetStream.Data.Start) message failed. ret=%d", ret); | 444 | srs_error("send onStatus(NetStream.Data.Start) message failed. ret=%d", ret); |
| @@ -463,7 +460,7 @@ int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int strea | @@ -463,7 +460,7 @@ int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int strea | ||
| 463 | SrsMessage* msg = new SrsMessage(); | 460 | SrsMessage* msg = new SrsMessage(); |
| 464 | SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id); | 461 | SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id); |
| 465 | 462 | ||
| 466 | - msg->set_packet(pkt); | 463 | + msg->set_packet(pkt, 0); |
| 467 | 464 | ||
| 468 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 465 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 469 | srs_error("send createStream response message failed. ret=%d", ret); | 466 | srs_error("send createStream response message failed. ret=%d", ret); |
| @@ -519,7 +516,7 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | @@ -519,7 +516,7 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | ||
| 519 | SrsMessage* msg = new SrsMessage(); | 516 | SrsMessage* msg = new SrsMessage(); |
| 520 | SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id); | 517 | SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id); |
| 521 | 518 | ||
| 522 | - msg->set_packet(pkt); | 519 | + msg->set_packet(pkt, 0); |
| 523 | 520 | ||
| 524 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 521 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 525 | srs_error("send releaseStream response message failed. ret=%d", ret); | 522 | srs_error("send releaseStream response message failed. ret=%d", ret); |
| @@ -547,7 +544,7 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | @@ -547,7 +544,7 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | ||
| 547 | SrsMessage* msg = new SrsMessage(); | 544 | SrsMessage* msg = new SrsMessage(); |
| 548 | SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(fc_publish_tid); | 545 | SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(fc_publish_tid); |
| 549 | 546 | ||
| 550 | - msg->set_packet(pkt); | 547 | + msg->set_packet(pkt, 0); |
| 551 | 548 | ||
| 552 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 549 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 553 | srs_error("send FCPublish response message failed. ret=%d", ret); | 550 | srs_error("send FCPublish response message failed. ret=%d", ret); |
| @@ -575,7 +572,7 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | @@ -575,7 +572,7 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | ||
| 575 | SrsMessage* msg = new SrsMessage(); | 572 | SrsMessage* msg = new SrsMessage(); |
| 576 | SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(create_stream_tid, stream_id); | 573 | SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(create_stream_tid, stream_id); |
| 577 | 574 | ||
| 578 | - msg->set_packet(pkt); | 575 | + msg->set_packet(pkt, 0); |
| 579 | 576 | ||
| 580 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | 577 | if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { |
| 581 | srs_error("send createStream response message failed. ret=%d", ret); | 578 | srs_error("send createStream response message failed. ret=%d", ret); |
| @@ -584,6 +581,64 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | @@ -584,6 +581,64 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | ||
| 584 | srs_info("send createStream response message success."); | 581 | srs_info("send createStream response message success."); |
| 585 | } | 582 | } |
| 586 | 583 | ||
| 584 | + // publish | ||
| 585 | + if (true) { | ||
| 586 | + SrsMessage* msg = NULL; | ||
| 587 | + SrsPublishPacket* pkt = NULL; | ||
| 588 | + if ((ret = srs_rtmp_expect_message<SrsPublishPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { | ||
| 589 | + srs_error("recv publish message failed. ret=%d", ret); | ||
| 590 | + return ret; | ||
| 591 | + } | ||
| 592 | + srs_info("recv publish request message success."); | ||
| 593 | + | ||
| 594 | + SrsAutoFree(SrsMessage, msg, false); | ||
| 595 | + } | ||
| 596 | + // publish response onFCPublish(NetStream.Publish.Start) | ||
| 597 | + if (true) { | ||
| 598 | + SrsMessage* msg = new SrsMessage(); | ||
| 599 | + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket(); | ||
| 600 | + | ||
| 601 | + pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_PUBLISH; | ||
| 602 | + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart)); | ||
| 603 | + pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream.")); | ||
| 604 | + | ||
| 605 | + msg->set_packet(pkt, stream_id); | ||
| 606 | + | ||
| 607 | + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
| 608 | + srs_error("send onFCPublish(NetStream.Publish.Start) message failed. ret=%d", ret); | ||
| 609 | + return ret; | ||
| 610 | + } | ||
| 611 | + srs_info("send onFCPublish(NetStream.Publish.Start) message success."); | ||
| 612 | + } | ||
| 613 | + // publish response onStatus(NetStream.Publish.Start) | ||
| 614 | + if (true) { | ||
| 615 | + SrsMessage* msg = new SrsMessage(); | ||
| 616 | + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket(); | ||
| 617 | + | ||
| 618 | + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus)); | ||
| 619 | + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart)); | ||
| 620 | + pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream.")); | ||
| 621 | + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID)); | ||
| 622 | + | ||
| 623 | + msg->set_packet(pkt, stream_id); | ||
| 624 | + | ||
| 625 | + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
| 626 | + srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret); | ||
| 627 | + return ret; | ||
| 628 | + } | ||
| 629 | + srs_info("send onStatus(NetStream.Publish.Start) message success."); | ||
| 630 | + } | ||
| 631 | + | ||
| 632 | + while (true) { | ||
| 633 | + SrsMessage* msg = NULL; | ||
| 634 | + if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) { | ||
| 635 | + srs_error("recv identify client message failed. ret=%d", ret); | ||
| 636 | + return ret; | ||
| 637 | + } | ||
| 638 | + | ||
| 639 | + SrsAutoFree(SrsMessage, msg, false); | ||
| 640 | + } | ||
| 641 | + | ||
| 587 | return ret; | 642 | return ret; |
| 588 | } | 643 | } |
| 589 | 644 |
| @@ -45,7 +45,7 @@ SrsServer::~SrsServer() | @@ -45,7 +45,7 @@ SrsServer::~SrsServer() | ||
| 45 | { | 45 | { |
| 46 | for (std::vector<SrsConnection*>::iterator it = conns.begin(); it != conns.end(); ++it) { | 46 | for (std::vector<SrsConnection*>::iterator it = conns.begin(); it != conns.end(); ++it) { |
| 47 | SrsConnection* conn = *it; | 47 | SrsConnection* conn = *it; |
| 48 | - delete conn; | 48 | + srs_freep(conn); |
| 49 | } | 49 | } |
| 50 | conns.clear(); | 50 | conns.clear(); |
| 51 | } | 51 | } |
| @@ -151,8 +151,8 @@ void SrsServer::remove(SrsConnection* conn) | @@ -151,8 +151,8 @@ void SrsServer::remove(SrsConnection* conn) | ||
| 151 | srs_info("conn removed. conns=%d", (int)conns.size()); | 151 | srs_info("conn removed. conns=%d", (int)conns.size()); |
| 152 | 152 | ||
| 153 | // all connections are created by server, | 153 | // all connections are created by server, |
| 154 | - // so we delete it here. | ||
| 155 | - delete conn; | 154 | + // so we free it here. |
| 155 | + srs_freep(conn); | ||
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | int SrsServer::accept_client(st_netfd_t client_stfd) | 158 | int SrsServer::accept_client(st_netfd_t client_stfd) |
-
请 注册 或 登录 后发表评论