Gnash 0.8.9
|
00001 // 00002 // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 00003 // 00004 // This program is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 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 // Forward declarations. 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 // The size of the data. 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 // 00502 // 00504 typedef std::map<size_t, RTMPPacket> ChannelSet; 00505 00506 Socket _socket; 00507 00509 ChannelSet _inChannels; 00510 00512 ChannelSet _outChannels; 00513 00514 std::deque<boost::shared_ptr<SimpleBuffer> > _messageQueue; 00515 std::deque<boost::shared_ptr<SimpleBuffer> > _flvQueue; 00516 00518 boost::uint32_t _serverBandwidth; 00519 00521 boost::uint32_t _bandwidth; 00522 00524 size_t _outChunkSize; 00525 00526 boost::scoped_ptr<HandShaker> _handShaker; 00527 00528 bool _connected; 00529 00530 bool _error; 00531 00533 // 00536 boost::scoped_ptr<RTMPPacket> _incompletePacket; 00537 00538 }; 00539 00541 bool sendServerBW(RTMP& r); 00542 00544 bool sendCtrl(RTMP& r, ControlType, unsigned int nObject, unsigned int nTime); 00545 00547 std::ostream& operator<<(std::ostream& o, PacketType p); 00548 00550 std::ostream& operator<<(std::ostream& o, ControlType t); 00551 00552 } // namespace rtmp 00553 00554 } // namespace gnash 00555 #endif