Gnash  0.8.11dev
RTMP.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
3 // Free Software Foundation, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 #ifndef GNASH_RTMP_H
20 #define GNASH_RTMP_H
21 
22 #include <boost/cstdint.hpp>
23 #include <boost/shared_ptr.hpp>
24 #include <boost/scoped_ptr.hpp>
25 #include <deque>
26 #include <map>
27 
28 #include "SimpleBuffer.h"
29 #include "Socket.h"
30 #include "dsodefs.h"
31 
32 #define RTMP_DEFAULT_CHUNKSIZE 128
33 
34 // Forward declarations.
35 namespace gnash {
36  namespace rtmp {
37  class HandShaker;
38  }
39  class URL;
40 }
41 
42 namespace gnash {
43 namespace rtmp {
44 
46 //
48 //
71 {
77  CONTROL_PING = 0x06,
78  CONTROL_PONG = 0x07,
83 };
84 
86 //
91 //
93 //
101 //
104 {
108 };
109 
112 {
128 };
129 
131 //
137 //
143 //
150 };
151 
154 {
156  static const size_t headerSize = 18;
157 
159  :
162  _timestamp(0),
163  _streamID(0),
164  channel(0),
165  dataSize(0)
166  {}
167 
170 
172  //
175  boost::uint32_t _timestamp;
176 
178  boost::uint32_t _streamID;
179 
180  size_t channel;
181 
182  // The size of the data.
183  size_t dataSize;
184 
185 };
186 
188 //
192 //
196 {
198  //
204  explicit RTMPPacket(size_t reserve = 0);
205 
207  //
210  RTMPPacket(const RTMPPacket& other);
211 
213 
215 
217  //
220  boost::shared_ptr<SimpleBuffer> buffer;
221 
222  size_t bytesRead;
223 };
224 
225 
227 //
230 inline bool
232 {
233  return (p.buffer.get());
234 }
235 
237 //
241 inline void
243 {
244  p.buffer.reset();
245  p.bytesRead = 0;
246 }
247 
249 //
252 inline size_t
254 {
255  assert(hasPayload(p));
256  const SimpleBuffer& buf = *p.buffer;
258  return buf.size() - RTMPHeader::headerSize;
259 }
260 
262 inline boost::uint8_t*
264 {
265  assert(hasPayload(p));
266  SimpleBuffer& buf = *p.buffer;
267  return buf.data() + RTMPHeader::headerSize;
268 }
269 
271 inline const boost::uint8_t*
273 {
274  assert(hasPayload(p));
275  const SimpleBuffer& buf = *p.buffer;
276  return buf.data() + RTMPHeader::headerSize;
277 }
278 
280 //
284 inline const boost::uint8_t*
286 {
287  assert(hasPayload(p));
288  SimpleBuffer& buf = *p.buffer;
289  return buf.data() + buf.size();
290 }
291 
293 //
297 inline bool
299  return p.bytesRead == p.header.dataSize;
300 }
301 
302 
304 //
307 //
310 //
320 //
328 {
329 
331  RTMP();
332 
333  ~RTMP();
334 
336  //
340  //
344  bool connect(const URL& url);
345 
347  //
354  void call(const SimpleBuffer& amf);
355 
357  //
360  //
363  void play(const SimpleBuffer& amf, int id);
364 
366  //
369  void setBufferTime(size_t time, int streamID);
370 
372  //
376  //
379  bool connected() const {
380  return _connected;
381  }
382 
384  //
386  bool error() const {
387  return _error;
388  }
389 
391  //
394  //
400  //
404  void update();
405 
407  //
409  void close();
410 
412  //
416  boost::shared_ptr<SimpleBuffer> getMessage() {
417  if (_messageQueue.empty()) return boost::shared_ptr<SimpleBuffer>();
418  boost::shared_ptr<SimpleBuffer> b = _messageQueue.front();
419  _messageQueue.pop_front();
420  return b;
421  }
422 
424  //
428  boost::shared_ptr<SimpleBuffer> getFLVFrame() {
429  if (_flvQueue.empty()) return boost::shared_ptr<SimpleBuffer>();
430  boost::shared_ptr<SimpleBuffer> b = _flvQueue.front();
431  _flvQueue.pop_front();
432  return b;
433  }
434 
436  void handlePacket(const RTMPPacket& packet);
437 
439  int readSocket(boost::uint8_t* dst, int num);
440 
442  bool sendPacket(RTMPPacket& packet);
443 
445  //
447  void setServerBandwidth(boost::uint32_t bw) {
448  _serverBandwidth = bw;
449  }
450 
452  boost::uint32_t serverBandwidth() const {
453  return _serverBandwidth;
454  }
455 
457  void setBandwidth(boost::uint32_t bw) {
458  _bandwidth = bw;
459  }
460 
462  boost::uint32_t bandwidth() const {
463  return _bandwidth;
464  }
465 
468  boost::uint8_t m_nClientBW2;
469  size_t _bytesIn;
470  size_t _bytesInSent;
471 
472 private:
473 
474  enum ChannelType {
475  CHANNELS_IN,
476  CHANNELS_OUT
477  };
478 
480  bool readPacketHeader(RTMPPacket& packet);
481 
482  bool readPacketPayload(RTMPPacket& packet);
483 
485  bool hasPacket(ChannelType t, size_t channel) const;
486 
488  //
491  RTMPPacket& getPacket(ChannelType t, size_t channel);
492 
494  //
497  RTMPPacket& storePacket(ChannelType t, size_t channel, const RTMPPacket& p);
498 
500  //
504  //
506  typedef std::map<size_t, RTMPPacket> ChannelSet;
507 
508  Socket _socket;
509 
511  ChannelSet _inChannels;
512 
514  ChannelSet _outChannels;
515 
516  std::deque<boost::shared_ptr<SimpleBuffer> > _messageQueue;
517  std::deque<boost::shared_ptr<SimpleBuffer> > _flvQueue;
518 
520  boost::uint32_t _serverBandwidth;
521 
523  boost::uint32_t _bandwidth;
524 
526  size_t _outChunkSize;
527 
528  boost::scoped_ptr<HandShaker> _handShaker;
529 
530  bool _connected;
531 
532  bool _error;
533 
535  //
538  boost::scoped_ptr<RTMPPacket> _incompletePacket;
539 
540 };
541 
543 DSOEXPORT bool sendServerBW(RTMP& r);
544 
546 bool sendCtrl(RTMP& r, ControlType, unsigned int nObject, unsigned int nTime);
547 
549 std::ostream& operator<<(std::ostream& o, PacketType p);
550 
552 std::ostream& operator<<(std::ostream& o, ControlType t);
553 
554 } // namespace rtmp
555 
556 } // namespace gnash
557 #endif