2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
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.
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.
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.
25 #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
26 #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
31 #include "webrtc/base/constructormagic.h"
32 #include "webrtc/modules/interface/module_common_types.h"
33 #include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
34 #include "webrtc/typedefs.h"
38 enum VP8PacketizerMode {
39 kStrict = 0, // Split partitions if too large;
40 // never aggregate, balance size.
41 kAggregate, // Split partitions if too large; aggregate whole partitions.
42 kEqualSize, // Split entire payload without considering partition limits.
43 // This will produce equal size packets for the whole frame.
47 // Packetizer for VP8.
48 class RtpPacketizerVp8 : public RtpPacketizer {
50 // Initialize with payload from encoder and fragmentation info.
51 // The payload_data must be exactly one encoded VP8 frame.
52 RtpPacketizerVp8(const RTPVideoHeaderVP8& hdr_info,
54 VP8PacketizerMode mode);
56 // Initialize without fragmentation info. Mode kEqualSize will be used.
57 // The payload_data must be exactly one encoded VP8 frame.
58 RtpPacketizerVp8(const RTPVideoHeaderVP8& hdr_info, int max_payload_len);
60 virtual ~RtpPacketizerVp8();
62 virtual void SetPayloadData(
63 const uint8_t* payload_data,
65 const RTPFragmentationHeader* fragmentation) OVERRIDE;
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
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 virtual bool NextPacket(uint8_t* buffer,
79 size_t* bytes_to_send,
80 bool* last_packet) OVERRIDE;
82 virtual ProtectionType GetProtectionType() OVERRIDE;
84 virtual StorageType GetStorageType(uint32_t retransmission_settings) OVERRIDE;
86 virtual std::string ToString() OVERRIDE;
90 int payload_start_pos;
93 int first_partition_ix;
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.
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;
116 // Calculate size of next chunk to send. Returns 0 if none can be sent.
117 int CalcNextSize(int max_payload_len,
119 bool split_payload) const;
121 // Calculate all packet sizes and load to packet info queue.
122 int GeneratePackets();
124 // Calculate all packet sizes using Vp8PartitionAggregator and load to packet
126 int GeneratePacketsBalancedAggregates();
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,
141 // Insert packet into packet queue.
142 void QueuePacket(int start_pos,
144 int first_partition_in_packet,
145 bool start_on_new_fragment);
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,
152 int buffer_length) const;
154 // Write the X field and the appropriate extension fields to buffer.
155 // The function returns the extension length (including X field), or -1
157 int WriteExtensionFields(uint8_t* buffer, int buffer_length) const;
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,
164 int* extension_length) const;
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,
171 int* extension_length) const;
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,
176 int WriteTIDAndKeyIdxFields(uint8_t* x_field,
179 int* extension_length) const;
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, int buffer_length) const;
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 int PayloadDescriptorExtraLength() const;
190 // Calculate and return length (octets) of PictureID field in the next
191 // header. Can be 0, 1, or 2.
192 int PictureIdLength() const;
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;
199 bool PictureIdPresent() const { return (PictureIdLength() > 0); }
201 const uint8_t* payload_data_;
203 RTPFragmentationHeader part_info_;
204 const int vp8_fixed_payload_descriptor_bytes_; // Length of VP8 payload
205 // descriptors's fixed part.
206 const AggregationMode aggr_mode_;
208 const bool separate_first_;
209 const RTPVideoHeaderVP8 hdr_info_;
211 const int max_payload_len_;
213 bool packets_calculated_;
215 DISALLOW_COPY_AND_ASSIGN(RtpPacketizerVp8);
218 // Depacketizer for VP8.
219 class RtpDepacketizerVp8 : public RtpDepacketizer {
221 explicit RtpDepacketizerVp8(RtpData* const callback);
223 virtual ~RtpDepacketizerVp8() {}
225 virtual bool Parse(WebRtcRTPHeader* rtp_header,
226 const uint8_t* payload_data,
227 size_t payload_data_length) OVERRIDE;
230 RtpData* const callback_;
232 DISALLOW_COPY_AND_ASSIGN(RtpDepacketizerVp8);
234 } // namespace webrtc
235 #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_