vp8_impl.cc: Make it possible to base postproc deblocking level for arm on qp (e.g. turn off deblocking for low qp values).

BUG=webrtc:6634

Review-Url: https://codereview.webrtc.org/2970923002
Cr-Commit-Position: refs/heads/master@{#19300}
This commit is contained in:
asapersson
2017-08-09 23:37:05 -07:00
committed by Commit Bot
parent 44d8f56959
commit e5d02f9204
3 changed files with 86 additions and 7 deletions

View File

@ -234,6 +234,7 @@ rtc_static_library("webrtc_vp8") {
"../../api/video_codecs:video_codecs_api",
"../../common_video",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:rtc_numerics",
"../../rtc_base:sequenced_task_checker",
"../../system_wrappers",
]

View File

@ -29,6 +29,7 @@
#include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/numerics/exp_filter.h"
#include "webrtc/rtc_base/random.h"
#include "webrtc/rtc_base/timeutils.h"
#include "webrtc/rtc_base/trace_event.h"
@ -122,6 +123,28 @@ bool GetGfBoostPercentageFromFieldTrialGroup(int* boost_percentage) {
return true;
}
void GetPostProcParamsFromFieldTrialGroup(
VP8DecoderImpl::DeblockParams* deblock_params) {
std::string group =
webrtc::field_trial::FindFullName(kVp8PostProcArmFieldTrial);
if (group.empty())
return;
VP8DecoderImpl::DeblockParams params;
if (sscanf(group.c_str(), "Enabled-%d,%d,%d", &params.max_level,
&params.min_qp, &params.degrade_qp) != 3)
return;
if (params.max_level < 0 || params.max_level > 16)
return;
if (params.min_qp < 0 || params.degrade_qp <= params.min_qp)
return;
*deblock_params = params;
}
} // namespace
VP8Encoder* VP8Encoder::Create() {
@ -925,9 +948,33 @@ int VP8EncoderImpl::RegisterEncodeCompleteCallback(
return WEBRTC_VIDEO_CODEC_OK;
}
class VP8DecoderImpl::QpSmoother {
public:
QpSmoother() : last_sample_ms_(rtc::TimeMillis()), smoother_(kAlpha) {}
int GetAvg() const {
float value = smoother_.filtered();
return (value == rtc::ExpFilter::kValueUndefined) ? 0
: static_cast<int>(value);
}
void Add(float sample) {
int64_t now_ms = rtc::TimeMillis();
smoother_.Apply(static_cast<float>(now_ms - last_sample_ms_), sample);
last_sample_ms_ = now_ms;
}
void Reset() { smoother_.Reset(kAlpha); }
private:
const float kAlpha = 0.95f;
int64_t last_sample_ms_;
rtc::ExpFilter smoother_;
};
VP8DecoderImpl::VP8DecoderImpl()
: use_postproc_arm_(webrtc::field_trial::FindFullName(
kVp8PostProcArmFieldTrial) == "Enabled"),
: use_postproc_arm_(
webrtc::field_trial::IsEnabled(kVp8PostProcArmFieldTrial)),
buffer_pool_(false, 300 /* max_number_of_buffers*/),
decode_complete_callback_(NULL),
inited_(false),
@ -935,7 +982,11 @@ VP8DecoderImpl::VP8DecoderImpl()
propagation_cnt_(-1),
last_frame_width_(0),
last_frame_height_(0),
key_frame_required_(true) {}
key_frame_required_(true),
qp_smoother_(use_postproc_arm_ ? new QpSmoother() : nullptr) {
if (use_postproc_arm_)
GetPostProcParamsFromFieldTrialGroup(&deblock_);
}
VP8DecoderImpl::~VP8DecoderImpl() {
inited_ = true; // in order to do the actual release
@ -999,12 +1050,23 @@ int VP8DecoderImpl::Decode(const EncodedImage& input_image,
if (use_postproc_arm_) {
vp8_postproc_cfg_t ppcfg;
ppcfg.post_proc_flag = VP8_MFQE;
// For low resolutions, use stronger deblocking filter and enable the
// deblock and demacroblocker.
// For low resolutions, use stronger deblocking filter.
int last_width_x_height = last_frame_width_ * last_frame_height_;
if (last_width_x_height > 0 && last_width_x_height <= 320 * 240) {
ppcfg.deblocking_level = 6; // Only affects VP8_DEMACROBLOCK.
ppcfg.post_proc_flag |= VP8_DEBLOCK | VP8_DEMACROBLOCK;
// Enable the deblock and demacroblocker based on qp thresholds.
RTC_DCHECK(qp_smoother_);
int qp = qp_smoother_->GetAvg();
if (qp > deblock_.min_qp) {
int level = deblock_.max_level;
if (qp < deblock_.degrade_qp) {
// Use lower level.
level = deblock_.max_level * (qp - deblock_.min_qp) /
(deblock_.degrade_qp - deblock_.min_qp);
}
// Deblocking level only affects VP8_DEMACROBLOCK.
ppcfg.deblocking_level = std::max(level, 1);
ppcfg.post_proc_flag |= VP8_DEBLOCK | VP8_DEMACROBLOCK;
}
}
vpx_codec_control(decoder_, VP8_SET_POSTPROC, &ppcfg);
}
@ -1104,6 +1166,13 @@ int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img,
// Decoder OK and NULL image => No show frame
return WEBRTC_VIDEO_CODEC_NO_OUTPUT;
}
if (qp_smoother_) {
if (last_frame_width_ != static_cast<int>(img->d_w) ||
last_frame_height_ != static_cast<int>(img->d_h)) {
qp_smoother_->Reset();
}
qp_smoother_->Add(qp);
}
last_frame_width_ = img->d_w;
last_frame_height_ = img->d_h;
// Allocate memory for decoded image.

View File

@ -135,7 +135,14 @@ class VP8DecoderImpl : public VP8Decoder {
const char* ImplementationName() const override;
struct DeblockParams {
int max_level = 6; // Deblocking strength: [0, 16].
int degrade_qp = 1; // If QP value is below, start lowering |max_level|.
int min_qp = 0; // If QP value is below, turn off deblocking.
};
private:
class QpSmoother;
int ReturnFrame(const vpx_image_t* img,
uint32_t timeStamp,
int64_t ntp_time_ms,
@ -151,6 +158,8 @@ class VP8DecoderImpl : public VP8Decoder {
int last_frame_width_;
int last_frame_height_;
bool key_frame_required_;
DeblockParams deblock_;
const std::unique_ptr<QpSmoother> qp_smoother_;
};
} // namespace webrtc