1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

fix #405, improve the HTTP FLV performance to 6k. 2.0.171

This commit is contained in:
winlin 2015-05-25 01:02:06 +08:00
parent 4df19ba99a
commit d12fc7fcc5
13 changed files with 1193 additions and 922 deletions

View file

@ -120,318 +120,6 @@ using namespace std;
/****************************************************************************
*****************************************************************************
****************************************************************************/
/**
* the chunk stream id used for some under-layer message,
* for example, the PC(protocol control) message.
*/
#define RTMP_CID_ProtocolControl 0x02
/**
* the AMF0/AMF3 command message, invoke method and return the result, over NetConnection.
* generally use 0x03.
*/
#define RTMP_CID_OverConnection 0x03
/**
* the AMF0/AMF3 command message, invoke method and return the result, over NetConnection,
* the midst state(we guess).
* rarely used, e.g. onStatus(NetStream.Play.Reset).
*/
#define RTMP_CID_OverConnection2 0x04
/**
* the stream message(amf0/amf3), over NetStream.
* generally use 0x05.
*/
#define RTMP_CID_OverStream 0x05
/**
* the stream message(amf0/amf3), over NetStream, the midst state(we guess).
* rarely used, e.g. play("mp4:mystram.f4v")
*/
#define RTMP_CID_OverStream2 0x08
/**
* the stream message(video), over NetStream
* generally use 0x06.
*/
#define RTMP_CID_Video 0x06
/**
* the stream message(audio), over NetStream.
* generally use 0x07.
*/
#define RTMP_CID_Audio 0x07
/****************************************************************************
*****************************************************************************
****************************************************************************/
SrsMessageHeader::SrsMessageHeader()
{
message_type = 0;
payload_length = 0;
timestamp_delta = 0;
stream_id = 0;
timestamp = 0;
// we always use the connection chunk-id
perfer_cid = RTMP_CID_OverConnection;
}
SrsMessageHeader::~SrsMessageHeader()
{
}
bool SrsMessageHeader::is_audio()
{
return message_type == RTMP_MSG_AudioMessage;
}
bool SrsMessageHeader::is_video()
{
return message_type == RTMP_MSG_VideoMessage;
}
bool SrsMessageHeader::is_amf0_command()
{
return message_type == RTMP_MSG_AMF0CommandMessage;
}
bool SrsMessageHeader::is_amf0_data()
{
return message_type == RTMP_MSG_AMF0DataMessage;
}
bool SrsMessageHeader::is_amf3_command()
{
return message_type == RTMP_MSG_AMF3CommandMessage;
}
bool SrsMessageHeader::is_amf3_data()
{
return message_type == RTMP_MSG_AMF3DataMessage;
}
bool SrsMessageHeader::is_window_ackledgement_size()
{
return message_type == RTMP_MSG_WindowAcknowledgementSize;
}
bool SrsMessageHeader::is_ackledgement()
{
return message_type == RTMP_MSG_Acknowledgement;
}
bool SrsMessageHeader::is_set_chunk_size()
{
return message_type == RTMP_MSG_SetChunkSize;
}
bool SrsMessageHeader::is_user_control_message()
{
return message_type == RTMP_MSG_UserControlMessage;
}
bool SrsMessageHeader::is_set_peer_bandwidth()
{
return message_type == RTMP_MSG_SetPeerBandwidth;
}
bool SrsMessageHeader::is_aggregate()
{
return message_type == RTMP_MSG_AggregateMessage;
}
void SrsMessageHeader::initialize_amf0_script(int size, int stream)
{
message_type = RTMP_MSG_AMF0DataMessage;
payload_length = (int32_t)size;
timestamp_delta = (int32_t)0;
timestamp = (int64_t)0;
stream_id = (int32_t)stream;
// amf0 script use connection2 chunk-id
perfer_cid = RTMP_CID_OverConnection2;
}
void SrsMessageHeader::initialize_audio(int size, u_int32_t time, int stream)
{
message_type = RTMP_MSG_AudioMessage;
payload_length = (int32_t)size;
timestamp_delta = (int32_t)time;
timestamp = (int64_t)time;
stream_id = (int32_t)stream;
// audio chunk-id
perfer_cid = RTMP_CID_Audio;
}
void SrsMessageHeader::initialize_video(int size, u_int32_t time, int stream)
{
message_type = RTMP_MSG_VideoMessage;
payload_length = (int32_t)size;
timestamp_delta = (int32_t)time;
timestamp = (int64_t)time;
stream_id = (int32_t)stream;
// video chunk-id
perfer_cid = RTMP_CID_Video;
}
SrsCommonMessage::SrsCommonMessage()
{
payload = NULL;
size = 0;
}
SrsCommonMessage::~SrsCommonMessage()
{
srs_freep(payload);
}
SrsSharedPtrMessage::SrsSharedPtrPayload::SrsSharedPtrPayload()
{
payload = NULL;
size = 0;
shared_count = 0;
}
SrsSharedPtrMessage::SrsSharedPtrPayload::~SrsSharedPtrPayload()
{
srs_freep(payload);
}
SrsSharedPtrMessage::SrsSharedPtrMessage()
{
ptr = NULL;
}
SrsSharedPtrMessage::~SrsSharedPtrMessage()
{
if (ptr) {
if (ptr->shared_count == 0) {
srs_freep(ptr);
} else {
ptr->shared_count--;
}
}
}
int SrsSharedPtrMessage::create(SrsCommonMessage* msg)
{
int ret = ERROR_SUCCESS;
if ((ret = create(&msg->header, msg->payload, msg->size)) != ERROR_SUCCESS) {
return ret;
}
// to prevent double free of payload:
// initialize already attach the payload of msg,
// detach the payload to transfer the owner to shared ptr.
msg->payload = NULL;
msg->size = 0;
return ret;
}
int SrsSharedPtrMessage::create(SrsMessageHeader* pheader, char* payload, int size)
{
int ret = ERROR_SUCCESS;
if (ptr) {
ret = ERROR_SYSTEM_ASSERT_FAILED;
srs_error("should not set the payload twice. ret=%d", ret);
srs_assert(false);
return ret;
}
ptr = new SrsSharedPtrPayload();
// direct attach the data.
if (pheader) {
ptr->header.message_type = pheader->message_type;
ptr->header.payload_length = size;
ptr->header.perfer_cid = pheader->perfer_cid;
this->timestamp = pheader->timestamp;
this->stream_id = pheader->stream_id;
}
ptr->payload = payload;
ptr->size = size;
// message can access it.
this->payload = ptr->payload;
this->size = ptr->size;
return ret;
}
int SrsSharedPtrMessage::count()
{
srs_assert(ptr);
return ptr->shared_count;
}
bool SrsSharedPtrMessage::check(int stream_id)
{
// we donot use the complex basic header,
// ensure the basic header is 1bytes.
if (ptr->header.perfer_cid < 2) {
srs_info("change the chunk_id=%d to default=%d",
ptr->header.perfer_cid, RTMP_CID_ProtocolControl);
ptr->header.perfer_cid = RTMP_CID_ProtocolControl;
}
// we assume that the stream_id in a group must be the same.
if (this->stream_id == stream_id) {
return true;
}
this->stream_id = stream_id;
return false;
}
bool SrsSharedPtrMessage::is_av()
{
return ptr->header.message_type == RTMP_MSG_AudioMessage
|| ptr->header.message_type == RTMP_MSG_VideoMessage;
}
bool SrsSharedPtrMessage::is_audio()
{
return ptr->header.message_type == RTMP_MSG_AudioMessage;
}
bool SrsSharedPtrMessage::is_video()
{
return ptr->header.message_type == RTMP_MSG_VideoMessage;
}
int SrsSharedPtrMessage::chunk_header(char* cache, int nb_cache, bool c0)
{
if (c0) {
return srs_chunk_header_c0(
ptr->header.perfer_cid, timestamp, ptr->header.payload_length,
ptr->header.message_type, stream_id,
cache, nb_cache);
} else {
return srs_chunk_header_c3(
ptr->header.perfer_cid, timestamp,
cache, nb_cache);
}
}
SrsSharedPtrMessage* SrsSharedPtrMessage::copy()
{
srs_assert(ptr);
SrsSharedPtrMessage* copy = new SrsSharedPtrMessage();
copy->ptr = ptr;
ptr->shared_count++;
copy->timestamp = timestamp;
copy->stream_id = stream_id;
copy->payload = ptr->payload;
copy->size = ptr->size;
return copy;
}
SrsPacket::SrsPacket()
{
@ -904,41 +592,7 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
int SrsProtocol::do_iovs_send(iovec* iovs, int size)
{
int ret = ERROR_SUCCESS;
// the limits of writev iovs.
// for srs-librtmp, @see https://github.com/simple-rtmp-server/srs/issues/213
#ifndef _WIN32
static int limits = sysconf(_SC_IOV_MAX);
#else
static int limits = 1024;
#endif
// send in a time.
if (size < limits) {
if ((ret = skt->writev(iovs, size, NULL)) != ERROR_SUCCESS) {
if (!srs_is_client_gracefully_close(ret)) {
srs_error("send with writev failed. ret=%d", ret);
}
return ret;
}
return ret;
}
// send in multiple times.
int cur_iov = 0;
while (cur_iov < size) {
int cur_count = srs_min(limits, size - cur_iov);
if ((ret = skt->writev(iovs + cur_iov, cur_count, NULL)) != ERROR_SUCCESS) {
if (!srs_is_client_gracefully_close(ret)) {
srs_error("send with writev failed. ret=%d", ret);
}
return ret;
}
cur_iov += cur_count;
}
return ret;
return srs_write_large_iovs(skt, iovs, size);
}
int SrsProtocol::do_send_and_free_packet(SrsPacket* packet, int stream_id)