Replace Check for too many pending frames in I420_buffer_pool with returning nullptr. Added histograms for when this happens in VP8Impl.
BUG=chromium:542522 R=tommi@webrtc.org Review URL: https://codereview.webrtc.org/2474783005 . Cr-Commit-Position: refs/heads/master@{#14930}
This commit is contained in:
parent
f752bca4a5
commit
00983572b0
@ -14,10 +14,10 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
const size_t I420BufferPool::kMaxNumberOfFramesBeforeCrash = 300;
|
||||
|
||||
I420BufferPool::I420BufferPool(bool zero_initialize)
|
||||
: zero_initialize_(zero_initialize) {}
|
||||
I420BufferPool::I420BufferPool(bool zero_initialize,
|
||||
size_t max_number_of_buffers)
|
||||
: zero_initialize_(zero_initialize),
|
||||
max_number_of_buffers_(max_number_of_buffers) {}
|
||||
|
||||
void I420BufferPool::Release() {
|
||||
buffers_.clear();
|
||||
@ -26,8 +26,6 @@ void I420BufferPool::Release() {
|
||||
rtc::scoped_refptr<I420Buffer> I420BufferPool::CreateBuffer(int width,
|
||||
int height) {
|
||||
RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
|
||||
RTC_CHECK_LT(buffers_.size(), kMaxNumberOfFramesBeforeCrash)
|
||||
<< "I420BufferPool too big.";
|
||||
// Release buffers with wrong resolution.
|
||||
for (auto it = buffers_.begin(); it != buffers_.end();) {
|
||||
if ((*it)->width() != width || (*it)->height() != height)
|
||||
@ -44,6 +42,9 @@ rtc::scoped_refptr<I420Buffer> I420BufferPool::CreateBuffer(int width,
|
||||
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);
|
||||
|
||||
@ -63,4 +63,11 @@ TEST(TestI420BufferPool, FrameValidAfterPoolDestruction) {
|
||||
memset(buffer->MutableDataY(), 0xA5, 16 * buffer->StrideY());
|
||||
}
|
||||
|
||||
TEST(TestI420BufferPool, MaxNumberOfBuffers) {
|
||||
I420BufferPool pool(false, 1);
|
||||
rtc::scoped_refptr<VideoFrameBuffer> buffer1 = pool.CreateBuffer(16, 16);
|
||||
EXPECT_NE(nullptr, buffer1.get());
|
||||
EXPECT_EQ(nullptr, pool.CreateBuffer(16, 16).get());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#define WEBRTC_COMMON_VIDEO_INCLUDE_I420_BUFFER_POOL_H_
|
||||
|
||||
#include <list>
|
||||
#include <limits>
|
||||
|
||||
#include "webrtc/base/race_checker.h"
|
||||
#include "webrtc/common_video/include/video_frame_buffer.h"
|
||||
@ -27,18 +28,21 @@ namespace webrtc {
|
||||
// are created. This is to prevent memory leaks where frames are not returned.
|
||||
class I420BufferPool {
|
||||
public:
|
||||
I420BufferPool() : I420BufferPool(false) {}
|
||||
explicit I420BufferPool(bool zero_initialize);
|
||||
I420BufferPool()
|
||||
: I420BufferPool(false, std::numeric_limits<size_t>::max()) {}
|
||||
explicit I420BufferPool(bool zero_initialize)
|
||||
: I420BufferPool(zero_initialize, std::numeric_limits<size_t>::max()) {}
|
||||
I420BufferPool(bool zero_initialze, size_t max_number_of_buffers);
|
||||
|
||||
// Returns a buffer from the pool, or creates a new buffer if no suitable
|
||||
// buffer exists in the pool.
|
||||
// Returns a buffer from the pool. If no suitable buffer exist in the pool
|
||||
// and there are less than |max_number_of_buffers| pending, a buffer is
|
||||
// created. Returns null otherwise.
|
||||
rtc::scoped_refptr<I420Buffer> CreateBuffer(int width, int height);
|
||||
// Clears buffers_ and detaches the thread checker so that it can be reused
|
||||
// later from another thread.
|
||||
void Release();
|
||||
|
||||
private:
|
||||
static const size_t kMaxNumberOfFramesBeforeCrash;
|
||||
// Explicitly use a RefCountedObject to get access to HasOneRef,
|
||||
// needed by the pool to check exclusive access.
|
||||
using PooledI420Buffer = rtc::RefCountedObject<I420Buffer>;
|
||||
@ -51,6 +55,8 @@ class I420BufferPool {
|
||||
// initial allocation (as shown by FFmpeg's own buffer allocation code). It
|
||||
// has to do with "Use-of-uninitialized-value" on "Linux_msan_chrome".
|
||||
bool zero_initialize_;
|
||||
// Max number of buffers this pool can have pending.
|
||||
size_t max_number_of_buffers_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
|
||||
#include "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h"
|
||||
#include "webrtc/system_wrappers/include/clock.h"
|
||||
#include "webrtc/system_wrappers/include/metrics.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
@ -1055,7 +1056,8 @@ int VP8EncoderImpl::RegisterEncodeCompleteCallback(
|
||||
}
|
||||
|
||||
VP8DecoderImpl::VP8DecoderImpl()
|
||||
: decode_complete_callback_(NULL),
|
||||
: buffer_pool_(false, 300 /* max_number_of_buffers*/),
|
||||
decode_complete_callback_(NULL),
|
||||
inited_(false),
|
||||
feedback_mode_(false),
|
||||
decoder_(NULL),
|
||||
@ -1270,6 +1272,12 @@ int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img,
|
||||
// Allocate memory for decoded image.
|
||||
rtc::scoped_refptr<I420Buffer> buffer =
|
||||
buffer_pool_.CreateBuffer(img->d_w, img->d_h);
|
||||
if (!buffer.get()) {
|
||||
// Pool has too many pending frames.
|
||||
RTC_HISTOGRAM_BOOLEAN("WebRTC.Video.VP8DecoderImpl.TooManyPendingFrames",
|
||||
1);
|
||||
return WEBRTC_VIDEO_CODEC_NO_OUTPUT;
|
||||
}
|
||||
|
||||
libyuv::I420Copy(img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y],
|
||||
img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user