1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-13 11:51:57 +00:00

for bug #251, somhc(session-oriented message-header cache). 2.0.61

This commit is contained in:
winlin 2014-12-06 00:59:10 +08:00
parent de993b6465
commit d073adde58
3 changed files with 77 additions and 29 deletions

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 60 #define VERSION_REVISION 61
// server info. // server info.
#define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_KEY "SRS"
#define RTMP_SIG_SRS_ROLE "origin/edge server" #define RTMP_SIG_SRS_ROLE "origin/edge server"

View file

@ -729,6 +729,13 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
int c0c3_cache_index = 0; int c0c3_cache_index = 0;
char* c0c3_cache = out_c0c3_caches + c0c3_cache_index; char* c0c3_cache = out_c0c3_caches + c0c3_cache_index;
// the somc(session-oriented message-header cache),
// many message header are same, use cache.
// @see https://github.com/winlinvip/simple-rtmp-server/issues/251
SrsMessageHeader* somhc = NULL;
char* somhc_bytes = NULL;
int nb_somhc_bytes = 0;
// try to send use the c0c3 header cache, // try to send use the c0c3 header cache,
// if cache is consumed, try another loop. // if cache is consumed, try another loop.
for (int i = 0; i < nb_msgs; i++) { for (int i = 0; i < nb_msgs; i++) {
@ -755,8 +762,20 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
// always write the header event payload is empty. // always write the header event payload is empty.
while (p < pend) { while (p < pend) {
// the first chunk is c0, others is c3.
bool is_c0 = p == msg->payload;
// header use iov[0]. // header use iov[0].
generate_chunk_header(c0c3_cache, &msg->header, p == msg->payload, iov); generate_chunk_header(somhc, somhc_bytes, nb_somhc_bytes,
c0c3_cache, SRS_CONSTS_C0C3_HEADERS_MAX - c0c3_cache_index,
&msg->header, is_c0, iov);
// set somhc to the first header.
if (!somhc) {
somhc = &msg->header;
somhc_bytes = (char*)iov[0].iov_base;
nb_somhc_bytes = iov[0].iov_len;
}
// payload use iov[1]. // payload use iov[1].
int payload_size = pend - p; int payload_size = pend - p;
@ -898,8 +917,10 @@ int SrsProtocol::do_send_and_free_packet(SrsPacket* packet, int stream_id)
return ret; return ret;
} }
void SrsProtocol::generate_chunk_header(char* cache, SrsMessageHeader* mh, bool c0, iovec* iov) void SrsProtocol::generate_chunk_header(
{ SrsMessageHeader* somhc, char* somhc_bytes, int nb_somhc_bytes,
char* cache, int nb_cache, SrsMessageHeader* mh, bool c0, iovec* iov
) {
// to directly set the field. // to directly set the field.
char* pp = NULL; char* pp = NULL;
@ -910,37 +931,55 @@ void SrsProtocol::generate_chunk_header(char* cache, SrsMessageHeader* mh, bool
u_int32_t timestamp = (u_int32_t)mh->timestamp; u_int32_t timestamp = (u_int32_t)mh->timestamp;
if (c0) { if (c0) {
// if cached header, copy it.
if (somhc) {
srs_assert(nb_cache >= nb_somhc_bytes);
memcpy(cache, somhc_bytes, nb_somhc_bytes);
}
// write new chunk stream header, fmt is 0 // write new chunk stream header, fmt is 0
*p++ = 0x00 | (mh->perfer_cid & 0x3F); *p++ = 0x00 | (mh->perfer_cid & 0x3F);
// chunk message header, 11 bytes // chunk message header, 11 bytes
// timestamp, 3bytes, big-endian // timestamp, 3bytes, big-endian
if (timestamp < RTMP_EXTENDED_TIMESTAMP) { if (somhc && somhc->timestamp == mh->timestamp) {
pp = (char*)&timestamp; p += 3;
*p++ = pp[2];
*p++ = pp[1];
*p++ = pp[0];
} else { } else {
*p++ = 0xFF; if (timestamp < RTMP_EXTENDED_TIMESTAMP) {
*p++ = 0xFF; pp = (char*)&timestamp;
*p++ = 0xFF; *p++ = pp[2];
*p++ = pp[1];
*p++ = pp[0];
} else {
*p++ = 0xFF;
*p++ = 0xFF;
*p++ = 0xFF;
}
} }
// message_length, 3bytes, big-endian // message_length, 3bytes, big-endian
pp = (char*)&mh->payload_length; if (somhc && somhc->payload_length == mh->payload_length) {
*p++ = pp[2]; p += 3;
*p++ = pp[1]; } else {
*p++ = pp[0]; pp = (char*)&mh->payload_length;
*p++ = pp[2];
*p++ = pp[1];
*p++ = pp[0];
}
// message_type, 1bytes // message_type, 1bytes
*p++ = mh->message_type; *p++ = mh->message_type;
// message_length, 3bytes, little-endian // stream_id, 4bytes, little-endian.
pp = (char*)&mh->stream_id; if (somhc && somhc->stream_id == mh->stream_id) {
*p++ = pp[0]; p += 4;
*p++ = pp[1]; } else {
*p++ = pp[2]; pp = (char*)&mh->stream_id;
*p++ = pp[3]; *p++ = pp[0];
*p++ = pp[1];
*p++ = pp[2];
*p++ = pp[3];
}
} else { } else {
// write no message header chunk stream, fmt is 3 // write no message header chunk stream, fmt is 3
// @remark, if perfer_cid > 0x3F, that is, use 2B/3B chunk header, // @remark, if perfer_cid > 0x3F, that is, use 2B/3B chunk header,
@ -967,11 +1006,15 @@ void SrsProtocol::generate_chunk_header(char* cache, SrsMessageHeader* mh, bool
// @see: http://blog.csdn.net/win_lin/article/details/13363699 // @see: http://blog.csdn.net/win_lin/article/details/13363699
// TODO: FIXME: extract to outer. // TODO: FIXME: extract to outer.
if (timestamp >= RTMP_EXTENDED_TIMESTAMP) { if (timestamp >= RTMP_EXTENDED_TIMESTAMP) {
pp = (char*)&timestamp; if (somhc && somhc->payload_length == mh->payload_length) {
*p++ = pp[3]; p += 4;
*p++ = pp[2]; } else {
*p++ = pp[1]; pp = (char*)&timestamp;
*p++ = pp[0]; *p++ = pp[3];
*p++ = pp[2];
*p++ = pp[1];
*p++ = pp[0];
}
} }
// always has header // always has header

View file

@ -84,7 +84,7 @@ public:
/** /**
* 4bytes. * 4bytes.
* Four-byte field that identifies the stream of the message. These * Four-byte field that identifies the stream of the message. These
* bytes are set in big-endian format. * bytes are set in little-endian format.
*/ */
int32_t stream_id; int32_t stream_id;
@ -494,11 +494,16 @@ private:
virtual int do_send_and_free_packet(SrsPacket* packet, int stream_id); virtual int do_send_and_free_packet(SrsPacket* packet, int stream_id);
/** /**
* generate the chunk header for msg. * generate the chunk header for msg.
* @param somhc, session-oriented message-header cache.
* @param somhc_bytes, the serialized bytes.
* @param nb_somhc_bytes, the size of somhc_bytes.
* @param mh, the header of msg to send. * @param mh, the header of msg to send.
* @param c0, whether the first chunk, the c0 chunk. * @param c0, whether the first chunk, the c0 chunk.
* @param iov, output the header and size to iovec. * @param iov, output the header and size to iovec.
*/ */
virtual void generate_chunk_header(char* cache, SrsMessageHeader* mh, bool c0, iovec* iov); virtual void generate_chunk_header(
SrsMessageHeader* somhc, char* somhc_bytes, int nb_somhc_bytes,
char* cache, int nb_cache, SrsMessageHeader* mh, bool c0, iovec* iov);
/** /**
* imp for decode_message * imp for decode_message
*/ */