Skip to content

Commit 960341b

Browse files
committed
for #405, improve the HTT FLV to 3k. 2.0.169
1 parent b53e981 commit 960341b

File tree

8 files changed

+140
-26
lines changed

8 files changed

+140
-26
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,8 @@ The play HTTP FLV benchmark by [SB](https://github.com/simple-rtmp-server/srs-be
716716
| Update | SRS | Clients | Type | CPU | Memory | Commit |
717717
| ------------- | --------- | ------------- | ------------- | --------- | -------- | ------------ |
718718
| 2014-05-24 | 2.0.167 | 1.0k(1000) | players | 82% | 86MB | - |
719-
| 2014-05-24 | 2.0.168 | 2.3k(2300) | players | 92% | 276MB | - |
719+
| 2014-05-24 | 2.0.168 | 2.3k(2300) | players | 92% | 276MB | [code][p17] |
720+
| 2014-05-24 | 2.0.169 | 3.0k(3000) | players | 94% | 188MB | [code][p18] |
720721

721722
### Latency benchmark
722723

@@ -832,6 +833,7 @@ Winlin
832833
[p14]: https://github.com/simple-rtmp-server/srs/commit/10297fab519811845b549a8af40a6bcbd23411e8
833834
[p15]: https://github.com/simple-rtmp-server/srs/commit/0d6b91039d408328caab31a1077d56a809b6bebc
834835
[p16]: https://github.com/simple-rtmp-server/srs/commit/0d6b91039d408328caab31a1077d56a809b6bebc
836+
[p17]: https://github.com/simple-rtmp-server/srs/commit/fc995473eb02c7cf64b5b212b456e11f34aa7984
835837

836838
[authors]: https://github.com/simple-rtmp-server/srs/blob/develop/AUTHORS.txt
837839
[bigthanks]: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_Product#bigthanks

trunk/src/app/srs_app_http_conn.cpp

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,20 +98,21 @@ int SrsHttpResponseWriter::write(char* data, int size)
9898

9999
if (!header_wrote) {
100100
write_header(SRS_CONSTS_HTTP_OK);
101+
102+
if ((ret = send_header(data, size)) != ERROR_SUCCESS) {
103+
srs_error("http: send header failed. ret=%d", ret);
104+
return ret;
105+
}
101106
}
102107

108+
// check the bytes send and content length.
103109
written += size;
104110
if (content_length != -1 && written > content_length) {
105111
ret = ERROR_HTTP_CONTENT_LENGTH;
106112
srs_error("http: exceed content length. ret=%d", ret);
107113
return ret;
108114
}
109115

110-
if ((ret = send_header(data, size)) != ERROR_SUCCESS) {
111-
srs_error("http: send header failed. ret=%d", ret);
112-
return ret;
113-
}
114-
115116
// ignore NULL content.
116117
if (!data) {
117118
return ret;
@@ -143,6 +144,71 @@ int SrsHttpResponseWriter::write(char* data, int size)
143144
return ret;
144145
}
145146

147+
int SrsHttpResponseWriter::writev(iovec* iov, int iovcnt, ssize_t* pnwrite)
148+
{
149+
int ret = ERROR_SUCCESS;
150+
151+
// when header not ready, or not chunked, send one by one.
152+
if (!header_wrote || content_length != -1) {
153+
ssize_t nwrite = 0;
154+
for (int i = 0; i < iovcnt; i++) {
155+
iovec* piovc = iov + i;
156+
nwrite += piovc->iov_len;
157+
if ((ret = write((char*)piovc->iov_base, (int)piovc->iov_len)) != ERROR_SUCCESS) {
158+
return ret;
159+
}
160+
}
161+
162+
if (pnwrite) {
163+
*pnwrite = nwrite;
164+
}
165+
166+
return ret;
167+
}
168+
169+
// ignore NULL content.
170+
if (iovcnt <= 0) {
171+
return ret;
172+
}
173+
174+
// send in chunked encoding.
175+
int nb_iovss = iovcnt * 4;
176+
iovec* iovss = new iovec[nb_iovss];
177+
SrsAutoFree(iovec, iovss);
178+
179+
char* pheader_cache = header_cache;
180+
for (int i = 0; i < iovcnt; i++) {
181+
int left = SRS_HTTP_HEADER_CACHE_SIZE - (int)(pheader_cache - header_cache);
182+
srs_assert(left > 0);
183+
184+
iovec* data_iov = iov + i;
185+
int nb_size = snprintf(pheader_cache, left, "%x", (int)data_iov->iov_len);
186+
187+
iovec* iovs = iovss + (i * 4);
188+
iovs[0].iov_base = (char*)pheader_cache;
189+
iovs[0].iov_len = (int)nb_size;
190+
iovs[1].iov_base = (char*)SRS_HTTP_CRLF;
191+
iovs[1].iov_len = 2;
192+
iovs[2].iov_base = (char*)data_iov->iov_base;
193+
iovs[2].iov_len = (int)data_iov->iov_len;
194+
iovs[3].iov_base = (char*)SRS_HTTP_CRLF;
195+
iovs[3].iov_len = 2;
196+
197+
pheader_cache += nb_size;
198+
}
199+
200+
ssize_t nwrite;
201+
if ((ret = skt->writev(iovss, nb_iovss, &nwrite)) != ERROR_SUCCESS) {
202+
return ret;
203+
}
204+
205+
if (pnwrite) {
206+
*pnwrite = nwrite;
207+
}
208+
209+
return ret;
210+
}
211+
146212
void SrsHttpResponseWriter::write_header(int code)
147213
{
148214
if (header_wrote) {
@@ -1513,6 +1579,11 @@ int SrsStreamWriter::write(void* buf, size_t count, ssize_t* pnwrite)
15131579
return writer->write((char*)buf, (int)count);
15141580
}
15151581

1582+
int SrsStreamWriter::writev(iovec* iov, int iovcnt, ssize_t* pnwrite)
1583+
{
1584+
return writer->writev(iov, iovcnt, pnwrite);
1585+
}
1586+
15161587
SrsLiveStream::SrsLiveStream(SrsSource* s, SrsRequest* r, SrsStreamCache* c)
15171588
{
15181589
source = s;

trunk/src/app/srs_app_http_conn.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,11 @@ class SrsHttpMessage;
7171

7272
#ifdef SRS_AUTO_HTTP_PARSER
7373

74-
#define SRS_HTTP_HEADER_CACHE_SIZE 16
74+
// for HTTP FLV, each video/audio packet is send by 3 iovs,
75+
// while each iov is send by 4 sub iovs, that is needs 3 chunk header,
76+
// suppose each header is 16 length, 3*16=48 is ok.
77+
// that is, 512 can used for 16 iovs to send.
78+
#define SRS_HTTP_HEADER_CACHE_SIZE 512
7579

7680
/**
7781
* response writer use st socket
@@ -105,6 +109,7 @@ class SrsHttpResponseWriter : public ISrsHttpResponseWriter
105109
virtual int final_request();
106110
virtual SrsHttpHeader* header();
107111
virtual int write(char* data, int size);
112+
virtual int writev(iovec* iov, int iovcnt, ssize_t* pnwrite);
108113
virtual void write_header(int code);
109114
virtual int send_header(char* data, int size);
110115
};
@@ -541,6 +546,7 @@ class SrsStreamWriter : public SrsFileWriter
541546
virtual int64_t tellg();
542547
public:
543548
virtual int write(void* buf, size_t count, ssize_t* pnwrite);
549+
virtual int writev(iovec* iov, int iovcnt, ssize_t* pnwrite);
544550
};
545551

546552
/**

trunk/src/core/srs_core.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3131
// current release version
3232
#define VERSION_MAJOR 2
3333
#define VERSION_MINOR 0
34-
#define VERSION_REVISION 168
34+
#define VERSION_REVISION 169
3535

3636
// server info.
3737
#define RTMP_SIG_SRS_KEY "SRS"

trunk/src/kernel/srs_kernel_file.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3030

3131
#include <fcntl.h>
3232
#include <sstream>
33+
#include <sys/uio.h>
3334
using namespace std;
3435

3536
#include <srs_kernel_log.hpp>
@@ -145,6 +146,27 @@ int SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
145146
return ret;
146147
}
147148

149+
int SrsFileWriter::writev(iovec* iov, int iovcnt, ssize_t* pnwrite)
150+
{
151+
int ret = ERROR_SUCCESS;
152+
153+
ssize_t nwrite = 0;
154+
for (int i = 0; i < iovcnt; i++) {
155+
iovec* piov = iov + i;
156+
ssize_t this_nwrite = 0;
157+
if ((ret = write(piov->iov_base, piov->iov_len, &this_nwrite)) != ERROR_SUCCESS) {
158+
return ret;
159+
}
160+
nwrite += this_nwrite;
161+
}
162+
163+
if (pnwrite) {
164+
*pnwrite = nwrite;
165+
}
166+
167+
return ret;
168+
}
169+
148170
SrsFileReader::SrsFileReader()
149171
{
150172
fd = -1;

trunk/src/kernel/srs_kernel_file.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3131

3232
#include <string>
3333

34+
// for srs-librtmp, @see https://github.com/simple-rtmp-server/srs/issues/213
35+
#ifndef _WIN32
36+
#include <sys/uio.h>
37+
#endif
38+
3439
/**
3540
* file writer, to write to file.
3641
*/
@@ -62,6 +67,11 @@ class SrsFileWriter
6267
* @param pnwrite the output nb_write, NULL to ignore.
6368
*/
6469
virtual int write(void* buf, size_t count, ssize_t* pnwrite);
70+
/**
71+
* for the HTTP FLV, to writev to improve performance.
72+
* @see https://github.com/simple-rtmp-server/srs/issues/405
73+
*/
74+
virtual int writev(iovec* iov, int iovcnt, ssize_t* pnwrite);
6575
};
6676

6777
/**

trunk/src/kernel/srs_kernel_flv.cpp

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -223,31 +223,24 @@ int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_s
223223
{
224224
int ret = ERROR_SUCCESS;
225225

226-
// write tag header.
227-
if ((ret = _fs->write(header, header_size, NULL)) != ERROR_SUCCESS) {
228-
if (!srs_is_client_gracefully_close(ret)) {
229-
srs_error("write flv tag header failed. ret=%d", ret);
230-
}
231-
return ret;
232-
}
233-
234-
// write tag data.
235-
if ((ret = _fs->write(tag, tag_size, NULL)) != ERROR_SUCCESS) {
236-
if (!srs_is_client_gracefully_close(ret)) {
237-
srs_error("write flv tag failed. ret=%d", ret);
238-
}
239-
return ret;
240-
}
241-
242226
// PreviousTagSizeN UI32 Size of last tag, including its header, in bytes.
243227
char pre_size[SRS_FLV_PREVIOUS_TAG_SIZE];
244228
if ((ret = tag_stream->initialize(pre_size, SRS_FLV_PREVIOUS_TAG_SIZE)) != ERROR_SUCCESS) {
245229
return ret;
246230
}
247231
tag_stream->write_4bytes(tag_size + header_size);
248-
if ((ret = _fs->write(pre_size, sizeof(pre_size), NULL)) != ERROR_SUCCESS) {
232+
233+
iovec iovs[3];
234+
iovs[0].iov_base = header;
235+
iovs[0].iov_len = header_size;
236+
iovs[1].iov_base = tag;
237+
iovs[1].iov_len = tag_size;
238+
iovs[2].iov_base = pre_size;
239+
iovs[2].iov_len = sizeof(SRS_FLV_PREVIOUS_TAG_SIZE);
240+
241+
if ((ret = _fs->writev(iovs, 3, NULL)) != ERROR_SUCCESS) {
249242
if (!srs_is_client_gracefully_close(ret)) {
250-
srs_error("write flv previous tag size failed. ret=%d", ret);
243+
srs_error("write flv tag failed. ret=%d", ret);
251244
}
252245
return ret;
253246
}

trunk/src/protocol/srs_http_stack.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
#include <string>
3434
#include <vector>
3535

36+
// for srs-librtmp, @see https://github.com/simple-rtmp-server/srs/issues/213
37+
#ifndef _WIN32
38+
#include <sys/uio.h>
39+
#endif
40+
3641
class SrsFileReader;
3742
class SrsHttpHeader;
3843
class ISrsHttpMessage;
@@ -188,6 +193,11 @@ class ISrsHttpResponseWriter
188193
// the initial 512 bytes of written data to DetectContentType.
189194
// @param data, the data to send. NULL to flush header only.
190195
virtual int write(char* data, int size) = 0;
196+
/**
197+
* for the HTTP FLV, to writev to improve performance.
198+
* @see https://github.com/simple-rtmp-server/srs/issues/405
199+
*/
200+
virtual int writev(iovec* iov, int iovcnt, ssize_t* pnwrite) = 0;
191201

192202
// WriteHeader sends an HTTP response header with status code.
193203
// If WriteHeader is not called explicitly, the first call to Write

0 commit comments

Comments
 (0)