VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gvrtpavcpacket.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file gvrtpavcpacket.h
19 ///
20 
21 #ifndef GV_RTPAVCPACKET__H
22 #define GV_RTPAVCPACKET__H
23 
24 #include "gdef.h"
25 #include "gassert.h"
26 #include "gvrtppacket.h"
27 #include <string>
28 #include <deque>
29 
30 namespace Gv
31 {
32  class RtpAvcPacket ;
33  class RtpAvcPacketStream ;
34 } ;
35 
36 /// \class Gv::RtpAvcPacket
37 /// An RTP payload parser for the "H264" payload type. Note that the RTP payload
38 /// type for H264 is not fixed; it is communicated out-of-band by eg. RTSP.
39 ///
40 /// The RTP payload for AVC can either be exactly one AVC NALU, more than one NALU,
41 /// or just a NALU fragment (ie. single, aggregated or fragmented). The first byte
42 /// of the RTP payload is cunningly defined so that is can double-up as the
43 /// first byte of a NALU, ie. the NALU header byte. If the first byte is a valid
44 /// NALU type (ie. 1-23 in the low bits) then the RTP payload is a single NALU
45 /// and there is no structure added by the RTP-AVC layer.
46 ///
47 /// Note that AVC NALUs are composed of a single header byte followed by byte-stuffed
48 /// RBSP data (see Gr::Avc). They are often chained together using a four-byte
49 /// 00-00-00-01 start code and a three-byte 00-00-01 separator.
50 ///
51 /// \see RFC-6184
52 ///
54 {
55 public:
56 
57  enum Type {
58  SINGLE_NALU_1 = 1 , // Single Network Abstraction Layer Unit
59  // ...
60  SINGLE_NALU_23 = 23 , // Single Network Abstraction Layer Unit
61  STAP_A = 24 , // Single Time Aggregation Packet without DONs
62  STAP_B = 25 , // Single Time Aggregation Packet with DONs
63  MTAP16 = 26 , // Multi Time Aggregation Packet
64  MTAP24 = 27 , // Multi Time Aggregation Packet
65  FU_A = 28 , // Fragmentation Unit without DONs
66  FU_B = 29 , // Fragmentation Unit with DONs
67  } ;
68 
69  static size_t smallest() ;
70  ///< The smallest parsable packet.
71 
72  RtpAvcPacket( const unsigned char * begin , const unsigned char * end ) ;
73  ///< Constructor taking in an RTP payload with Payload Type of
74  ///< H264/90000. The data should start with the RTP H264 header defined
75  ///< in RFC-6184 section 5.2.
76  ///< Precondition: (end-begin) >= smallest().
77 
78  explicit RtpAvcPacket( const std::string & data ) ;
79  ///< Constructor overload taking a string packet.
80 
81  const char * reason() const ;
82  ///< Returns the in-valid() reason, or nullptr.
83 
84  bool valid() const ;
85  ///< Returns true if a valid packet.
86 
87  std::string str( bool more = false ) const ;
88  ///< Returns a summary of the packet header for debugging purposes.
89 
90  unsigned int type() const ;
91  ///< Returns the RTP-AVC packet type, matching the Type enum.
92  ///< This is also the NALU type iff the value is in the
93  ///< range 1..23 (ie. if type_is_single()).
94 
95  unsigned int nri() const ;
96  ///< Returns the NALU nal_ref_idc value, in the range 0..3.
97  ///< This indicates the discardability of the packet; zero
98  ///< indicates that the packet is discardable, and 3 that
99  ///< it is not.
100 
101  bool type_is_fu() const ;
102  ///< Returns true if type() is FU_A or FU_B.
103 
104  bool type_is_single() const ;
105  ///< Returns true if type() is SINGLE_NALU_x.
106 
107  bool type_is_sequence_parameter_set() const ;
108  ///< Returns true if type() is SINGLE_NALU_7.
109 
110  bool type_is_picture_parameter_set() const ;
111  ///< Returns true if type() is SINGLE_NALU_8.
112 
113  bool fu_start() const ;
114  ///< Returns true for the first FU packet in the fragmented NALU.
115  ///< Precondition: fu()
116 
117  bool fu_end() const ;
118  ///< Returns true for the last FU packet in the fragmented NALU.
119  ///< Precondition: fu()
120 
121  unsigned int fu_type() const ;
122  ///< Returns the type of the fragmented NALU.
123  ///< Precondition: fu()
124 
125  size_t payloadSize() const ;
126  ///< Returns the RTP-AVC payload size.
127 
128  char payloadFirst() const ;
129  ///< Returns the first RTP-AVC payload byte.
130  ///<
131  ///< This byte is split across two bytes in the raw data of an
132  ///< initial fragmentated packet, but to copy the raw data just
133  ///< to fix up the first byte would be too expensive.
134 
135  const char * payloadBegin() const ;
136  ///< Returns the RTP-AVC payload pointer, but the first byte
137  ///< may be wrong so use payloadFirst() to overwrite it after
138  ///< copying.
139  ///<
140  ///< Note that payloadBegin()/payloadEnd() data will only be
141  ///< a NALU if type_is_single(), and RBSP byte stuffing is
142  ///< never used.
143 
144  const char * payloadEnd() const ;
145  ///< Returns the RTP-AVC payload end pointer.
146 
147 private:
148  RtpAvcPacket( const RtpAvcPacket & ) ;
149  void operator=( const RtpAvcPacket & ) ;
150  static unsigned int make_word( const unsigned char * p ) ;
151  static unsigned long make_dword( unsigned long , unsigned long , unsigned long , unsigned long ) ;
152  unsigned int payloadOffset() const ;
153 
154 private:
155  const unsigned char * m_p ;
156  size_t m_n ;
157 } ;
158 
159 /// \class Gv::RtpAvcPacketStream
160 /// A class that accumulates RTP-AVC packets and serves up AVC NALUs.
161 /// Note that there is no one-to-one correspondence between RTP-AVC
162 /// packets and NALUs; NALUs can be fragmented over multiple
163 /// packets, and multiple NULUs can be aggregated into one packet.
164 ///
166 {
167 public:
169  ///< Default constructor.
170 
171  bool add( const RtpPacket & ) ;
172  ///< Adds a packet.
173 
174  bool add( const RtpPacket & , const RtpAvcPacket & ) ;
175  ///< Adds a packet.
176 
177  bool more() const ;
178  ///< Returns true if NALUs are available.
179 
180  std::string nalu() ;
181  ///< Extracts a NALU.
182 
183 private:
185  void operator=( const RtpAvcPacketStream & ) ;
186  bool contiguous() const ;
187  void commit() ;
188  void clear() ;
189 
190 private:
191  unsigned long m_timestamp ;
192  std::vector<unsigned int> m_seq_list ;
193  std::string m_buffer ;
194  std::deque<std::string> m_list ;
195 } ;
196 
197 #endif
const char * payloadBegin() const
Returns the RTP-AVC payload pointer, but the first byte may be wrong so use payloadFirst() to overwri...
static size_t smallest()
The smallest parsable packet.
A class that accumulates RTP-AVC packets and serves up AVC NALUs.
bool type_is_single() const
Returns true if type() is SINGLE_NALU_x.
std::string nalu()
Extracts a NALU.
unsigned int type() const
Returns the RTP-AVC packet type, matching the Type enum.
bool valid() const
Returns true if a valid packet.
bool fu_start() const
Returns true for the first FU packet in the fragmented NALU.
bool more() const
Returns true if NALUs are available.
const char * payloadEnd() const
Returns the RTP-AVC payload end pointer.
RtpAvcPacket(const unsigned char *begin, const unsigned char *end)
Constructor taking in an RTP payload with Payload Type of H264/90000.
bool type_is_picture_parameter_set() const
Returns true if type() is SINGLE_NALU_8.
bool add(const RtpPacket &)
Adds a packet.
unsigned int nri() const
Returns the NALU nal_ref_idc value, in the range 0..3.
An RTP packet parser, as per RFC 3550 (section 5).
Definition: gvrtppacket.h:44
unsigned int fu_type() const
Returns the type of the fragmented NALU.
RtpAvcPacketStream()
Default constructor.
An RTP payload parser for the "H264" payload type.
char payloadFirst() const
Returns the first RTP-AVC payload byte.
std::string str(bool more=false) const
Returns a summary of the packet header for debugging purposes.
const char * reason() const
Returns the in-valid() reason, or nullptr.
bool type_is_fu() const
Returns true if type() is FU_A or FU_B.
bool fu_end() const
Returns true for the last FU packet in the fragmented NALU.
size_t payloadSize() const
Returns the RTP-AVC payload size.
bool type_is_sequence_parameter_set() const
Returns true if type() is SINGLE_NALU_7.