00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef GNASH_LIBNET_RTMP_H
00020 #define GNASH_LIBNET_RTMP_H
00021
00022 #include <deque>
00023 #include <boost/cstdint.hpp>
00024 #include <boost/shared_ptr.hpp>
00025 #include <boost/scoped_ptr.hpp>
00026 #include <boost/lexical_cast.hpp>
00027 #include <string>
00028 #include <vector>
00029 #include <time.h>
00030
00031 #include "amf.h"
00032 #include "element.h"
00033 #include "network.h"
00034 #include "buffer.h"
00035 #include "rtmp_msg.h"
00036 #include "cque.h"
00037 #include "dsodefs.h"
00038 #include "utility.h"
00039
00040 namespace gnash
00041 {
00042
00066
00067
00070 const int RTMP_HANDSHAKE_VERSION_SIZE = 1;
00073 const boost::uint8_t RTMP_VERSION = 0x3;
00077 const int RTMP_HANDSHAKE_SIZE = 1536;
00080 const int RTMP_RANDOM_SIZE = 1528;
00083 const int RTMP_HANDSHAKE_HEADER_SIZE = 8;
00084
00088 const int MAX_AMF_INDEXES = 64;
00089
00094 const int RTMP_HEADSIZE_MASK = 0xc0;
00097 const char RTMP_INDEX_MASK = 0x3f;
00100 const int RTMP_VIDEO_PACKET_SIZE = 128;
00103 const int RTMP_AUDIO_PACKET_SIZE = 64;
00107 const int RTMP_MAX_HEADER_SIZE = 12;
00110 const int PING_MSG_SIZE = 6;
00113 const int RTMP_SYSTEM_CHANNEL = 2;
00114
00115
00116 const char TERMINATOR = 0x09;
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 typedef struct {
00132 boost::uint8_t version;
00133 boost::uint8_t source;
00134 boost::uint32_t count;
00135 } amfpacket_t;
00136
00137 typedef enum {
00138 onStatus,
00139 onResult,
00140 onDebugEvents
00141 } amfresponse_e;
00142
00143 class DSOEXPORT RTMP : public Network
00144 {
00145 public:
00146 typedef std::map<const char*, amf::Element> AMFProperties;
00147 typedef std::deque<CQue *> queues_t;
00148 typedef enum {
00149 ENCODE_AMF0=0x0,
00150 ENCODE_AMF3=0x3
00151 } encoding_types_e;
00152 typedef enum {
00153 RAW = 0x0001,
00154 ADPCM = 0x0002,
00155 MP3 = 0x0004,
00156 INTEL = 0x0005,
00157 CELT = 0x0008,
00158 NELLY8 = 0x0020,
00159 NELLY = 0x0040,
00160 G711A = 0x0080,
00161 G711U = 0x0100,
00162 NELLY16 = 0x0200,
00163 AAC = 0x0400,
00164 SPEEX = 0x0800,
00165 DEFAULT_AUDIO_SET = 0x0267,
00166 ALLAUDIO = 0x0fff
00167 } audiocodecs_e;
00168 typedef enum {
00169 UNUSED = 0x0001,
00170 JPEG = 0x0002,
00171 SORENSON = 0x4,
00172 ADOBE = 0x0008,
00173 VP6 = 0x0010,
00174 VP6ALPHA = 0x0020,
00175 SCREEN2 = 0x0040,
00176 H264 = 0x0080,
00177 DEFAULT_VIDEO_SET = 0x007c,
00178 ALLVIDEO = 0x00ff
00179 } videocodecs_e;
00180 typedef enum {
00181 SEEK = 0x1,
00182 AMF0 = 0x0,
00183 AMF3 = 0x3
00184 } videofunction_e;
00185
00186
00187
00188 typedef enum {
00189 NONE = 0x0,
00190 CHUNK_SIZE = 0x1,
00191 ABORT = 0x2,
00192 BYTES_READ = 0x3,
00193 USER = 0x4,
00194 WINDOW_SIZE = 0x5,
00195 SET_BANDWITH = 0x6,
00196 ROUTE = 0x7,
00197 AUDIO_DATA = 0x8,
00198 VIDEO_DATA = 0x9,
00199 SHARED_OBJ = 0xa,
00200 AMF3_NOTIFY = 0xf,
00201 AMF3_SHARED_OBJ = 0x10,
00202 AMF3_INVOKE = 0x11,
00203 NOTIFY = 0x12,
00204 INVOKE = 0x14,
00205 FLV_DATA = 0x16
00206 } content_types_e;
00207 typedef enum {
00208 STREAM_START = 0x0,
00209 STREAM_EOF = 0x1,
00210 STREAM_NODATA = 0x2,
00211 STREAM_BUFFER = 0x3,
00212 STREAM_LIVE = 0x4,
00213 STREAM_PING = 0x6,
00214 STREAM_PONG = 0x7
00215 } user_control_e;
00216 typedef enum {
00217 CREATE_OBJ = 0x1,
00218 DELETE_OBJ = 0x2,
00219 REQUEST_CHANGE = 0x3,
00220 CHANGE = 0x4,
00221 SUCCESS_CLIENT = 0x5,
00222 SEND_MESSAGE = 0x6,
00223 STATUS = 0x7,
00224 CLEAR = 0x8,
00225 DELETE_SLOT = 0x9,
00226 REQUEST_DELETE_SLOT = 0xa,
00227 SUCCESS_SERVER = 0xb
00228 } sharedobj_types_e;
00229 typedef enum {
00230 PING_CLEAR = 0x0,
00231 PING_PLAY = 0x1,
00232 PING_TIME = 0x3,
00233 PING_RESET = 0x4,
00234 PING_CLIENT = 0x6,
00235 PONG_CLIENT = 0x7
00236 } rtmp_ping_e;
00237 typedef enum {
00238 STREAM_PLAY,
00239 STREAM_PAUSE,
00240 STREAM_PUBLISH,
00241 STREAM_STOP,
00242 STREAM_SEEK
00243 } rtmp_op_e;
00244 typedef struct {
00245 rtmp_ping_e type;
00246 boost::uint16_t target;
00247 boost::uint16_t param1;
00248 boost::uint16_t param2;
00249 boost::uint16_t param3;
00250 } rtmp_ping_t;
00251 typedef struct {
00252 user_control_e type;
00253 boost::uint32_t param1;
00254 boost::uint32_t param2;
00255 } user_event_t;
00256 typedef enum {
00257 RTMP_STATE_HANDSHAKE_SEND,
00258 RTMP_STATE_HANDSHAKE_RECV,
00259 RTMP_STATE_HANDSHAKE_ACK,
00260 RTMP_STATE_CONNECT,
00261 RTMP_STATE_NETCONNECT,
00262 RTMP_STATE_NETSTREAM,
00263 RTMP_STATE_HEADER,
00264 RTMP_STATE_DONE
00265 } rtmp_state_t;
00266
00267
00268
00269
00270
00271
00272 typedef enum {
00273 RTMP_ERR_UNDEF,
00274 RTMP_ERR_NOTFOUND,
00275 RTMP_ERR_PERM,
00276 RTMP_ERR_DISKFULL,
00277 RTMP_ERR_ILLEGAL,
00278 RTMP_ERR_UNKNOWNID,
00279 RTMP_ERR_EXISTS,
00280 RTMP_ERR_NOSUCHUSER,
00281 RTMP_ERR_TIMEOUT,
00282 RTMP_ERR_NORESPONSE
00283 } rtmp_error_t;
00284
00285
00286
00287
00288
00289
00290
00291 typedef struct {
00292 int channel;
00293 int head_size;
00294 int bodysize;
00295 RTMPMsg::rtmp_source_e src_dest;
00296 content_types_e type;
00297 } rtmp_head_t;
00298 typedef struct {
00299 boost::uint32_t uptime;
00300 boost::uint8_t version[4];
00301 } rtmp_handshake_head_t;
00302 typedef enum {
00303 HEADER_12 = 0x0,
00304 HEADER_8 = 0x40,
00305 HEADER_4 = 0x80,
00306 HEADER_1 = 0xc0
00307 } rtmp_headersize_e;
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 RTMP();
00323 virtual ~RTMP();
00324
00325
00326 boost::shared_ptr<rtmp_head_t> decodeHeader(boost::uint8_t *header);
00327 boost::shared_ptr<rtmp_head_t> decodeHeader(amf::Buffer &data);
00328
00329 boost::shared_ptr<amf::Buffer> encodeHeader(int amf_index,
00330 rtmp_headersize_e head_size,
00331 size_t total_size, content_types_e type,
00332 RTMPMsg::rtmp_source_e routing);
00333 boost::shared_ptr<amf::Buffer> encodeHeader(int amf_index,
00334 rtmp_headersize_e head_size);
00335
00336 void addProperty(amf::Element &el);
00337 void addProperty(char *name, amf::Element &el);
00338 void addProperty(std::string &name, amf::Element &el);
00339 amf::Element &getProperty(const std::string &name);
00340
00341 int headerSize(boost::uint8_t header);
00342
00343 rtmp_head_t *getHeader() { return &_header; };
00344 int getHeaderSize() { return _header.head_size; };
00345 int getTotalSize() { return _header.bodysize; };
00346 RTMPMsg::rtmp_source_e getRouting() { return _header.src_dest; };
00347 int getChannel() { return _header.channel; };
00348 int getPacketSize() { return _packet_size; };
00349 int getMysteryWord() { return _mystery_word; };
00350
00351
00352 boost::shared_ptr<RTMPMsg> decodeMsgBody(boost::uint8_t *data, size_t size);
00353 boost::shared_ptr<RTMPMsg> decodeMsgBody(amf::Buffer &buf);
00354
00355 virtual boost::shared_ptr<rtmp_ping_t> decodePing(boost::uint8_t *data);
00356 boost::shared_ptr<rtmp_ping_t> decodePing(amf::Buffer &buf);
00357
00358 virtual boost::shared_ptr<user_event_t> decodeUserControl(boost::uint8_t *data);
00359 boost::shared_ptr<user_event_t> decodeUserControl(amf::Buffer &buf);
00360 virtual boost::shared_ptr<amf::Buffer> encodeUserControl(user_control_e, boost::uint32_t data);
00361
00362
00363
00364 virtual boost::shared_ptr<amf::Buffer> encodeChunkSize(int size);
00365 virtual void decodeChunkSize();
00366
00367 virtual boost::shared_ptr<amf::Buffer> encodeBytesRead();
00368 virtual void decodeBytesRead();
00369 virtual boost::shared_ptr<amf::Buffer> encodeServer();
00370 virtual void decodeServer();
00371
00372 virtual boost::shared_ptr<amf::Buffer> encodeClient();
00373 virtual void decodeClient();
00374
00375 virtual boost::shared_ptr<amf::Buffer> encodeAudioData();
00376 virtual void decodeAudioData();
00377
00378 virtual boost::shared_ptr<amf::Buffer> encodeVideoData();
00379 virtual void decodeVideoData();
00380
00381 virtual boost::shared_ptr<amf::Buffer> encodeNotify();
00382 virtual void decodeNotify();
00383
00384 virtual boost::shared_ptr<amf::Buffer> encodeSharedObj();
00385 virtual void decodeSharedObj();
00386
00387 virtual boost::shared_ptr<amf::Buffer> encodeInvoke();
00388 virtual void decodeInvoke();
00389
00390
00391
00392
00393 boost::shared_ptr<amf::Buffer> recvMsg();
00394 boost::shared_ptr<amf::Buffer> recvMsg(int fd);
00395
00396
00397
00398
00399
00400 bool sendMsg(amf::Buffer &data);
00401 bool sendMsg(int channel, rtmp_headersize_e head_size,
00402 size_t total_size, content_types_e type,
00403 RTMPMsg::rtmp_source_e routing, amf::Buffer &data);
00404 bool sendMsg(int fd, int channel, rtmp_headersize_e head_size,
00405 size_t total_size, content_types_e type,
00406 RTMPMsg::rtmp_source_e routing, amf::Buffer &data);
00407 bool sendMsg(int channel, rtmp_headersize_e head_size,
00408 size_t total_size, content_types_e type,
00409 RTMPMsg::rtmp_source_e routing, boost::uint8_t *data, size_t size);
00410 bool sendMsg(int fd, int channel, rtmp_headersize_e head_size,
00411 size_t total_size, content_types_e type,
00412 RTMPMsg::rtmp_source_e routing, boost::uint8_t *data, size_t size);
00413
00414 #if 0
00415
00416 RTMPMsg *sendRecvMsg(int amf_index, rtmp_headersize_e head_size,
00417 size_t total_size, content_types_e type,
00418 RTMPMsg::rtmp_source_e routing, amf::Buffer &buf);
00419 #endif
00420
00421
00422
00423
00424
00425 boost::shared_ptr<queues_t> split(amf::Buffer &buf);
00426 boost::shared_ptr<queues_t> split(boost::uint8_t *data, size_t size);
00427
00428 CQue &operator[] (size_t x) { return _queues[x]; }
00429
00434 boost::uint32_t getTime() {
00435 time_t t;
00436 time(&t);
00437 return boost::lexical_cast<boost::uint32_t>(t);
00438 };
00439
00440 void dump();
00441 protected:
00442 AMFProperties _properties;
00443 amf::Buffer *_handshake;
00444
00445 rtmp_head_t _header;
00446 int _packet_size;
00447 int _mystery_word;
00448 size_t _chunksize[MAX_AMF_INDEXES];
00449 size_t _lastsize[MAX_AMF_INDEXES];
00450 std::vector<size_t> _bodysize;
00451 std::vector<content_types_e> _type;
00452 int _timeout;
00453 CQue _queues[MAX_AMF_INDEXES];
00454
00455 amf::Buffer _buffer;
00456 rtmp_handshake_head_t _handshake_header;
00457 };
00458
00459 }
00460
00461 #endif
00462
00463
00464
00465
00466
00467