webrtc/common_video/i420_buffer_pool.cc
Noah Richards 408a3c63d3 Add explicit stride options to I420BufferPool.
Also fix tests that relied on memory allocation behaviors. These only
worked by chance in the past because the allocated sizes of planes
changed enough to put them in a different location in memory. But there's
no easy/valid way to ensure memory *wasn't* re-used, and the test doesn't
really care anyways (if I420BufferPool could re-use the buffer object but
change the resolution/stride, it'd still be fine).

Bug: None
Change-Id: I28135d58d23f194a0142e5a037fa9d315af6b1c8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/130821
Commit-Queue: Noah Richards <noahric@chromium.org>
Reviewed-by: Magnus Flodman <mflodman@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27551}
2019-04-10 17:53:19 +00:00

76 lines
2.8 KiB
C++

/*
* Copyright (c) 2015 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 "common_video/include/i420_buffer_pool.h"
#include <limits>
#include "rtc_base/checks.h"
namespace webrtc {
I420BufferPool::I420BufferPool() : I420BufferPool(false) {}
I420BufferPool::I420BufferPool(bool zero_initialize)
: I420BufferPool(zero_initialize, std::numeric_limits<size_t>::max()) {}
I420BufferPool::I420BufferPool(bool zero_initialize,
size_t max_number_of_buffers)
: zero_initialize_(zero_initialize),
max_number_of_buffers_(max_number_of_buffers) {}
I420BufferPool::~I420BufferPool() = default;
void I420BufferPool::Release() {
buffers_.clear();
}
rtc::scoped_refptr<I420Buffer> I420BufferPool::CreateBuffer(int width,
int height) {
// Default stride_y is width, default uv stride is width / 2 (rounding up).
return CreateBuffer(width, height, width, (width + 1) / 2, (width + 1) / 2);
}
rtc::scoped_refptr<I420Buffer> I420BufferPool::CreateBuffer(int width,
int height,
int stride_y,
int stride_u,
int stride_v) {
RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
// Release buffers with wrong resolution.
for (auto it = buffers_.begin(); it != buffers_.end();) {
const auto& buffer = *it;
if (buffer->width() != width || buffer->height() != height ||
buffer->StrideY() != stride_y || buffer->StrideU() != stride_u ||
buffer->StrideV() != stride_v) {
it = buffers_.erase(it);
} else {
++it;
}
}
// Look for a free buffer.
for (const rtc::scoped_refptr<PooledI420Buffer>& buffer : buffers_) {
// If the buffer is in use, the ref count will be >= 2, one from the list we
// are looping over and one from the application. If the ref count is 1,
// then the list we are looping over holds the only reference and it's safe
// to reuse.
if (buffer->HasOneRef())
return buffer;
}
if (buffers_.size() >= max_number_of_buffers_)
return nullptr;
// Allocate new buffer.
rtc::scoped_refptr<PooledI420Buffer> buffer =
new PooledI420Buffer(width, height, stride_y, stride_u, stride_v);
if (zero_initialize_)
buffer->InitializeData();
buffers_.push_back(buffer);
return buffer;
}
} // namespace webrtc