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 MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
26 #define MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
27 
28 #include <queue>
29 #include <string>
30 #include <vector>
31 
32 #include "modules/include/module_common_types.h"
33 #include "modules/rtp_rtcp/source/rtp_format.h"
34 #include "rtc_base/constructormagic.h"
35 #include "typedefs.h"  // NOLINT(build/include)
36 
37 namespace webrtc {
38 
39 // Packetizer for VP8.
40 class RtpPacketizerVp8 : public RtpPacketizer {
41  public:
42   // Initialize with payload from encoder.
43   // The payload_data must be exactly one encoded VP8 frame.
44   RtpPacketizerVp8(const RTPVideoHeaderVP8& hdr_info,
45                    size_t max_payload_len,
46                    size_t last_packet_reduction_len);
47 
48   virtual ~RtpPacketizerVp8();
49 
50   size_t SetPayloadData(const uint8_t* payload_data,
51                         size_t payload_size,
52                         const RTPFragmentationHeader* fragmentation) override;
53 
54   // Get the next payload with VP8 payload header.
55   // Write payload and set marker bit of the |packet|.
56   // Returns true on success, false otherwise.
57   bool NextPacket(RtpPacketToSend* packet) override;
58 
59   std::string ToString() override;
60 
61  private:
62   typedef struct {
63     size_t payload_start_pos;
64     size_t size;
65     bool first_packet;
66   } InfoStruct;
67   typedef std::queue<InfoStruct> InfoQueue;
68 
69   static const int kXBit = 0x80;
70   static const int kNBit = 0x20;
71   static const int kSBit = 0x10;
72   static const int kPartIdField = 0x0F;
73   static const int kKeyIdxField = 0x1F;
74   static const int kIBit = 0x80;
75   static const int kLBit = 0x40;
76   static const int kTBit = 0x20;
77   static const int kKBit = 0x10;
78   static const int kYBit = 0x20;
79 
80   // Calculate all packet sizes and load to packet info queue.
81   int GeneratePackets();
82 
83   // Splits given part of payload to packets with a given capacity. The last
84   // packet should be reduced by last_packet_reduction_len_.
85   void GeneratePacketsSplitPayloadBalanced(size_t payload_len,
86                                            size_t capacity);
87 
88   // Insert packet into packet queue.
89   void QueuePacket(size_t start_pos,
90                    size_t packet_size,
91                    bool first_packet);
92 
93   // Write the payload header and copy the payload to the buffer.
94   // The info in packet_info determines which part of the payload is written
95   // and what to write in the header fields.
96   int WriteHeaderAndPayload(const InfoStruct& packet_info,
97                             uint8_t* buffer,
98                             size_t buffer_length) const;
99 
100   // Write the X field and the appropriate extension fields to buffer.
101   // The function returns the extension length (including X field), or -1
102   // on error.
103   int WriteExtensionFields(uint8_t* buffer, size_t buffer_length) const;
104 
105   // Set the I bit in the x_field, and write PictureID to the appropriate
106   // position in buffer. The function returns 0 on success, -1 otherwise.
107   int WritePictureIDFields(uint8_t* x_field,
108                            uint8_t* buffer,
109                            size_t buffer_length,
110                            size_t* extension_length) const;
111 
112   // Set the L bit in the x_field, and write Tl0PicIdx to the appropriate
113   // position in buffer. The function returns 0 on success, -1 otherwise.
114   int WriteTl0PicIdxFields(uint8_t* x_field,
115                            uint8_t* buffer,
116                            size_t buffer_length,
117                            size_t* extension_length) const;
118 
119   // Set the T and K bits in the x_field, and write TID, Y and KeyIdx to the
120   // appropriate position in buffer. The function returns 0 on success,
121   // -1 otherwise.
122   int WriteTIDAndKeyIdxFields(uint8_t* x_field,
123                               uint8_t* buffer,
124                               size_t buffer_length,
125                               size_t* extension_length) const;
126 
127   // Write the PictureID from codec_specific_info_ to buffer. One or two
128   // bytes are written, depending on magnitude of PictureID. The function
129   // returns the number of bytes written.
130   int WritePictureID(uint8_t* buffer, size_t buffer_length) const;
131 
132   // Calculate and return length (octets) of the variable header fields in
133   // the next header (i.e., header length in addition to vp8_header_bytes_).
134   size_t PayloadDescriptorExtraLength() const;
135 
136   // Calculate and return length (octets) of PictureID field in the next
137   // header. Can be 0, 1, or 2.
138   size_t PictureIdLength() const;
139 
140   // Check whether each of the optional fields will be included in the header.
141   bool XFieldPresent() const;
142   bool TIDFieldPresent() const;
143   bool KeyIdxFieldPresent() const;
144   bool TL0PicIdxFieldPresent() const;
PictureIdPresent()145   bool PictureIdPresent() const { return (PictureIdLength() > 0); }
146 
147   const uint8_t* payload_data_;
148   size_t payload_size_;
149   const size_t vp8_fixed_payload_descriptor_bytes_;  // Length of VP8 payload
150                                                      // descriptors' fixed part.
151   const RTPVideoHeaderVP8 hdr_info_;
152   const size_t max_payload_len_;
153   const size_t last_packet_reduction_len_;
154   InfoQueue packets_;
155 
156   RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerVp8);
157 };
158 
159 // Depacketizer for VP8.
160 class RtpDepacketizerVp8 : public RtpDepacketizer {
161  public:
~RtpDepacketizerVp8()162   virtual ~RtpDepacketizerVp8() {}
163 
164   bool Parse(ParsedPayload* parsed_payload,
165              const uint8_t* payload_data,
166              size_t payload_data_length) override;
167 };
168 }  // namespace webrtc
169 #endif  // MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
170