From 3f21ba68bcba42f4bba860190557a4f92412a1b0 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Thu, 28 Jul 2022 09:58:58 +0200 Subject: [PATCH] Improve LibvpxVp9Encoder::UpdateReferenceBuffers perfomance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change speeds up vp9 encoder reference fuzzer Bug: chromium:1281020 Change-Id: I8def449b2bf7a525c8d4c8179b68d0b89594bdc1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/269216 Auto-Submit: Danil Chapovalov Reviewed-by: Erik Språng Commit-Queue: Erik Språng Cr-Commit-Position: refs/heads/main@{#37642} --- .../codecs/vp9/libvpx_vp9_encoder.cc | 33 ++++++++++--------- .../codecs/vp9/libvpx_vp9_encoder.h | 20 ++++------- 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc index 833afeb19e..54585082db 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc @@ -738,7 +738,7 @@ int LibvpxVp9Encoder::InitEncode(const VideoCodec* inst, return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } } - ref_buf_.clear(); + ref_buf_ = {}; return InitAndSetControlSettings(inst); } @@ -1464,10 +1464,10 @@ void LibvpxVp9Encoder::FillReferenceIndices(const vpx_codec_cx_pkt& pkt, if (enc_layer_conf.reference_last[layer_id.spatial_layer_id]) { const size_t fb_idx = enc_layer_conf.lst_fb_idx[layer_id.spatial_layer_id]; - RTC_DCHECK(ref_buf_.find(fb_idx) != ref_buf_.end()); + RTC_DCHECK_LT(fb_idx, ref_buf_.size()); if (std::find(ref_buf_list.begin(), ref_buf_list.end(), - ref_buf_.at(fb_idx)) == ref_buf_list.end()) { - ref_buf_list.push_back(ref_buf_.at(fb_idx)); + ref_buf_[fb_idx]) == ref_buf_list.end()) { + ref_buf_list.push_back(ref_buf_[fb_idx]); ref_buf_flags |= 1 << fb_idx; } } @@ -1475,10 +1475,10 @@ void LibvpxVp9Encoder::FillReferenceIndices(const vpx_codec_cx_pkt& pkt, if (enc_layer_conf.reference_alt_ref[layer_id.spatial_layer_id]) { const size_t fb_idx = enc_layer_conf.alt_fb_idx[layer_id.spatial_layer_id]; - RTC_DCHECK(ref_buf_.find(fb_idx) != ref_buf_.end()); + RTC_DCHECK_LT(fb_idx, ref_buf_.size()); if (std::find(ref_buf_list.begin(), ref_buf_list.end(), - ref_buf_.at(fb_idx)) == ref_buf_list.end()) { - ref_buf_list.push_back(ref_buf_.at(fb_idx)); + ref_buf_[fb_idx]) == ref_buf_list.end()) { + ref_buf_list.push_back(ref_buf_[fb_idx]); ref_buf_flags |= 1 << fb_idx; } } @@ -1486,10 +1486,10 @@ void LibvpxVp9Encoder::FillReferenceIndices(const vpx_codec_cx_pkt& pkt, if (enc_layer_conf.reference_golden[layer_id.spatial_layer_id]) { const size_t fb_idx = enc_layer_conf.gld_fb_idx[layer_id.spatial_layer_id]; - RTC_DCHECK(ref_buf_.find(fb_idx) != ref_buf_.end()); + RTC_DCHECK_LT(fb_idx, ref_buf_.size()); if (std::find(ref_buf_list.begin(), ref_buf_list.end(), - ref_buf_.at(fb_idx)) == ref_buf_list.end()) { - ref_buf_list.push_back(ref_buf_.at(fb_idx)); + ref_buf_[fb_idx]) == ref_buf_list.end()) { + ref_buf_list.push_back(ref_buf_[fb_idx]); ref_buf_flags |= 1 << fb_idx; } } @@ -1511,7 +1511,7 @@ void LibvpxVp9Encoder::FillReferenceIndices(const vpx_codec_cx_pkt& pkt, RTC_DCHECK_EQ(num_temporal_layers_, 1); // In non-SVC mode encoder doesn't provide reference list. Assume each frame // refers previous one, which is stored in buffer 0. - ref_buf_list.push_back(ref_buf_.at(0)); + ref_buf_list.push_back(ref_buf_[0]); } std::vector ref_pid_list; @@ -1559,8 +1559,9 @@ void LibvpxVp9Encoder::UpdateReferenceBuffers(const vpx_codec_cx_pkt& pkt, vpx_svc_layer_id_t layer_id = {0}; libvpx_->codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); - RefFrameBuffer frame_buf(pic_num, layer_id.spatial_layer_id, - layer_id.temporal_layer_id); + RefFrameBuffer frame_buf = {.pic_num = pic_num, + .spatial_layer_id = layer_id.spatial_layer_id, + .temporal_layer_id = layer_id.temporal_layer_id}; if (is_svc_) { vpx_svc_ref_frame_config_t enc_layer_conf = {{0}}; @@ -1569,7 +1570,7 @@ void LibvpxVp9Encoder::UpdateReferenceBuffers(const vpx_codec_cx_pkt& pkt, const int update_buffer_slot = enc_layer_conf.update_buffer_slot[layer_id.spatial_layer_id]; - for (size_t i = 0; i < kNumVp9Buffers; ++i) { + for (size_t i = 0; i < ref_buf_.size(); ++i) { if (update_buffer_slot & (1 << i)) { ref_buf_[i] = frame_buf; } @@ -1597,7 +1598,7 @@ void LibvpxVp9Encoder::UpdateReferenceBuffers(const vpx_codec_cx_pkt& pkt, vpx_svc_ref_frame_config_t LibvpxVp9Encoder::SetReferences( bool is_key_pic, - size_t first_active_spatial_layer_id) { + int first_active_spatial_layer_id) { // kRefBufIdx, kUpdBufIdx need to be updated to support longer GOFs. RTC_DCHECK_LE(gof_.num_frames_in_gof, 4); @@ -1619,7 +1620,7 @@ vpx_svc_ref_frame_config_t LibvpxVp9Encoder::SetReferences( // for temporal references plus 1 buffer for spatial reference. 7 buffers // in total. - for (size_t sl_idx = first_active_spatial_layer_id; + for (int sl_idx = first_active_spatial_layer_id; sl_idx < num_active_spatial_layers_; ++sl_idx) { const size_t curr_pic_num = is_key_pic ? 0 : pics_since_key_ + 1; const size_t gof_idx = curr_pic_num % gof_.num_frames_in_gof; diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h index 4e9dd794a1..fb6f234ead 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h @@ -14,6 +14,7 @@ #ifdef RTC_ENABLE_VP9 +#include #include #include @@ -74,9 +75,8 @@ class LibvpxVp9Encoder : public VP9Encoder { bool inter_layer_predicted, CodecSpecificInfoVP9* vp9_info); void UpdateReferenceBuffers(const vpx_codec_cx_pkt& pkt, size_t pic_num); - vpx_svc_ref_frame_config_t SetReferences( - bool is_key_pic, - size_t first_active_spatial_layer_id); + vpx_svc_ref_frame_config_t SetReferences(bool is_key_pic, + int first_active_spatial_layer_id); bool ExplicitlyConfiguredSpatialLayers() const; bool SetSvcRates(const VideoBitrateAllocation& bitrate_allocation); @@ -156,24 +156,16 @@ class LibvpxVp9Encoder : public VP9Encoder { // Used for flexible mode. bool is_flexible_mode_; struct RefFrameBuffer { - RefFrameBuffer(size_t pic_num, - size_t spatial_layer_id, - size_t temporal_layer_id) - : pic_num(pic_num), - spatial_layer_id(spatial_layer_id), - temporal_layer_id(temporal_layer_id) {} - RefFrameBuffer() {} - bool operator==(const RefFrameBuffer& o) { return pic_num == o.pic_num && spatial_layer_id == o.spatial_layer_id && temporal_layer_id == o.temporal_layer_id; } size_t pic_num = 0; - size_t spatial_layer_id = 0; - size_t temporal_layer_id = 0; + int spatial_layer_id = 0; + int temporal_layer_id = 0; }; - flat_map ref_buf_; + std::array ref_buf_; std::vector layer_frames_; // Variable frame-rate related fields and methods.