Gnash 0.8.10dev
RTMP.h
Go to the documentation of this file.
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 #include "dsodefs.h"
00030 
00031 #define RTMP_DEFAULT_CHUNKSIZE  128
00032 
00033 // Forward declarations.
00034 namespace gnash {
00035     namespace rtmp {
00036         class HandShaker;
00037     }
00038     class URL;
00039 }
00040 
00041 namespace gnash {
00042 namespace rtmp {
00043 
00045 //
00047 //
00069 enum ControlType
00070 {
00071     CONTROL_CLEAR_STREAM = 0x00,
00072     CONTROL_CLEAR_BUFFER = 0x01,
00073     CONTROL_STREAM_DRY = 0x02,
00074     CONTROL_BUFFER_TIME = 0x03,
00075     CONTROL_RESET_STREAM = 0x04,
00076     CONTROL_PING = 0x06,
00077     CONTROL_PONG = 0x07,
00078     CONTROL_REQUEST_VERIFY = 0x1a,
00079     CONTROL_RESPOND_VERIFY = 0x1b,
00080     CONTROL_BUFFER_EMPTY = 0x1f,
00081     CONTROL_BUFFER_READY = 0x20
00082 };
00083 
00085 //
00090 //
00092 //
00100 //
00102 enum Channels
00103 {
00104     CHANNEL_CONTROL1 = 0x02,
00105     CHANNEL_CONTROL2 = 0x03,
00106     CHANNEL_VIDEO = 0x08
00107 };
00108 
00110 enum PacketType
00111 {
00112     PACKET_TYPE_NONE = 0x00,
00113     PACKET_TYPE_CHUNK_SIZE = 0x01,
00114     PACKET_TYPE_BYTES_READ = 0x03,
00115     PACKET_TYPE_CONTROL = 0x04,
00116     PACKET_TYPE_SERVERBW = 0x05,
00117     PACKET_TYPE_CLIENTBW = 0x06,
00118     PACKET_TYPE_AUDIO = 0x08,
00119     PACKET_TYPE_VIDEO = 0x09,
00120     PACKET_TYPE_FLEX_STREAM_SEND = 0x0f,
00121     PACKET_TYPE_FLEX_SHARED_OBJECT = 0x10,
00122     PACKET_TYPE_FLEX_MESSAGE = 0x11,
00123     PACKET_TYPE_METADATA = 0x12,
00124     PACKET_TYPE_SHARED_OBJECT = 0x13,
00125     PACKET_TYPE_INVOKE = 0x14,
00126     PACKET_TYPE_FLV = 0x16
00127 };
00128 
00130 //
00136 //
00142 //
00144 enum PacketSize {
00145     RTMP_PACKET_SIZE_LARGE = 0,
00146     RTMP_PACKET_SIZE_MEDIUM = 1,
00147     RTMP_PACKET_SIZE_SMALL = 2,
00148     RTMP_PACKET_SIZE_MINIMUM = 3
00149 };
00150 
00152 struct RTMPHeader
00153 {
00155     static const size_t headerSize = 18;
00156 
00157     RTMPHeader()
00158         :
00159         headerType(RTMP_PACKET_SIZE_LARGE),
00160         packetType(PACKET_TYPE_NONE),
00161         _timestamp(0),
00162         _streamID(0),
00163         channel(0),
00164         dataSize(0)
00165     {}
00166 
00167     PacketSize headerType;
00168     PacketType packetType;
00169 
00171     //
00174     boost::uint32_t _timestamp;
00175 
00177     boost::uint32_t _streamID;
00178 
00179     size_t channel;
00180 
00181     // The size of the data.
00182     size_t dataSize;
00183 
00184 };
00185 
00187 //
00191 //
00194 struct RTMPPacket
00195 {
00197     //
00203     explicit RTMPPacket(size_t reserve = 0);
00204     
00206     //
00209     RTMPPacket(const RTMPPacket& other);
00210 
00211     ~RTMPPacket() {}
00212 
00213     RTMPHeader header;
00214 
00216     //
00219     boost::shared_ptr<SimpleBuffer> buffer;
00220 
00221     size_t bytesRead;
00222 };
00223 
00224 
00226 //
00229 inline bool
00230 hasPayload(const RTMPPacket& p)
00231 {
00232     return (p.buffer.get());
00233 }
00234 
00236 //
00240 inline void
00241 clearPayload(RTMPPacket& p)
00242 {
00243     p.buffer.reset();
00244     p.bytesRead = 0;
00245 }
00246 
00248 //
00251 inline size_t
00252 payloadSize(const RTMPPacket& p)
00253 {
00254     assert(hasPayload(p));
00255     const SimpleBuffer& buf = *p.buffer;
00256     assert(buf.size() >= RTMPHeader::headerSize);
00257     return buf.size() - RTMPHeader::headerSize;
00258 }
00259 
00261 inline boost::uint8_t*
00262 payloadData(RTMPPacket& p)
00263 {
00264     assert(hasPayload(p));
00265     SimpleBuffer& buf = *p.buffer;
00266     return buf.data() + RTMPHeader::headerSize;
00267 }
00268 
00270 inline const boost::uint8_t*
00271 payloadData(const RTMPPacket& p)
00272 {
00273     assert(hasPayload(p));
00274     const SimpleBuffer& buf = *p.buffer;
00275     return buf.data() + RTMPHeader::headerSize;
00276 }
00277 
00279 //
00283 inline const boost::uint8_t*
00284 payloadEnd(const RTMPPacket& p)
00285 {
00286     assert(hasPayload(p));
00287     SimpleBuffer& buf = *p.buffer;
00288     return buf.data() + buf.size();
00289 }
00290 
00292 //
00296 inline bool
00297 isReady(const RTMPPacket& p) {
00298     return p.bytesRead == p.header.dataSize;
00299 }
00300 
00301 
00303 //
00306 //
00309 //
00319 //
00326 struct DSOEXPORT RTMP
00327 {
00328 
00330     RTMP();
00331 
00332     ~RTMP();
00333 
00335     //
00339     //
00343     bool connect(const URL& url);
00344 
00346     //
00353     void call(const SimpleBuffer& amf);
00354 
00356     //
00359     //
00362     void play(const SimpleBuffer& amf, int id);
00363 
00365     //
00368     void setBufferTime(size_t time, int streamID);
00369 
00371     //
00375     //
00378     bool connected() const {
00379         return _connected;
00380     }
00381 
00383     //
00385     bool error() const {
00386         return _error;
00387     }
00388 
00390     //
00393     //
00399     //
00403     void update();
00404 
00406     //
00408     void close();
00409 
00411     //
00415     boost::shared_ptr<SimpleBuffer> getMessage() {
00416         if (_messageQueue.empty()) return boost::shared_ptr<SimpleBuffer>();
00417         boost::shared_ptr<SimpleBuffer> b = _messageQueue.front();
00418         _messageQueue.pop_front();
00419         return b;
00420     }
00421     
00423     //
00427     boost::shared_ptr<SimpleBuffer> getFLVFrame() {
00428         if (_flvQueue.empty()) return boost::shared_ptr<SimpleBuffer>();
00429         boost::shared_ptr<SimpleBuffer> b = _flvQueue.front();
00430         _flvQueue.pop_front();
00431         return b;
00432     }
00433 
00435     void handlePacket(const RTMPPacket& packet);
00436     
00438     int readSocket(boost::uint8_t* dst, int num);
00439 
00441     bool sendPacket(RTMPPacket& packet);
00442 
00444     //
00446     void setServerBandwidth(boost::uint32_t bw) {
00447         _serverBandwidth = bw;
00448     }
00449 
00451     boost::uint32_t serverBandwidth() const {
00452         return _serverBandwidth;
00453     }
00454 
00456     void setBandwidth(boost::uint32_t bw) {
00457         _bandwidth = bw;
00458     }
00459 
00461     boost::uint32_t bandwidth() const {
00462         return _bandwidth;
00463     }
00464 
00465     int _inChunkSize;
00466     int m_mediaChannel;
00467     boost::uint8_t m_nClientBW2;
00468     size_t _bytesIn;
00469     size_t _bytesInSent;
00470 
00471 private:
00472 
00473     enum ChannelType {
00474         CHANNELS_IN,
00475         CHANNELS_OUT
00476     };
00477     
00479     bool readPacketHeader(RTMPPacket& packet);
00480 
00481     bool readPacketPayload(RTMPPacket& packet);
00482 
00484     bool hasPacket(ChannelType t, size_t channel) const;
00485 
00487     //
00490     RTMPPacket& getPacket(ChannelType t, size_t channel);
00491 
00493     //
00496     RTMPPacket& storePacket(ChannelType t, size_t channel, const RTMPPacket& p);
00497 
00499     //
00503     //
00505     typedef std::map<size_t, RTMPPacket> ChannelSet;
00506     
00507     Socket _socket;
00508 
00510     ChannelSet _inChannels;
00511 
00513     ChannelSet _outChannels;
00514     
00515     std::deque<boost::shared_ptr<SimpleBuffer> > _messageQueue;
00516     std::deque<boost::shared_ptr<SimpleBuffer> > _flvQueue;
00517 
00519     boost::uint32_t _serverBandwidth;
00520 
00522     boost::uint32_t _bandwidth;
00523 
00525     size_t _outChunkSize;
00526 
00527     boost::scoped_ptr<HandShaker> _handShaker;
00528 
00529     bool _connected;
00530 
00531     bool _error;
00532 
00534     //
00537     boost::scoped_ptr<RTMPPacket> _incompletePacket;
00538 
00539 };
00540 
00542 DSOEXPORT bool sendServerBW(RTMP& r);
00543 
00545 bool sendCtrl(RTMP& r, ControlType, unsigned int nObject, unsigned int nTime);
00546 
00548 std::ostream& operator<<(std::ostream& o, PacketType p);
00549 
00551 std::ostream& operator<<(std::ostream& o, ControlType t);
00552 
00553 } // namespace rtmp
00554 
00555 } // namespace gnash
00556 #endif