00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef GNASH_RTMP_H
00019 #define GNASH_RTMP_H
00020
00021 #include <boost/cstdint.hpp>
00022 #include <boost/shared_ptr.hpp>
00023 #include <boost/scoped_ptr.hpp>
00024 #include <deque>
00025 #include <map>
00026
00027 #include "SimpleBuffer.h"
00028 #include "Socket.h"
00029
00030 #define RTMP_DEFAULT_CHUNKSIZE 128
00031
00032
00033 namespace gnash {
00034 namespace rtmp {
00035 class HandShaker;
00036 }
00037 class URL;
00038 }
00039
00040 namespace gnash {
00041 namespace rtmp {
00042
00044
00046
00068 enum ControlType
00069 {
00070 CONTROL_CLEAR_STREAM = 0x00,
00071 CONTROL_CLEAR_BUFFER = 0x01,
00072 CONTROL_STREAM_DRY = 0x02,
00073 CONTROL_BUFFER_TIME = 0x03,
00074 CONTROL_RESET_STREAM = 0x04,
00075 CONTROL_PING = 0x06,
00076 CONTROL_PONG = 0x07,
00077 CONTROL_REQUEST_VERIFY = 0x1a,
00078 CONTROL_RESPOND_VERIFY = 0x1b,
00079 CONTROL_BUFFER_EMPTY = 0x1f,
00080 CONTROL_BUFFER_READY = 0x20
00081 };
00082
00084
00089
00091
00099
00101 enum Channels
00102 {
00103 CHANNEL_CONTROL1 = 0x02,
00104 CHANNEL_CONTROL2 = 0x03,
00105 CHANNEL_VIDEO = 0x08
00106 };
00107
00109 enum PacketType
00110 {
00111 PACKET_TYPE_NONE = 0x00,
00112 PACKET_TYPE_CHUNK_SIZE = 0x01,
00113 PACKET_TYPE_BYTES_READ = 0x03,
00114 PACKET_TYPE_CONTROL = 0x04,
00115 PACKET_TYPE_SERVERBW = 0x05,
00116 PACKET_TYPE_CLIENTBW = 0x06,
00117 PACKET_TYPE_AUDIO = 0x08,
00118 PACKET_TYPE_VIDEO = 0x09,
00119 PACKET_TYPE_FLEX_STREAM_SEND = 0x0f,
00120 PACKET_TYPE_FLEX_SHARED_OBJECT = 0x10,
00121 PACKET_TYPE_FLEX_MESSAGE = 0x11,
00122 PACKET_TYPE_METADATA = 0x12,
00123 PACKET_TYPE_SHARED_OBJECT = 0x13,
00124 PACKET_TYPE_INVOKE = 0x14,
00125 PACKET_TYPE_FLV = 0x16
00126 };
00127
00129
00135
00141
00143 enum PacketSize {
00144 RTMP_PACKET_SIZE_LARGE = 0,
00145 RTMP_PACKET_SIZE_MEDIUM = 1,
00146 RTMP_PACKET_SIZE_SMALL = 2,
00147 RTMP_PACKET_SIZE_MINIMUM = 3
00148 };
00149
00151 struct RTMPHeader
00152 {
00154 static const size_t headerSize = 18;
00155
00156 RTMPHeader()
00157 :
00158 headerType(RTMP_PACKET_SIZE_LARGE),
00159 packetType(PACKET_TYPE_NONE),
00160 _timestamp(0),
00161 _streamID(0),
00162 channel(0),
00163 dataSize(0)
00164 {}
00165
00166 PacketSize headerType;
00167 PacketType packetType;
00168
00170
00173 boost::uint32_t _timestamp;
00174
00176 boost::uint32_t _streamID;
00177
00178 size_t channel;
00179
00180
00181 size_t dataSize;
00182
00183 };
00184
00186
00190
00193 struct RTMPPacket
00194 {
00196
00202 explicit RTMPPacket(size_t reserve = 0);
00203
00205
00208 RTMPPacket(const RTMPPacket& other);
00209
00210 ~RTMPPacket() {}
00211
00212 RTMPHeader header;
00213
00215
00218 boost::shared_ptr<SimpleBuffer> buffer;
00219
00220 size_t bytesRead;
00221 };
00222
00223
00225
00228 inline bool
00229 hasPayload(const RTMPPacket& p)
00230 {
00231 return (p.buffer.get());
00232 }
00233
00235
00239 inline void
00240 clearPayload(RTMPPacket& p)
00241 {
00242 p.buffer.reset();
00243 p.bytesRead = 0;
00244 }
00245
00247
00250 inline size_t
00251 payloadSize(const RTMPPacket& p)
00252 {
00253 assert(hasPayload(p));
00254 const SimpleBuffer& buf = *p.buffer;
00255 assert(buf.size() >= RTMPHeader::headerSize);
00256 return buf.size() - RTMPHeader::headerSize;
00257 }
00258
00260 inline boost::uint8_t*
00261 payloadData(RTMPPacket& p)
00262 {
00263 assert(hasPayload(p));
00264 SimpleBuffer& buf = *p.buffer;
00265 return buf.data() + RTMPHeader::headerSize;
00266 }
00267
00269 inline const boost::uint8_t*
00270 payloadData(const RTMPPacket& p)
00271 {
00272 assert(hasPayload(p));
00273 const SimpleBuffer& buf = *p.buffer;
00274 return buf.data() + RTMPHeader::headerSize;
00275 }
00276
00278
00282 inline const boost::uint8_t*
00283 payloadEnd(const RTMPPacket& p)
00284 {
00285 assert(hasPayload(p));
00286 SimpleBuffer& buf = *p.buffer;
00287 return buf.data() + buf.size();
00288 }
00289
00291
00295 inline bool
00296 isReady(const RTMPPacket& p) {
00297 return p.bytesRead == p.header.dataSize;
00298 }
00299
00300
00302
00305
00308
00318
00325 struct DSOEXPORT RTMP
00326 {
00327
00329 RTMP();
00330
00331 ~RTMP();
00332
00334
00338
00342 bool connect(const URL& url);
00343
00345
00352 void call(const SimpleBuffer& amf);
00353
00355
00358
00361 void play(const SimpleBuffer& amf, int id);
00362
00364
00367 void setBufferTime(size_t time, int streamID);
00368
00370
00374
00377 bool connected() const {
00378 return _connected;
00379 }
00380
00382
00384 bool error() const {
00385 return _error;
00386 }
00387
00389
00392
00398
00402 void update();
00403
00405
00407 void close();
00408
00410
00414 boost::shared_ptr<SimpleBuffer> getMessage() {
00415 if (_messageQueue.empty()) return boost::shared_ptr<SimpleBuffer>();
00416 boost::shared_ptr<SimpleBuffer> b = _messageQueue.front();
00417 _messageQueue.pop_front();
00418 return b;
00419 }
00420
00422
00426 boost::shared_ptr<SimpleBuffer> getFLVFrame() {
00427 if (_flvQueue.empty()) return boost::shared_ptr<SimpleBuffer>();
00428 boost::shared_ptr<SimpleBuffer> b = _flvQueue.front();
00429 _flvQueue.pop_front();
00430 return b;
00431 }
00432
00434 void handlePacket(const RTMPPacket& packet);
00435
00437 int readSocket(boost::uint8_t* dst, int num);
00438
00440 bool sendPacket(RTMPPacket& packet);
00441
00443
00445 void setServerBandwidth(boost::uint32_t bw) {
00446 _serverBandwidth = bw;
00447 }
00448
00450 boost::uint32_t serverBandwidth() const {
00451 return _serverBandwidth;
00452 }
00453
00455 void setBandwidth(boost::uint32_t bw) {
00456 _bandwidth = bw;
00457 }
00458
00460 boost::uint32_t bandwidth() const {
00461 return _bandwidth;
00462 }
00463
00464 int _inChunkSize;
00465 int m_mediaChannel;
00466 boost::uint8_t m_nClientBW2;
00467 size_t _bytesIn;
00468 size_t _bytesInSent;
00469
00470 private:
00471
00472 enum ChannelType {
00473 CHANNELS_IN,
00474 CHANNELS_OUT
00475 };
00476
00478 bool readPacketHeader(RTMPPacket& packet);
00479
00480 bool readPacketPayload(RTMPPacket& packet);
00481
00483 bool hasPacket(ChannelType t, size_t channel) const;
00484
00486
00489 RTMPPacket& getPacket(ChannelType t, size_t channel);
00490
00492
00495 RTMPPacket& storePacket(ChannelType t, size_t channel, const RTMPPacket& p);
00496
00498
00500 bool handShake();
00501
00503
00507
00509 typedef std::map<size_t, RTMPPacket> ChannelSet;
00510
00511 Socket _socket;
00512
00514 ChannelSet _inChannels;
00515
00517 ChannelSet _outChannels;
00518
00519 std::deque<boost::shared_ptr<SimpleBuffer> > _messageQueue;
00520 std::deque<boost::shared_ptr<SimpleBuffer> > _flvQueue;
00521
00523 boost::uint32_t _serverBandwidth;
00524
00526 boost::uint32_t _bandwidth;
00527
00529 size_t _outChunkSize;
00530
00531 boost::scoped_ptr<HandShaker> _handShaker;
00532
00533 bool _connected;
00534
00535 bool _error;
00536
00538
00541 boost::scoped_ptr<RTMPPacket> _incompletePacket;
00542
00543 };
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