From 6b57597718d8ea278e2612b35b84242a1e977656 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 2 Dec 2014 22:26:04 +0800 Subject: [PATCH] for bug #241, merge big chunks for publish, no use. --- trunk/src/app/srs_app_recv_thread.cpp | 10 ++++++++-- trunk/src/kernel/srs_kernel_buffer.cpp | 25 ++++++++++++++++++++----- trunk/src/kernel/srs_kernel_buffer.hpp | 26 ++++++++++++++++++++++++++ trunk/src/rtmp/srs_protocol_io.hpp | 20 ++++++-------------- trunk/src/rtmp/srs_protocol_rtmp.cpp | 5 +++++ trunk/src/rtmp/srs_protocol_rtmp.hpp | 7 +++++++ trunk/src/rtmp/srs_protocol_stack.cpp | 5 +++++ trunk/src/rtmp/srs_protocol_stack.hpp | 7 +++++++ trunk/src/utest/srs_utest_kernel.cpp | 5 +++++ trunk/src/utest/srs_utest_kernel.hpp | 1 + 10 files changed, 90 insertions(+), 21 deletions(-) diff --git a/trunk/src/app/srs_app_recv_thread.cpp b/trunk/src/app/srs_app_recv_thread.cpp index 40d888881c..5cecf27715 100644 --- a/trunk/src/app/srs_app_recv_thread.cpp +++ b/trunk/src/app/srs_app_recv_thread.cpp @@ -288,10 +288,16 @@ void SrsPublishRecvThread::on_thread_start() { // we donot set the auto response to false, // for the main thread never send message. + + // notice the protocol stack to merge chunks to big buffer. + // for example, the buffer is 64KB=512kb, it's 1s buffer for 500kbps video stream. + // so we can use read_fullly(64KB) to merge all chunks in 1s. + // @see https://github.com/winlinvip/simple-rtmp-server/issues/241 + rtmp->set_merge_chunks(true); } void SrsPublishRecvThread::on_thread_stop() { - // we donot set the auto response to true, - // for we donot set to false yet. + // revert state + rtmp->set_merge_chunks(false); } diff --git a/trunk/src/kernel/srs_kernel_buffer.cpp b/trunk/src/kernel/srs_kernel_buffer.cpp index d60690de4f..fd49672d61 100644 --- a/trunk/src/kernel/srs_kernel_buffer.cpp +++ b/trunk/src/kernel/srs_kernel_buffer.cpp @@ -26,7 +26,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -#define SOCKET_READ_SIZE 4096 +// 4096=4KB +// 16384=16KB +// 65536=64KB +#define SOCKET_READ_SIZE 16384 ISrsBufferReader::ISrsBufferReader() { @@ -38,10 +41,13 @@ ISrsBufferReader::~ISrsBufferReader() SrsBuffer::SrsBuffer() { + merge_chunks_in_big_buffer = false; + buffer = new char[SOCKET_READ_SIZE]; } SrsBuffer::~SrsBuffer() { + srs_freep(buffer); } int SrsBuffer::length() @@ -88,11 +94,15 @@ int SrsBuffer::grow(ISrsBufferReader* reader, int required_size) } while (length() < required_size) { - char buffer[SOCKET_READ_SIZE]; - ssize_t nread; - if ((ret = reader->read(buffer, SOCKET_READ_SIZE, &nread)) != ERROR_SUCCESS) { - return ret; + if (merge_chunks_in_big_buffer) { + if ((ret = reader->read_fully(buffer, SOCKET_READ_SIZE, &nread)) != ERROR_SUCCESS) { + return ret; + } + } else { + if ((ret = reader->read(buffer, SOCKET_READ_SIZE, &nread)) != ERROR_SUCCESS) { + return ret; + } } srs_assert((int)nread > 0); @@ -102,4 +112,9 @@ int SrsBuffer::grow(ISrsBufferReader* reader, int required_size) return ret; } +void SrsBuffer::set_merge_chunks(bool v) +{ + merge_chunks_in_big_buffer = v; +} + diff --git a/trunk/src/kernel/srs_kernel_buffer.hpp b/trunk/src/kernel/srs_kernel_buffer.hpp index 93d3a56832..9523377019 100644 --- a/trunk/src/kernel/srs_kernel_buffer.hpp +++ b/trunk/src/kernel/srs_kernel_buffer.hpp @@ -42,7 +42,16 @@ class ISrsBufferReader virtual ~ISrsBufferReader(); // for protocol/amf0/msg-codec public: + /** + * read some bytes of data. + * @param nread, the actually read size, NULL to ignore. + */ virtual int read(void* buf, size_t size, ssize_t* nread) = 0; + /** + * read specified size bytes of data + * @param nread, the actually read size, NULL to ignore. + */ + virtual int read_fully(void* buf, size_t size, ssize_t* nread) = 0; }; /** @@ -53,6 +62,15 @@ class SrsBuffer { private: std::vector data; + /** + * notice the protocol stack to merge chunks to big buffer. + * for example, the buffer is 64KB=512kb, it's 1s buffer for 500kbps video stream. + * so we can use read_fullly(64KB) to merge all chunks in 1s. + * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 + */ + bool merge_chunks_in_big_buffer; + // the socket recv buffer. + char* buffer; public: SrsBuffer(); virtual ~SrsBuffer(); @@ -89,6 +107,14 @@ class SrsBuffer * @remark, we actually maybe read more than required_size, maybe 4k for example. */ virtual int grow(ISrsBufferReader* reader, int required_size); +public: + /** + * notice the protocol stack to merge chunks to big buffer. + * for example, the buffer is 64KB=512kb, it's 1s buffer for 500kbps video stream. + * so we can use read_fullly(64KB) to merge all chunks in 1s. + * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 + */ + virtual void set_merge_chunks(bool v); }; #endif diff --git a/trunk/src/rtmp/srs_protocol_io.hpp b/trunk/src/rtmp/srs_protocol_io.hpp index bc816309f4..0de54ece32 100644 --- a/trunk/src/rtmp/srs_protocol_io.hpp +++ b/trunk/src/rtmp/srs_protocol_io.hpp @@ -43,17 +43,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | IBufferReader | | IStatistic | | IBufferWriter | +---------------+ +--------------------+ +---------------+ | + read() | | + get_recv_bytes() | | + write() | -+------+--------+ | + get_recv_bytes() | | + writev() | - / \ +---+--------------+-+ +-------+-------+ - | / \ / \ / \ +| + readfully() | | + get_recv_bytes() | | + writev() | ++------+--------+ +---+--------------+-+ +-------+-------+ + / \ / \ / \ / \ | | | | +------+------------------+-+ +-----+----------------+--+ | IProtocolReader | | IProtocolWriter | +---------------------------+ +-------------------------+ -| + readfully() | | + set_send_timeout() | -| + set_recv_timeout() | +-------+-----------------+ -+------------+--------------+ / \ - / \ | +| + set_recv_timeout() | | + set_send_timeout() | ++------------+--------------+ +-------+-----------------+ + / \ / \ | | +--+-----------------------------+-+ | IProtocolReaderWriter | @@ -123,13 +122,6 @@ class ISrsProtocolReader : public virtual ISrsBufferReader, public virtual ISrsP * get the recv timeout in us. */ virtual int64_t get_recv_timeout() = 0; -// for handshake. -public: - /** - * read specified size bytes of data - * @param nread, the actually read size, NULL to ignore. - */ - virtual int read_fully(void* buf, size_t size, ssize_t* nread) = 0; }; /** diff --git a/trunk/src/rtmp/srs_protocol_rtmp.cpp b/trunk/src/rtmp/srs_protocol_rtmp.cpp index 39ccb21319..b61b89c009 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp.cpp +++ b/trunk/src/rtmp/srs_protocol_rtmp.cpp @@ -745,6 +745,11 @@ void SrsRtmpServer::set_auto_response(bool v) protocol->set_auto_response(v); } +void SrsRtmpServer::set_merge_chunks(bool v) +{ + protocol->set_merge_chunks(v); +} + void SrsRtmpServer::set_recv_timeout(int64_t timeout_us) { protocol->set_recv_timeout(timeout_us); diff --git a/trunk/src/rtmp/srs_protocol_rtmp.hpp b/trunk/src/rtmp/srs_protocol_rtmp.hpp index 9846d76191..217acd6e9f 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp.hpp +++ b/trunk/src/rtmp/srs_protocol_rtmp.hpp @@ -343,6 +343,13 @@ class SrsRtmpServer */ virtual void set_auto_response(bool v); /** + * notice the protocol stack to merge chunks to big buffer. + * for example, the buffer is 64KB=512kb, it's 1s buffer for 500kbps video stream. + * so we can use read_fullly(64KB) to merge all chunks in 1s. + * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 + */ + virtual void set_merge_chunks(bool v); + /** * set/get the recv timeout in us. * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. */ diff --git a/trunk/src/rtmp/srs_protocol_stack.cpp b/trunk/src/rtmp/srs_protocol_stack.cpp index 6f79e202b6..dd7aea0e8d 100644 --- a/trunk/src/rtmp/srs_protocol_stack.cpp +++ b/trunk/src/rtmp/srs_protocol_stack.cpp @@ -478,6 +478,11 @@ int SrsProtocol::manual_response_flush() return ret; } +void SrsProtocol::set_merge_chunks(bool v) +{ + in_buffer->set_merge_chunks(v); +} + void SrsProtocol::set_recv_timeout(int64_t timeout_us) { return skt->set_recv_timeout(timeout_us); diff --git a/trunk/src/rtmp/srs_protocol_stack.hpp b/trunk/src/rtmp/srs_protocol_stack.hpp index d9ba0ee847..328d1aec76 100644 --- a/trunk/src/rtmp/srs_protocol_stack.hpp +++ b/trunk/src/rtmp/srs_protocol_stack.hpp @@ -269,6 +269,13 @@ class SrsProtocol * @see the auto_response_when_recv and manual_response_queue. */ virtual int manual_response_flush(); + /** + * notice the protocol stack to merge chunks to big buffer. + * for example, the buffer is 64KB=512kb, it's 1s buffer for 500kbps video stream. + * so we can use read_fullly(64KB) to merge all chunks in 1s. + * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 + */ + virtual void set_merge_chunks(bool v); public: /** * set/get the recv timeout in us. diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index 166981cc84..445f41d244 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -199,6 +199,11 @@ int MockBufferReader::read(void* buf, size_t size, ssize_t* nread) return ERROR_SUCCESS; } +int MockBufferReader::read_fully(void* buf, size_t size, ssize_t* nread) +{ + return read(buf, size, nread); +} + #ifdef ENABLE_UTEST_KERNEL VOID TEST(KernelBufferTest, DefaultObject) diff --git a/trunk/src/utest/srs_utest_kernel.hpp b/trunk/src/utest/srs_utest_kernel.hpp index 44b7fd6765..5057e57fd5 100644 --- a/trunk/src/utest/srs_utest_kernel.hpp +++ b/trunk/src/utest/srs_utest_kernel.hpp @@ -42,6 +42,7 @@ class MockBufferReader: public ISrsBufferReader virtual ~MockBufferReader(); public: virtual int read(void* buf, size_t size, ssize_t* nread); + virtual int read_fully(void* buf, size_t size, ssize_t* nread); }; class MockSrsFileWriter : public SrsFileWriter