Add ability to resize buffers pool in decoder and use it in IVF generator

Bug: webrtc:10138
Change-Id: I452f08f1d9af57de789bd947a1fcb95536845f80
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/162183
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30098}
This commit is contained in:
Artem Titov
2019-12-16 11:41:57 +01:00
committed by Commit Bot
parent 77eb338ae4
commit 8525a8028a
9 changed files with 111 additions and 11 deletions

View File

@ -218,6 +218,12 @@ int32_t H264DecoderImpl::InitDecode(const VideoCodec* codec_settings,
}
av_frame_.reset(av_frame_alloc());
if (codec_settings && codec_settings->buffer_pool_size) {
if (!pool_.Resize(*codec_settings->buffer_pool_size)) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
}
return WEBRTC_VIDEO_CODEC_OK;
}

View File

@ -149,6 +149,11 @@ int LibvpxVp8Decoder::InitDecode(const VideoCodec* inst, int number_of_cores) {
// Always start with a complete key frame.
key_frame_required_ = true;
if (inst && inst->buffer_pool_size) {
if (!buffer_pool_.Resize(*inst->buffer_pool_size)) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
}
return WEBRTC_VIDEO_CODEC_OK;
}

View File

@ -97,6 +97,36 @@ int Vp9FrameBufferPool::GetNumBuffersInUse() const {
return num_buffers_in_use;
}
bool Vp9FrameBufferPool::Resize(size_t max_number_of_buffers) {
rtc::CritScope cs(&buffers_lock_);
size_t used_buffers_count = 0;
for (const auto& buffer : allocated_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()) {
used_buffers_count++;
}
}
if (used_buffers_count > max_number_of_buffers) {
return false;
}
max_num_buffers_ = max_number_of_buffers;
size_t buffers_to_purge = allocated_buffers_.size() - max_num_buffers_;
auto iter = allocated_buffers_.begin();
while (iter != allocated_buffers_.end() && buffers_to_purge > 0) {
if ((*iter)->HasOneRef()) {
iter = allocated_buffers_.erase(iter);
buffers_to_purge--;
} else {
++iter;
}
}
return true;
}
void Vp9FrameBufferPool::ClearPool() {
rtc::CritScope cs(&buffers_lock_);
allocated_buffers_.clear();

View File

@ -26,6 +26,17 @@ struct vpx_codec_frame_buffer;
namespace webrtc {
// If more buffers than this are allocated we print warnings and crash if in
// debug mode. VP9 is defined to have 8 reference buffers, of which 3 can be
// referenced by any frame, see
// https://tools.ietf.org/html/draft-grange-vp9-bitstream-00#section-2.2.2.
// Assuming VP9 holds on to at most 8 buffers, any more buffers than that
// would have to be by application code. Decoded frames should not be
// referenced for longer than necessary. If we allow ~60 additional buffers
// then the application has ~1 second to e.g. render each frame of a 60 fps
// video.
constexpr size_t kDefaultMaxNumBuffers = 68;
// This memory pool is used to serve buffers to libvpx for decoding purposes in
// VP9, which is set up in InitializeVPXUsePool. After the initialization any
// time libvpx wants to decode a frame it will use buffers provided and released
@ -77,6 +88,10 @@ class Vp9FrameBufferPool {
rtc::scoped_refptr<Vp9FrameBuffer> GetFrameBuffer(size_t min_size);
// Gets the number of buffers currently in use (not ready to be recycled).
int GetNumBuffersInUse() const;
// Changes the max amount of buffers in the pool to the new value.
// Returns true if change was successful and false if the amount of already
// allocated buffers is bigger than new value.
bool Resize(size_t max_number_of_buffers);
// Releases allocated buffers, deleting available buffers. Buffers in use are
// not deleted until they are no longer referenced.
void ClearPool();
@ -108,16 +123,7 @@ class Vp9FrameBufferPool {
// All buffers, in use or ready to be recycled.
std::vector<rtc::scoped_refptr<Vp9FrameBuffer>> allocated_buffers_
RTC_GUARDED_BY(buffers_lock_);
// If more buffers than this are allocated we print warnings and crash if in
// debug mode. VP9 is defined to have 8 reference buffers, of which 3 can be
// referenced by any frame, see
// https://tools.ietf.org/html/draft-grange-vp9-bitstream-00#section-2.2.2.
// Assuming VP9 holds on to at most 8 buffers, any more buffers than that
// would have to be by application code. Decoded frames should not be
// referenced for longer than necessary. If we allow ~60 additional buffers
// then the application has ~1 second to e.g. render each frame of a 60 fps
// video.
static const size_t max_num_buffers_ = 68;
size_t max_num_buffers_ = kDefaultMaxNumBuffers;
};
} // namespace webrtc

View File

@ -1652,6 +1652,11 @@ int VP9DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) {
inited_ = true;
// Always start with a complete key frame.
key_frame_required_ = true;
if (inst && inst->buffer_pool_size) {
if (!frame_buffer_pool_.Resize(*inst->buffer_pool_size)) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
}
return WEBRTC_VIDEO_CODEC_OK;
}