• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 /*
12  * This file contains the declaration of the VP8 packetizer class.
13  * A packetizer object is created for each encoded video frame. The
14  * constructor is called with the payload data and size,
15  * together with the fragmentation information and a packetizer mode
16  * of choice. Alternatively, if no fragmentation info is available, the
17  * second constructor can be used with only payload data and size; in that
18  * case the mode kEqualSize is used.
19  *
20  * After creating the packetizer, the method NextPacket is called
21  * repeatedly to get all packets for the frame. The method returns
22  * false as long as there are more packets left to fetch.
23  */
24 
25 #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
26 #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
27 
28 #include <queue>
29 #include <string>
30 #include <vector>
31 
32 #include "webrtc/base/constructormagic.h"
33 #include "webrtc/modules/include/module_common_types.h"
34 #include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
35 #include "webrtc/typedefs.h"
36 
37 namespace webrtc {
38 
39 enum VP8PacketizerMode {
40   kStrict = 0,  // Split partitions if too large;
41                 // never aggregate, balance size.
42   kAggregate,   // Split partitions if too large; aggregate whole partitions.
43   kEqualSize,   // Split entire payload without considering partition limits.
44                 // This will produce equal size packets for the whole frame.
45   kNumModes,
46 };
47 
48 // Packetizer for VP8.
49 class RtpPacketizerVp8 : public RtpPacketizer {
50  public:
51   // Initialize with payload from encoder and fragmentation info.
52   // The payload_data must be exactly one encoded VP8 frame.
53   RtpPacketizerVp8(const RTPVideoHeaderVP8& hdr_info,
54                    size_t max_payload_len,
55                    VP8PacketizerMode mode);
56 
57   // Initialize without fragmentation info. Mode kEqualSize will be used.
58   // The payload_data must be exactly one encoded VP8 frame.
59   RtpPacketizerVp8(const RTPVideoHeaderVP8& hdr_info, size_t max_payload_len);
60 
61   virtual ~RtpPacketizerVp8();
62 
63   void SetPayloadData(const uint8_t* payload_data,
64                       size_t payload_size,
65                       const RTPFragmentationHeader* fragmentation) override;
66 
67   // Get the next payload with VP8 payload header.
68   // max_payload_len limits the sum length of payload and VP8 payload header.
69   // buffer is a pointer to where the output will be written.
70   // bytes_to_send is an output variable that will contain number of bytes
71   // written to buffer. Parameter last_packet is true for the last packet of
72   // the frame, false otherwise (i.e., call the function again to get the
73   // next packet).
74   // For the kStrict and kAggregate mode: returns the partition index from which
75   // the first payload byte in the packet is taken, with the first partition
76   // having index 0; returns negative on error.
77   // For the kEqualSize mode: returns 0 on success, return negative on error.
78   bool NextPacket(uint8_t* buffer,
79                   size_t* bytes_to_send,
80                   bool* last_packet) override;
81 
82   ProtectionType GetProtectionType() override;
83 
84   StorageType GetStorageType(uint32_t retransmission_settings) override;
85 
86   std::string ToString() override;
87 
88  private:
89   typedef struct {
90     size_t payload_start_pos;
91     size_t size;
92     bool first_fragment;
93     size_t first_partition_ix;
94   } InfoStruct;
95   typedef std::queue<InfoStruct> InfoQueue;
96   enum AggregationMode {
97     kAggrNone = 0,    // No aggregation.
98     kAggrPartitions,  // Aggregate intact partitions.
99     kAggrFragments    // Aggregate intact and fragmented partitions.
100   };
101 
102   static const AggregationMode aggr_modes_[kNumModes];
103   static const bool balance_modes_[kNumModes];
104   static const bool separate_first_modes_[kNumModes];
105   static const int kXBit = 0x80;
106   static const int kNBit = 0x20;
107   static const int kSBit = 0x10;
108   static const int kPartIdField = 0x0F;
109   static const int kKeyIdxField = 0x1F;
110   static const int kIBit = 0x80;
111   static const int kLBit = 0x40;
112   static const int kTBit = 0x20;
113   static const int kKBit = 0x10;
114   static const int kYBit = 0x20;
115 
116   // Calculate size of next chunk to send. Returns 0 if none can be sent.
117   size_t CalcNextSize(size_t max_payload_len,
118                       size_t remaining_bytes,
119                       bool split_payload) const;
120 
121   // Calculate all packet sizes and load to packet info queue.
122   int GeneratePackets();
123 
124   // Calculate all packet sizes using Vp8PartitionAggregator and load to packet
125   // info queue.
126   int GeneratePacketsBalancedAggregates();
127 
128   // Helper function to GeneratePacketsBalancedAggregates(). Find all
129   // continuous sets of partitions smaller than the max payload size (not
130   // max_size), and aggregate them into balanced packets. The result is written
131   // to partition_vec, which is of the same length as the number of partitions.
132   // A value of -1 indicates that the partition is too large and must be split.
133   // Aggregates are numbered 0, 1, 2, etc. For each set of small partitions,
134   // the aggregate numbers restart at 0. Output values min_size and max_size
135   // will hold the smallest and largest resulting aggregates (i.e., not counting
136   // those that must be split).
137   void AggregateSmallPartitions(std::vector<int>* partition_vec,
138                                 int* min_size,
139                                 int* max_size);
140 
141   // Insert packet into packet queue.
142   void QueuePacket(size_t start_pos,
143                    size_t packet_size,
144                    size_t first_partition_in_packet,
145                    bool start_on_new_fragment);
146 
147   // Write the payload header and copy the payload to the buffer.
148   // The info in packet_info determines which part of the payload is written
149   // and what to write in the header fields.
150   int WriteHeaderAndPayload(const InfoStruct& packet_info,
151                             uint8_t* buffer,
152                             size_t buffer_length) const;
153 
154   // Write the X field and the appropriate extension fields to buffer.
155   // The function returns the extension length (including X field), or -1
156   // on error.
157   int WriteExtensionFields(uint8_t* buffer, size_t buffer_length) const;
158 
159   // Set the I bit in the x_field, and write PictureID to the appropriate
160   // position in buffer. The function returns 0 on success, -1 otherwise.
161   int WritePictureIDFields(uint8_t* x_field,
162                            uint8_t* buffer,
163                            size_t buffer_length,
164                            size_t* extension_length) const;
165 
166   // Set the L bit in the x_field, and write Tl0PicIdx to the appropriate
167   // position in buffer. The function returns 0 on success, -1 otherwise.
168   int WriteTl0PicIdxFields(uint8_t* x_field,
169                            uint8_t* buffer,
170                            size_t buffer_length,
171                            size_t* extension_length) const;
172 
173   // Set the T and K bits in the x_field, and write TID, Y and KeyIdx to the
174   // appropriate position in buffer. The function returns 0 on success,
175   // -1 otherwise.
176   int WriteTIDAndKeyIdxFields(uint8_t* x_field,
177                               uint8_t* buffer,
178                               size_t buffer_length,
179                               size_t* extension_length) const;
180 
181   // Write the PictureID from codec_specific_info_ to buffer. One or two
182   // bytes are written, depending on magnitude of PictureID. The function
183   // returns the number of bytes written.
184   int WritePictureID(uint8_t* buffer, size_t buffer_length) const;
185 
186   // Calculate and return length (octets) of the variable header fields in
187   // the next header (i.e., header length in addition to vp8_header_bytes_).
188   size_t PayloadDescriptorExtraLength() const;
189 
190   // Calculate and return length (octets) of PictureID field in the next
191   // header. Can be 0, 1, or 2.
192   size_t PictureIdLength() const;
193 
194   // Check whether each of the optional fields will be included in the header.
195   bool XFieldPresent() const;
196   bool TIDFieldPresent() const;
197   bool KeyIdxFieldPresent() const;
198   bool TL0PicIdxFieldPresent() const;
PictureIdPresent()199   bool PictureIdPresent() const { return (PictureIdLength() > 0); }
200 
201   const uint8_t* payload_data_;
202   size_t payload_size_;
203   RTPFragmentationHeader part_info_;
204   const size_t vp8_fixed_payload_descriptor_bytes_;  // Length of VP8 payload
205                                                      // descriptors' fixed part.
206   const AggregationMode aggr_mode_;
207   const bool balance_;
208   const bool separate_first_;
209   const RTPVideoHeaderVP8 hdr_info_;
210   size_t num_partitions_;
211   const size_t max_payload_len_;
212   InfoQueue packets_;
213   bool packets_calculated_;
214 
215   RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerVp8);
216 };
217 
218 // Depacketizer for VP8.
219 class RtpDepacketizerVp8 : public RtpDepacketizer {
220  public:
~RtpDepacketizerVp8()221   virtual ~RtpDepacketizerVp8() {}
222 
223   bool Parse(ParsedPayload* parsed_payload,
224              const uint8_t* payload_data,
225              size_t payload_data_length) override;
226 };
227 }  // namespace webrtc
228 #endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
229