• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

RTMP.h

Go to the documentation of this file.
00001 //
00002 //   Copyright (C) 2007, 2008, 2009, 2010 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     //
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 } // namespace rtmp
00555 
00556 } // namespace gnash
00557 #endif

Generated on Thu Sep 30 2010 14:35:02 for Gnash by  doxygen 1.7.1