winlin

support FMLE releaseStream, FCPublish

@@ -89,6 +89,11 @@ bool SrsAmf0Any::is_null() @@ -89,6 +89,11 @@ bool SrsAmf0Any::is_null()
89 return marker == RTMP_AMF0_Null; 89 return marker == RTMP_AMF0_Null;
90 } 90 }
91 91
  92 +bool SrsAmf0Any::is_undefined()
  93 +{
  94 + return marker == RTMP_AMF0_Undefined;
  95 +}
  96 +
92 bool SrsAmf0Any::is_object() 97 bool SrsAmf0Any::is_object()
93 { 98 {
94 return marker == RTMP_AMF0_Object; 99 return marker == RTMP_AMF0_Object;
@@ -145,6 +150,15 @@ SrsAmf0Null::~SrsAmf0Null() @@ -145,6 +150,15 @@ SrsAmf0Null::~SrsAmf0Null()
145 { 150 {
146 } 151 }
147 152
  153 +SrsAmf0Undefined::SrsAmf0Undefined()
  154 +{
  155 + marker = RTMP_AMF0_Undefined;
  156 +}
  157 +
  158 +SrsAmf0Undefined::~SrsAmf0Undefined()
  159 +{
  160 +}
  161 +
148 SrsAmf0ObjectEOF::SrsAmf0ObjectEOF() 162 SrsAmf0ObjectEOF::SrsAmf0ObjectEOF()
149 { 163 {
150 marker = RTMP_AMF0_ObjectEnd; 164 marker = RTMP_AMF0_ObjectEnd;
@@ -523,6 +537,45 @@ int srs_amf0_write_null(SrsStream* stream) @@ -523,6 +537,45 @@ int srs_amf0_write_null(SrsStream* stream)
523 return ret; 537 return ret;
524 } 538 }
525 539
  540 +int srs_amf0_read_undefined(SrsStream* stream)
  541 +{
  542 + int ret = ERROR_SUCCESS;
  543 +
  544 + // marker
  545 + if (!stream->require(1)) {
  546 + ret = ERROR_RTMP_AMF0_DECODE;
  547 + srs_error("amf0 read undefined marker failed. ret=%d", ret);
  548 + return ret;
  549 + }
  550 +
  551 + char marker = stream->read_1bytes();
  552 + if (marker != RTMP_AMF0_Undefined) {
  553 + ret = ERROR_RTMP_AMF0_DECODE;
  554 + srs_error("amf0 check undefined marker failed. "
  555 + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Undefined, ret);
  556 + return ret;
  557 + }
  558 + srs_verbose("amf0 read undefined success");
  559 +
  560 + return ret;
  561 +}
  562 +int srs_amf0_write_undefined(SrsStream* stream)
  563 +{
  564 + int ret = ERROR_SUCCESS;
  565 +
  566 + // marker
  567 + if (!stream->require(1)) {
  568 + ret = ERROR_RTMP_AMF0_ENCODE;
  569 + srs_error("amf0 write undefined marker failed. ret=%d", ret);
  570 + return ret;
  571 + }
  572 +
  573 + stream->write_1bytes(RTMP_AMF0_Undefined);
  574 + srs_verbose("amf0 write undefined marker success");
  575 +
  576 + return ret;
  577 +}
  578 +
526 int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) 579 int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
527 { 580 {
528 int ret = ERROR_SUCCESS; 581 int ret = ERROR_SUCCESS;
@@ -572,6 +625,10 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) @@ -572,6 +625,10 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
572 value = new SrsAmf0Null(); 625 value = new SrsAmf0Null();
573 return ret; 626 return ret;
574 } 627 }
  628 + case RTMP_AMF0_Undefined: {
  629 + value = new SrsAmf0Undefined();
  630 + return ret;
  631 + }
575 case RTMP_AMF0_ObjectEnd: { 632 case RTMP_AMF0_ObjectEnd: {
576 SrsAmf0ObjectEOF* p = NULL; 633 SrsAmf0ObjectEOF* p = NULL;
577 if ((ret = srs_amf0_read_object_eof(stream, p)) != ERROR_SUCCESS) { 634 if ((ret = srs_amf0_read_object_eof(stream, p)) != ERROR_SUCCESS) {
@@ -628,6 +685,9 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value) @@ -628,6 +685,9 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
628 case RTMP_AMF0_Null: { 685 case RTMP_AMF0_Null: {
629 return srs_amf0_write_null(stream); 686 return srs_amf0_write_null(stream);
630 } 687 }
  688 + case RTMP_AMF0_Undefined: {
  689 + return srs_amf0_write_undefined(stream);
  690 + }
631 case RTMP_AMF0_ObjectEnd: { 691 case RTMP_AMF0_ObjectEnd: {
632 SrsAmf0ObjectEOF* p = srs_amf0_convert<SrsAmf0ObjectEOF>(value); 692 SrsAmf0ObjectEOF* p = srs_amf0_convert<SrsAmf0ObjectEOF>(value);
633 return srs_amf0_write_object_eof(stream, p); 693 return srs_amf0_write_object_eof(stream, p);
@@ -676,6 +736,10 @@ int srs_amf0_get_any_size(SrsAmf0Any* value) @@ -676,6 +736,10 @@ int srs_amf0_get_any_size(SrsAmf0Any* value)
676 size += srs_amf0_get_null_size(); 736 size += srs_amf0_get_null_size();
677 break; 737 break;
678 } 738 }
  739 + case RTMP_AMF0_Undefined: {
  740 + size += srs_amf0_get_undefined_size();
  741 + break;
  742 + }
679 case RTMP_AMF0_ObjectEnd: { 743 case RTMP_AMF0_ObjectEnd: {
680 size += srs_amf0_get_object_eof_size(); 744 size += srs_amf0_get_object_eof_size();
681 break; 745 break;
@@ -1009,6 +1073,11 @@ int srs_amf0_get_null_size() @@ -1009,6 +1073,11 @@ int srs_amf0_get_null_size()
1009 return 1; 1073 return 1;
1010 } 1074 }
1011 1075
  1076 +int srs_amf0_get_undefined_size()
  1077 +{
  1078 + return 1;
  1079 +}
  1080 +
1012 int srs_amf0_get_boolean_size() 1081 int srs_amf0_get_boolean_size()
1013 { 1082 {
1014 return 1 + 1; 1083 return 1 + 1;
@@ -55,6 +55,7 @@ struct SrsAmf0Any @@ -55,6 +55,7 @@ struct SrsAmf0Any
55 virtual bool is_boolean(); 55 virtual bool is_boolean();
56 virtual bool is_number(); 56 virtual bool is_number();
57 virtual bool is_null(); 57 virtual bool is_null();
  58 + virtual bool is_undefined();
58 virtual bool is_object(); 59 virtual bool is_object();
59 virtual bool is_object_eof(); 60 virtual bool is_object_eof();
60 virtual bool is_ecma_array(); 61 virtual bool is_ecma_array();
@@ -115,6 +116,17 @@ struct SrsAmf0Null : public SrsAmf0Any @@ -115,6 +116,17 @@ struct SrsAmf0Null : public SrsAmf0Any
115 }; 116 };
116 117
117 /** 118 /**
  119 +* read amf0 undefined from stream.
  120 +* 2.8 undefined Type
  121 +* undefined-type = undefined-marker
  122 +*/
  123 +struct SrsAmf0Undefined : public SrsAmf0Any
  124 +{
  125 + SrsAmf0Undefined();
  126 + virtual ~SrsAmf0Undefined();
  127 +};
  128 +
  129 +/**
118 * 2.11 Object End Type 130 * 2.11 Object End Type
119 * object-end-type = UTF-8-empty object-end-marker 131 * object-end-type = UTF-8-empty object-end-marker
120 * 0x00 0x00 0x09 132 * 0x00 0x00 0x09
@@ -208,6 +220,14 @@ extern int srs_amf0_read_null(SrsStream* stream); @@ -208,6 +220,14 @@ extern int srs_amf0_read_null(SrsStream* stream);
208 extern int srs_amf0_write_null(SrsStream* stream); 220 extern int srs_amf0_write_null(SrsStream* stream);
209 221
210 /** 222 /**
  223 +* read amf0 undefined from stream.
  224 +* 2.8 undefined Type
  225 +* undefined-type = undefined-marker
  226 +*/
  227 +extern int srs_amf0_read_undefined(SrsStream* stream);
  228 +extern int srs_amf0_write_undefined(SrsStream* stream);
  229 +
  230 +/**
211 * read amf0 object from stream. 231 * read amf0 object from stream.
212 * 2.5 Object Type 232 * 2.5 Object Type
213 * anonymous-object-type = object-marker *(object-property) 233 * anonymous-object-type = object-marker *(object-property)
@@ -233,6 +253,7 @@ extern int srs_amf0_get_utf8_size(std::string value); @@ -233,6 +253,7 @@ extern int srs_amf0_get_utf8_size(std::string value);
233 extern int srs_amf0_get_string_size(std::string value); 253 extern int srs_amf0_get_string_size(std::string value);
234 extern int srs_amf0_get_number_size(); 254 extern int srs_amf0_get_number_size();
235 extern int srs_amf0_get_null_size(); 255 extern int srs_amf0_get_null_size();
  256 +extern int srs_amf0_get_undefined_size();
236 extern int srs_amf0_get_boolean_size(); 257 extern int srs_amf0_get_boolean_size();
237 extern int srs_amf0_get_object_size(SrsAmf0Object* obj); 258 extern int srs_amf0_get_object_size(SrsAmf0Object* obj);
238 extern int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr); 259 extern int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr);
@@ -197,6 +197,8 @@ messages. @@ -197,6 +197,8 @@ messages.
197 #define RTMP_AMF0_COMMAND_ON_BW_DONE "onBWDone" 197 #define RTMP_AMF0_COMMAND_ON_BW_DONE "onBWDone"
198 #define RTMP_AMF0_COMMAND_ON_STATUS "onStatus" 198 #define RTMP_AMF0_COMMAND_ON_STATUS "onStatus"
199 #define RTMP_AMF0_COMMAND_RESULT "_result" 199 #define RTMP_AMF0_COMMAND_RESULT "_result"
  200 +#define RTMP_AMF0_COMMAND_RELEASE_STREAM "releaseStream"
  201 +#define RTMP_AMF0_COMMAND_FC_PUBLISH "FCPublish"
200 #define RTMP_AMF0_DATA_SAMPLE_ACCESS "|RtmpSampleAccess" 202 #define RTMP_AMF0_DATA_SAMPLE_ACCESS "|RtmpSampleAccess"
201 203
202 /**************************************************************************** 204 /****************************************************************************
@@ -952,6 +954,14 @@ int SrsMessage::decode_packet() @@ -952,6 +954,14 @@ int SrsMessage::decode_packet()
952 srs_info("decode the AMF0/AMF3 command(paly message)."); 954 srs_info("decode the AMF0/AMF3 command(paly message).");
953 packet = new SrsPlayPacket(); 955 packet = new SrsPlayPacket();
954 return packet->decode(stream); 956 return packet->decode(stream);
  957 + } else if(command == RTMP_AMF0_COMMAND_RELEASE_STREAM) {
  958 + srs_info("decode the AMF0/AMF3 command(FMLE releaseStream message).");
  959 + packet = new SrsFMLEStartPacket();
  960 + return packet->decode(stream);
  961 + } else if(command == RTMP_AMF0_COMMAND_FC_PUBLISH) {
  962 + srs_info("decode the AMF0/AMF3 command(FMLE FCPublish message).");
  963 + packet = new SrsFMLEStartPacket();
  964 + return packet->decode(stream);
955 } 965 }
956 966
957 // default packet to drop message. 967 // default packet to drop message.
@@ -1351,6 +1361,119 @@ int SrsCreateStreamResPacket::encode_packet(SrsStream* stream) @@ -1351,6 +1361,119 @@ int SrsCreateStreamResPacket::encode_packet(SrsStream* stream)
1351 return ret; 1361 return ret;
1352 } 1362 }
1353 1363
  1364 +SrsFMLEStartPacket::SrsFMLEStartPacket()
  1365 +{
  1366 + command_name = RTMP_AMF0_COMMAND_CREATE_STREAM;
  1367 + transaction_id = 0;
  1368 +}
  1369 +
  1370 +SrsFMLEStartPacket::~SrsFMLEStartPacket()
  1371 +{
  1372 +}
  1373 +
  1374 +int SrsFMLEStartPacket::decode(SrsStream* stream)
  1375 +{
  1376 + int ret = ERROR_SUCCESS;
  1377 +
  1378 + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) {
  1379 + srs_error("amf0 decode FMLE start command_name failed. ret=%d", ret);
  1380 + return ret;
  1381 + }
  1382 + if (command_name.empty()
  1383 + || command_name != RTMP_AMF0_COMMAND_RELEASE_STREAM
  1384 + || command_name != RTMP_AMF0_COMMAND_FC_PUBLISH
  1385 + ) {
  1386 + ret = ERROR_RTMP_AMF0_DECODE;
  1387 + srs_error("amf0 decode FMLE start command_name failed. "
  1388 + "command_name=%s, ret=%d", command_name.c_str(), ret);
  1389 + return ret;
  1390 + }
  1391 +
  1392 + if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) {
  1393 + srs_error("amf0 decode FMLE start transaction_id failed. ret=%d", ret);
  1394 + return ret;
  1395 + }
  1396 +
  1397 + if ((ret = srs_amf0_read_string(stream, stream_name)) != ERROR_SUCCESS) {
  1398 + srs_error("amf0 decode FMLE start stream_name failed. ret=%d", ret);
  1399 + return ret;
  1400 + }
  1401 +
  1402 + srs_info("amf0 decode FMLE start packet success");
  1403 +
  1404 + return ret;
  1405 +}
  1406 +
  1407 +SrsFMLEStartResPacket::SrsFMLEStartResPacket(double _transaction_id)
  1408 +{
  1409 + command_name = RTMP_AMF0_COMMAND_RESULT;
  1410 + transaction_id = _transaction_id;
  1411 + command_object = new SrsAmf0Null();
  1412 + args = new SrsAmf0Undefined();
  1413 +}
  1414 +
  1415 +SrsFMLEStartResPacket::~SrsFMLEStartResPacket()
  1416 +{
  1417 + if (command_object) {
  1418 + delete command_object;
  1419 + command_object = NULL;
  1420 + }
  1421 + if (args) {
  1422 + delete args;
  1423 + args = NULL;
  1424 + }
  1425 +}
  1426 +
  1427 +int SrsFMLEStartResPacket::get_perfer_cid()
  1428 +{
  1429 + return RTMP_CID_OverConnection;
  1430 +}
  1431 +
  1432 +int SrsFMLEStartResPacket::get_message_type()
  1433 +{
  1434 + return RTMP_MSG_AMF0CommandMessage;
  1435 +}
  1436 +
  1437 +int SrsFMLEStartResPacket::get_size()
  1438 +{
  1439 + return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size()
  1440 + + srs_amf0_get_null_size() + srs_amf0_get_undefined_size();
  1441 +}
  1442 +
  1443 +int SrsFMLEStartResPacket::encode_packet(SrsStream* stream)
  1444 +{
  1445 + int ret = ERROR_SUCCESS;
  1446 +
  1447 + if ((ret = srs_amf0_write_string(stream, command_name)) != ERROR_SUCCESS) {
  1448 + srs_error("encode command_name failed. ret=%d", ret);
  1449 + return ret;
  1450 + }
  1451 + srs_verbose("encode command_name success.");
  1452 +
  1453 + if ((ret = srs_amf0_write_number(stream, transaction_id)) != ERROR_SUCCESS) {
  1454 + srs_error("encode transaction_id failed. ret=%d", ret);
  1455 + return ret;
  1456 + }
  1457 + srs_verbose("encode transaction_id success.");
  1458 +
  1459 + if ((ret = srs_amf0_write_null(stream)) != ERROR_SUCCESS) {
  1460 + srs_error("encode command_object failed. ret=%d", ret);
  1461 + return ret;
  1462 + }
  1463 + srs_verbose("encode command_object success.");
  1464 +
  1465 + if ((ret = srs_amf0_write_undefined(stream)) != ERROR_SUCCESS) {
  1466 + srs_error("encode args failed. ret=%d", ret);
  1467 + return ret;
  1468 + }
  1469 + srs_verbose("encode args success.");
  1470 +
  1471 +
  1472 + srs_info("encode FMLE start response packet success.");
  1473 +
  1474 + return ret;
  1475 +}
  1476 +
1354 SrsPlayPacket::SrsPlayPacket() 1477 SrsPlayPacket::SrsPlayPacket()
1355 { 1478 {
1356 command_name = RTMP_AMF0_COMMAND_PLAY; 1479 command_name = RTMP_AMF0_COMMAND_PLAY;
@@ -46,6 +46,7 @@ class SrsMessage; @@ -46,6 +46,7 @@ class SrsMessage;
46 class SrsChunkStream; 46 class SrsChunkStream;
47 class SrsAmf0Object; 47 class SrsAmf0Object;
48 class SrsAmf0Null; 48 class SrsAmf0Null;
  49 +class SrsAmf0Undefined;
49 50
50 // convert class name to string. 51 // convert class name to string.
51 #define CLASS_NAME_STRING(className) #className 52 #define CLASS_NAME_STRING(className) #className
@@ -428,6 +429,57 @@ protected: @@ -428,6 +429,57 @@ protected:
428 }; 429 };
429 430
430 /** 431 /**
  432 +* FMLE start publish: ReleaseStream/PublishStream
  433 +*/
  434 +class SrsFMLEStartPacket : public SrsPacket
  435 +{
  436 +private:
  437 + typedef SrsPacket super;
  438 +protected:
  439 + virtual const char* get_class_name()
  440 + {
  441 + return CLASS_NAME_STRING(SrsFMLEStartPacket);
  442 + }
  443 +public:
  444 + std::string command_name;
  445 + double transaction_id;
  446 + std::string stream_name;
  447 +public:
  448 + SrsFMLEStartPacket();
  449 + virtual ~SrsFMLEStartPacket();
  450 +public:
  451 + virtual int decode(SrsStream* stream);
  452 +};
  453 +/**
  454 +* response for SrsFMLEStartPacket.
  455 +*/
  456 +class SrsFMLEStartResPacket : public SrsPacket
  457 +{
  458 +private:
  459 + typedef SrsPacket super;
  460 +protected:
  461 + virtual const char* get_class_name()
  462 + {
  463 + return CLASS_NAME_STRING(SrsFMLEStartResPacket);
  464 + }
  465 +public:
  466 + std::string command_name;
  467 + double transaction_id;
  468 + SrsAmf0Null* command_object;
  469 + SrsAmf0Undefined* args;
  470 +public:
  471 + SrsFMLEStartResPacket(double _transaction_id);
  472 + virtual ~SrsFMLEStartResPacket();
  473 +public:
  474 + virtual int get_perfer_cid();
  475 +public:
  476 + virtual int get_message_type();
  477 +protected:
  478 + virtual int get_size();
  479 + virtual int encode_packet(SrsStream* stream);
  480 +};
  481 +
  482 +/**
431 * 4.2.1. play 483 * 4.2.1. play
432 * The client sends this command to the server to play a stream. 484 * The client sends this command to the server to play a stream.
433 */ 485 */
@@ -307,9 +307,15 @@ int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& st @@ -307,9 +307,15 @@ int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& st
307 307
308 SrsPacket* pkt = msg->get_packet(); 308 SrsPacket* pkt = msg->get_packet();
309 if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) { 309 if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) {
  310 + srs_info("identify client by create stream, play or flash publish.");
310 return identify_create_stream_client( 311 return identify_create_stream_client(
311 dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name); 312 dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name);
312 } 313 }
  314 + if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
  315 + srs_info("identify client by releaseStream, fmle publish.");
  316 + return identify_fmle_publish_client(
  317 + dynamic_cast<SrsFMLEStartPacket*>(pkt), stream_id, type, stream_name);
  318 + }
313 319
314 srs_trace("ignore AMF0/AMF3 command message."); 320 srs_trace("ignore AMF0/AMF3 command message.");
315 } 321 }
@@ -487,3 +493,83 @@ int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int strea @@ -487,3 +493,83 @@ int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int strea
487 return ret; 493 return ret;
488 } 494 }
489 495
  496 +int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id, SrsClientType& type, std::string& stream_name)
  497 +{
  498 + int ret = ERROR_SUCCESS;
  499 +
  500 + type = SrsClientPublish;
  501 + stream_name = req->stream_name;
  502 +
  503 + // createStream response
  504 + if (true) {
  505 + SrsMessage* msg = new SrsMessage();
  506 + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id);
  507 +
  508 + msg->set_packet(pkt);
  509 +
  510 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  511 + srs_error("send releaseStream response message failed. ret=%d", ret);
  512 + return ret;
  513 + }
  514 + srs_info("send releaseStream response message success.");
  515 + }
  516 +
  517 + // FCPublish
  518 + double fc_publish_tid = 0;
  519 + if (true) {
  520 + SrsMessage* msg = NULL;
  521 + SrsFMLEStartPacket* pkt = NULL;
  522 + if ((ret = srs_rtmp_expect_message<SrsFMLEStartPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  523 + srs_error("recv FCPublish message failed. ret=%d", ret);
  524 + return ret;
  525 + }
  526 + srs_info("recv FCPublish request message success.");
  527 +
  528 + SrsAutoFree(SrsMessage, msg, false);
  529 + fc_publish_tid = pkt->transaction_id;
  530 + }
  531 + // FCPublish response
  532 + if (true) {
  533 + SrsMessage* msg = new SrsMessage();
  534 + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(fc_publish_tid);
  535 +
  536 + msg->set_packet(pkt);
  537 +
  538 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  539 + srs_error("send FCPublish response message failed. ret=%d", ret);
  540 + return ret;
  541 + }
  542 + srs_info("send FCPublish response message success.");
  543 + }
  544 +
  545 + // createStream
  546 + double create_stream_tid = 0;
  547 + if (true) {
  548 + SrsMessage* msg = NULL;
  549 + SrsCreateStreamPacket* pkt = NULL;
  550 + if ((ret = srs_rtmp_expect_message<SrsCreateStreamPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  551 + srs_error("recv createStream message failed. ret=%d", ret);
  552 + return ret;
  553 + }
  554 + srs_info("recv createStream request message success.");
  555 +
  556 + SrsAutoFree(SrsMessage, msg, false);
  557 + create_stream_tid = pkt->transaction_id;
  558 + }
  559 + // createStream response
  560 + if (true) {
  561 + SrsMessage* msg = new SrsMessage();
  562 + SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(create_stream_tid, stream_id);
  563 +
  564 + msg->set_packet(pkt);
  565 +
  566 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  567 + srs_error("send createStream response message failed. ret=%d", ret);
  568 + return ret;
  569 + }
  570 + srs_info("send createStream response message success.");
  571 + }
  572 +
  573 + return ret;
  574 +}
  575 +
@@ -36,6 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -36,6 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 36
37 class SrsProtocol; 37 class SrsProtocol;
38 class SrsCreateStreamPacket; 38 class SrsCreateStreamPacket;
  39 +class SrsFMLEStartPacket;
39 40
40 /** 41 /**
41 * the original request from client. 42 * the original request from client.
@@ -113,6 +114,7 @@ public: @@ -113,6 +114,7 @@ public:
113 virtual int start_play(int stream_id); 114 virtual int start_play(int stream_id);
114 private: 115 private:
115 virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name); 116 virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name);
  117 + virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id, SrsClientType& type, std::string& stream_name);
116 }; 118 };
117 119
118 #endif 120 #endif