Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(369)

Unified Diff: webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc

Issue 2871173008: Fix packetization logic to leave space for extensions in the last packet (Closed)
Patch Set: Impelement Danilchap@ comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc
diff --git a/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc b/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc
deleted file mode 100644
index 9721a7e9ac5b5b0058d3a7159aed678e8af4958a..0000000000000000000000000000000000000000
--- a/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (c) 2012 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.
- */
-
-#include "webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.h"
-
-#include <assert.h>
-#include <stdlib.h> // NULL
-
-#include <algorithm>
-#include <limits>
-
-namespace webrtc {
-
-PartitionTreeNode::PartitionTreeNode(PartitionTreeNode* parent,
- const size_t* size_vector,
- size_t num_partitions,
- size_t this_size)
- : parent_(parent),
- this_size_(this_size),
- size_vector_(size_vector),
- num_partitions_(num_partitions),
- max_parent_size_(0),
- min_parent_size_(std::numeric_limits<int>::max()),
- packet_start_(false) {
- // If |this_size_| > INT_MAX, Cost() and CreateChildren() won't work properly.
- assert(this_size_ <= static_cast<size_t>(std::numeric_limits<int>::max()));
- children_[kLeftChild] = NULL;
- children_[kRightChild] = NULL;
-}
-
-PartitionTreeNode* PartitionTreeNode::CreateRootNode(const size_t* size_vector,
- size_t num_partitions) {
- PartitionTreeNode* root_node = new PartitionTreeNode(
- NULL, &size_vector[1], num_partitions - 1, size_vector[0]);
- root_node->set_packet_start(true);
- return root_node;
-}
-
-PartitionTreeNode::~PartitionTreeNode() {
- delete children_[kLeftChild];
- delete children_[kRightChild];
-}
-
-int PartitionTreeNode::Cost(size_t penalty) {
- int cost = 0;
- if (num_partitions_ == 0) {
- // This is a solution node.
- cost = std::max(max_parent_size_, this_size_int()) -
- std::min(min_parent_size_, this_size_int());
- } else {
- cost = std::max(max_parent_size_, this_size_int()) - min_parent_size_;
- }
- return cost + NumPackets() * penalty;
-}
-
-bool PartitionTreeNode::CreateChildren(size_t max_size) {
- assert(max_size > 0);
- bool children_created = false;
- if (num_partitions_ > 0) {
- if (this_size_ + size_vector_[0] <= max_size) {
- assert(!children_[kLeftChild]);
- children_[kLeftChild] =
- new PartitionTreeNode(this, &size_vector_[1], num_partitions_ - 1,
- this_size_ + size_vector_[0]);
- children_[kLeftChild]->set_max_parent_size(max_parent_size_);
- children_[kLeftChild]->set_min_parent_size(min_parent_size_);
- // "Left" child is continuation of same packet.
- children_[kLeftChild]->set_packet_start(false);
- children_created = true;
- }
- if (this_size_ > 0) {
- assert(!children_[kRightChild]);
- children_[kRightChild] = new PartitionTreeNode(
- this, &size_vector_[1], num_partitions_ - 1, size_vector_[0]);
- children_[kRightChild]->set_max_parent_size(
- std::max(max_parent_size_, this_size_int()));
- children_[kRightChild]->set_min_parent_size(
- std::min(min_parent_size_, this_size_int()));
- // "Right" child starts a new packet.
- children_[kRightChild]->set_packet_start(true);
- children_created = true;
- }
- }
- return children_created;
-}
-
-size_t PartitionTreeNode::NumPackets() {
- if (parent_ == NULL) {
- // Root node is a "right" child by definition.
- return 1;
- }
- if (parent_->children_[kLeftChild] == this) {
- // This is a "left" child.
- return parent_->NumPackets();
- } else {
- // This is a "right" child.
- return 1 + parent_->NumPackets();
- }
-}
-
-PartitionTreeNode* PartitionTreeNode::GetOptimalNode(size_t max_size,
- size_t penalty) {
- CreateChildren(max_size);
- PartitionTreeNode* left = children_[kLeftChild];
- PartitionTreeNode* right = children_[kRightChild];
- if ((left == NULL) && (right == NULL)) {
- // This is a solution node; return it.
- return this;
- } else if (left == NULL) {
- // One child empty, return the other.
- return right->GetOptimalNode(max_size, penalty);
- } else if (right == NULL) {
- // One child empty, return the other.
- return left->GetOptimalNode(max_size, penalty);
- } else {
- PartitionTreeNode* first;
- PartitionTreeNode* second;
- if (left->Cost(penalty) <= right->Cost(penalty)) {
- first = left;
- second = right;
- } else {
- first = right;
- second = left;
- }
- first = first->GetOptimalNode(max_size, penalty);
- if (second->Cost(penalty) <= first->Cost(penalty)) {
- second = second->GetOptimalNode(max_size, penalty);
- // Compare cost estimate for "second" with actual cost for "first".
- if (second->Cost(penalty) < first->Cost(penalty)) {
- return second;
- }
- }
- return first;
- }
-}
-
-Vp8PartitionAggregator::Vp8PartitionAggregator(
- const RTPFragmentationHeader& fragmentation,
- size_t first_partition_idx,
- size_t last_partition_idx)
- : root_(NULL),
- num_partitions_(last_partition_idx - first_partition_idx + 1),
- size_vector_(new size_t[num_partitions_]),
- largest_partition_size_(0) {
- assert(last_partition_idx >= first_partition_idx);
- assert(last_partition_idx < fragmentation.fragmentationVectorSize);
- for (size_t i = 0; i < num_partitions_; ++i) {
- size_vector_[i] =
- fragmentation.fragmentationLength[i + first_partition_idx];
- largest_partition_size_ =
- std::max(largest_partition_size_, size_vector_[i]);
- }
- root_ = PartitionTreeNode::CreateRootNode(size_vector_, num_partitions_);
-}
-
-Vp8PartitionAggregator::~Vp8PartitionAggregator() {
- delete[] size_vector_;
- delete root_;
-}
-
-void Vp8PartitionAggregator::SetPriorMinMax(int min_size, int max_size) {
- assert(root_);
- assert(min_size >= 0);
- assert(max_size >= min_size);
- root_->set_min_parent_size(min_size);
- root_->set_max_parent_size(max_size);
-}
-
-Vp8PartitionAggregator::ConfigVec
-Vp8PartitionAggregator::FindOptimalConfiguration(size_t max_size,
- size_t penalty) {
- assert(root_);
- assert(max_size >= largest_partition_size_);
- PartitionTreeNode* opt = root_->GetOptimalNode(max_size, penalty);
- ConfigVec config_vector(num_partitions_, 0);
- PartitionTreeNode* temp_node = opt;
- size_t packet_index = opt->NumPackets();
- for (size_t i = num_partitions_; i > 0; --i) {
- assert(packet_index > 0);
- assert(temp_node != NULL);
- config_vector[i - 1] = packet_index - 1;
- if (temp_node->packet_start())
- --packet_index;
- temp_node = temp_node->parent();
- }
- return config_vector;
-}
-
-void Vp8PartitionAggregator::CalcMinMax(const ConfigVec& config,
- int* min_size,
- int* max_size) const {
- if (*min_size < 0) {
- *min_size = std::numeric_limits<int>::max();
- }
- if (*max_size < 0) {
- *max_size = 0;
- }
- size_t i = 0;
- while (i < config.size()) {
- size_t this_size = 0;
- size_t j = i;
- while (j < config.size() && config[i] == config[j]) {
- this_size += size_vector_[j];
- ++j;
- }
- i = j;
- if (this_size < static_cast<size_t>(*min_size)) {
- *min_size = this_size;
- }
- if (this_size > static_cast<size_t>(*max_size)) {
- *max_size = this_size;
- }
- }
-}
-
-size_t Vp8PartitionAggregator::CalcNumberOfFragments(
- size_t large_partition_size,
- size_t max_payload_size,
- size_t penalty,
- int min_size,
- int max_size) {
- assert(large_partition_size > 0);
- assert(max_payload_size > 0);
- assert(min_size != 0);
- assert(min_size <= max_size);
- assert(max_size <= static_cast<int>(max_payload_size));
- // Divisions with rounding up.
- const size_t min_number_of_fragments =
- (large_partition_size + max_payload_size - 1) / max_payload_size;
- if (min_size < 0 || max_size < 0) {
- // No aggregates produced, so we do not have any size boundaries.
- // Simply split in as few partitions as possible.
- return min_number_of_fragments;
- }
- const size_t max_number_of_fragments =
- (large_partition_size + min_size - 1) / min_size;
- int num_fragments = -1;
- size_t best_cost = std::numeric_limits<size_t>::max();
- for (size_t n = min_number_of_fragments; n <= max_number_of_fragments; ++n) {
- // Round up so that we use the largest fragment.
- size_t fragment_size = (large_partition_size + n - 1) / n;
- size_t cost = 0;
- if (fragment_size < static_cast<size_t>(min_size)) {
- cost = min_size - fragment_size + n * penalty;
- } else if (fragment_size > static_cast<size_t>(max_size)) {
- cost = fragment_size - max_size + n * penalty;
- } else {
- cost = n * penalty;
- }
- if (fragment_size <= max_payload_size && cost < best_cost) {
- num_fragments = n;
- best_cost = cost;
- }
- }
- assert(num_fragments > 0);
- // TODO(mflodman) Assert disabled since it's falsely triggered, see issue 293.
- // assert(large_partition_size / num_fragments + 1 <= max_payload_size);
- return num_fragments;
-}
-
-} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698