Line data Source code
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 : // Write payload and set marker bit of the |packet|.
69 : // The parameter |last_packet| is true for the last packet of the frame, false
70 : // otherwise (i.e., call the function again to get the next packet).
71 : // Returns true on success, false otherwise.
72 : bool NextPacket(RtpPacketToSend* packet, bool* last_packet) override;
73 :
74 : ProtectionType GetProtectionType() override;
75 :
76 : StorageType GetStorageType(uint32_t retransmission_settings) override;
77 :
78 : std::string ToString() override;
79 :
80 : private:
81 : typedef struct {
82 : size_t payload_start_pos;
83 : size_t size;
84 : bool first_fragment;
85 : size_t first_partition_ix;
86 : } InfoStruct;
87 : typedef std::queue<InfoStruct> InfoQueue;
88 : enum AggregationMode {
89 : kAggrNone = 0, // No aggregation.
90 : kAggrPartitions, // Aggregate intact partitions.
91 : kAggrFragments // Aggregate intact and fragmented partitions.
92 : };
93 :
94 : static const AggregationMode aggr_modes_[kNumModes];
95 : static const bool balance_modes_[kNumModes];
96 : static const bool separate_first_modes_[kNumModes];
97 : static const int kXBit = 0x80;
98 : static const int kNBit = 0x20;
99 : static const int kSBit = 0x10;
100 : static const int kPartIdField = 0x0F;
101 : static const int kKeyIdxField = 0x1F;
102 : static const int kIBit = 0x80;
103 : static const int kLBit = 0x40;
104 : static const int kTBit = 0x20;
105 : static const int kKBit = 0x10;
106 : static const int kYBit = 0x20;
107 :
108 : // Calculate size of next chunk to send. Returns 0 if none can be sent.
109 : size_t CalcNextSize(size_t max_payload_len,
110 : size_t remaining_bytes,
111 : bool split_payload) const;
112 :
113 : // Calculate all packet sizes and load to packet info queue.
114 : int GeneratePackets();
115 :
116 : // Calculate all packet sizes using Vp8PartitionAggregator and load to packet
117 : // info queue.
118 : int GeneratePacketsBalancedAggregates();
119 :
120 : // Helper function to GeneratePacketsBalancedAggregates(). Find all
121 : // continuous sets of partitions smaller than the max payload size (not
122 : // max_size), and aggregate them into balanced packets. The result is written
123 : // to partition_vec, which is of the same length as the number of partitions.
124 : // A value of -1 indicates that the partition is too large and must be split.
125 : // Aggregates are numbered 0, 1, 2, etc. For each set of small partitions,
126 : // the aggregate numbers restart at 0. Output values min_size and max_size
127 : // will hold the smallest and largest resulting aggregates (i.e., not counting
128 : // those that must be split).
129 : void AggregateSmallPartitions(std::vector<int>* partition_vec,
130 : int* min_size,
131 : int* max_size);
132 :
133 : // Insert packet into packet queue.
134 : void QueuePacket(size_t start_pos,
135 : size_t packet_size,
136 : size_t first_partition_in_packet,
137 : bool start_on_new_fragment);
138 :
139 : // Write the payload header and copy the payload to the buffer.
140 : // The info in packet_info determines which part of the payload is written
141 : // and what to write in the header fields.
142 : int WriteHeaderAndPayload(const InfoStruct& packet_info,
143 : uint8_t* buffer,
144 : size_t buffer_length) const;
145 :
146 : // Write the X field and the appropriate extension fields to buffer.
147 : // The function returns the extension length (including X field), or -1
148 : // on error.
149 : int WriteExtensionFields(uint8_t* buffer, size_t buffer_length) const;
150 :
151 : // Set the I bit in the x_field, and write PictureID to the appropriate
152 : // position in buffer. The function returns 0 on success, -1 otherwise.
153 : int WritePictureIDFields(uint8_t* x_field,
154 : uint8_t* buffer,
155 : size_t buffer_length,
156 : size_t* 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,
161 : uint8_t* buffer,
162 : size_t buffer_length,
163 : size_t* extension_length) const;
164 :
165 : // Set the T and K bits in the x_field, and write TID, Y and KeyIdx to the
166 : // appropriate position in buffer. The function returns 0 on success,
167 : // -1 otherwise.
168 : int WriteTIDAndKeyIdxFields(uint8_t* x_field,
169 : uint8_t* buffer,
170 : size_t buffer_length,
171 : size_t* extension_length) const;
172 :
173 : // Write the PictureID from codec_specific_info_ to buffer. One or two
174 : // bytes are written, depending on magnitude of PictureID. The function
175 : // returns the number of bytes written.
176 : int WritePictureID(uint8_t* buffer, size_t buffer_length) const;
177 :
178 : // Calculate and return length (octets) of the variable header fields in
179 : // the next header (i.e., header length in addition to vp8_header_bytes_).
180 : size_t PayloadDescriptorExtraLength() const;
181 :
182 : // Calculate and return length (octets) of PictureID field in the next
183 : // header. Can be 0, 1, or 2.
184 : size_t PictureIdLength() const;
185 :
186 : // Check whether each of the optional fields will be included in the header.
187 : bool XFieldPresent() const;
188 : bool TIDFieldPresent() const;
189 : bool KeyIdxFieldPresent() const;
190 : bool TL0PicIdxFieldPresent() const;
191 0 : bool PictureIdPresent() const { return (PictureIdLength() > 0); }
192 :
193 : const uint8_t* payload_data_;
194 : size_t payload_size_;
195 : RTPFragmentationHeader part_info_;
196 : const size_t vp8_fixed_payload_descriptor_bytes_; // Length of VP8 payload
197 : // descriptors' fixed part.
198 : const AggregationMode aggr_mode_;
199 : const bool balance_;
200 : const bool separate_first_;
201 : const RTPVideoHeaderVP8 hdr_info_;
202 : size_t num_partitions_;
203 : const size_t max_payload_len_;
204 : InfoQueue packets_;
205 : bool packets_calculated_;
206 :
207 : RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerVp8);
208 : };
209 :
210 : // Depacketizer for VP8.
211 0 : class RtpDepacketizerVp8 : public RtpDepacketizer {
212 : public:
213 0 : virtual ~RtpDepacketizerVp8() {}
214 :
215 : bool Parse(ParsedPayload* parsed_payload,
216 : const uint8_t* payload_data,
217 : size_t payload_data_length) override;
218 : };
219 : } // namespace webrtc
220 : #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
|