rtp_format_vp8.h revision 88fbb2d86b33a3886bba1af4d098efa2c19eb1e7
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 <vector>
30
31#include "webrtc/base/constructormagic.h"
32#include "webrtc/modules/interface/module_common_types.h"
33#include "webrtc/typedefs.h"
34
35namespace webrtc {
36
37enum VP8PacketizerMode {
38  kStrict = 0,  // Split partitions if too large;
39                // never aggregate, balance size.
40  kAggregate,   // Split partitions if too large; aggregate whole partitions.
41  kEqualSize,   // Split entire payload without considering partition limits.
42                // This will produce equal size packets for the whole frame.
43  kNumModes,
44};
45
46// Packetizer for VP8.
47class RtpFormatVp8 {
48 public:
49  // Initialize with payload from encoder and fragmentation info.
50  // The payload_data must be exactly one encoded VP8 frame.
51  RtpFormatVp8(const uint8_t* payload_data,
52               uint32_t payload_size,
53               const RTPVideoHeaderVP8& hdr_info,
54               int max_payload_len,
55               const RTPFragmentationHeader& fragmentation,
56               VP8PacketizerMode mode);
57
58  // Initialize without fragmentation info. Mode kEqualSize will be used.
59  // The payload_data must be exactly one encoded VP8 frame.
60  RtpFormatVp8(const uint8_t* payload_data,
61               uint32_t payload_size,
62               const RTPVideoHeaderVP8& hdr_info,
63               int max_payload_len);
64
65  ~RtpFormatVp8();
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  int NextPacket(uint8_t* buffer,
79                 int* bytes_to_send,
80                 bool* last_packet);
81
82 private:
83  typedef struct {
84    int payload_start_pos;
85    int size;
86    bool first_fragment;
87    int first_partition_ix;
88  } InfoStruct;
89  typedef std::queue<InfoStruct> InfoQueue;
90  enum AggregationMode {
91    kAggrNone = 0,    // No aggregation.
92    kAggrPartitions,  // Aggregate intact partitions.
93    kAggrFragments    // Aggregate intact and fragmented partitions.
94  };
95
96  static const AggregationMode aggr_modes_[kNumModes];
97  static const bool balance_modes_[kNumModes];
98  static const bool separate_first_modes_[kNumModes];
99  static const int kXBit        = 0x80;
100  static const int kNBit        = 0x20;
101  static const int kSBit        = 0x10;
102  static const int kPartIdField = 0x0F;
103  static const int kKeyIdxField = 0x1F;
104  static const int kIBit        = 0x80;
105  static const int kLBit        = 0x40;
106  static const int kTBit        = 0x20;
107  static const int kKBit        = 0x10;
108  static const int kYBit        = 0x20;
109
110  // Calculate size of next chunk to send. Returns 0 if none can be sent.
111  int CalcNextSize(int max_payload_len, int remaining_bytes,
112                   bool split_payload) const;
113
114  // Calculate all packet sizes and load to packet info queue.
115  int GeneratePackets();
116
117  // Calculate all packet sizes using Vp8PartitionAggregator and load to packet
118  // info queue.
119  int GeneratePacketsBalancedAggregates();
120
121  // Helper function to GeneratePacketsBalancedAggregates(). Find all
122  // continuous sets of partitions smaller than the max payload size (not
123  // max_size), and aggregate them into balanced packets. The result is written
124  // to partition_vec, which is of the same length as the number of partitions.
125  // A value of -1 indicates that the partition is too large and must be split.
126  // Aggregates are numbered 0, 1, 2, etc. For each set of small partitions,
127  // the aggregate numbers restart at 0. Output values min_size and max_size
128  // will hold the smallest and largest resulting aggregates (i.e., not counting
129  // those that must be split).
130  void AggregateSmallPartitions(std::vector<int>* partition_vec,
131                                int* min_size,
132                                int* max_size);
133
134  // Insert packet into packet queue.
135  void QueuePacket(int start_pos,
136                   int packet_size,
137                   int first_partition_in_packet,
138                   bool start_on_new_fragment);
139
140  // Write the payload header and copy the payload to the buffer.
141  // The info in packet_info determines which part of the payload is written
142  // and what to write in the header fields.
143  int WriteHeaderAndPayload(const InfoStruct& packet_info,
144                            uint8_t* buffer,
145                            int buffer_length) const;
146
147
148  // Write the X field and the appropriate extension fields to buffer.
149  // The function returns the extension length (including X field), or -1
150  // on error.
151  int WriteExtensionFields(uint8_t* buffer, int buffer_length) const;
152
153  // Set the I bit in the x_field, and write PictureID to the appropriate
154  // position in buffer. The function returns 0 on success, -1 otherwise.
155  int WritePictureIDFields(uint8_t* x_field, uint8_t* buffer,
156                           int buffer_length, int* extension_length) const;
157
158  // Set the L bit in the x_field, and write Tl0PicIdx to the appropriate
159  // position in buffer. The function returns 0 on success, -1 otherwise.
160  int WriteTl0PicIdxFields(uint8_t* x_field, uint8_t* buffer,
161                           int buffer_length, int* extension_length) const;
162
163  // Set the T and K bits in the x_field, and write TID, Y and KeyIdx to the
164  // appropriate position in buffer. The function returns 0 on success,
165  // -1 otherwise.
166  int WriteTIDAndKeyIdxFields(uint8_t* x_field, uint8_t* buffer,
167                              int buffer_length, int* extension_length) const;
168
169  // Write the PictureID from codec_specific_info_ to buffer. One or two
170  // bytes are written, depending on magnitude of PictureID. The function
171  // returns the number of bytes written.
172  int WritePictureID(uint8_t* buffer, int buffer_length) const;
173
174  // Calculate and return length (octets) of the variable header fields in
175  // the next header (i.e., header length in addition to vp8_header_bytes_).
176  int PayloadDescriptorExtraLength() const;
177
178  // Calculate and return length (octets) of PictureID field in the next
179  // header. Can be 0, 1, or 2.
180  int PictureIdLength() const;
181
182  // Check whether each of the optional fields will be included in the header.
183  bool XFieldPresent() const;
184  bool TIDFieldPresent() const;
185  bool KeyIdxFieldPresent() const;
186  bool TL0PicIdxFieldPresent() const;
187  bool PictureIdPresent() const { return (PictureIdLength() > 0); }
188
189  const uint8_t* payload_data_;
190  const int payload_size_;
191  RTPFragmentationHeader part_info_;
192  const int vp8_fixed_payload_descriptor_bytes_;  // Length of VP8 payload
193                                                  // descriptors's fixed part.
194  const AggregationMode aggr_mode_;
195  const bool balance_;
196  const bool separate_first_;
197  const RTPVideoHeaderVP8 hdr_info_;
198  const int num_partitions_;
199  const int max_payload_len_;
200  InfoQueue packets_;
201  bool packets_calculated_;
202
203  DISALLOW_COPY_AND_ASSIGN(RtpFormatVp8);
204};
205
206}  // namespace
207
208#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
209