00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef GNASH_RTMP_H
00020 #define GNASH_RTMP_H
00021
00022 #include <boost/cstdint.hpp>
00023 #include <boost/shared_ptr.hpp>
00024 #include <boost/scoped_ptr.hpp>
00025 #include <deque>
00026 #include <map>
00027
00028 #include "SimpleBuffer.h"
00029 #include "Socket.h"
00030 #include "dsodefs.h"
00031
00032 #define RTMP_DEFAULT_CHUNKSIZE 128
00033
00034
00035 namespace gnash {
00036 namespace rtmp {
00037 class HandShaker;
00038 }
00039 class URL;
00040 }
00041
00042 namespace gnash {
00043 namespace rtmp {
00044
00046
00048
00070 enum ControlType
00071 {
00072 CONTROL_CLEAR_STREAM = 0x00,
00073 CONTROL_CLEAR_BUFFER = 0x01,
00074 CONTROL_STREAM_DRY = 0x02,
00075 CONTROL_BUFFER_TIME = 0x03,
00076 CONTROL_RESET_STREAM = 0x04,
00077 CONTROL_PING = 0x06,
00078 CONTROL_PONG = 0x07,
00079 CONTROL_REQUEST_VERIFY = 0x1a,
00080 CONTROL_RESPOND_VERIFY = 0x1b,
00081 CONTROL_BUFFER_EMPTY = 0x1f,
00082 CONTROL_BUFFER_READY = 0x20
00083 };
00084
00086
00091
00093
00101
00103 enum Channels
00104 {
00105 CHANNEL_CONTROL1 = 0x02,
00106 CHANNEL_CONTROL2 = 0x03,
00107 CHANNEL_VIDEO = 0x08
00108 };
00109
00111 enum PacketType
00112 {
00113 PACKET_TYPE_NONE = 0x00,
00114 PACKET_TYPE_CHUNK_SIZE = 0x01,
00115 PACKET_TYPE_BYTES_READ = 0x03,
00116 PACKET_TYPE_CONTROL = 0x04,
00117 PACKET_TYPE_SERVERBW = 0x05,
00118 PACKET_TYPE_CLIENTBW = 0x06,
00119 PACKET_TYPE_AUDIO = 0x08,
00120 PACKET_TYPE_VIDEO = 0x09,
00121 PACKET_TYPE_FLEX_STREAM_SEND = 0x0f,
00122 PACKET_TYPE_FLEX_SHARED_OBJECT = 0x10,
00123 PACKET_TYPE_FLEX_MESSAGE = 0x11,
00124 PACKET_TYPE_METADATA = 0x12,
00125 PACKET_TYPE_SHARED_OBJECT = 0x13,
00126 PACKET_TYPE_INVOKE = 0x14,
00127 PACKET_TYPE_FLV = 0x16
00128 };
00129
00131
00137
00143
00145 enum PacketSize {
00146 RTMP_PACKET_SIZE_LARGE = 0,
00147 RTMP_PACKET_SIZE_MEDIUM = 1,
00148 RTMP_PACKET_SIZE_SMALL = 2,
00149 RTMP_PACKET_SIZE_MINIMUM = 3
00150 };
00151
00153 struct RTMPHeader
00154 {
00156 static const size_t headerSize = 18;
00157
00158 RTMPHeader()
00159 :
00160 headerType(RTMP_PACKET_SIZE_LARGE),
00161 packetType(PACKET_TYPE_NONE),
00162 _timestamp(0),
00163 _streamID(0),
00164 channel(0),
00165 dataSize(0)
00166 {}
00167
00168 PacketSize headerType;
00169 PacketType packetType;
00170
00172
00175 boost::uint32_t _timestamp;
00176
00178 boost::uint32_t _streamID;
00179
00180 size_t channel;
00181
00182
00183 size_t dataSize;
00184
00185 };
00186
00188
00192
00195 struct RTMPPacket
00196 {
00198
00204 explicit RTMPPacket(size_t reserve = 0);
00205
00207
00210 RTMPPacket(const RTMPPacket& other);
00211
00212 ~RTMPPacket() {}
00213
00214 RTMPHeader header;
00215
00217
00220 boost::shared_ptr<SimpleBuffer> buffer;
00221
00222 size_t bytesRead;
00223 };
00224
00225
00227
00230 inline bool
00231 hasPayload(const RTMPPacket& p)
00232 {
00233 return (p.buffer.get());
00234 }
00235
00237
00241 inline void
00242 clearPayload(RTMPPacket& p)
00243 {
00244 p.buffer.reset();
00245 p.bytesRead = 0;
00246 }
00247
00249
00252 inline size_t
00253 payloadSize(const RTMPPacket& p)
00254 {
00255 assert(hasPayload(p));
00256 const SimpleBuffer& buf = *p.buffer;
00257 assert(buf.size() >= RTMPHeader::headerSize);
00258 return buf.size() - RTMPHeader::headerSize;
00259 }
00260
00262 inline boost::uint8_t*
00263 payloadData(RTMPPacket& p)
00264 {
00265 assert(hasPayload(p));
00266 SimpleBuffer& buf = *p.buffer;
00267 return buf.data() + RTMPHeader::headerSize;
00268 }
00269
00271 inline const boost::uint8_t*
00272 payloadData(const RTMPPacket& p)
00273 {
00274 assert(hasPayload(p));
00275 const SimpleBuffer& buf = *p.buffer;
00276 return buf.data() + RTMPHeader::headerSize;
00277 }
00278
00280
00284 inline const boost::uint8_t*
00285 payloadEnd(const RTMPPacket& p)
00286 {
00287 assert(hasPayload(p));
00288 SimpleBuffer& buf = *p.buffer;
00289 return buf.data() + buf.size();
00290 }
00291
00293
00297 inline bool
00298 isReady(const RTMPPacket& p) {
00299 return p.bytesRead == p.header.dataSize;
00300 }
00301
00302
00304
00307
00310
00320
00327 struct DSOEXPORT RTMP
00328 {
00329
00331 RTMP();
00332
00333 ~RTMP();
00334
00336
00340
00344 bool connect(const URL& url);
00345
00347
00354 void call(const SimpleBuffer& amf);
00355
00357
00360
00363 void play(const SimpleBuffer& amf, int id);
00364
00366
00369 void setBufferTime(size_t time, int streamID);
00370
00372
00376
00379 bool connected() const {
00380 return _connected;
00381 }
00382
00384
00386 bool error() const {
00387 return _error;
00388 }
00389
00391
00394
00400
00404 void update();
00405
00407
00409 void close();
00410
00412
00416 boost::shared_ptr<SimpleBuffer> getMessage() {
00417 if (_messageQueue.empty()) return boost::shared_ptr<SimpleBuffer>();
00418 boost::shared_ptr<SimpleBuffer> b = _messageQueue.front();
00419 _messageQueue.pop_front();
00420 return b;
00421 }
00422
00424
00428 boost::shared_ptr<SimpleBuffer> getFLVFrame() {
00429 if (_flvQueue.empty()) return boost::shared_ptr<SimpleBuffer>();
00430 boost::shared_ptr<SimpleBuffer> b = _flvQueue.front();
00431 _flvQueue.pop_front();
00432 return b;
00433 }
00434
00436 void handlePacket(const RTMPPacket& packet);
00437
00439 int readSocket(boost::uint8_t* dst, int num);
00440
00442 bool sendPacket(RTMPPacket& packet);
00443
00445
00447 void setServerBandwidth(boost::uint32_t bw) {
00448 _serverBandwidth = bw;
00449 }
00450
00452 boost::uint32_t serverBandwidth() const {
00453 return _serverBandwidth;
00454 }
00455
00457 void setBandwidth(boost::uint32_t bw) {
00458 _bandwidth = bw;
00459 }
00460
00462 boost::uint32_t bandwidth() const {
00463 return _bandwidth;
00464 }
00465
00466 int _inChunkSize;
00467 int m_mediaChannel;
00468 boost::uint8_t m_nClientBW2;
00469 size_t _bytesIn;
00470 size_t _bytesInSent;
00471
00472 private:
00473
00474 enum ChannelType {
00475 CHANNELS_IN,
00476 CHANNELS_OUT
00477 };
00478
00480 bool readPacketHeader(RTMPPacket& packet);
00481
00482 bool readPacketPayload(RTMPPacket& packet);
00483
00485 bool hasPacket(ChannelType t, size_t channel) const;
00486
00488
00491 RTMPPacket& getPacket(ChannelType t, size_t channel);
00492
00494
00497 RTMPPacket& storePacket(ChannelType t, size_t channel, const RTMPPacket& p);
00498
00500
00504
00506 typedef std::map<size_t, RTMPPacket> ChannelSet;
00507
00508 Socket _socket;
00509
00511 ChannelSet _inChannels;
00512
00514 ChannelSet _outChannels;
00515
00516 std::deque<boost::shared_ptr<SimpleBuffer> > _messageQueue;
00517 std::deque<boost::shared_ptr<SimpleBuffer> > _flvQueue;
00518
00520 boost::uint32_t _serverBandwidth;
00521
00523 boost::uint32_t _bandwidth;
00524
00526 size_t _outChunkSize;
00527
00528 boost::scoped_ptr<HandShaker> _handShaker;
00529
00530 bool _connected;
00531
00532 bool _error;
00533
00535
00538 boost::scoped_ptr<RTMPPacket> _incompletePacket;
00539
00540 };
00541
00543 DSOEXPORT bool sendServerBW(RTMP& r);
00544
00546 bool sendCtrl(RTMP& r, ControlType, unsigned int nObject, unsigned int nTime);
00547
00549 std::ostream& operator<<(std::ostream& o, PacketType p);
00550
00552 std::ostream& operator<<(std::ostream& o, ControlType t);
00553
00554 }
00555
00556 }
00557 #endif