/* * Copyright (c) 2012 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
/* Adjustments <=7, and each element in acc_diff can fit in signed * char.
*/
acc_diff = _mm_adds_epi8(acc_diff, padj);
acc_diff = _mm_subs_epi8(acc_diff, nadj);
/* Update pointers for next iteration. */
sig += sig_stride;
mc_running_avg_y += mc_avg_y_stride;
running_avg_y += avg_y_stride;
}
{ /* Compute the sum of all pixel differences of this MB. */ unsignedint abs_sum_diff = abs_sum_diff_16x1(acc_diff);
sum_diff_thresh = SUM_DIFF_THRESHOLD; if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH; if (abs_sum_diff > sum_diff_thresh) { // Before returning to copy the block (i.e., apply no denoising), // check if we can still apply some (weaker) temporal filtering to // this block, that would otherwise not be denoised at all. Simplest // is to apply an additional adjustment to running_avg_y to bring it // closer to sig. The adjustment is capped by a maximum delta, and // chosen such that in most cases the resulting sum_diff will be // within the acceptable range given by sum_diff_thresh.
// The delta is set by the excess of absolute pixel diff over the // threshold. int delta = ((abs_sum_diff - sum_diff_thresh) >> 8) + 1; // Only apply the adjustment for max delta up to 3. if (delta < 4) { const __m128i k_delta = _mm_set1_epi8(delta);
sig -= sig_stride * 16;
mc_running_avg_y -= mc_avg_y_stride * 16;
running_avg_y -= avg_y_stride * 16; for (r = 0; r < 16; ++r) {
__m128i v_running_avg_y =
_mm_loadu_si128((__m128i *)(&running_avg_y[0])); // Calculate differences. const __m128i v_sig = _mm_loadu_si128((__m128i *)(&sig[0])); const __m128i v_mc_running_avg_y =
_mm_loadu_si128((__m128i *)(&mc_running_avg_y[0])); const __m128i pdiff = _mm_subs_epu8(v_mc_running_avg_y, v_sig); const __m128i ndiff = _mm_subs_epu8(v_sig, v_mc_running_avg_y); // Obtain the sign. FF if diff is negative. const __m128i diff_sign = _mm_cmpeq_epi8(pdiff, k_0); // Clamp absolute difference to delta to get the adjustment. const __m128i adj = _mm_min_epu8(_mm_or_si128(pdiff, ndiff), k_delta); // Restore the sign and get positive and negative adjustments.
__m128i padj, nadj;
padj = _mm_andnot_si128(diff_sign, adj);
nadj = _mm_and_si128(diff_sign, adj); // Calculate filtered value.
v_running_avg_y = _mm_subs_epu8(v_running_avg_y, padj);
v_running_avg_y = _mm_adds_epu8(v_running_avg_y, nadj);
_mm_storeu_si128((__m128i *)running_avg_y, v_running_avg_y);
/* Adjustments <=7, and each element in acc_diff can fit in signed * char.
*/
acc_diff = _mm_adds_epi8(acc_diff, padj);
acc_diff = _mm_subs_epi8(acc_diff, nadj);
/* Update pointers for next iteration. */
sig += sig_stride * 2;
mc_running_avg += mc_avg_stride * 2;
running_avg += avg_stride * 2;
}
{ unsignedint abs_sum_diff = abs_sum_diff_16x1(acc_diff);
sum_diff_thresh = SUM_DIFF_THRESHOLD_UV; if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH_UV; if (abs_sum_diff > sum_diff_thresh) { // Before returning to copy the block (i.e., apply no denoising), // check if we can still apply some (weaker) temporal filtering to // this block, that would otherwise not be denoised at all. Simplest // is to apply an additional adjustment to running_avg_y to bring it // closer to sig. The adjustment is capped by a maximum delta, and // chosen such that in most cases the resulting sum_diff will be // within the acceptable range given by sum_diff_thresh.
// The delta is set by the excess of absolute pixel diff over the // threshold. int delta = ((abs_sum_diff - sum_diff_thresh) >> 8) + 1; // Only apply the adjustment for max delta up to 3. if (delta < 4) { const __m128i k_delta = _mm_set1_epi8(delta);
sig -= sig_stride * 8;
mc_running_avg -= mc_avg_stride * 8;
running_avg -= avg_stride * 8; for (r = 0; r < 4; ++r) { // Calculate differences. const __m128i v_sig_low =
_mm_castpd_si128(_mm_load_sd((double *)(&sig[0]))); const __m128i v_sig = _mm_castpd_si128(_mm_loadh_pd(
_mm_castsi128_pd(v_sig_low), (double *)(&sig[sig_stride]))); const __m128i v_mc_running_avg_low =
_mm_castpd_si128(_mm_load_sd((double *)(&mc_running_avg[0]))); const __m128i v_mc_running_avg = _mm_castpd_si128(
_mm_loadh_pd(_mm_castsi128_pd(v_mc_running_avg_low),
(double *)(&mc_running_avg[mc_avg_stride]))); const __m128i pdiff = _mm_subs_epu8(v_mc_running_avg, v_sig); const __m128i ndiff = _mm_subs_epu8(v_sig, v_mc_running_avg); // Obtain the sign. FF if diff is negative. const __m128i diff_sign = _mm_cmpeq_epi8(pdiff, k_0); // Clamp absolute difference to delta to get the adjustment. const __m128i adj = _mm_min_epu8(_mm_or_si128(pdiff, ndiff), k_delta); // Restore the sign and get positive and negative adjustments.
__m128i padj, nadj; const __m128i v_running_avg_low =
_mm_castpd_si128(_mm_load_sd((double *)(&running_avg[0])));
__m128i v_running_avg = _mm_castpd_si128(
_mm_loadh_pd(_mm_castsi128_pd(v_running_avg_low),
(double *)(&running_avg[avg_stride])));
padj = _mm_andnot_si128(diff_sign, adj);
nadj = _mm_and_si128(diff_sign, adj); // Calculate filtered value.
v_running_avg = _mm_subs_epu8(v_running_avg, padj);
v_running_avg = _mm_adds_epu8(v_running_avg, nadj);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.