Remove webrtc::ScopedVector

We can (and should) use std::vector<std::unique_ptr<T>> instead.
Because it's standard, and because it's safer since callers have to
manually wrap elements in std::unique_ptr before inserting them and
manually unwrap them after inserting them.

Review URL: https://codereview.webrtc.org/1839603002

Cr-Commit-Position: refs/heads/master@{#12182}
This commit is contained in:
kwiberg 2016-03-31 10:24:26 -07:00 committed by Commit bot
parent c0d31e915c
commit 4a206a96c1
21 changed files with 93 additions and 562 deletions

View File

@ -11,13 +11,14 @@
#include "webrtc/common_audio/audio_converter.h"
#include <cstring>
#include <memory>
#include <utility>
#include <vector>
#include "webrtc/base/checks.h"
#include "webrtc/base/safe_conversions.h"
#include "webrtc/common_audio/channel_buffer.h"
#include "webrtc/common_audio/resampler/push_sinc_resampler.h"
#include "webrtc/system_wrappers/include/scoped_vector.h"
using rtc::checked_cast;
@ -86,7 +87,8 @@ class ResampleConverter : public AudioConverter {
: AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {
resamplers_.reserve(src_channels);
for (size_t i = 0; i < src_channels; ++i)
resamplers_.push_back(new PushSincResampler(src_frames, dst_frames));
resamplers_.push_back(std::unique_ptr<PushSincResampler>(
new PushSincResampler(src_frames, dst_frames)));
}
~ResampleConverter() override {};
@ -98,20 +100,21 @@ class ResampleConverter : public AudioConverter {
}
private:
ScopedVector<PushSincResampler> resamplers_;
std::vector<std::unique_ptr<PushSincResampler>> resamplers_;
};
// Apply a vector of converters in serial, in the order given. At least two
// converters must be provided.
class CompositionConverter : public AudioConverter {
public:
CompositionConverter(ScopedVector<AudioConverter> converters)
CompositionConverter(std::vector<std::unique_ptr<AudioConverter>> converters)
: converters_(std::move(converters)) {
RTC_CHECK_GE(converters_.size(), 2u);
// We need an intermediate buffer after every converter.
for (auto it = converters_.begin(); it != converters_.end() - 1; ++it)
buffers_.push_back(new ChannelBuffer<float>((*it)->dst_frames(),
(*it)->dst_channels()));
buffers_.push_back(
std::unique_ptr<ChannelBuffer<float>>(new ChannelBuffer<float>(
(*it)->dst_frames(), (*it)->dst_channels())));
}
~CompositionConverter() override {};
@ -120,8 +123,8 @@ class CompositionConverter : public AudioConverter {
converters_.front()->Convert(src, src_size, buffers_.front()->channels(),
buffers_.front()->size());
for (size_t i = 2; i < converters_.size(); ++i) {
auto src_buffer = buffers_[i - 2];
auto dst_buffer = buffers_[i - 1];
auto& src_buffer = buffers_[i - 2];
auto& dst_buffer = buffers_[i - 1];
converters_[i]->Convert(src_buffer->channels(),
src_buffer->size(),
dst_buffer->channels(),
@ -132,8 +135,8 @@ class CompositionConverter : public AudioConverter {
}
private:
ScopedVector<AudioConverter> converters_;
ScopedVector<ChannelBuffer<float>> buffers_;
std::vector<std::unique_ptr<AudioConverter>> converters_;
std::vector<std::unique_ptr<ChannelBuffer<float>>> buffers_;
};
std::unique_ptr<AudioConverter> AudioConverter::Create(size_t src_channels,
@ -143,11 +146,12 @@ std::unique_ptr<AudioConverter> AudioConverter::Create(size_t src_channels,
std::unique_ptr<AudioConverter> sp;
if (src_channels > dst_channels) {
if (src_frames != dst_frames) {
ScopedVector<AudioConverter> converters;
converters.push_back(new DownmixConverter(src_channels, src_frames,
dst_channels, src_frames));
converters.push_back(new ResampleConverter(dst_channels, src_frames,
dst_channels, dst_frames));
std::vector<std::unique_ptr<AudioConverter>> converters;
converters.push_back(std::unique_ptr<AudioConverter>(new DownmixConverter(
src_channels, src_frames, dst_channels, src_frames)));
converters.push_back(
std::unique_ptr<AudioConverter>(new ResampleConverter(
dst_channels, src_frames, dst_channels, dst_frames)));
sp.reset(new CompositionConverter(std::move(converters)));
} else {
sp.reset(new DownmixConverter(src_channels, src_frames, dst_channels,
@ -155,11 +159,12 @@ std::unique_ptr<AudioConverter> AudioConverter::Create(size_t src_channels,
}
} else if (src_channels < dst_channels) {
if (src_frames != dst_frames) {
ScopedVector<AudioConverter> converters;
converters.push_back(new ResampleConverter(src_channels, src_frames,
src_channels, dst_frames));
converters.push_back(new UpmixConverter(src_channels, dst_frames,
dst_channels, dst_frames));
std::vector<std::unique_ptr<AudioConverter>> converters;
converters.push_back(
std::unique_ptr<AudioConverter>(new ResampleConverter(
src_channels, src_frames, src_channels, dst_frames)));
converters.push_back(std::unique_ptr<AudioConverter>(new UpmixConverter(
src_channels, dst_frames, dst_channels, dst_frames)));
sp.reset(new CompositionConverter(std::move(converters)));
} else {
sp.reset(new UpmixConverter(src_channels, src_frames, dst_channels,

View File

@ -46,8 +46,7 @@ class AudioRingBuffer final {
void MoveReadPositionBackward(size_t frames);
private:
// We don't use a ScopedVector because it doesn't support a specialized
// deleter (like unique_ptr for instance.)
// TODO(kwiberg): Use std::vector<std::unique_ptr<RingBuffer>> instead.
std::vector<RingBuffer*> buffers_;
};

View File

@ -75,17 +75,15 @@ AudioBuffer::AudioBuffer(size_t input_num_frames,
if (input_num_frames_ != proc_num_frames_) {
for (size_t i = 0; i < num_proc_channels_; ++i) {
input_resamplers_.push_back(
new PushSincResampler(input_num_frames_,
proc_num_frames_));
input_resamplers_.push_back(std::unique_ptr<PushSincResampler>(
new PushSincResampler(input_num_frames_, proc_num_frames_)));
}
}
if (output_num_frames_ != proc_num_frames_) {
for (size_t i = 0; i < num_proc_channels_; ++i) {
output_resamplers_.push_back(
new PushSincResampler(proc_num_frames_,
output_num_frames_));
output_resamplers_.push_back(std::unique_ptr<PushSincResampler>(
new PushSincResampler(proc_num_frames_, output_num_frames_)));
}
}
}

View File

@ -12,12 +12,12 @@
#define WEBRTC_MODULES_AUDIO_PROCESSING_AUDIO_BUFFER_H_
#include <memory>
#include <vector>
#include "webrtc/common_audio/channel_buffer.h"
#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/modules/audio_processing/splitting_filter.h"
#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/system_wrappers/include/scoped_vector.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@ -155,8 +155,8 @@ class AudioBuffer {
std::unique_ptr<IFChannelBuffer> input_buffer_;
std::unique_ptr<IFChannelBuffer> output_buffer_;
std::unique_ptr<ChannelBuffer<float> > process_buffer_;
ScopedVector<PushSincResampler> input_resamplers_;
ScopedVector<PushSincResampler> output_resamplers_;
std::vector<std::unique_ptr<PushSincResampler>> input_resamplers_;
std::vector<std::unique_ptr<PushSincResampler>> output_resamplers_;
};
} // namespace webrtc

View File

@ -334,8 +334,8 @@ void NonlinearBeamformer::InitInterfCovMats() {
for (size_t i = 0; i < kNumFreqBins; ++i) {
interf_cov_mats_[i].clear();
for (size_t j = 0; j < interf_angles_radians_.size(); ++j) {
interf_cov_mats_[i].push_back(new ComplexMatrixF(num_input_channels_,
num_input_channels_));
interf_cov_mats_[i].push_back(std::unique_ptr<ComplexMatrixF>(
new ComplexMatrixF(num_input_channels_, num_input_channels_)));
ComplexMatrixF angled_cov_mat(num_input_channels_, num_input_channels_);
CovarianceMatrixGenerator::AngledCovarianceMatrix(
kSpeedOfSoundMeterSeconds,

View File

@ -23,7 +23,6 @@
#include "webrtc/common_audio/channel_buffer.h"
#include "webrtc/modules/audio_processing/beamformer/beamformer.h"
#include "webrtc/modules/audio_processing/beamformer/complex_matrix.h"
#include "webrtc/system_wrappers/include/scoped_vector.h"
namespace webrtc {
@ -169,9 +168,9 @@ class NonlinearBeamformer
ComplexMatrixF target_cov_mats_[kNumFreqBins];
ComplexMatrixF uniform_cov_mat_[kNumFreqBins];
// Array of length |kNumFreqBins|, Matrix of size |num_input_channels_| x
// |num_input_channels_|. ScopedVector has a size equal to the number of
// |num_input_channels_|. The vector has a size equal to the number of
// interferer scenarios.
ScopedVector<ComplexMatrixF> interf_cov_mats_[kNumFreqBins];
std::vector<std::unique_ptr<ComplexMatrixF>> interf_cov_mats_[kNumFreqBins];
// Of length |kNumFreqBins|.
float wave_numbers_[kNumFreqBins];

View File

@ -12,6 +12,7 @@
#define WEBRTC_MODULES_AUDIO_PROCESSING_HIGH_PASS_FILTER_IMPL_H_
#include <memory>
#include <vector>
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/criticalsection.h"

View File

@ -25,7 +25,8 @@ SplittingFilter::SplittingFilter(size_t num_channels,
two_bands_states_.resize(num_channels);
} else if (num_bands_ == 3) {
for (size_t i = 0; i < num_channels; ++i) {
three_band_filter_banks_.push_back(new ThreeBandFilterBank(num_frames));
three_band_filter_banks_.push_back(std::unique_ptr<ThreeBandFilterBank>(
new ThreeBandFilterBank(num_frames)));
}
}
}

View File

@ -12,10 +12,10 @@
#define WEBRTC_MODULES_AUDIO_PROCESSING_SPLITTING_FILTER_H_
#include <cstring>
#include <memory>
#include <vector>
#include "webrtc/modules/audio_processing/three_band_filter_bank.h"
#include "webrtc/system_wrappers/include/scoped_vector.h"
namespace webrtc {
@ -60,7 +60,7 @@ class SplittingFilter {
const size_t num_bands_;
std::vector<TwoBandsStates> two_bands_states_;
ScopedVector<ThreeBandFilterBank> three_band_filter_banks_;
std::vector<std::unique_ptr<ThreeBandFilterBank>> three_band_filter_banks_;
};
} // namespace webrtc

View File

@ -113,10 +113,12 @@ ThreeBandFilterBank::ThreeBandFilterBank(size_t length)
out_buffer_(in_buffer_.size()) {
for (size_t i = 0; i < kSparsity; ++i) {
for (size_t j = 0; j < kNumBands; ++j) {
analysis_filters_.push_back(new SparseFIRFilter(
kLowpassCoeffs[i * kNumBands + j], kNumCoeffs, kSparsity, i));
synthesis_filters_.push_back(new SparseFIRFilter(
kLowpassCoeffs[i * kNumBands + j], kNumCoeffs, kSparsity, i));
analysis_filters_.push_back(
std::unique_ptr<SparseFIRFilter>(new SparseFIRFilter(
kLowpassCoeffs[i * kNumBands + j], kNumCoeffs, kSparsity, i)));
synthesis_filters_.push_back(
std::unique_ptr<SparseFIRFilter>(new SparseFIRFilter(
kLowpassCoeffs[i * kNumBands + j], kNumCoeffs, kSparsity, i)));
}
}
dct_modulation_.resize(kNumBands * kSparsity);

View File

@ -12,10 +12,10 @@
#define WEBRTC_MODULES_AUDIO_PROCESSING_THREE_BAND_FILTER_BANK_H_
#include <cstring>
#include <memory>
#include <vector>
#include "webrtc/common_audio/sparse_fir_filter.h"
#include "webrtc/system_wrappers/include/scoped_vector.h"
namespace webrtc {
@ -58,8 +58,8 @@ class ThreeBandFilterBank final {
std::vector<float> in_buffer_;
std::vector<float> out_buffer_;
ScopedVector<SparseFIRFilter> analysis_filters_;
ScopedVector<SparseFIRFilter> synthesis_filters_;
std::vector<std::unique_ptr<SparseFIRFilter>> analysis_filters_;
std::vector<std::unique_ptr<SparseFIRFilter>> synthesis_filters_;
std::vector<std::vector<float>> dct_modulation_;
};

View File

@ -20,7 +20,6 @@
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
#include "webrtc/system_wrappers/include/scoped_vector.h"
#include "webrtc/test/rtcp_packet_parser.h"
using ::testing::_;

View File

@ -29,7 +29,6 @@ static_library("system_wrappers") {
"include/metrics.h",
"include/rtp_to_ntp.h",
"include/rw_lock_wrapper.h",
"include/scoped_vector.h",
"include/sleep.h",
"include/sort.h",
"include/static_instance.h",

View File

@ -1,152 +0,0 @@
/*
* Copyright (c) 2014 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.
*/
// Borrowed from Chromium's src/base/memory/scoped_vector.h.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INCLUDE_SCOPED_VECTOR_H_
#define WEBRTC_SYSTEM_WRAPPERS_INCLUDE_SCOPED_VECTOR_H_
#include <vector>
#include "webrtc/base/checks.h"
#include "webrtc/system_wrappers/include/stl_util.h"
namespace webrtc {
// ScopedVector wraps a vector deleting the elements from its
// destructor.
template <class T>
class ScopedVector {
public:
typedef typename std::vector<T*>::allocator_type allocator_type;
typedef typename std::vector<T*>::size_type size_type;
typedef typename std::vector<T*>::difference_type difference_type;
typedef typename std::vector<T*>::pointer pointer;
typedef typename std::vector<T*>::const_pointer const_pointer;
typedef typename std::vector<T*>::reference reference;
typedef typename std::vector<T*>::const_reference const_reference;
typedef typename std::vector<T*>::value_type value_type;
typedef typename std::vector<T*>::iterator iterator;
typedef typename std::vector<T*>::const_iterator const_iterator;
typedef typename std::vector<T*>::reverse_iterator reverse_iterator;
typedef typename std::vector<T*>::const_reverse_iterator
const_reverse_iterator;
ScopedVector() {}
~ScopedVector() { clear(); }
// Move construction and assignment.
ScopedVector(ScopedVector&& other) { *this = std::move(other); }
ScopedVector& operator=(ScopedVector&& other) {
std::swap(v_, other.v_); // The arguments are std::vectors, so std::swap
// is the one that we want.
other.clear();
return *this;
}
// Deleted copy constructor and copy assignment, to make the type move-only.
ScopedVector(const ScopedVector& other) = delete;
ScopedVector& operator=(const ScopedVector& other) = delete;
reference operator[](size_t index) { return v_[index]; }
const_reference operator[](size_t index) const { return v_[index]; }
bool empty() const { return v_.empty(); }
size_t size() const { return v_.size(); }
reverse_iterator rbegin() { return v_.rbegin(); }
const_reverse_iterator rbegin() const { return v_.rbegin(); }
reverse_iterator rend() { return v_.rend(); }
const_reverse_iterator rend() const { return v_.rend(); }
iterator begin() { return v_.begin(); }
const_iterator begin() const { return v_.begin(); }
iterator end() { return v_.end(); }
const_iterator end() const { return v_.end(); }
const_reference front() const { return v_.front(); }
reference front() { return v_.front(); }
const_reference back() const { return v_.back(); }
reference back() { return v_.back(); }
void push_back(T* elem) { v_.push_back(elem); }
void pop_back() {
RTC_DCHECK(!empty());
delete v_.back();
v_.pop_back();
}
std::vector<T*>& get() { return v_; }
const std::vector<T*>& get() const { return v_; }
void swap(std::vector<T*>& other) { v_.swap(other); }
void swap(ScopedVector<T>& other) { v_.swap(other.v_); }
void release(std::vector<T*>* out) {
out->swap(v_);
v_.clear();
}
void reserve(size_t capacity) { v_.reserve(capacity); }
// Resize, deleting elements in the disappearing range if we are shrinking.
void resize(size_t new_size) {
if (v_.size() > new_size)
STLDeleteContainerPointers(v_.begin() + new_size, v_.end());
v_.resize(new_size);
}
template<typename InputIterator>
void assign(InputIterator begin, InputIterator end) {
v_.assign(begin, end);
}
void clear() { STLDeleteElements(&v_); }
// Like |clear()|, but doesn't delete any elements.
void weak_clear() { v_.clear(); }
// Lets the ScopedVector take ownership of |x|.
iterator insert(iterator position, T* x) {
return v_.insert(position, x);
}
// Lets the ScopedVector take ownership of elements in [first,last).
template<typename InputIterator>
void insert(iterator position, InputIterator first, InputIterator last) {
v_.insert(position, first, last);
}
iterator erase(iterator position) {
delete *position;
return v_.erase(position);
}
iterator erase(iterator first, iterator last) {
STLDeleteContainerPointers(first, last);
return v_.erase(first, last);
}
// Like |erase()|, but doesn't delete the element at |position|.
iterator weak_erase(iterator position) {
return v_.erase(position);
}
// Like |erase()|, but doesn't delete the elements in [first, last).
iterator weak_erase(iterator first, iterator last) {
return v_.erase(first, last);
}
private:
std::vector<T*> v_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INCLUDE_SCOPED_VECTOR_H_

View File

@ -1,325 +0,0 @@
/*
* Copyright (c) 2014 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.
*/
// Borrowed from Chromium's src/base/memory/scoped_vector_unittest.cc
#include "webrtc/system_wrappers/include/scoped_vector.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
namespace webrtc {
namespace {
// The LifeCycleObject notifies its Observer upon construction & destruction.
class LifeCycleObject {
public:
class Observer {
public:
virtual void OnLifeCycleConstruct(LifeCycleObject* o) = 0;
virtual void OnLifeCycleDestroy(LifeCycleObject* o) = 0;
protected:
virtual ~Observer() {}
};
~LifeCycleObject() {
observer_->OnLifeCycleDestroy(this);
}
private:
friend class LifeCycleWatcher;
explicit LifeCycleObject(Observer* observer)
: observer_(observer) {
observer_->OnLifeCycleConstruct(this);
}
Observer* observer_;
RTC_DISALLOW_COPY_AND_ASSIGN(LifeCycleObject);
};
// The life cycle states we care about for the purposes of testing ScopedVector
// against objects.
enum LifeCycleState {
LC_INITIAL,
LC_CONSTRUCTED,
LC_DESTROYED,
};
// Because we wish to watch the life cycle of an object being constructed and
// destroyed, and further wish to test expectations against the state of that
// object, we cannot save state in that object itself. Instead, we use this
// pairing of the watcher, which observes the object and notifies of
// construction & destruction. Since we also may be testing assumptions about
// things not getting freed, this class also acts like a scoping object and
// deletes the |constructed_life_cycle_object_|, if any when the
// LifeCycleWatcher is destroyed. To keep this simple, the only expected state
// changes are:
// INITIAL -> CONSTRUCTED -> DESTROYED.
// Anything more complicated than that should start another test.
class LifeCycleWatcher : public LifeCycleObject::Observer {
public:
LifeCycleWatcher() : life_cycle_state_(LC_INITIAL) {}
virtual ~LifeCycleWatcher() {}
// Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this
// LifeCycleWatcher.
void OnLifeCycleConstruct(LifeCycleObject* object) override {
ASSERT_EQ(LC_INITIAL, life_cycle_state_);
ASSERT_EQ(NULL, constructed_life_cycle_object_.get());
life_cycle_state_ = LC_CONSTRUCTED;
constructed_life_cycle_object_.reset(object);
}
// Assert CONSTRUCTED -> DESTROYED and the |object| being destroyed is the
// same one we saw constructed.
void OnLifeCycleDestroy(LifeCycleObject* object) override {
ASSERT_EQ(LC_CONSTRUCTED, life_cycle_state_);
LifeCycleObject* constructed_life_cycle_object =
constructed_life_cycle_object_.release();
ASSERT_EQ(constructed_life_cycle_object, object);
life_cycle_state_ = LC_DESTROYED;
}
LifeCycleState life_cycle_state() const { return life_cycle_state_; }
// Factory method for creating a new LifeCycleObject tied to this
// LifeCycleWatcher.
LifeCycleObject* NewLifeCycleObject() {
return new LifeCycleObject(this);
}
// Returns true iff |object| is the same object that this watcher is tracking.
bool IsWatching(LifeCycleObject* object) const {
return object == constructed_life_cycle_object_.get();
}
private:
LifeCycleState life_cycle_state_;
rtc::scoped_ptr<LifeCycleObject> constructed_life_cycle_object_;
RTC_DISALLOW_COPY_AND_ASSIGN(LifeCycleWatcher);
};
TEST(ScopedVectorTest, LifeCycleWatcher) {
LifeCycleWatcher watcher;
EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
LifeCycleObject* object = watcher.NewLifeCycleObject();
EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
delete object;
EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
}
TEST(ScopedVectorTest, PopBack) {
LifeCycleWatcher watcher;
EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
ScopedVector<LifeCycleObject> scoped_vector;
scoped_vector.push_back(watcher.NewLifeCycleObject());
EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
scoped_vector.pop_back();
EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
EXPECT_TRUE(scoped_vector.empty());
}
TEST(ScopedVectorTest, Clear) {
LifeCycleWatcher watcher;
EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
ScopedVector<LifeCycleObject> scoped_vector;
scoped_vector.push_back(watcher.NewLifeCycleObject());
EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
scoped_vector.clear();
EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
EXPECT_TRUE(scoped_vector.empty());
}
TEST(ScopedVectorTest, WeakClear) {
LifeCycleWatcher watcher;
EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
ScopedVector<LifeCycleObject> scoped_vector;
scoped_vector.push_back(watcher.NewLifeCycleObject());
EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
scoped_vector.weak_clear();
EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
EXPECT_TRUE(scoped_vector.empty());
}
TEST(ScopedVectorTest, ResizeShrink) {
LifeCycleWatcher first_watcher;
EXPECT_EQ(LC_INITIAL, first_watcher.life_cycle_state());
LifeCycleWatcher second_watcher;
EXPECT_EQ(LC_INITIAL, second_watcher.life_cycle_state());
ScopedVector<LifeCycleObject> scoped_vector;
scoped_vector.push_back(first_watcher.NewLifeCycleObject());
EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
EXPECT_EQ(LC_INITIAL, second_watcher.life_cycle_state());
EXPECT_TRUE(first_watcher.IsWatching(scoped_vector[0]));
EXPECT_FALSE(second_watcher.IsWatching(scoped_vector[0]));
scoped_vector.push_back(second_watcher.NewLifeCycleObject());
EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
EXPECT_EQ(LC_CONSTRUCTED, second_watcher.life_cycle_state());
EXPECT_FALSE(first_watcher.IsWatching(scoped_vector[1]));
EXPECT_TRUE(second_watcher.IsWatching(scoped_vector[1]));
// Test that shrinking a vector deletes elements in the disappearing range.
scoped_vector.resize(1);
EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
EXPECT_EQ(LC_DESTROYED, second_watcher.life_cycle_state());
EXPECT_EQ(1u, scoped_vector.size());
EXPECT_TRUE(first_watcher.IsWatching(scoped_vector[0]));
}
TEST(ScopedVectorTest, ResizeGrow) {
LifeCycleWatcher watcher;
EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
ScopedVector<LifeCycleObject> scoped_vector;
scoped_vector.push_back(watcher.NewLifeCycleObject());
EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
scoped_vector.resize(5);
EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
ASSERT_EQ(5u, scoped_vector.size());
EXPECT_TRUE(watcher.IsWatching(scoped_vector[0]));
EXPECT_FALSE(watcher.IsWatching(scoped_vector[1]));
EXPECT_FALSE(watcher.IsWatching(scoped_vector[2]));
EXPECT_FALSE(watcher.IsWatching(scoped_vector[3]));
EXPECT_FALSE(watcher.IsWatching(scoped_vector[4]));
}
TEST(ScopedVectorTest, Scope) {
LifeCycleWatcher watcher;
EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
{
ScopedVector<LifeCycleObject> scoped_vector;
scoped_vector.push_back(watcher.NewLifeCycleObject());
EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
}
EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
}
TEST(ScopedVectorTest, MoveConstruct) {
LifeCycleWatcher watcher;
EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
{
ScopedVector<LifeCycleObject> scoped_vector;
scoped_vector.push_back(watcher.NewLifeCycleObject());
EXPECT_FALSE(scoped_vector.empty());
EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
ScopedVector<LifeCycleObject> scoped_vector_copy(std::move(scoped_vector));
EXPECT_TRUE(scoped_vector.empty());
EXPECT_FALSE(scoped_vector_copy.empty());
EXPECT_TRUE(watcher.IsWatching(scoped_vector_copy.back()));
EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
}
EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
}
TEST(ScopedVectorTest, MoveAssign) {
LifeCycleWatcher watcher;
EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
{
ScopedVector<LifeCycleObject> scoped_vector;
scoped_vector.push_back(watcher.NewLifeCycleObject());
ScopedVector<LifeCycleObject> scoped_vector_assign;
EXPECT_FALSE(scoped_vector.empty());
EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
scoped_vector_assign = std::move(scoped_vector);
EXPECT_TRUE(scoped_vector.empty());
EXPECT_FALSE(scoped_vector_assign.empty());
EXPECT_TRUE(watcher.IsWatching(scoped_vector_assign.back()));
EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
}
EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
}
class DeleteCounter {
public:
explicit DeleteCounter(int* deletes)
: deletes_(deletes) {
}
~DeleteCounter() {
(*deletes_)++;
}
void VoidMethod0() {}
private:
int* const deletes_;
RTC_DISALLOW_COPY_AND_ASSIGN(DeleteCounter);
};
// This class is used in place of Chromium's base::Callback.
template <typename T>
class PassThru {
public:
explicit PassThru(ScopedVector<T> scoper) : scoper_(std::move(scoper)) {}
ScopedVector<T> Run() { return std::move(scoper_); }
private:
ScopedVector<T> scoper_;
};
TEST(ScopedVectorTest, Passed) {
int deletes = 0;
ScopedVector<DeleteCounter> deleter_vector;
deleter_vector.push_back(new DeleteCounter(&deletes));
EXPECT_EQ(0, deletes);
PassThru<DeleteCounter> pass_thru(std::move(deleter_vector));
EXPECT_EQ(0, deletes);
ScopedVector<DeleteCounter> result = pass_thru.Run();
EXPECT_EQ(0, deletes);
result.clear();
EXPECT_EQ(1, deletes);
};
TEST(ScopedVectorTest, InsertRange) {
LifeCycleWatcher watchers[5];
size_t watchers_size = sizeof(watchers) / sizeof(*watchers);
std::vector<LifeCycleObject*> vec;
for (LifeCycleWatcher* it = watchers; it != watchers + watchers_size;
++it) {
EXPECT_EQ(LC_INITIAL, it->life_cycle_state());
vec.push_back(it->NewLifeCycleObject());
EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
}
// Start scope for ScopedVector.
{
ScopedVector<LifeCycleObject> scoped_vector;
scoped_vector.insert(scoped_vector.end(), vec.begin() + 1, vec.begin() + 3);
for (LifeCycleWatcher* it = watchers; it != watchers + watchers_size;
++it)
EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
}
for (LifeCycleWatcher* it = watchers; it != watchers + 1; ++it)
EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
for (LifeCycleWatcher* it = watchers + 1; it != watchers + 3; ++it)
EXPECT_EQ(LC_DESTROYED, it->life_cycle_state());
for (LifeCycleWatcher* it = watchers + 3; it != watchers + watchers_size;
++it)
EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
}
} // namespace
} // namespace webrtc

View File

@ -37,7 +37,6 @@
'include/ntp_time.h',
'include/rtp_to_ntp.h',
'include/rw_lock_wrapper.h',
'include/scoped_vector.h',
'include/sleep.h',
'include/sort.h',
'include/static_instance.h',

View File

@ -34,7 +34,6 @@
'source/metrics_unittest.cc',
'source/ntp_time_unittest.cc',
'source/rtp_to_ntp_unittest.cc',
'source/scoped_vector_unittest.cc',
'source/stringize_macros_unittest.cc',
'source/stl_util_unittest.cc',
],

View File

@ -216,7 +216,8 @@ void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) {
for (size_t i = 0; i < video_send_config_.rtp.ssrcs.size(); ++i) {
VideoReceiveStream::Decoder decoder =
test::CreateMatchingDecoder(video_send_config_.encoder_settings);
allocated_decoders_.push_back(decoder.decoder);
allocated_decoders_.push_back(
std::unique_ptr<VideoDecoder>(decoder.decoder));
video_config.decoders.clear();
video_config.decoders.push_back(decoder);
video_config.rtp.remote_ssrc = video_send_config_.rtp.ssrcs[i];

View File

@ -10,11 +10,11 @@
#ifndef WEBRTC_TEST_CALL_TEST_H_
#define WEBRTC_TEST_CALL_TEST_H_
#include <memory>
#include <vector>
#include "webrtc/call.h"
#include "webrtc/call/transport_adapter.h"
#include "webrtc/system_wrappers/include/scoped_vector.h"
#include "webrtc/test/fake_audio_device.h"
#include "webrtc/test/fake_decoder.h"
#include "webrtc/test/fake_encoder.h"
@ -100,7 +100,7 @@ class CallTest : public ::testing::Test {
rtc::scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
test::FakeEncoder fake_encoder_;
ScopedVector<VideoDecoder> allocated_decoders_;
std::vector<std::unique_ptr<VideoDecoder>> allocated_decoders_;
size_t num_video_streams_;
size_t num_audio_streams_;

View File

@ -13,6 +13,7 @@
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#include "testing/gtest/include/gtest/gtest.h"
@ -1246,7 +1247,7 @@ class MultiStreamTest {
VideoReceiveStream* receive_streams[kNumStreams];
test::FrameGeneratorCapturer* frame_generators[kNumStreams];
ScopedVector<VideoDecoder> allocated_decoders;
std::vector<std::unique_ptr<VideoDecoder>> allocated_decoders;
for (size_t i = 0; i < kNumStreams; ++i) {
uint32_t ssrc = codec_settings[i].ssrc;
int width = codec_settings[i].width;
@ -1277,7 +1278,8 @@ class MultiStreamTest {
receive_config.rtp.local_ssrc = test::CallTest::kReceiverLocalVideoSsrc;
VideoReceiveStream::Decoder decoder =
test::CreateMatchingDecoder(send_config.encoder_settings);
allocated_decoders.push_back(decoder.decoder);
allocated_decoders.push_back(
std::unique_ptr<VideoDecoder>(decoder.decoder));
receive_config.decoders.push_back(decoder);
UpdateReceiveConfig(i, &receive_config);

View File

@ -15,7 +15,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/event.h"
#include "webrtc/base/refcount.h"
#include "webrtc/system_wrappers/include/scoped_vector.h"
#include "webrtc/test/fake_texture_frame.h"
#include "webrtc/video/send_statistics_proxy.h"
@ -27,9 +26,9 @@ namespace webrtc {
bool EqualFrames(const VideoFrame& frame1, const VideoFrame& frame2);
bool EqualTextureFrames(const VideoFrame& frame1, const VideoFrame& frame2);
bool EqualBufferFrames(const VideoFrame& frame1, const VideoFrame& frame2);
bool EqualFramesVector(const ScopedVector<VideoFrame>& frames1,
const ScopedVector<VideoFrame>& frames2);
VideoFrame* CreateVideoFrame(uint8_t length);
bool EqualFramesVector(const std::vector<std::unique_ptr<VideoFrame>>& frames1,
const std::vector<std::unique_ptr<VideoFrame>>& frames2);
std::unique_ptr<VideoFrame> CreateVideoFrame(uint8_t length);
class VideoCaptureInputTest : public ::testing::Test {
protected:
@ -59,7 +58,8 @@ class VideoCaptureInputTest : public ::testing::Test {
output_frame_ybuffers_.push_back(
static_cast<const VideoFrame*>(&frame)->buffer(kYPlane));
}
output_frames_.push_back(new VideoFrame(frame));
output_frames_.push_back(
std::unique_ptr<VideoFrame>(new VideoFrame(frame)));
}
SendStatisticsProxy stats_proxy_;
@ -72,10 +72,10 @@ class VideoCaptureInputTest : public ::testing::Test {
std::unique_ptr<internal::VideoCaptureInput> input_;
// Input capture frames of VideoCaptureInput.
ScopedVector<VideoFrame> input_frames_;
std::vector<std::unique_ptr<VideoFrame>> input_frames_;
// Output delivered frames of VideoCaptureInput.
ScopedVector<VideoFrame> output_frames_;
std::vector<std::unique_ptr<VideoFrame>> output_frames_;
// The pointers of Y plane buffers of output frames. This is used to verify
// the frame are swapped and not copied.
@ -114,7 +114,7 @@ TEST_F(VideoCaptureInputTest, TestNtpTimeStampSetIfRenderTimeSet) {
input_frames_[0]->set_render_time_ms(5);
input_frames_[0]->set_ntp_time_ms(0);
AddInputFrame(input_frames_[0]);
AddInputFrame(input_frames_[0].get());
WaitOutputFrame();
EXPECT_GT(output_frames_[0]->ntp_time_ms(),
input_frames_[0]->render_time_ms());
@ -126,7 +126,7 @@ TEST_F(VideoCaptureInputTest, TestRtpTimeStampSet) {
input_frames_[0]->set_ntp_time_ms(1);
input_frames_[0]->set_timestamp(0);
AddInputFrame(input_frames_[0]);
AddInputFrame(input_frames_[0].get());
WaitOutputFrame();
EXPECT_EQ(output_frames_[0]->timestamp(),
input_frames_[0]->ntp_time_ms() * 90);
@ -136,23 +136,23 @@ TEST_F(VideoCaptureInputTest, DropsFramesWithSameOrOldNtpTimestamp) {
input_frames_.push_back(CreateVideoFrame(0));
input_frames_[0]->set_ntp_time_ms(17);
AddInputFrame(input_frames_[0]);
AddInputFrame(input_frames_[0].get());
WaitOutputFrame();
EXPECT_EQ(output_frames_[0]->timestamp(),
input_frames_[0]->ntp_time_ms() * 90);
// Repeat frame with the same NTP timestamp should drop.
AddInputFrame(input_frames_[0]);
AddInputFrame(input_frames_[0].get());
EXPECT_FALSE(capture_event_.Wait(FRAME_TIMEOUT_MS));
// As should frames with a decreased NTP timestamp.
input_frames_[0]->set_ntp_time_ms(input_frames_[0]->ntp_time_ms() - 1);
AddInputFrame(input_frames_[0]);
AddInputFrame(input_frames_[0].get());
EXPECT_FALSE(capture_event_.Wait(FRAME_TIMEOUT_MS));
// But delivering with an increased NTP timestamp should succeed.
input_frames_[0]->set_ntp_time_ms(4711);
AddInputFrame(input_frames_[0]);
AddInputFrame(input_frames_[0].get());
WaitOutputFrame();
EXPECT_EQ(output_frames_[1]->timestamp(),
input_frames_[0]->ntp_time_ms() * 90);
@ -163,9 +163,10 @@ TEST_F(VideoCaptureInputTest, TestTextureFrames) {
for (int i = 0 ; i < kNumFrame; ++i) {
test::FakeNativeHandle* dummy_handle = new test::FakeNativeHandle();
// Add one to |i| so that width/height > 0.
input_frames_.push_back(new VideoFrame(test::FakeNativeHandle::CreateFrame(
dummy_handle, i + 1, i + 1, i + 1, i + 1, webrtc::kVideoRotation_0)));
AddInputFrame(input_frames_[i]);
input_frames_.push_back(std::unique_ptr<VideoFrame>(new VideoFrame(
test::FakeNativeHandle::CreateFrame(dummy_handle, i + 1, i + 1, i + 1,
i + 1, webrtc::kVideoRotation_0))));
AddInputFrame(input_frames_[i].get());
WaitOutputFrame();
EXPECT_EQ(dummy_handle, output_frames_[i]->native_handle());
}
@ -178,9 +179,9 @@ TEST_F(VideoCaptureInputTest, TestI420Frames) {
std::vector<const uint8_t*> ybuffer_pointers;
for (int i = 0; i < kNumFrame; ++i) {
input_frames_.push_back(CreateVideoFrame(static_cast<uint8_t>(i + 1)));
const VideoFrame* const_input_frame = input_frames_[i];
const VideoFrame* const_input_frame = input_frames_[i].get();
ybuffer_pointers.push_back(const_input_frame->buffer(kYPlane));
AddInputFrame(input_frames_[i]);
AddInputFrame(input_frames_[i].get());
WaitOutputFrame();
}
@ -192,14 +193,15 @@ TEST_F(VideoCaptureInputTest, TestI420Frames) {
TEST_F(VideoCaptureInputTest, TestI420FrameAfterTextureFrame) {
test::FakeNativeHandle* dummy_handle = new test::FakeNativeHandle();
input_frames_.push_back(new VideoFrame(test::FakeNativeHandle::CreateFrame(
dummy_handle, 1, 1, 1, 1, webrtc::kVideoRotation_0)));
AddInputFrame(input_frames_[0]);
input_frames_.push_back(std::unique_ptr<VideoFrame>(
new VideoFrame(test::FakeNativeHandle::CreateFrame(
dummy_handle, 1, 1, 1, 1, webrtc::kVideoRotation_0))));
AddInputFrame(input_frames_[0].get());
WaitOutputFrame();
EXPECT_EQ(dummy_handle, output_frames_[0]->native_handle());
input_frames_.push_back(CreateVideoFrame(2));
AddInputFrame(input_frames_[1]);
AddInputFrame(input_frames_[1].get());
WaitOutputFrame();
EXPECT_TRUE(EqualFramesVector(input_frames_, output_frames_));
@ -207,13 +209,14 @@ TEST_F(VideoCaptureInputTest, TestI420FrameAfterTextureFrame) {
TEST_F(VideoCaptureInputTest, TestTextureFrameAfterI420Frame) {
input_frames_.push_back(CreateVideoFrame(1));
AddInputFrame(input_frames_[0]);
AddInputFrame(input_frames_[0].get());
WaitOutputFrame();
test::FakeNativeHandle* dummy_handle = new test::FakeNativeHandle();
input_frames_.push_back(new VideoFrame(test::FakeNativeHandle::CreateFrame(
dummy_handle, 1, 1, 2, 2, webrtc::kVideoRotation_0)));
AddInputFrame(input_frames_[1]);
input_frames_.push_back(std::unique_ptr<VideoFrame>(
new VideoFrame(test::FakeNativeHandle::CreateFrame(
dummy_handle, 1, 1, 2, 2, webrtc::kVideoRotation_0))));
AddInputFrame(input_frames_[1].get());
WaitOutputFrame();
EXPECT_TRUE(EqualFramesVector(input_frames_, output_frames_));
@ -248,8 +251,9 @@ bool EqualBufferFrames(const VideoFrame& frame1, const VideoFrame& frame2) {
frame1.allocated_size(kVPlane)) == 0));
}
bool EqualFramesVector(const ScopedVector<VideoFrame>& frames1,
const ScopedVector<VideoFrame>& frames2) {
bool EqualFramesVector(
const std::vector<std::unique_ptr<VideoFrame>>& frames1,
const std::vector<std::unique_ptr<VideoFrame>>& frames2) {
if (frames1.size() != frames2.size())
return false;
for (size_t i = 0; i < frames1.size(); ++i) {
@ -259,8 +263,8 @@ bool EqualFramesVector(const ScopedVector<VideoFrame>& frames1,
return true;
}
VideoFrame* CreateVideoFrame(uint8_t data) {
VideoFrame* frame = new VideoFrame();
std::unique_ptr<VideoFrame> CreateVideoFrame(uint8_t data) {
std::unique_ptr<VideoFrame> frame(new VideoFrame());
const int width = 36;
const int height = 24;
const int kSizeY = width * height * 2;