Gnash  0.8.10
RTMP.h
Go to the documentation of this file.
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