winlin

decode basic header

@@ -23,6 +23,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,6 +23,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_core_buffer.hpp> 24 #include <srs_core_buffer.hpp>
25 25
  26 +#include <srs_core_error.hpp>
  27 +#include <srs_core_socket.hpp>
  28 +
  29 +#define SOCKET_READ_SIZE 4096
  30 +
26 SrsBuffer::SrsBuffer() 31 SrsBuffer::SrsBuffer()
27 { 32 {
28 } 33 }
@@ -31,3 +36,39 @@ SrsBuffer::~SrsBuffer() @@ -31,3 +36,39 @@ SrsBuffer::~SrsBuffer()
31 { 36 {
32 } 37 }
33 38
  39 +int SrsBuffer::size()
  40 +{
  41 + return (int)data.size();
  42 +}
  43 +
  44 +char* SrsBuffer::bytes()
  45 +{
  46 + return &data.at(0);
  47 +}
  48 +
  49 +void SrsBuffer::append(char* bytes, int size)
  50 +{
  51 + std::vector<char> vec(bytes, bytes + size);
  52 +
  53 + data.insert(data.begin(), vec.begin(), vec.end());
  54 +}
  55 +
  56 +int SrsBuffer::ensure_buffer_bytes(SrsSocket* skt, int required_size)
  57 +{
  58 + int ret = ERROR_SUCCESS;
  59 +
  60 + ssize_t nread;
  61 + while (size() < required_size) {
  62 + char buffer[SOCKET_READ_SIZE];
  63 +
  64 + if ((ret = skt->read(buffer, SOCKET_READ_SIZE, &nread)) != ERROR_SUCCESS) {
  65 + return ret;
  66 + }
  67 +
  68 + srs_assert((int)nread > 0);
  69 + append(buffer, (int)nread);
  70 + }
  71 +
  72 + return ret;
  73 +}
  74 +
@@ -30,6 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,6 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 30
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
  33 +#include <vector>
  34 +
  35 +class SrsSocket;
  36 +
33 /** 37 /**
34 * the buffer provices bytes cache for protocol. generally, 38 * the buffer provices bytes cache for protocol. generally,
35 * protocol recv data from socket, put into buffer, decode to RTMP message. 39 * protocol recv data from socket, put into buffer, decode to RTMP message.
@@ -37,9 +41,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -37,9 +41,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 */ 41 */
38 class SrsBuffer 42 class SrsBuffer
39 { 43 {
  44 +private:
  45 + std::vector<char> data;
40 public: 46 public:
41 SrsBuffer(); 47 SrsBuffer();
42 virtual ~SrsBuffer(); 48 virtual ~SrsBuffer();
  49 +public:
  50 + virtual char* bytes();
  51 +private:
  52 + virtual int size();
  53 + virtual void append(char* bytes, int size);
  54 +public:
  55 + virtual int ensure_buffer_bytes(SrsSocket* skt, int required_size);
43 }; 56 };
44 57
45 #endif 58 #endif
@@ -31,23 +31,167 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,23 +31,167 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 SrsProtocol::SrsProtocol(st_netfd_t client_stfd) 31 SrsProtocol::SrsProtocol(st_netfd_t client_stfd)
32 { 32 {
33 stfd = client_stfd; 33 stfd = client_stfd;
  34 + buffer = new SrsBuffer();
  35 + skt = new SrsSocket(stfd);
34 } 36 }
35 37
36 SrsProtocol::~SrsProtocol() 38 SrsProtocol::~SrsProtocol()
37 { 39 {
  40 + std::map<int, SrsChunkStream*>::iterator it;
  41 +
  42 + for (it = chunk_streams.begin(); it != chunk_streams.end(); ++it) {
  43 + SrsChunkStream* stream = it->second;
  44 +
  45 + if (stream) {
  46 + delete stream;
  47 + }
  48 + }
  49 +
  50 + chunk_streams.clear();
  51 +
  52 + if (buffer) {
  53 + delete buffer;
  54 + buffer = NULL;
  55 + }
  56 +
  57 + if (skt) {
  58 + delete skt;
  59 + skt = NULL;
  60 + }
38 } 61 }
39 62
40 int SrsProtocol::recv_message(SrsMessage** pmsg) 63 int SrsProtocol::recv_message(SrsMessage** pmsg)
41 { 64 {
42 int ret = ERROR_SUCCESS; 65 int ret = ERROR_SUCCESS;
  66 +
  67 + while (true) {
  68 + // chunk stream basic header.
  69 + char fmt = 0;
  70 + int cid = 0;
  71 + int size = 0;
  72 + if ((ret = read_basic_header(fmt, cid, size)) != ERROR_SUCCESS) {
  73 + srs_error("read basic header failed. ret=%d", ret);
  74 + return ret;
  75 + }
  76 + srs_info("read basic header success. fmt=%d, cid=%d, size=%d", fmt, cid, size);
  77 +
  78 + // get the cached chunk stream.
  79 + SrsChunkStream* chunk = NULL;
  80 +
  81 + if (chunk_streams.find(cid) == chunk_streams.end()) {
  82 + chunk = chunk_streams[cid] = new SrsChunkStream(cid);
  83 + srs_info("cache new chunk stream: fmt=%d, cid=%d", fmt, cid);
  84 + } else {
  85 + chunk = chunk_streams[cid];
  86 + srs_info("cached chunk stream: fmt=%d, cid=%d, message(type=%d, size=%d, time=%d, sid=%d)",
  87 + chunk->fmt, chunk->cid, chunk->header.message_type, chunk->header.payload_length,
  88 + chunk->header.timestamp, chunk->header.stream_id);
  89 + }
  90 +
  91 + // chunk stream message header
  92 + SrsMessage* msg = NULL;
  93 + if ((ret = read_message_header(chunk, fmt, &msg)) != ERROR_SUCCESS) {
  94 + srs_error("read message header failed. ret=%d", ret);
  95 + return ret;
  96 + }
  97 +
  98 + // not got an entire RTMP message, try next chunk.
  99 + if (!msg) {
  100 + continue;
  101 + }
  102 +
  103 + // decode the msg
  104 + }
  105 +
  106 + return ret;
  107 +}
  108 +
  109 +int SrsProtocol::read_basic_header(char& fmt, int& cid, int& size)
  110 +{
  111 + int ret = ERROR_SUCCESS;
  112 +
  113 + if ((ret = buffer->ensure_buffer_bytes(skt, 1)) != ERROR_SUCCESS) {
  114 + return ret;
  115 + }
  116 +
  117 + char* p = buffer->bytes();
  118 +
  119 + fmt = (*p >> 6) & 0x03;
  120 + cid = *p & 0x3f;
  121 + size = 1;
  122 +
  123 + if (cid > 1) {
  124 + return ret;
  125 + }
  126 +
  127 + if (cid == 0) {
  128 + if ((ret = buffer->ensure_buffer_bytes(skt, 2)) != ERROR_SUCCESS) {
  129 + return ret;
  130 + }
  131 +
  132 + cid = 64;
  133 + cid += *(++p);
  134 + size = 2;
  135 + } else if (cid == 1) {
  136 + if ((ret = buffer->ensure_buffer_bytes(skt, 3)) != ERROR_SUCCESS) {
  137 + return ret;
  138 + }
  139 +
  140 + cid = 64;
  141 + cid += *(++p);
  142 + cid += *(++p) * 256;
  143 + size = 3;
  144 + } else {
  145 + srs_error("invalid path, impossible basic header.");
  146 + srs_assert(false);
  147 + }
  148 +
  149 + return ret;
  150 +}
  151 +
  152 +int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, SrsMessage** pmsg)
  153 +{
  154 + int ret = ERROR_SUCCESS;
43 return ret; 155 return ret;
44 } 156 }
45 157
  158 +SrsMessageHeader::SrsMessageHeader()
  159 +{
  160 + message_type = 0;
  161 + payload_length = 0;
  162 + timestamp = 0;
  163 + stream_id = 0;
  164 +}
  165 +
  166 +SrsMessageHeader::~SrsMessageHeader()
  167 +{
  168 +}
  169 +
  170 +SrsChunkStream::SrsChunkStream(int _cid)
  171 +{
  172 + fmt = 0;
  173 + cid = _cid;
  174 + msg = NULL;
  175 +}
  176 +
  177 +SrsChunkStream::~SrsChunkStream()
  178 +{
  179 + if (msg) {
  180 + delete msg;
  181 + msg = NULL;
  182 + }
  183 +}
  184 +
46 SrsMessage::SrsMessage() 185 SrsMessage::SrsMessage()
47 { 186 {
  187 + payload = NULL;
48 } 188 }
49 189
50 SrsMessage::~SrsMessage() 190 SrsMessage::~SrsMessage()
51 { 191 {
  192 + if (payload) {
  193 + delete[] payload;
  194 + payload = NULL;
  195 + }
52 } 196 }
53 197
@@ -30,9 +30,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,9 +30,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 30
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
  33 +#include <map>
  34 +
33 #include <st.h> 35 #include <st.h>
34 36
  37 +class SrsSocket;
  38 +class SrsBuffer;
35 class SrsMessage; 39 class SrsMessage;
  40 +class SrsChunkStream;
36 41
37 /** 42 /**
38 * the protocol provides the rtmp-message-protocol services, 43 * the protocol provides the rtmp-message-protocol services,
@@ -42,19 +47,98 @@ class SrsMessage; @@ -42,19 +47,98 @@ class SrsMessage;
42 class SrsProtocol 47 class SrsProtocol
43 { 48 {
44 private: 49 private:
  50 + std::map<int, SrsChunkStream*> chunk_streams;
45 st_netfd_t stfd; 51 st_netfd_t stfd;
  52 + SrsBuffer* buffer;
  53 + SrsSocket* skt;
46 public: 54 public:
47 SrsProtocol(st_netfd_t client_stfd); 55 SrsProtocol(st_netfd_t client_stfd);
48 virtual ~SrsProtocol(); 56 virtual ~SrsProtocol();
49 public: 57 public:
50 virtual int recv_message(SrsMessage** pmsg); 58 virtual int recv_message(SrsMessage** pmsg);
  59 +private:
  60 + virtual int read_basic_header(char& fmt, int& cid, int& size);
  61 + virtual int read_message_header(SrsChunkStream* chunk, char fmt, SrsMessage** pmsg);
51 }; 62 };
52 63
  64 +/**
  65 +* 4.1. Message Header
  66 +*/
  67 +struct SrsMessageHeader
  68 +{
  69 + /**
  70 + * One byte field to represent the message type. A range of type IDs
  71 + * (1-7) are reserved for protocol control messages.
  72 + */
  73 + int8_t message_type;
  74 + /**
  75 + * Three-byte field that represents the size of the payload in bytes.
  76 + * It is set in big-endian format.
  77 + */
  78 + int32_t payload_length;
  79 + /**
  80 + * Four-byte field that contains a timestamp of the message.
  81 + * The 4 bytes are packed in the big-endian order.
  82 + */
  83 + int32_t timestamp;
  84 + /**
  85 + * Three-byte field that identifies the stream of the message. These
  86 + * bytes are set in big-endian format.
  87 + */
  88 + int32_t stream_id;
  89 +
  90 + SrsMessageHeader();
  91 + virtual ~SrsMessageHeader();
  92 +};
  93 +
  94 +/**
  95 +* incoming chunk stream maybe interlaced,
  96 +* use the chunk stream to cache the input RTMP chunk streams.
  97 +*/
  98 +class SrsChunkStream
  99 +{
  100 +public:
  101 + /**
  102 + * represents the basic header fmt,
  103 + * which used to identify the variant message header type.
  104 + */
  105 + char fmt;
  106 + /**
  107 + * represents the basic header cid,
  108 + * which is the chunk stream id.
  109 + */
  110 + int cid;
  111 + /**
  112 + * cached message header
  113 + */
  114 + SrsMessageHeader header;
  115 + /**
  116 + * partially read message.
  117 + */
  118 + SrsMessage* msg;
  119 +public:
  120 + SrsChunkStream(int _cid);
  121 + virtual ~SrsChunkStream();
  122 +public:
  123 +};
  124 +
  125 +/**
  126 +* common RTMP message defines in rtmp.part2.Message-Formats.pdf.
  127 +*/
53 class SrsMessage 128 class SrsMessage
54 { 129 {
  130 +// 4.1. Message Header
55 public: 131 public:
56 - int8_t message_type;  
57 - int24_t payload_length; 132 + SrsMessageHeader header;
  133 +// 4.2. Message Payload
  134 +public:
  135 + /**
  136 + * The other part which is the payload is the actual data that is
  137 + * contained in the message. For example, it could be some audio samples
  138 + * or compressed video data. The payload format and interpretation are
  139 + * beyond the scope of this document.
  140 + */
  141 + int8_t* payload;
58 public: 142 public:
59 SrsMessage(); 143 SrsMessage();
60 virtual ~SrsMessage(); 144 virtual ~SrsMessage();
@@ -48,7 +48,7 @@ int SrsRtmp::handshake() @@ -48,7 +48,7 @@ int SrsRtmp::handshake()
48 int ret = ERROR_SUCCESS; 48 int ret = ERROR_SUCCESS;
49 49
50 ssize_t nsize; 50 ssize_t nsize;
51 - Socket skt(stfd); 51 + SrsSocket skt(stfd);
52 52
53 char* c0c1 = new char[1537]; 53 char* c0c1 = new char[1537];
54 SrsAutoFree(char, c0c1, true); 54 SrsAutoFree(char, c0c1, true);
@@ -92,6 +92,10 @@ int SrsRtmp::handshake() @@ -92,6 +92,10 @@ int SrsRtmp::handshake()
92 int SrsRtmp::connect_app(SrsApp** papp) 92 int SrsRtmp::connect_app(SrsApp** papp)
93 { 93 {
94 int ret = ERROR_SUCCESS; 94 int ret = ERROR_SUCCESS;
  95 +
  96 + SrsMessage* msg = NULL;
  97 + protocol->recv_message(&msg);
  98 +
95 return ret; 99 return ret;
96 } 100 }
97 101
@@ -25,16 +25,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -25,16 +25,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 25
26 #include <srs_core_error.hpp> 26 #include <srs_core_error.hpp>
27 27
28 -Socket::Socket(st_netfd_t client_stfd) 28 +SrsSocket::SrsSocket(st_netfd_t client_stfd)
29 { 29 {
30 stfd = client_stfd; 30 stfd = client_stfd;
31 } 31 }
32 32
33 -Socket::~Socket() 33 +SrsSocket::~SrsSocket()
34 { 34 {
35 } 35 }
36 36
37 -int Socket::read(const void* buf, size_t size, ssize_t* nread) 37 +int SrsSocket::read(const void* buf, size_t size, ssize_t* nread)
38 { 38 {
39 int ret = ERROR_SUCCESS; 39 int ret = ERROR_SUCCESS;
40 40
@@ -53,7 +53,7 @@ int Socket::read(const void* buf, size_t size, ssize_t* nread) @@ -53,7 +53,7 @@ int Socket::read(const void* buf, size_t size, ssize_t* nread)
53 return ret; 53 return ret;
54 } 54 }
55 55
56 -int Socket::read_fully(const void* buf, size_t size, ssize_t* nread) 56 +int SrsSocket::read_fully(const void* buf, size_t size, ssize_t* nread)
57 { 57 {
58 int ret = ERROR_SUCCESS; 58 int ret = ERROR_SUCCESS;
59 59
@@ -72,7 +72,7 @@ int Socket::read_fully(const void* buf, size_t size, ssize_t* nread) @@ -72,7 +72,7 @@ int Socket::read_fully(const void* buf, size_t size, ssize_t* nread)
72 return ret; 72 return ret;
73 } 73 }
74 74
75 -int Socket::write(const void* buf, size_t size, ssize_t* nwrite) 75 +int SrsSocket::write(const void* buf, size_t size, ssize_t* nwrite)
76 { 76 {
77 int ret = ERROR_SUCCESS; 77 int ret = ERROR_SUCCESS;
78 78
@@ -36,13 +36,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -36,13 +36,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 * the socket provides TCP socket over st, 36 * the socket provides TCP socket over st,
37 * that is, the sync socket mechanism. 37 * that is, the sync socket mechanism.
38 */ 38 */
39 -class Socket 39 +class SrsSocket
40 { 40 {
41 private: 41 private:
42 st_netfd_t stfd; 42 st_netfd_t stfd;
43 public: 43 public:
44 - Socket(st_netfd_t client_stfd);  
45 - virtual ~Socket(); 44 + SrsSocket(st_netfd_t client_stfd);
  45 + virtual ~SrsSocket();
46 public: 46 public:
47 virtual int read(const void* buf, size_t size, ssize_t* nread); 47 virtual int read(const void* buf, size_t size, ssize_t* nread);
48 virtual int read_fully(const void* buf, size_t size, ssize_t* nread); 48 virtual int read_fully(const void* buf, size_t size, ssize_t* nread);