aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h
diff options
context:
space:
mode:
Diffstat (limited to 'webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h')
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h228
1 files changed, 228 insertions, 0 deletions
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h b/webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h
new file mode 100644
index 0000000000..63db349c74
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * This file contains the declaration of the VP8 packetizer class.
+ * A packetizer object is created for each encoded video frame. The
+ * constructor is called with the payload data and size,
+ * together with the fragmentation information and a packetizer mode
+ * of choice. Alternatively, if no fragmentation info is available, the
+ * second constructor can be used with only payload data and size; in that
+ * case the mode kEqualSize is used.
+ *
+ * After creating the packetizer, the method NextPacket is called
+ * repeatedly to get all packets for the frame. The method returns
+ * false as long as there are more packets left to fetch.
+ */
+
+#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
+
+#include <queue>
+#include <string>
+#include <vector>
+
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+
+enum VP8PacketizerMode {
+ kStrict = 0, // Split partitions if too large;
+ // never aggregate, balance size.
+ kAggregate, // Split partitions if too large; aggregate whole partitions.
+ kEqualSize, // Split entire payload without considering partition limits.
+ // This will produce equal size packets for the whole frame.
+ kNumModes,
+};
+
+// Packetizer for VP8.
+class RtpPacketizerVp8 : public RtpPacketizer {
+ public:
+ // Initialize with payload from encoder and fragmentation info.
+ // The payload_data must be exactly one encoded VP8 frame.
+ RtpPacketizerVp8(const RTPVideoHeaderVP8& hdr_info,
+ size_t max_payload_len,
+ VP8PacketizerMode mode);
+
+ // Initialize without fragmentation info. Mode kEqualSize will be used.
+ // The payload_data must be exactly one encoded VP8 frame.
+ RtpPacketizerVp8(const RTPVideoHeaderVP8& hdr_info, size_t max_payload_len);
+
+ virtual ~RtpPacketizerVp8();
+
+ void SetPayloadData(const uint8_t* payload_data,
+ size_t payload_size,
+ const RTPFragmentationHeader* fragmentation) override;
+
+ // Get the next payload with VP8 payload header.
+ // max_payload_len limits the sum length of payload and VP8 payload header.
+ // buffer is a pointer to where the output will be written.
+ // bytes_to_send is an output variable that will contain number of bytes
+ // written to buffer. Parameter last_packet is true for the last packet of
+ // the frame, false otherwise (i.e., call the function again to get the
+ // next packet).
+ // For the kStrict and kAggregate mode: returns the partition index from which
+ // the first payload byte in the packet is taken, with the first partition
+ // having index 0; returns negative on error.
+ // For the kEqualSize mode: returns 0 on success, return negative on error.
+ bool NextPacket(uint8_t* buffer,
+ size_t* bytes_to_send,
+ bool* last_packet) override;
+
+ ProtectionType GetProtectionType() override;
+
+ StorageType GetStorageType(uint32_t retransmission_settings) override;
+
+ std::string ToString() override;
+
+ private:
+ typedef struct {
+ size_t payload_start_pos;
+ size_t size;
+ bool first_fragment;
+ size_t first_partition_ix;
+ } InfoStruct;
+ typedef std::queue<InfoStruct> InfoQueue;
+ enum AggregationMode {
+ kAggrNone = 0, // No aggregation.
+ kAggrPartitions, // Aggregate intact partitions.
+ kAggrFragments // Aggregate intact and fragmented partitions.
+ };
+
+ static const AggregationMode aggr_modes_[kNumModes];
+ static const bool balance_modes_[kNumModes];
+ static const bool separate_first_modes_[kNumModes];
+ static const int kXBit = 0x80;
+ static const int kNBit = 0x20;
+ static const int kSBit = 0x10;
+ static const int kPartIdField = 0x0F;
+ static const int kKeyIdxField = 0x1F;
+ static const int kIBit = 0x80;
+ static const int kLBit = 0x40;
+ static const int kTBit = 0x20;
+ static const int kKBit = 0x10;
+ static const int kYBit = 0x20;
+
+ // Calculate size of next chunk to send. Returns 0 if none can be sent.
+ size_t CalcNextSize(size_t max_payload_len,
+ size_t remaining_bytes,
+ bool split_payload) const;
+
+ // Calculate all packet sizes and load to packet info queue.
+ int GeneratePackets();
+
+ // Calculate all packet sizes using Vp8PartitionAggregator and load to packet
+ // info queue.
+ int GeneratePacketsBalancedAggregates();
+
+ // Helper function to GeneratePacketsBalancedAggregates(). Find all
+ // continuous sets of partitions smaller than the max payload size (not
+ // max_size), and aggregate them into balanced packets. The result is written
+ // to partition_vec, which is of the same length as the number of partitions.
+ // A value of -1 indicates that the partition is too large and must be split.
+ // Aggregates are numbered 0, 1, 2, etc. For each set of small partitions,
+ // the aggregate numbers restart at 0. Output values min_size and max_size
+ // will hold the smallest and largest resulting aggregates (i.e., not counting
+ // those that must be split).
+ void AggregateSmallPartitions(std::vector<int>* partition_vec,
+ int* min_size,
+ int* max_size);
+
+ // Insert packet into packet queue.
+ void QueuePacket(size_t start_pos,
+ size_t packet_size,
+ size_t first_partition_in_packet,
+ bool start_on_new_fragment);
+
+ // Write the payload header and copy the payload to the buffer.
+ // The info in packet_info determines which part of the payload is written
+ // and what to write in the header fields.
+ int WriteHeaderAndPayload(const InfoStruct& packet_info,
+ uint8_t* buffer,
+ size_t buffer_length) const;
+
+ // Write the X field and the appropriate extension fields to buffer.
+ // The function returns the extension length (including X field), or -1
+ // on error.
+ int WriteExtensionFields(uint8_t* buffer, size_t buffer_length) const;
+
+ // Set the I bit in the x_field, and write PictureID to the appropriate
+ // position in buffer. The function returns 0 on success, -1 otherwise.
+ int WritePictureIDFields(uint8_t* x_field,
+ uint8_t* buffer,
+ size_t buffer_length,
+ size_t* extension_length) const;
+
+ // Set the L bit in the x_field, and write Tl0PicIdx to the appropriate
+ // position in buffer. The function returns 0 on success, -1 otherwise.
+ int WriteTl0PicIdxFields(uint8_t* x_field,
+ uint8_t* buffer,
+ size_t buffer_length,
+ size_t* extension_length) const;
+
+ // Set the T and K bits in the x_field, and write TID, Y and KeyIdx to the
+ // appropriate position in buffer. The function returns 0 on success,
+ // -1 otherwise.
+ int WriteTIDAndKeyIdxFields(uint8_t* x_field,
+ uint8_t* buffer,
+ size_t buffer_length,
+ size_t* extension_length) const;
+
+ // Write the PictureID from codec_specific_info_ to buffer. One or two
+ // bytes are written, depending on magnitude of PictureID. The function
+ // returns the number of bytes written.
+ int WritePictureID(uint8_t* buffer, size_t buffer_length) const;
+
+ // Calculate and return length (octets) of the variable header fields in
+ // the next header (i.e., header length in addition to vp8_header_bytes_).
+ size_t PayloadDescriptorExtraLength() const;
+
+ // Calculate and return length (octets) of PictureID field in the next
+ // header. Can be 0, 1, or 2.
+ size_t PictureIdLength() const;
+
+ // Check whether each of the optional fields will be included in the header.
+ bool XFieldPresent() const;
+ bool TIDFieldPresent() const;
+ bool KeyIdxFieldPresent() const;
+ bool TL0PicIdxFieldPresent() const;
+ bool PictureIdPresent() const { return (PictureIdLength() > 0); }
+
+ const uint8_t* payload_data_;
+ size_t payload_size_;
+ RTPFragmentationHeader part_info_;
+ const size_t vp8_fixed_payload_descriptor_bytes_; // Length of VP8 payload
+ // descriptors' fixed part.
+ const AggregationMode aggr_mode_;
+ const bool balance_;
+ const bool separate_first_;
+ const RTPVideoHeaderVP8 hdr_info_;
+ size_t num_partitions_;
+ const size_t max_payload_len_;
+ InfoQueue packets_;
+ bool packets_calculated_;
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerVp8);
+};
+
+// Depacketizer for VP8.
+class RtpDepacketizerVp8 : public RtpDepacketizer {
+ public:
+ virtual ~RtpDepacketizerVp8() {}
+
+ bool Parse(ParsedPayload* parsed_payload,
+ const uint8_t* payload_data,
+ size_t payload_data_length) override;
+};
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_