External VNR speed improvement.

Improved visual quality with 3x times speed-up.
Change list:
 1. Remove second chance filter in temporal denoising filter to mitigate trailing artifact.
 2. Add swap buffer to save one whole-frame memcpy.
 3. Do noise estimation on every N blocks.
 4. Adopt a faster moving object detection algorithm (change the structure).
 5. Refactor the for loops and PositionCheck().
 6. Refactor the function ReduceFalseDetection (RFD).
 7. Fix a bug in TrailingBlock() which causes a mismatch.
 8. Change unit test to support swap buffer test.
 9. Remove CopyMem8x8, use memcpy to copy U/V plane which can be optimized future.
 10. Remove DenoiseMetrics.

Review URL: https://codereview.webrtc.org/1871853003

Cr-Commit-Position: refs/heads/master@{#12340}
This commit is contained in:
jackychen
2016-04-12 23:02:55 -07:00
committed by Commit bot
parent a31fb75e44
commit afaae0d151
14 changed files with 391 additions and 581 deletions

View File

@ -27,10 +27,10 @@ void NoiseEstimation::GetNoise(int mb_index, uint32_t var, uint32_t luma) {
consec_low_var_[mb_index]++;
num_static_block_++;
if (consec_low_var_[mb_index] >= kConsecLowVarFrame &&
(luma >> 8) < kAverageLumaMax && (luma >> 8) > kAverageLumaMin) {
(luma >> 6) < kAverageLumaMax && (luma >> 6) > kAverageLumaMin) {
// Normalized var by the average luma value, this gives more weight to
// darker blocks.
int nor_var = var / (luma >> 12);
int nor_var = var / (luma >> 10);
noise_var_ +=
nor_var > kBlockSelectionVarMax ? kBlockSelectionVarMax : nor_var;
num_noisy_block_++;
@ -46,25 +46,28 @@ void NoiseEstimation::UpdateNoiseLevel() {
// condition more reasonable.
// No enough samples implies the motion of the camera or too many moving
// objects in the frame.
if (num_static_block_ < (0.65 * mb_cols_ * mb_rows_) || !num_noisy_block_) {
if (num_static_block_ <
(0.65 * mb_cols_ * mb_rows_ / NOISE_SUBSAMPLE_INTERVAL) ||
!num_noisy_block_) {
#if DISPLAY
printf("Not enough samples. %d \n", num_static_block_);
#endif
noise_var_ = 0;
noise_var_accum_ = 0;
num_static_block_ = 0;
num_noisy_block_ = 0;
#if DISPLAY
printf("Not enough samples.\n");
#endif
num_static_block_ = 0;
return;
} else {
#if DISPLAY
printf("%d %d fraction = %.3f\n", num_static_block_,
mb_cols_ * mb_rows_ / NOISE_SUBSAMPLE_INTERVAL,
percent_static_block_);
#endif
// Normalized by the number of noisy blocks.
noise_var_ /= num_noisy_block_;
// Get the percentage of static blocks.
percent_static_block_ =
static_cast<double>(num_static_block_) / (mb_cols_ * mb_rows_);
#if DISPLAY
printf("%d %d fraction = %.3f\n", num_static_block_, mb_cols_ * mb_rows_,
percent_static_block_);
#endif
percent_static_block_ = static_cast<double>(num_static_block_) /
(mb_cols_ * mb_rows_ / NOISE_SUBSAMPLE_INTERVAL);
num_noisy_block_ = 0;
num_static_block_ = 0;
}
@ -75,12 +78,12 @@ void NoiseEstimation::UpdateNoiseLevel() {
} else {
noise_var_accum_ = (noise_var_accum_ * 15 + noise_var_) / 16;
}
// Reset noise_var_ for the next frame.
noise_var_ = 0;
#if DISPLAY
printf("noise_var_accum_ = %.1f, noise_var_ = %d.\n", noise_var_accum_,
noise_var_);
#endif
// Reset noise_var_ for the next frame.
noise_var_ = 0;
}
uint8_t NoiseEstimation::GetNoiseLevel() {