正在显示
8 个修改的文件
包含
140 行增加
和
26 行删除
| @@ -716,7 +716,8 @@ The play HTTP FLV benchmark by [SB](https://github.com/simple-rtmp-server/srs-be | @@ -716,7 +716,8 @@ The play HTTP FLV benchmark by [SB](https://github.com/simple-rtmp-server/srs-be | ||
| 716 | | Update | SRS | Clients | Type | CPU | Memory | Commit | | 716 | | Update | SRS | Clients | Type | CPU | Memory | Commit | |
| 717 | | ------------- | --------- | ------------- | ------------- | --------- | -------- | ------------ | | 717 | | ------------- | --------- | ------------- | ------------- | --------- | -------- | ------------ | |
| 718 | | 2014-05-24 | 2.0.167 | 1.0k(1000) | players | 82% | 86MB | - | | 718 | | 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] | | ||
| 720 | 721 | ||
| 721 | ### Latency benchmark | 722 | ### Latency benchmark |
| 722 | 723 | ||
| @@ -832,6 +833,7 @@ Winlin | @@ -832,6 +833,7 @@ Winlin | ||
| 832 | [p14]: https://github.com/simple-rtmp-server/srs/commit/10297fab519811845b549a8af40a6bcbd23411e8 | 833 | [p14]: https://github.com/simple-rtmp-server/srs/commit/10297fab519811845b549a8af40a6bcbd23411e8 |
| 833 | [p15]: https://github.com/simple-rtmp-server/srs/commit/0d6b91039d408328caab31a1077d56a809b6bebc | 834 | [p15]: https://github.com/simple-rtmp-server/srs/commit/0d6b91039d408328caab31a1077d56a809b6bebc |
| 834 | [p16]: https://github.com/simple-rtmp-server/srs/commit/0d6b91039d408328caab31a1077d56a809b6bebc | 835 | [p16]: https://github.com/simple-rtmp-server/srs/commit/0d6b91039d408328caab31a1077d56a809b6bebc |
| 836 | +[p17]: https://github.com/simple-rtmp-server/srs/commit/fc995473eb02c7cf64b5b212b456e11f34aa7984 | ||
| 835 | 837 | ||
| 836 | [authors]: https://github.com/simple-rtmp-server/srs/blob/develop/AUTHORS.txt | 838 | [authors]: https://github.com/simple-rtmp-server/srs/blob/develop/AUTHORS.txt |
| 837 | [bigthanks]: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_Product#bigthanks | 839 | [bigthanks]: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_Product#bigthanks |
| @@ -98,8 +98,14 @@ int SrsHttpResponseWriter::write(char* data, int size) | @@ -98,8 +98,14 @@ int SrsHttpResponseWriter::write(char* data, int size) | ||
| 98 | 98 | ||
| 99 | if (!header_wrote) { | 99 | if (!header_wrote) { |
| 100 | write_header(SRS_CONSTS_HTTP_OK); | 100 | 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 | + } | ||
| 101 | } | 106 | } |
| 102 | 107 | ||
| 108 | + // check the bytes send and content length. | ||
| 103 | written += size; | 109 | written += size; |
| 104 | if (content_length != -1 && written > content_length) { | 110 | if (content_length != -1 && written > content_length) { |
| 105 | ret = ERROR_HTTP_CONTENT_LENGTH; | 111 | ret = ERROR_HTTP_CONTENT_LENGTH; |
| @@ -107,11 +113,6 @@ int SrsHttpResponseWriter::write(char* data, int size) | @@ -107,11 +113,6 @@ int SrsHttpResponseWriter::write(char* data, int size) | ||
| 107 | return ret; | 113 | return ret; |
| 108 | } | 114 | } |
| 109 | 115 | ||
| 110 | - if ((ret = send_header(data, size)) != ERROR_SUCCESS) { | ||
| 111 | - srs_error("http: send header failed. ret=%d", ret); | ||
| 112 | - return ret; | ||
| 113 | - } | ||
| 114 | - | ||
| 115 | // ignore NULL content. | 116 | // ignore NULL content. |
| 116 | if (!data) { | 117 | if (!data) { |
| 117 | return ret; | 118 | return ret; |
| @@ -143,6 +144,71 @@ int SrsHttpResponseWriter::write(char* data, int size) | @@ -143,6 +144,71 @@ int SrsHttpResponseWriter::write(char* data, int size) | ||
| 143 | return ret; | 144 | return ret; |
| 144 | } | 145 | } |
| 145 | 146 | ||
| 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 | + | ||
| 146 | void SrsHttpResponseWriter::write_header(int code) | 212 | void SrsHttpResponseWriter::write_header(int code) |
| 147 | { | 213 | { |
| 148 | if (header_wrote) { | 214 | if (header_wrote) { |
| @@ -1513,6 +1579,11 @@ int SrsStreamWriter::write(void* buf, size_t count, ssize_t* pnwrite) | @@ -1513,6 +1579,11 @@ int SrsStreamWriter::write(void* buf, size_t count, ssize_t* pnwrite) | ||
| 1513 | return writer->write((char*)buf, (int)count); | 1579 | return writer->write((char*)buf, (int)count); |
| 1514 | } | 1580 | } |
| 1515 | 1581 | ||
| 1582 | +int SrsStreamWriter::writev(iovec* iov, int iovcnt, ssize_t* pnwrite) | ||
| 1583 | +{ | ||
| 1584 | + return writer->writev(iov, iovcnt, pnwrite); | ||
| 1585 | +} | ||
| 1586 | + | ||
| 1516 | SrsLiveStream::SrsLiveStream(SrsSource* s, SrsRequest* r, SrsStreamCache* c) | 1587 | SrsLiveStream::SrsLiveStream(SrsSource* s, SrsRequest* r, SrsStreamCache* c) |
| 1517 | { | 1588 | { |
| 1518 | source = s; | 1589 | source = s; |
| @@ -71,7 +71,11 @@ class SrsHttpMessage; | @@ -71,7 +71,11 @@ class SrsHttpMessage; | ||
| 71 | 71 | ||
| 72 | #ifdef SRS_AUTO_HTTP_PARSER | 72 | #ifdef SRS_AUTO_HTTP_PARSER |
| 73 | 73 | ||
| 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 | ||
| 75 | 79 | ||
| 76 | /** | 80 | /** |
| 77 | * response writer use st socket | 81 | * response writer use st socket |
| @@ -105,6 +109,7 @@ public: | @@ -105,6 +109,7 @@ public: | ||
| 105 | virtual int final_request(); | 109 | virtual int final_request(); |
| 106 | virtual SrsHttpHeader* header(); | 110 | virtual SrsHttpHeader* header(); |
| 107 | virtual int write(char* data, int size); | 111 | virtual int write(char* data, int size); |
| 112 | + virtual int writev(iovec* iov, int iovcnt, ssize_t* pnwrite); | ||
| 108 | virtual void write_header(int code); | 113 | virtual void write_header(int code); |
| 109 | virtual int send_header(char* data, int size); | 114 | virtual int send_header(char* data, int size); |
| 110 | }; | 115 | }; |
| @@ -541,6 +546,7 @@ public: | @@ -541,6 +546,7 @@ public: | ||
| 541 | virtual int64_t tellg(); | 546 | virtual int64_t tellg(); |
| 542 | public: | 547 | public: |
| 543 | virtual int write(void* buf, size_t count, ssize_t* pnwrite); | 548 | virtual int write(void* buf, size_t count, ssize_t* pnwrite); |
| 549 | + virtual int writev(iovec* iov, int iovcnt, ssize_t* pnwrite); | ||
| 544 | }; | 550 | }; |
| 545 | 551 | ||
| 546 | /** | 552 | /** |
| @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 31 | // current release version | 31 | // current release version |
| 32 | #define VERSION_MAJOR 2 | 32 | #define VERSION_MAJOR 2 |
| 33 | #define VERSION_MINOR 0 | 33 | #define VERSION_MINOR 0 |
| 34 | -#define VERSION_REVISION 168 | 34 | +#define VERSION_REVISION 169 |
| 35 | 35 | ||
| 36 | // server info. | 36 | // server info. |
| 37 | #define RTMP_SIG_SRS_KEY "SRS" | 37 | #define RTMP_SIG_SRS_KEY "SRS" |
| @@ -30,6 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -30,6 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 30 | 30 | ||
| 31 | #include <fcntl.h> | 31 | #include <fcntl.h> |
| 32 | #include <sstream> | 32 | #include <sstream> |
| 33 | +#include <sys/uio.h> | ||
| 33 | using namespace std; | 34 | using namespace std; |
| 34 | 35 | ||
| 35 | #include <srs_kernel_log.hpp> | 36 | #include <srs_kernel_log.hpp> |
| @@ -145,6 +146,27 @@ int SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite) | @@ -145,6 +146,27 @@ int SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite) | ||
| 145 | return ret; | 146 | return ret; |
| 146 | } | 147 | } |
| 147 | 148 | ||
| 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 | + | ||
| 148 | SrsFileReader::SrsFileReader() | 170 | SrsFileReader::SrsFileReader() |
| 149 | { | 171 | { |
| 150 | fd = -1; | 172 | fd = -1; |
| @@ -31,6 +31,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,6 +31,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 31 | 31 | ||
| 32 | #include <string> | 32 | #include <string> |
| 33 | 33 | ||
| 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 | + | ||
| 34 | /** | 39 | /** |
| 35 | * file writer, to write to file. | 40 | * file writer, to write to file. |
| 36 | */ | 41 | */ |
| @@ -62,6 +67,11 @@ public: | @@ -62,6 +67,11 @@ public: | ||
| 62 | * @param pnwrite the output nb_write, NULL to ignore. | 67 | * @param pnwrite the output nb_write, NULL to ignore. |
| 63 | */ | 68 | */ |
| 64 | virtual int write(void* buf, size_t count, ssize_t* pnwrite); | 69 | 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); | ||
| 65 | }; | 75 | }; |
| 66 | 76 | ||
| 67 | /** | 77 | /** |
| @@ -223,31 +223,24 @@ int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_s | @@ -223,31 +223,24 @@ int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_s | ||
| 223 | { | 223 | { |
| 224 | int ret = ERROR_SUCCESS; | 224 | int ret = ERROR_SUCCESS; |
| 225 | 225 | ||
| 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 | - | ||
| 242 | // PreviousTagSizeN UI32 Size of last tag, including its header, in bytes. | 226 | // PreviousTagSizeN UI32 Size of last tag, including its header, in bytes. |
| 243 | char pre_size[SRS_FLV_PREVIOUS_TAG_SIZE]; | 227 | char pre_size[SRS_FLV_PREVIOUS_TAG_SIZE]; |
| 244 | if ((ret = tag_stream->initialize(pre_size, SRS_FLV_PREVIOUS_TAG_SIZE)) != ERROR_SUCCESS) { | 228 | if ((ret = tag_stream->initialize(pre_size, SRS_FLV_PREVIOUS_TAG_SIZE)) != ERROR_SUCCESS) { |
| 245 | return ret; | 229 | return ret; |
| 246 | } | 230 | } |
| 247 | tag_stream->write_4bytes(tag_size + header_size); | 231 | 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) { | ||
| 249 | if (!srs_is_client_gracefully_close(ret)) { | 242 | 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); |
| 251 | } | 244 | } |
| 252 | return ret; | 245 | return ret; |
| 253 | } | 246 | } |
| @@ -33,6 +33,11 @@ | @@ -33,6 +33,11 @@ | ||
| 33 | #include <string> | 33 | #include <string> |
| 34 | #include <vector> | 34 | #include <vector> |
| 35 | 35 | ||
| 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 | + | ||
| 36 | class SrsFileReader; | 41 | class SrsFileReader; |
| 37 | class SrsHttpHeader; | 42 | class SrsHttpHeader; |
| 38 | class ISrsHttpMessage; | 43 | class ISrsHttpMessage; |
| @@ -188,6 +193,11 @@ public: | @@ -188,6 +193,11 @@ public: | ||
| 188 | // the initial 512 bytes of written data to DetectContentType. | 193 | // the initial 512 bytes of written data to DetectContentType. |
| 189 | // @param data, the data to send. NULL to flush header only. | 194 | // @param data, the data to send. NULL to flush header only. |
| 190 | virtual int write(char* data, int size) = 0; | 195 | 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; | ||
| 191 | 201 | ||
| 192 | // WriteHeader sends an HTTP response header with status code. | 202 | // WriteHeader sends an HTTP response header with status code. |
| 193 | // If WriteHeader is not called explicitly, the first call to Write | 203 | // If WriteHeader is not called explicitly, the first call to Write |
-
请 注册 或 登录 后发表评论