Gnash
0.8.10
|
00001 // 00002 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 00003 // Free Software Foundation, Inc. 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 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 // Forward declarations. 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 // The size of the data. 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 } // namespace rtmp 00555 00556 } // namespace gnash 00557 #endif