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:
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user