winlin

support fmle publish. fix bug of rtmp chunk stream.

@@ -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*)&timestamp_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)