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:
parent
c0d31e915c
commit
4a206a96c1
@ -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,
|
||||
|
||||
@ -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_;
|
||||
};
|
||||
|
||||
|
||||
@ -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_)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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_;
|
||||
};
|
||||
|
||||
|
||||
@ -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::_;
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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',
|
||||
|
||||
@ -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',
|
||||
],
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -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_;
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user