Skip to content

Commit 29324fa

Browse files
committed
fix #248, improve about 15% performance for fast buffer. 2.0.49
1 parent 8423974 commit 29324fa

File tree

6 files changed

+129
-110
lines changed

6 files changed

+129
-110
lines changed

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 48
34+
#define VERSION_REVISION 49
3535
// server info.
3636
#define RTMP_SIG_SRS_KEY "SRS"
3737
#define RTMP_SIG_SRS_ROLE "origin/edge server"

trunk/src/kernel/srs_kernel_error.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
134134
#define ERROR_OpenSslSha256DigestSize 2037
135135
#define ERROR_OpenSslGetPeerPublicKey 2038
136136
#define ERROR_OpenSslComputeSharedKey 2039
137+
#define ERROR_RTMP_BUFFER_OVERFLOW 2040
137138
//
138139
// system control message,
139140
// not an error, but special control logic.

trunk/src/rtmp/srs_protocol_buffer.cpp

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2727
#include <srs_kernel_log.hpp>
2828
#include <srs_kernel_utility.hpp>
2929

30+
// the max header size,
31+
// @see SrsProtocol::read_message_header().
32+
#define SRS_RTMP_MAX_MESSAGE_HEADER 11
33+
3034
SrsSimpleBuffer::SrsSimpleBuffer()
3135
{
3236
}
@@ -81,46 +85,45 @@ SrsFastBuffer::SrsFastBuffer()
8185
merged_read = false;
8286
_handler = NULL;
8387

84-
nb_buffer = SOCKET_READ_SIZE;
85-
buffer = new char[nb_buffer];
88+
p = end = buffer = NULL;
89+
nb_buffer = 0;
90+
91+
reset_buffer(SOCKET_READ_SIZE);
8692
}
8793

8894
SrsFastBuffer::~SrsFastBuffer()
8995
{
9096
srs_freep(buffer);
9197
}
9298

93-
int SrsFastBuffer::length()
99+
char SrsFastBuffer::read_1byte()
94100
{
95-
int len = (int)data.size();
96-
srs_assert(len >= 0);
97-
return len;
98-
}
99-
100-
char* SrsFastBuffer::bytes()
101-
{
102-
return (length() == 0)? NULL : &data.at(0);
101+
srs_assert(end - p >= 1);
102+
return *p++;
103103
}
104104

105-
void SrsFastBuffer::erase(int size)
105+
char* SrsFastBuffer::read_slice(int size)
106106
{
107-
if (size <= 0) {
108-
return;
109-
}
107+
srs_assert(end - p >= size);
108+
srs_assert(p + size > buffer);
110109

111-
if (size >= length()) {
112-
data.clear();
113-
return;
114-
}
110+
char* ptr = p;
111+
p += size;
115112

116-
data.erase(data.begin(), data.begin() + size);
113+
// reset when consumed all.
114+
if (p == end) {
115+
p = end = buffer;
116+
srs_verbose("all consumed, reset fast buffer");
117+
}
118+
119+
return ptr;
117120
}
118121

119-
void SrsFastBuffer::append(const char* bytes, int size)
122+
void SrsFastBuffer::skip(int size)
120123
{
121-
srs_assert(size > 0);
122-
123-
data.insert(data.end(), bytes, bytes + size);
124+
srs_assert(end - p >= size);
125+
srs_assert(p + size > buffer);
126+
p += size;
124127
}
125128

126129
int SrsFastBuffer::grow(ISrsBufferReader* reader, int required_size)
@@ -133,9 +136,27 @@ int SrsFastBuffer::grow(ISrsBufferReader* reader, int required_size)
133136
return ret;
134137
}
135138

136-
while (length() < required_size) {
139+
// when read payload and need to grow, reset buffer.
140+
if (end - p < required_size && required_size > SRS_RTMP_MAX_MESSAGE_HEADER) {
141+
int nb_cap = end - p;
142+
srs_verbose("move fast buffer %d bytes", nb_cap);
143+
buffer = (char*)memmove(buffer, p, nb_cap);
144+
p = buffer;
145+
end = p + nb_cap;
146+
}
147+
148+
while (end - p < required_size) {
149+
// the max to read is the left bytes.
150+
size_t max_to_read = buffer + nb_buffer - end;
151+
152+
if (max_to_read <= 0) {
153+
ret = ERROR_RTMP_BUFFER_OVERFLOW;
154+
srs_error("buffer overflow, required=%d, max=%d, ret=%d", required_size, nb_buffer, ret);
155+
return ret;
156+
}
157+
137158
ssize_t nread;
138-
if ((ret = reader->read(buffer, nb_buffer, &nread)) != ERROR_SUCCESS) {
159+
if ((ret = reader->read(end, max_to_read, &nread)) != ERROR_SUCCESS) {
139160
return ret;
140161
}
141162

@@ -149,8 +170,9 @@ int SrsFastBuffer::grow(ISrsBufferReader* reader, int required_size)
149170
_handler->on_read(nread);
150171
}
151172

173+
// we just move the ptr to next.
152174
srs_assert((int)nread > 0);
153-
append(buffer, (int)nread);
175+
end += nread;
154176
}
155177

156178
return ret;
@@ -198,8 +220,19 @@ int SrsFastBuffer::buffer_size()
198220

199221
void SrsFastBuffer::reset_buffer(int size)
200222
{
223+
// remember the cap.
224+
int nb_cap = end - p;
225+
226+
// atleast to put the old data.
227+
nb_buffer = srs_max(nb_cap, size);
228+
229+
// copy old data to buf.
230+
char* buf = new char[nb_buffer];
231+
if (nb_cap > 0) {
232+
memcpy(buf, p, nb_cap);
233+
}
234+
201235
srs_freep(buffer);
202-
203-
nb_buffer = size;
204-
buffer = new char[nb_buffer];
236+
p = buffer = buf;
237+
end = p + nb_cap;
205238
}

trunk/src/rtmp/srs_protocol_buffer.hpp

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -116,39 +116,40 @@ class SrsFastBuffer
116116
// the merged handler
117117
bool merged_read;
118118
IMergeReadHandler* _handler;
119-
// data and socket buffer
120-
std::vector<char> data;
119+
// the user-space buffer to fill by reader,
120+
// which use fast index and reset when chunk body read ok.
121+
// @see https://github.com/winlinvip/simple-rtmp-server/issues/248
122+
// ptr to the current read position.
123+
char* p;
124+
// ptr to the content end.
125+
char* end;
126+
// ptr to the buffer.
127+
// buffer <= p <= end <= buffer+nb_buffer
121128
char* buffer;
129+
// the max size of buffer.
122130
int nb_buffer;
123131
public:
124132
SrsFastBuffer();
125133
virtual ~SrsFastBuffer();
126134
public:
127135
/**
128-
* get the length of buffer. empty if zero.
129-
* @remark assert length() is not negative.
130-
*/
131-
virtual int length();
132-
/**
133-
* get the buffer bytes.
134-
* @return the bytes, NULL if empty.
136+
* read 1byte from buffer, move to next bytes.
137+
* @remark assert buffer already grow(1).
135138
*/
136-
virtual char* bytes();
137-
public:
139+
virtual char read_1byte();
138140
/**
139-
* erase size of bytes from begin.
140-
* @param size to erase size of bytes.
141-
* clear if size greater than or equals to length()
142-
* @remark ignore size is not positive.
141+
* read a slice in size bytes, move to next bytes.
142+
* user can use this char* ptr directly, and should never free it.
143+
* @remark assert buffer already grow(size).
144+
* @remark the ptr returned maybe invalid after grow(x).
143145
*/
144-
virtual void erase(int size);
145-
private:
146+
virtual char* read_slice(int size);
146147
/**
147-
* append specified bytes to buffer.
148-
* @param size the size of bytes
149-
* @remark assert size is positive.
148+
* skip some bytes in buffer.
149+
* @param size the bytes to skip. positive to next; negative to previous.
150+
* @remark assert buffer already grow(size).
150151
*/
151-
virtual void append(const char* bytes, int size);
152+
virtual void skip(int size);
152153
public:
153154
/**
154155
* grow buffer to the required size, loop to read from skt to fill.

0 commit comments

Comments
 (0)