Skip to content

Commit

Permalink
fix #405, improve the HTTP FLV performance to 6k. 2.0.171
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed May 24, 2015
1 parent 4df19ba commit d12fc7f
Show file tree
Hide file tree
Showing 13 changed files with 1,187 additions and 916 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@ The play HTTP FLV benchmark by [SB](https://github.com/simple-rtmp-server/srs-be
| 2014-05-24 | 2.0.168 | 2.3k(2300) | players | 92% | 276MB | [code][p17] |
| 2014-05-24 | 2.0.169 | 3.0k(3000) | players | 94% | 188MB | [code][p18] |
| 2014-05-24 | 2.0.170 | 3.0k(3000) | players | 89% | 96MB | [code][p19] |
| 2014-05-25 | 2.0.171 | 6.0k(6000) | players | 84% | 297MB | [code][p20] |

### Latency benchmark

Expand Down
84 changes: 65 additions & 19 deletions trunk/src/app/srs_app_http_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,37 +175,52 @@ int SrsHttpResponseWriter::writev(iovec* iov, int iovcnt, ssize_t* pnwrite)
}

// send in chunked encoding.
int nb_iovss = iovcnt * 4;
int nb_iovss = 3 + iovcnt;
iovec* iovss = iovss_cache;
if (nb_iovss_cache < nb_iovss) {
srs_freep(iovss_cache);
nb_iovss_cache = nb_iovss;
iovss = iovss_cache = new iovec[nb_iovss];
}

char* pheader_cache = header_cache;
// send in chunked encoding.

// chunk size.
int size = 0;
for (int i = 0; i < iovcnt; i++) {
int left = SRS_HTTP_HEADER_CACHE_SIZE - (int)(pheader_cache - header_cache);
srs_assert(left > 0);

iovec* data_iov = iov + i;
int nb_size = snprintf(pheader_cache, left, "%x", (int)data_iov->iov_len);

iovec* iovs = iovss + (i * 4);
iovs[0].iov_base = (char*)pheader_cache;
iovs[0].iov_len = (int)nb_size;
iovs[1].iov_base = (char*)SRS_HTTP_CRLF;
iovs[1].iov_len = 2;
iovs[2].iov_base = (char*)data_iov->iov_base;
iovs[2].iov_len = (int)data_iov->iov_len;
iovs[3].iov_base = (char*)SRS_HTTP_CRLF;
iovs[3].iov_len = 2;

pheader_cache += nb_size;
size += data_iov->iov_len;
}
written += size;

// chunk header
int nb_size = snprintf(header_cache, SRS_HTTP_HEADER_CACHE_SIZE, "%x", size);
iovec* iovs = iovss;
iovs[0].iov_base = (char*)header_cache;
iovs[0].iov_len = (int)nb_size;
iovs++;

// chunk header eof.
iovs[0].iov_base = (char*)SRS_HTTP_CRLF;
iovs[0].iov_len = 2;
iovs++;

// chunk body.
for (int i = 0; i < iovcnt; i++) {
iovec* data_iov = iov + i;
iovs[0].iov_base = (char*)data_iov->iov_base;
iovs[0].iov_len = (int)data_iov->iov_len;
iovs++;
}

// chunk body eof.
iovs[0].iov_base = (char*)SRS_HTTP_CRLF;
iovs[0].iov_len = 2;
iovs++;

// sendout all ioves.
ssize_t nwrite;
if ((ret = skt->writev(iovss, nb_iovss, &nwrite)) != ERROR_SUCCESS) {
if ((ret = srs_write_large_iovs(skt, iovss, nb_iovss, &nwrite)) != ERROR_SUCCESS) {
return ret;
}

Expand Down Expand Up @@ -1442,6 +1457,21 @@ int SrsFlvStreamEncoder::dump_cache(SrsConsumer* /*consumer*/)
return ERROR_SUCCESS;
}

#ifdef SRS_PERF_FAST_FLV_ENCODER
SrsFastFlvStreamEncoder::SrsFastFlvStreamEncoder()
{
}

SrsFastFlvStreamEncoder::~SrsFastFlvStreamEncoder()
{
}

int SrsFastFlvStreamEncoder::write_tags(SrsSharedPtrMessage** msgs, int count)
{
return enc->write_tags(msgs, count);
}
#endif

SrsAacStreamEncoder::SrsAacStreamEncoder()
{
enc = new SrsAacEncoder();
Expand Down Expand Up @@ -1612,7 +1642,11 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
srs_assert(entry);
if (srs_string_ends_with(entry->pattern, ".flv")) {
w->header()->set_content_type("video/x-flv");
#ifdef SRS_PERF_FAST_FLV_ENCODER
enc = new SrsFastFlvStreamEncoder();
#else
enc = new SrsFlvStreamEncoder();
#endif
} else if (srs_string_ends_with(entry->pattern, ".aac")) {
w->header()->set_content_type("audio/x-aac");
enc = new SrsAacStreamEncoder();
Expand Down Expand Up @@ -1658,6 +1692,10 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
}
}

#ifdef SRS_PERF_FAST_FLV_ENCODER
SrsFastFlvStreamEncoder* ffe = dynamic_cast<SrsFastFlvStreamEncoder*>(enc);
#endif

while (true) {
pprint->elapse();

Expand All @@ -1684,7 +1722,15 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
}

// sendout all messages.
#ifdef SRS_PERF_FAST_FLV_ENCODER
if (ffe) {
ret = ffe->write_tags(msgs.msgs, count);
} else {
ret = streaming_send_messages(enc, msgs.msgs, count);
}
#else
ret = streaming_send_messages(enc, msgs.msgs, count);
#endif

// free the messages.
for (int i = 0; i < count; i++) {
Expand Down
32 changes: 24 additions & 8 deletions trunk/src/app/srs_app_http_conn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,9 @@ class SrsHttpMessage;

#ifdef SRS_AUTO_HTTP_PARSER

// for HTTP FLV, each video/audio packet is send by 3 iovs,
// while each iov is send by 4 sub iovs, that is needs 3 chunk header,
// suppose each header is 16 length, 3*16=48 is ok.
// that is, 512 can used for 16 iovs to send.
#define SRS_HTTP_HEADER_CACHE_SIZE 512
// the http chunked header size,
// for writev, there always one chunk to send it.
#define SRS_HTTP_HEADER_CACHE_SIZE 64

/**
* response writer use st socket
Expand Down Expand Up @@ -214,8 +212,8 @@ class SrsHttpMessage : public ISrsHttpMessage
* set the original messages, then update the message.
*/
virtual int update(std::string url, http_parser* header,
SrsFastBuffer* body, std::vector<SrsHttpHeaderField>& headers
);
SrsFastBuffer* body, std::vector<SrsHttpHeaderField>& headers
);
private:
virtual SrsConnection* connection();
public:
Expand Down Expand Up @@ -454,7 +452,7 @@ class ISrsStreamEncoder
*/
class SrsFlvStreamEncoder : public ISrsStreamEncoder
{
private:
protected:
SrsFlvEncoder* enc;
public:
SrsFlvStreamEncoder();
Expand All @@ -469,6 +467,24 @@ class SrsFlvStreamEncoder : public ISrsStreamEncoder
virtual int dump_cache(SrsConsumer* consumer);
};

#ifdef SRS_PERF_FAST_FLV_ENCODER
/**
* the fast flv stream encoder.
* @see https://github.com/simple-rtmp-server/srs/issues/405
*/
class SrsFastFlvStreamEncoder : public SrsFlvStreamEncoder
{
public:
SrsFastFlvStreamEncoder();
virtual ~SrsFastFlvStreamEncoder();
public:
/**
* write the tags in a time.
*/
virtual int write_tags(SrsSharedPtrMessage** msgs, int count);
};
#endif

/**
* the ts stream encoder, remux rtmp stream to ts stream.
*/
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
#define VERSION_REVISION 170
#define VERSION_REVISION 171

// server info.
#define RTMP_SIG_SRS_KEY "SRS"
Expand Down
7 changes: 7 additions & 0 deletions trunk/src/core/srs_core_performance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#undef SRS_PERF_SO_SNDBUF_SIZE
#endif

/**
* define the following macro to enable the fast flv encoder.
* @see https://github.com/simple-rtmp-server/srs/issues/405
*/
#undef SRS_PERF_FAST_FLV_ENCODER
#define SRS_PERF_FAST_FLV_ENCODER

#endif

Loading

0 comments on commit d12fc7f

Please sign in to comment.