1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-12 11:21:52 +00:00

Fix #844, support Haivision encoder. 2.0.238

This commit is contained in:
winlin 2017-04-15 20:44:02 +08:00
parent 1c139d8fd8
commit 33a0abdeff
6 changed files with 112 additions and 3 deletions

View file

@ -336,6 +336,7 @@ Remark:
## History ## History
* v2.0, 2017-04-15, Fix [#844][bug #844], support Haivision encoder. 2.0.238
* v2.0, 2017-04-15, Merge [#846][bug #846], fix fd leak for FLV stream caster. 2.0.237 * v2.0, 2017-04-15, Merge [#846][bug #846], fix fd leak for FLV stream caster. 2.0.237
* v2.0, 2017-04-15, Merge [#841][bug #841], avoid the duplicated sps/pps in ts. 2.0.236 * v2.0, 2017-04-15, Merge [#841][bug #841], avoid the duplicated sps/pps in ts. 2.0.236
* v2.0, 2017-04-09, Fix [#834][bug #834], crash for TS context corrupt. 2.0.235 * v2.0, 2017-04-09, Fix [#834][bug #834], crash for TS context corrupt. 2.0.235
@ -1285,6 +1286,7 @@ Winlin
[bug #834]: https://github.com/ossrs/srs/issues/834 [bug #834]: https://github.com/ossrs/srs/issues/834
[bug #841]: https://github.com/ossrs/srs/issues/841 [bug #841]: https://github.com/ossrs/srs/issues/841
[bug #846]: https://github.com/ossrs/srs/issues/846 [bug #846]: https://github.com/ossrs/srs/issues/846
[bug #844]: https://github.com/ossrs/srs/issues/844
[bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx [bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx
[exo #828]: https://github.com/google/ExoPlayer/pull/828 [exo #828]: https://github.com/google/ExoPlayer/pull/828

View file

@ -546,6 +546,16 @@ int SrsRtmpConn::stream_service_cycle()
return publishing(source); return publishing(source);
} }
case SrsRtmpConnHaivisionPublish: {
srs_verbose("Haivision start to publish stream %s.", req->stream.c_str());
if ((ret = rtmp->start_haivision_publish(res->stream_id)) != ERROR_SUCCESS) {
srs_error("start to publish stream failed. ret=%d", ret);
return ret;
}
return publishing(source);
}
case SrsRtmpConnFlashPublish: { case SrsRtmpConnFlashPublish: {
srs_verbose("flash start to publish stream %s.", req->stream.c_str()); srs_verbose("flash start to publish stream %s.", req->stream.c_str());
@ -839,7 +849,7 @@ int SrsRtmpConn::publishing(SrsSource* source)
// @see: https://github.com/ossrs/srs/issues/237 // @see: https://github.com/ossrs/srs/issues/237
SrsPublishRecvThread trd(rtmp, req, SrsPublishRecvThread trd(rtmp, req,
st_netfd_fileno(stfd), 0, this, source, st_netfd_fileno(stfd), 0, this, source,
client_type == SrsRtmpConnFMLEPublish, client_type != SrsRtmpConnFlashPublish,
vhost_is_edge); vhost_is_edge);
srs_info("start to publish stream %s success", req->stream.c_str()); srs_info("start to publish stream %s success", req->stream.c_str());

View file

@ -90,6 +90,7 @@ int SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std:
break; break;
case SrsRtmpConnFMLEPublish: case SrsRtmpConnFMLEPublish:
case SrsRtmpConnFlashPublish: case SrsRtmpConnFlashPublish:
case SrsRtmpConnHaivisionPublish:
if (rule->arg0() != "publish") { if (rule->arg0() != "publish") {
break; break;
} }
@ -135,6 +136,7 @@ int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::
break; break;
case SrsRtmpConnFMLEPublish: case SrsRtmpConnFMLEPublish:
case SrsRtmpConnFlashPublish: case SrsRtmpConnFlashPublish:
case SrsRtmpConnHaivisionPublish:
if (rule->arg0() != "publish") { if (rule->arg0() != "publish") {
break; break;
} }

View file

@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version // current release version
#define VERSION_MAJOR 2 #define VERSION_MAJOR 2
#define VERSION_MINOR 0 #define VERSION_MINOR 0
#define VERSION_REVISION 237 #define VERSION_REVISION 238
// generated by configure, only macros. // generated by configure, only macros.
#include <srs_auto_headers.hpp> #include <srs_auto_headers.hpp>

View file

@ -1791,6 +1791,7 @@ string srs_client_type_string(SrsRtmpConnType type)
case SrsRtmpConnPlay: return "Play"; case SrsRtmpConnPlay: return "Play";
case SrsRtmpConnFlashPublish: return "flash-publish"; case SrsRtmpConnFlashPublish: return "flash-publish";
case SrsRtmpConnFMLEPublish: return "fmle-publish"; case SrsRtmpConnFMLEPublish: return "fmle-publish";
case SrsRtmpConnHaivisionPublish: return "haivision-publish";
default: return "Unknown"; default: return "Unknown";
} }
} }
@ -2693,6 +2694,14 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string&
} }
return ret; return ret;
} }
// For encoder of Haivision, it always send a _checkbw call message.
// @Remark the next message is createStream, so we continue to identify it.
// @see https://github.com/ossrs/srs/issues/844
if (call->command_name == "_checkbw") {
srs_info("Haivision encoder identified.");
continue;
}
continue; continue;
} }
@ -2968,6 +2977,60 @@ int SrsRtmpServer::start_fmle_publish(int stream_id)
return ret; return ret;
} }
int SrsRtmpServer::start_haivision_publish(int stream_id)
{
int ret = ERROR_SUCCESS;
// publish
if (true) {
SrsCommonMessage* msg = NULL;
SrsPublishPacket* pkt = NULL;
if ((ret = expect_message<SrsPublishPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
srs_error("recv publish message failed. ret=%d", ret);
return ret;
}
srs_info("recv publish request message success.");
SrsAutoFree(SrsCommonMessage, msg);
SrsAutoFree(SrsPublishPacket, pkt);
}
// publish response onFCPublish(NetStream.Publish.Start)
if (true) {
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_PUBLISH;
pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodePublishStart));
pkt->data->set(StatusDescription, SrsAmf0Any::str("Started publishing stream."));
if ((ret = protocol->send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
srs_error("send onFCPublish(NetStream.Publish.Start) message failed. ret=%d", ret);
return ret;
}
srs_info("send onFCPublish(NetStream.Publish.Start) message success.");
}
// publish response onStatus(NetStream.Publish.Start)
if (true) {
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelStatus));
pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodePublishStart));
pkt->data->set(StatusDescription, SrsAmf0Any::str("Started publishing stream."));
pkt->data->set(StatusClientId, SrsAmf0Any::str(RTMP_SIG_CLIENT_ID));
if ((ret = protocol->send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) {
srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);
return ret;
}
srs_info("send onStatus(NetStream.Publish.Start) message success.");
}
srs_info("Haivision publish success.");
return ret;
}
int SrsRtmpServer::fmle_unpublish(int stream_id, double unpublish_tid) int SrsRtmpServer::fmle_unpublish(int stream_id, double unpublish_tid)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
@ -3102,6 +3165,10 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int
srs_info("identify client by create stream, play or flash publish."); srs_info("identify client by create stream, play or flash publish.");
return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name, duration); return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name, duration);
} }
if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
srs_info("identify client by FCPublish, haivision publish.");
return identify_haivision_publish_client(dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name);
}
srs_trace("ignore AMF0/AMF3 command message."); srs_trace("ignore AMF0/AMF3 command message.");
} }
@ -3129,6 +3196,26 @@ int SrsRtmpServer::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmp
return ret; return ret;
} }
int SrsRtmpServer::identify_haivision_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, string& stream_name)
{
int ret = ERROR_SUCCESS;
type = SrsRtmpConnHaivisionPublish;
stream_name = req->stream_name;
// FCPublish response
if (true) {
SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id);
if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
srs_error("send FCPublish response message failed. ret=%d", ret);
return ret;
}
srs_info("send FCPublish response message success.");
}
return ret;
}
int SrsRtmpServer::identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, string& stream_name) int SrsRtmpServer::identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, string& stream_name)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;

View file

@ -69,6 +69,7 @@ class SrsCommonMessage;
class SrsPacket; class SrsPacket;
class SrsAmf0Object; class SrsAmf0Object;
class IMergeReadHandler; class IMergeReadHandler;
class SrsCallPacket;
/**************************************************************************** /****************************************************************************
***************************************************************************** *****************************************************************************
@ -631,6 +632,7 @@ enum SrsRtmpConnType
SrsRtmpConnPlay, SrsRtmpConnPlay,
SrsRtmpConnFMLEPublish, SrsRtmpConnFMLEPublish,
SrsRtmpConnFlashPublish, SrsRtmpConnFlashPublish,
SrsRtmpConnHaivisionPublish,
}; };
std::string srs_client_type_string(SrsRtmpConnType type); std::string srs_client_type_string(SrsRtmpConnType type);
bool srs_client_type_is_publish(SrsRtmpConnType type); bool srs_client_type_is_publish(SrsRtmpConnType type);
@ -989,6 +991,11 @@ public:
* onStatus(NetStream.Publish.Start) * onStatus(NetStream.Publish.Start)
*/ */
virtual int start_fmle_publish(int stream_id); virtual int start_fmle_publish(int stream_id);
/**
* For encoder of Haivision, response the startup request.
* @see https://github.com/ossrs/srs/issues/844
*/
virtual int start_haivision_publish(int stream_id);
/** /**
* process the FMLE unpublish event. * process the FMLE unpublish event.
* @unpublish_tid the unpublish request transaction id. * @unpublish_tid the unpublish request transaction id.
@ -1025,6 +1032,7 @@ public:
private: private:
virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, std::string& stream_name, double& duration); virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, std::string& stream_name, double& duration);
virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name); virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name);
virtual int identify_haivision_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name);
virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, std::string& stream_name); virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, std::string& stream_name);
private: private:
virtual int identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, std::string& stream_name, double& duration); virtual int identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, std::string& stream_name, double& duration);
@ -1293,7 +1301,7 @@ public:
}; };
/** /**
* FMLE start publish: ReleaseStream/PublishStream * FMLE start publish: ReleaseStream/PublishStream/FCPublish/FCUnpublish
*/ */
class SrsFMLEStartPacket : public SrsPacket class SrsFMLEStartPacket : public SrsPacket
{ {