(61d00a474) v0.9.7.1
This commit is contained in:
@@ -0,0 +1,460 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "vp8/encoder/denoising.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "./vp8_rtcd.h"
|
||||
|
||||
/*
|
||||
* The filter function was modified to reduce the computational complexity.
|
||||
*
|
||||
* Step 1:
|
||||
* Instead of applying tap coefficients for each pixel, we calculated the
|
||||
* pixel adjustments vs. pixel diff value ahead of time.
|
||||
* adjustment = filtered_value - current_raw
|
||||
* = (filter_coefficient * diff + 128) >> 8
|
||||
* where
|
||||
* filter_coefficient = (255 << 8) / (256 + ((abs_diff * 330) >> 3));
|
||||
* filter_coefficient += filter_coefficient /
|
||||
* (3 + motion_magnitude_adjustment);
|
||||
* filter_coefficient is clamped to 0 ~ 255.
|
||||
*
|
||||
* Step 2:
|
||||
* The adjustment vs. diff curve becomes flat very quick when diff increases.
|
||||
* This allowed us to use only several levels to approximate the curve without
|
||||
* changing the filtering algorithm too much.
|
||||
* The adjustments were further corrected by checking the motion magnitude.
|
||||
* The levels used are:
|
||||
* diff level adjustment w/o adjustment w/
|
||||
* motion correction motion correction
|
||||
* [-255, -16] 3 -6 -7
|
||||
* [-15, -8] 2 -4 -5
|
||||
* [-7, -4] 1 -3 -4
|
||||
* [-3, 3] 0 diff diff
|
||||
* [4, 7] 1 3 4
|
||||
* [8, 15] 2 4 5
|
||||
* [16, 255] 3 6 7
|
||||
*/
|
||||
|
||||
int vp8_denoiser_filter_neon(unsigned char *mc_running_avg_y,
|
||||
int mc_running_avg_y_stride,
|
||||
unsigned char *running_avg_y,
|
||||
int running_avg_y_stride, unsigned char *sig,
|
||||
int sig_stride, unsigned int motion_magnitude,
|
||||
int increase_denoising) {
|
||||
/* If motion_magnitude is small, making the denoiser more aggressive by
|
||||
* increasing the adjustment for each level, level1 adjustment is
|
||||
* increased, the deltas stay the same.
|
||||
*/
|
||||
int shift_inc =
|
||||
(increase_denoising && motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD)
|
||||
? 1
|
||||
: 0;
|
||||
const uint8x16_t v_level1_adjustment = vmovq_n_u8(
|
||||
(motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) ? 4 + shift_inc : 3);
|
||||
const uint8x16_t v_delta_level_1_and_2 = vdupq_n_u8(1);
|
||||
const uint8x16_t v_delta_level_2_and_3 = vdupq_n_u8(2);
|
||||
const uint8x16_t v_level1_threshold = vmovq_n_u8(4 + shift_inc);
|
||||
const uint8x16_t v_level2_threshold = vdupq_n_u8(8);
|
||||
const uint8x16_t v_level3_threshold = vdupq_n_u8(16);
|
||||
int64x2_t v_sum_diff_total = vdupq_n_s64(0);
|
||||
|
||||
/* Go over lines. */
|
||||
int r;
|
||||
for (r = 0; r < 16; ++r) {
|
||||
/* Load inputs. */
|
||||
const uint8x16_t v_sig = vld1q_u8(sig);
|
||||
const uint8x16_t v_mc_running_avg_y = vld1q_u8(mc_running_avg_y);
|
||||
|
||||
/* Calculate absolute difference and sign masks. */
|
||||
const uint8x16_t v_abs_diff = vabdq_u8(v_sig, v_mc_running_avg_y);
|
||||
const uint8x16_t v_diff_pos_mask = vcltq_u8(v_sig, v_mc_running_avg_y);
|
||||
const uint8x16_t v_diff_neg_mask = vcgtq_u8(v_sig, v_mc_running_avg_y);
|
||||
|
||||
/* Figure out which level that put us in. */
|
||||
const uint8x16_t v_level1_mask = vcleq_u8(v_level1_threshold, v_abs_diff);
|
||||
const uint8x16_t v_level2_mask = vcleq_u8(v_level2_threshold, v_abs_diff);
|
||||
const uint8x16_t v_level3_mask = vcleq_u8(v_level3_threshold, v_abs_diff);
|
||||
|
||||
/* Calculate absolute adjustments for level 1, 2 and 3. */
|
||||
const uint8x16_t v_level2_adjustment =
|
||||
vandq_u8(v_level2_mask, v_delta_level_1_and_2);
|
||||
const uint8x16_t v_level3_adjustment =
|
||||
vandq_u8(v_level3_mask, v_delta_level_2_and_3);
|
||||
const uint8x16_t v_level1and2_adjustment =
|
||||
vaddq_u8(v_level1_adjustment, v_level2_adjustment);
|
||||
const uint8x16_t v_level1and2and3_adjustment =
|
||||
vaddq_u8(v_level1and2_adjustment, v_level3_adjustment);
|
||||
|
||||
/* Figure adjustment absolute value by selecting between the absolute
|
||||
* difference if in level0 or the value for level 1, 2 and 3.
|
||||
*/
|
||||
const uint8x16_t v_abs_adjustment =
|
||||
vbslq_u8(v_level1_mask, v_level1and2and3_adjustment, v_abs_diff);
|
||||
|
||||
/* Calculate positive and negative adjustments. Apply them to the signal
|
||||
* and accumulate them. Adjustments are less than eight and the maximum
|
||||
* sum of them (7 * 16) can fit in a signed char.
|
||||
*/
|
||||
const uint8x16_t v_pos_adjustment =
|
||||
vandq_u8(v_diff_pos_mask, v_abs_adjustment);
|
||||
const uint8x16_t v_neg_adjustment =
|
||||
vandq_u8(v_diff_neg_mask, v_abs_adjustment);
|
||||
|
||||
uint8x16_t v_running_avg_y = vqaddq_u8(v_sig, v_pos_adjustment);
|
||||
v_running_avg_y = vqsubq_u8(v_running_avg_y, v_neg_adjustment);
|
||||
|
||||
/* Store results. */
|
||||
vst1q_u8(running_avg_y, v_running_avg_y);
|
||||
|
||||
/* Sum all the accumulators to have the sum of all pixel differences
|
||||
* for this macroblock.
|
||||
*/
|
||||
{
|
||||
const int8x16_t v_sum_diff =
|
||||
vqsubq_s8(vreinterpretq_s8_u8(v_pos_adjustment),
|
||||
vreinterpretq_s8_u8(v_neg_adjustment));
|
||||
|
||||
const int16x8_t fe_dc_ba_98_76_54_32_10 = vpaddlq_s8(v_sum_diff);
|
||||
|
||||
const int32x4_t fedc_ba98_7654_3210 =
|
||||
vpaddlq_s16(fe_dc_ba_98_76_54_32_10);
|
||||
|
||||
const int64x2_t fedcba98_76543210 = vpaddlq_s32(fedc_ba98_7654_3210);
|
||||
|
||||
v_sum_diff_total = vqaddq_s64(v_sum_diff_total, fedcba98_76543210);
|
||||
}
|
||||
|
||||
/* Update pointers for next iteration. */
|
||||
sig += sig_stride;
|
||||
mc_running_avg_y += mc_running_avg_y_stride;
|
||||
running_avg_y += running_avg_y_stride;
|
||||
}
|
||||
|
||||
/* Too much adjustments => copy block. */
|
||||
{
|
||||
int64x1_t x = vqadd_s64(vget_high_s64(v_sum_diff_total),
|
||||
vget_low_s64(v_sum_diff_total));
|
||||
int sum_diff = vget_lane_s32(vabs_s32(vreinterpret_s32_s64(x)), 0);
|
||||
int sum_diff_thresh = SUM_DIFF_THRESHOLD;
|
||||
|
||||
if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH;
|
||||
if (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 accceptable range given by sum_diff_thresh.
|
||||
|
||||
// The delta is set by the excess of absolute pixel diff over the
|
||||
// threshold.
|
||||
int delta = ((sum_diff - sum_diff_thresh) >> 8) + 1;
|
||||
// Only apply the adjustment for max delta up to 3.
|
||||
if (delta < 4) {
|
||||
const uint8x16_t k_delta = vmovq_n_u8(delta);
|
||||
sig -= sig_stride * 16;
|
||||
mc_running_avg_y -= mc_running_avg_y_stride * 16;
|
||||
running_avg_y -= running_avg_y_stride * 16;
|
||||
for (r = 0; r < 16; ++r) {
|
||||
uint8x16_t v_running_avg_y = vld1q_u8(running_avg_y);
|
||||
const uint8x16_t v_sig = vld1q_u8(sig);
|
||||
const uint8x16_t v_mc_running_avg_y = vld1q_u8(mc_running_avg_y);
|
||||
|
||||
/* Calculate absolute difference and sign masks. */
|
||||
const uint8x16_t v_abs_diff = vabdq_u8(v_sig, v_mc_running_avg_y);
|
||||
const uint8x16_t v_diff_pos_mask =
|
||||
vcltq_u8(v_sig, v_mc_running_avg_y);
|
||||
const uint8x16_t v_diff_neg_mask =
|
||||
vcgtq_u8(v_sig, v_mc_running_avg_y);
|
||||
// Clamp absolute difference to delta to get the adjustment.
|
||||
const uint8x16_t v_abs_adjustment = vminq_u8(v_abs_diff, (k_delta));
|
||||
|
||||
const uint8x16_t v_pos_adjustment =
|
||||
vandq_u8(v_diff_pos_mask, v_abs_adjustment);
|
||||
const uint8x16_t v_neg_adjustment =
|
||||
vandq_u8(v_diff_neg_mask, v_abs_adjustment);
|
||||
|
||||
v_running_avg_y = vqsubq_u8(v_running_avg_y, v_pos_adjustment);
|
||||
v_running_avg_y = vqaddq_u8(v_running_avg_y, v_neg_adjustment);
|
||||
|
||||
/* Store results. */
|
||||
vst1q_u8(running_avg_y, v_running_avg_y);
|
||||
|
||||
{
|
||||
const int8x16_t v_sum_diff =
|
||||
vqsubq_s8(vreinterpretq_s8_u8(v_neg_adjustment),
|
||||
vreinterpretq_s8_u8(v_pos_adjustment));
|
||||
|
||||
const int16x8_t fe_dc_ba_98_76_54_32_10 = vpaddlq_s8(v_sum_diff);
|
||||
const int32x4_t fedc_ba98_7654_3210 =
|
||||
vpaddlq_s16(fe_dc_ba_98_76_54_32_10);
|
||||
const int64x2_t fedcba98_76543210 =
|
||||
vpaddlq_s32(fedc_ba98_7654_3210);
|
||||
|
||||
v_sum_diff_total = vqaddq_s64(v_sum_diff_total, fedcba98_76543210);
|
||||
}
|
||||
/* Update pointers for next iteration. */
|
||||
sig += sig_stride;
|
||||
mc_running_avg_y += mc_running_avg_y_stride;
|
||||
running_avg_y += running_avg_y_stride;
|
||||
}
|
||||
{
|
||||
// Update the sum of all pixel differences of this MB.
|
||||
x = vqadd_s64(vget_high_s64(v_sum_diff_total),
|
||||
vget_low_s64(v_sum_diff_total));
|
||||
sum_diff = vget_lane_s32(vabs_s32(vreinterpret_s32_s64(x)), 0);
|
||||
|
||||
if (sum_diff > sum_diff_thresh) {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell above level that block was filtered. */
|
||||
running_avg_y -= running_avg_y_stride * 16;
|
||||
sig -= sig_stride * 16;
|
||||
|
||||
vp8_copy_mem16x16(running_avg_y, running_avg_y_stride, sig, sig_stride);
|
||||
|
||||
return FILTER_BLOCK;
|
||||
}
|
||||
|
||||
int vp8_denoiser_filter_uv_neon(unsigned char *mc_running_avg,
|
||||
int mc_running_avg_stride,
|
||||
unsigned char *running_avg,
|
||||
int running_avg_stride, unsigned char *sig,
|
||||
int sig_stride, unsigned int motion_magnitude,
|
||||
int increase_denoising) {
|
||||
/* If motion_magnitude is small, making the denoiser more aggressive by
|
||||
* increasing the adjustment for each level, level1 adjustment is
|
||||
* increased, the deltas stay the same.
|
||||
*/
|
||||
int shift_inc =
|
||||
(increase_denoising && motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD_UV)
|
||||
? 1
|
||||
: 0;
|
||||
const uint8x16_t v_level1_adjustment = vmovq_n_u8(
|
||||
(motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD_UV) ? 4 + shift_inc : 3);
|
||||
|
||||
const uint8x16_t v_delta_level_1_and_2 = vdupq_n_u8(1);
|
||||
const uint8x16_t v_delta_level_2_and_3 = vdupq_n_u8(2);
|
||||
const uint8x16_t v_level1_threshold = vmovq_n_u8(4 + shift_inc);
|
||||
const uint8x16_t v_level2_threshold = vdupq_n_u8(8);
|
||||
const uint8x16_t v_level3_threshold = vdupq_n_u8(16);
|
||||
int64x2_t v_sum_diff_total = vdupq_n_s64(0);
|
||||
int r;
|
||||
|
||||
{
|
||||
uint16x4_t v_sum_block = vdup_n_u16(0);
|
||||
|
||||
// Avoid denoising color signal if its close to average level.
|
||||
for (r = 0; r < 8; ++r) {
|
||||
const uint8x8_t v_sig = vld1_u8(sig);
|
||||
const uint16x4_t _76_54_32_10 = vpaddl_u8(v_sig);
|
||||
v_sum_block = vqadd_u16(v_sum_block, _76_54_32_10);
|
||||
sig += sig_stride;
|
||||
}
|
||||
sig -= sig_stride * 8;
|
||||
{
|
||||
const uint32x2_t _7654_3210 = vpaddl_u16(v_sum_block);
|
||||
const uint64x1_t _76543210 = vpaddl_u32(_7654_3210);
|
||||
const int sum_block = vget_lane_s32(vreinterpret_s32_u64(_76543210), 0);
|
||||
if (abs(sum_block - (128 * 8 * 8)) < SUM_DIFF_FROM_AVG_THRESH_UV) {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Go over lines. */
|
||||
for (r = 0; r < 4; ++r) {
|
||||
/* Load inputs. */
|
||||
const uint8x8_t v_sig_lo = vld1_u8(sig);
|
||||
const uint8x8_t v_sig_hi = vld1_u8(&sig[sig_stride]);
|
||||
const uint8x16_t v_sig = vcombine_u8(v_sig_lo, v_sig_hi);
|
||||
const uint8x8_t v_mc_running_avg_lo = vld1_u8(mc_running_avg);
|
||||
const uint8x8_t v_mc_running_avg_hi =
|
||||
vld1_u8(&mc_running_avg[mc_running_avg_stride]);
|
||||
const uint8x16_t v_mc_running_avg =
|
||||
vcombine_u8(v_mc_running_avg_lo, v_mc_running_avg_hi);
|
||||
/* Calculate absolute difference and sign masks. */
|
||||
const uint8x16_t v_abs_diff = vabdq_u8(v_sig, v_mc_running_avg);
|
||||
const uint8x16_t v_diff_pos_mask = vcltq_u8(v_sig, v_mc_running_avg);
|
||||
const uint8x16_t v_diff_neg_mask = vcgtq_u8(v_sig, v_mc_running_avg);
|
||||
|
||||
/* Figure out which level that put us in. */
|
||||
const uint8x16_t v_level1_mask = vcleq_u8(v_level1_threshold, v_abs_diff);
|
||||
const uint8x16_t v_level2_mask = vcleq_u8(v_level2_threshold, v_abs_diff);
|
||||
const uint8x16_t v_level3_mask = vcleq_u8(v_level3_threshold, v_abs_diff);
|
||||
|
||||
/* Calculate absolute adjustments for level 1, 2 and 3. */
|
||||
const uint8x16_t v_level2_adjustment =
|
||||
vandq_u8(v_level2_mask, v_delta_level_1_and_2);
|
||||
const uint8x16_t v_level3_adjustment =
|
||||
vandq_u8(v_level3_mask, v_delta_level_2_and_3);
|
||||
const uint8x16_t v_level1and2_adjustment =
|
||||
vaddq_u8(v_level1_adjustment, v_level2_adjustment);
|
||||
const uint8x16_t v_level1and2and3_adjustment =
|
||||
vaddq_u8(v_level1and2_adjustment, v_level3_adjustment);
|
||||
|
||||
/* Figure adjustment absolute value by selecting between the absolute
|
||||
* difference if in level0 or the value for level 1, 2 and 3.
|
||||
*/
|
||||
const uint8x16_t v_abs_adjustment =
|
||||
vbslq_u8(v_level1_mask, v_level1and2and3_adjustment, v_abs_diff);
|
||||
|
||||
/* Calculate positive and negative adjustments. Apply them to the signal
|
||||
* and accumulate them. Adjustments are less than eight and the maximum
|
||||
* sum of them (7 * 16) can fit in a signed char.
|
||||
*/
|
||||
const uint8x16_t v_pos_adjustment =
|
||||
vandq_u8(v_diff_pos_mask, v_abs_adjustment);
|
||||
const uint8x16_t v_neg_adjustment =
|
||||
vandq_u8(v_diff_neg_mask, v_abs_adjustment);
|
||||
|
||||
uint8x16_t v_running_avg = vqaddq_u8(v_sig, v_pos_adjustment);
|
||||
v_running_avg = vqsubq_u8(v_running_avg, v_neg_adjustment);
|
||||
|
||||
/* Store results. */
|
||||
vst1_u8(running_avg, vget_low_u8(v_running_avg));
|
||||
vst1_u8(&running_avg[running_avg_stride], vget_high_u8(v_running_avg));
|
||||
|
||||
/* Sum all the accumulators to have the sum of all pixel differences
|
||||
* for this macroblock.
|
||||
*/
|
||||
{
|
||||
const int8x16_t v_sum_diff =
|
||||
vqsubq_s8(vreinterpretq_s8_u8(v_pos_adjustment),
|
||||
vreinterpretq_s8_u8(v_neg_adjustment));
|
||||
|
||||
const int16x8_t fe_dc_ba_98_76_54_32_10 = vpaddlq_s8(v_sum_diff);
|
||||
|
||||
const int32x4_t fedc_ba98_7654_3210 =
|
||||
vpaddlq_s16(fe_dc_ba_98_76_54_32_10);
|
||||
|
||||
const int64x2_t fedcba98_76543210 = vpaddlq_s32(fedc_ba98_7654_3210);
|
||||
|
||||
v_sum_diff_total = vqaddq_s64(v_sum_diff_total, fedcba98_76543210);
|
||||
}
|
||||
|
||||
/* Update pointers for next iteration. */
|
||||
sig += sig_stride * 2;
|
||||
mc_running_avg += mc_running_avg_stride * 2;
|
||||
running_avg += running_avg_stride * 2;
|
||||
}
|
||||
|
||||
/* Too much adjustments => copy block. */
|
||||
{
|
||||
int64x1_t x = vqadd_s64(vget_high_s64(v_sum_diff_total),
|
||||
vget_low_s64(v_sum_diff_total));
|
||||
int sum_diff = vget_lane_s32(vabs_s32(vreinterpret_s32_s64(x)), 0);
|
||||
int sum_diff_thresh = SUM_DIFF_THRESHOLD_UV;
|
||||
if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH_UV;
|
||||
if (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 accceptable range given by sum_diff_thresh.
|
||||
|
||||
// The delta is set by the excess of absolute pixel diff over the
|
||||
// threshold.
|
||||
int delta = ((sum_diff - sum_diff_thresh) >> 8) + 1;
|
||||
// Only apply the adjustment for max delta up to 3.
|
||||
if (delta < 4) {
|
||||
const uint8x16_t k_delta = vmovq_n_u8(delta);
|
||||
sig -= sig_stride * 8;
|
||||
mc_running_avg -= mc_running_avg_stride * 8;
|
||||
running_avg -= running_avg_stride * 8;
|
||||
for (r = 0; r < 4; ++r) {
|
||||
const uint8x8_t v_sig_lo = vld1_u8(sig);
|
||||
const uint8x8_t v_sig_hi = vld1_u8(&sig[sig_stride]);
|
||||
const uint8x16_t v_sig = vcombine_u8(v_sig_lo, v_sig_hi);
|
||||
const uint8x8_t v_mc_running_avg_lo = vld1_u8(mc_running_avg);
|
||||
const uint8x8_t v_mc_running_avg_hi =
|
||||
vld1_u8(&mc_running_avg[mc_running_avg_stride]);
|
||||
const uint8x16_t v_mc_running_avg =
|
||||
vcombine_u8(v_mc_running_avg_lo, v_mc_running_avg_hi);
|
||||
/* Calculate absolute difference and sign masks. */
|
||||
const uint8x16_t v_abs_diff = vabdq_u8(v_sig, v_mc_running_avg);
|
||||
const uint8x16_t v_diff_pos_mask = vcltq_u8(v_sig, v_mc_running_avg);
|
||||
const uint8x16_t v_diff_neg_mask = vcgtq_u8(v_sig, v_mc_running_avg);
|
||||
// Clamp absolute difference to delta to get the adjustment.
|
||||
const uint8x16_t v_abs_adjustment = vminq_u8(v_abs_diff, (k_delta));
|
||||
|
||||
const uint8x16_t v_pos_adjustment =
|
||||
vandq_u8(v_diff_pos_mask, v_abs_adjustment);
|
||||
const uint8x16_t v_neg_adjustment =
|
||||
vandq_u8(v_diff_neg_mask, v_abs_adjustment);
|
||||
const uint8x8_t v_running_avg_lo = vld1_u8(running_avg);
|
||||
const uint8x8_t v_running_avg_hi =
|
||||
vld1_u8(&running_avg[running_avg_stride]);
|
||||
uint8x16_t v_running_avg =
|
||||
vcombine_u8(v_running_avg_lo, v_running_avg_hi);
|
||||
|
||||
v_running_avg = vqsubq_u8(v_running_avg, v_pos_adjustment);
|
||||
v_running_avg = vqaddq_u8(v_running_avg, v_neg_adjustment);
|
||||
|
||||
/* Store results. */
|
||||
vst1_u8(running_avg, vget_low_u8(v_running_avg));
|
||||
vst1_u8(&running_avg[running_avg_stride],
|
||||
vget_high_u8(v_running_avg));
|
||||
|
||||
{
|
||||
const int8x16_t v_sum_diff =
|
||||
vqsubq_s8(vreinterpretq_s8_u8(v_neg_adjustment),
|
||||
vreinterpretq_s8_u8(v_pos_adjustment));
|
||||
|
||||
const int16x8_t fe_dc_ba_98_76_54_32_10 = vpaddlq_s8(v_sum_diff);
|
||||
const int32x4_t fedc_ba98_7654_3210 =
|
||||
vpaddlq_s16(fe_dc_ba_98_76_54_32_10);
|
||||
const int64x2_t fedcba98_76543210 =
|
||||
vpaddlq_s32(fedc_ba98_7654_3210);
|
||||
|
||||
v_sum_diff_total = vqaddq_s64(v_sum_diff_total, fedcba98_76543210);
|
||||
}
|
||||
/* Update pointers for next iteration. */
|
||||
sig += sig_stride * 2;
|
||||
mc_running_avg += mc_running_avg_stride * 2;
|
||||
running_avg += running_avg_stride * 2;
|
||||
}
|
||||
{
|
||||
// Update the sum of all pixel differences of this MB.
|
||||
x = vqadd_s64(vget_high_s64(v_sum_diff_total),
|
||||
vget_low_s64(v_sum_diff_total));
|
||||
sum_diff = vget_lane_s32(vabs_s32(vreinterpret_s32_s64(x)), 0);
|
||||
|
||||
if (sum_diff > sum_diff_thresh) {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell above level that block was filtered. */
|
||||
running_avg -= running_avg_stride * 8;
|
||||
sig -= sig_stride * 8;
|
||||
|
||||
vp8_copy_mem8x8(running_avg, running_avg_stride, sig, sig_stride);
|
||||
|
||||
return FILTER_BLOCK;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "vp8/encoder/block.h"
|
||||
|
||||
static const uint16_t inv_zig_zag[16] = { 1, 2, 6, 7, 3, 5, 8, 13,
|
||||
4, 9, 12, 14, 10, 11, 15, 16 };
|
||||
|
||||
void vp8_fast_quantize_b_neon(BLOCK *b, BLOCKD *d) {
|
||||
const int16x8_t one_q = vdupq_n_s16(-1), z0 = vld1q_s16(b->coeff),
|
||||
z1 = vld1q_s16(b->coeff + 8), round0 = vld1q_s16(b->round),
|
||||
round1 = vld1q_s16(b->round + 8),
|
||||
quant0 = vld1q_s16(b->quant_fast),
|
||||
quant1 = vld1q_s16(b->quant_fast + 8),
|
||||
dequant0 = vld1q_s16(d->dequant),
|
||||
dequant1 = vld1q_s16(d->dequant + 8);
|
||||
const uint16x8_t zig_zag0 = vld1q_u16(inv_zig_zag),
|
||||
zig_zag1 = vld1q_u16(inv_zig_zag + 8);
|
||||
int16x8_t x0, x1, sz0, sz1, y0, y1;
|
||||
uint16x8_t eob0, eob1;
|
||||
#ifndef __aarch64__
|
||||
uint16x4_t eob_d16;
|
||||
uint32x2_t eob_d32;
|
||||
uint32x4_t eob_q32;
|
||||
#endif // __arch64__
|
||||
|
||||
/* sign of z: z >> 15 */
|
||||
sz0 = vshrq_n_s16(z0, 15);
|
||||
sz1 = vshrq_n_s16(z1, 15);
|
||||
|
||||
/* x = abs(z) */
|
||||
x0 = vabsq_s16(z0);
|
||||
x1 = vabsq_s16(z1);
|
||||
|
||||
/* x += round */
|
||||
x0 = vaddq_s16(x0, round0);
|
||||
x1 = vaddq_s16(x1, round1);
|
||||
|
||||
/* y = 2 * (x * quant) >> 16 */
|
||||
y0 = vqdmulhq_s16(x0, quant0);
|
||||
y1 = vqdmulhq_s16(x1, quant1);
|
||||
|
||||
/* Compensate for doubling in vqdmulhq */
|
||||
y0 = vshrq_n_s16(y0, 1);
|
||||
y1 = vshrq_n_s16(y1, 1);
|
||||
|
||||
/* Restore sign bit */
|
||||
y0 = veorq_s16(y0, sz0);
|
||||
y1 = veorq_s16(y1, sz1);
|
||||
x0 = vsubq_s16(y0, sz0);
|
||||
x1 = vsubq_s16(y1, sz1);
|
||||
|
||||
/* find non-zero elements */
|
||||
eob0 = vtstq_s16(x0, one_q);
|
||||
eob1 = vtstq_s16(x1, one_q);
|
||||
|
||||
/* mask zig zag */
|
||||
eob0 = vandq_u16(eob0, zig_zag0);
|
||||
eob1 = vandq_u16(eob1, zig_zag1);
|
||||
|
||||
/* select the largest value */
|
||||
eob0 = vmaxq_u16(eob0, eob1);
|
||||
#ifdef __aarch64__
|
||||
*d->eob = (int8_t)vmaxvq_u16(eob0);
|
||||
#else
|
||||
eob_d16 = vmax_u16(vget_low_u16(eob0), vget_high_u16(eob0));
|
||||
eob_q32 = vmovl_u16(eob_d16);
|
||||
eob_d32 = vmax_u32(vget_low_u32(eob_q32), vget_high_u32(eob_q32));
|
||||
eob_d32 = vpmax_u32(eob_d32, eob_d32);
|
||||
|
||||
vst1_lane_s8((int8_t *)d->eob, vreinterpret_s8_u32(eob_d32), 0);
|
||||
#endif // __aarch64__
|
||||
|
||||
/* qcoeff = x */
|
||||
vst1q_s16(d->qcoeff, x0);
|
||||
vst1q_s16(d->qcoeff + 8, x1);
|
||||
|
||||
/* dqcoeff = x * dequant */
|
||||
vst1q_s16(d->dqcoeff, vmulq_s16(dequant0, x0));
|
||||
vst1q_s16(d->dqcoeff + 8, vmulq_s16(dequant1, x1));
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
|
||||
void vp8_short_fdct4x4_neon(int16_t *input, int16_t *output, int pitch) {
|
||||
int16x4_t d0s16, d1s16, d2s16, d3s16, d4s16, d5s16, d6s16, d7s16;
|
||||
int16x4_t d16s16, d17s16, d26s16, dEmptys16;
|
||||
uint16x4_t d4u16;
|
||||
int16x8_t q0s16, q1s16;
|
||||
int32x4_t q9s32, q10s32, q11s32, q12s32;
|
||||
int16x4x2_t v2tmp0, v2tmp1;
|
||||
int32x2x2_t v2tmp2, v2tmp3;
|
||||
|
||||
d16s16 = vdup_n_s16(5352);
|
||||
d17s16 = vdup_n_s16(2217);
|
||||
q9s32 = vdupq_n_s32(14500);
|
||||
q10s32 = vdupq_n_s32(7500);
|
||||
q11s32 = vdupq_n_s32(12000);
|
||||
q12s32 = vdupq_n_s32(51000);
|
||||
|
||||
// Part one
|
||||
pitch >>= 1;
|
||||
d0s16 = vld1_s16(input);
|
||||
input += pitch;
|
||||
d1s16 = vld1_s16(input);
|
||||
input += pitch;
|
||||
d2s16 = vld1_s16(input);
|
||||
input += pitch;
|
||||
d3s16 = vld1_s16(input);
|
||||
|
||||
v2tmp2 = vtrn_s32(vreinterpret_s32_s16(d0s16), vreinterpret_s32_s16(d2s16));
|
||||
v2tmp3 = vtrn_s32(vreinterpret_s32_s16(d1s16), vreinterpret_s32_s16(d3s16));
|
||||
v2tmp0 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[0]), // d0
|
||||
vreinterpret_s16_s32(v2tmp3.val[0])); // d1
|
||||
v2tmp1 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[1]), // d2
|
||||
vreinterpret_s16_s32(v2tmp3.val[1])); // d3
|
||||
|
||||
d4s16 = vadd_s16(v2tmp0.val[0], v2tmp1.val[1]);
|
||||
d5s16 = vadd_s16(v2tmp0.val[1], v2tmp1.val[0]);
|
||||
d6s16 = vsub_s16(v2tmp0.val[1], v2tmp1.val[0]);
|
||||
d7s16 = vsub_s16(v2tmp0.val[0], v2tmp1.val[1]);
|
||||
|
||||
d4s16 = vshl_n_s16(d4s16, 3);
|
||||
d5s16 = vshl_n_s16(d5s16, 3);
|
||||
d6s16 = vshl_n_s16(d6s16, 3);
|
||||
d7s16 = vshl_n_s16(d7s16, 3);
|
||||
|
||||
d0s16 = vadd_s16(d4s16, d5s16);
|
||||
d2s16 = vsub_s16(d4s16, d5s16);
|
||||
|
||||
q9s32 = vmlal_s16(q9s32, d7s16, d16s16);
|
||||
q10s32 = vmlal_s16(q10s32, d7s16, d17s16);
|
||||
q9s32 = vmlal_s16(q9s32, d6s16, d17s16);
|
||||
q10s32 = vmlsl_s16(q10s32, d6s16, d16s16);
|
||||
|
||||
d1s16 = vshrn_n_s32(q9s32, 12);
|
||||
d3s16 = vshrn_n_s32(q10s32, 12);
|
||||
|
||||
// Part two
|
||||
v2tmp2 = vtrn_s32(vreinterpret_s32_s16(d0s16), vreinterpret_s32_s16(d2s16));
|
||||
v2tmp3 = vtrn_s32(vreinterpret_s32_s16(d1s16), vreinterpret_s32_s16(d3s16));
|
||||
v2tmp0 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[0]), // d0
|
||||
vreinterpret_s16_s32(v2tmp3.val[0])); // d1
|
||||
v2tmp1 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[1]), // d2
|
||||
vreinterpret_s16_s32(v2tmp3.val[1])); // d3
|
||||
|
||||
d4s16 = vadd_s16(v2tmp0.val[0], v2tmp1.val[1]);
|
||||
d5s16 = vadd_s16(v2tmp0.val[1], v2tmp1.val[0]);
|
||||
d6s16 = vsub_s16(v2tmp0.val[1], v2tmp1.val[0]);
|
||||
d7s16 = vsub_s16(v2tmp0.val[0], v2tmp1.val[1]);
|
||||
|
||||
d26s16 = vdup_n_s16(7);
|
||||
d4s16 = vadd_s16(d4s16, d26s16);
|
||||
|
||||
d0s16 = vadd_s16(d4s16, d5s16);
|
||||
d2s16 = vsub_s16(d4s16, d5s16);
|
||||
|
||||
q11s32 = vmlal_s16(q11s32, d7s16, d16s16);
|
||||
q12s32 = vmlal_s16(q12s32, d7s16, d17s16);
|
||||
|
||||
dEmptys16 = vdup_n_s16(0);
|
||||
d4u16 = vceq_s16(d7s16, dEmptys16);
|
||||
|
||||
d0s16 = vshr_n_s16(d0s16, 4);
|
||||
d2s16 = vshr_n_s16(d2s16, 4);
|
||||
|
||||
q11s32 = vmlal_s16(q11s32, d6s16, d17s16);
|
||||
q12s32 = vmlsl_s16(q12s32, d6s16, d16s16);
|
||||
|
||||
d4u16 = vmvn_u16(d4u16);
|
||||
d1s16 = vshrn_n_s32(q11s32, 16);
|
||||
d1s16 = vsub_s16(d1s16, vreinterpret_s16_u16(d4u16));
|
||||
d3s16 = vshrn_n_s32(q12s32, 16);
|
||||
|
||||
q0s16 = vcombine_s16(d0s16, d1s16);
|
||||
q1s16 = vcombine_s16(d2s16, d3s16);
|
||||
|
||||
vst1q_s16(output, q0s16);
|
||||
vst1q_s16(output + 8, q1s16);
|
||||
return;
|
||||
}
|
||||
|
||||
void vp8_short_fdct8x4_neon(int16_t *input, int16_t *output, int pitch) {
|
||||
int16x4_t d0s16, d1s16, d2s16, d3s16, d4s16, d5s16, d6s16, d7s16;
|
||||
int16x4_t d16s16, d17s16, d26s16, d27s16, d28s16, d29s16;
|
||||
uint16x4_t d28u16, d29u16;
|
||||
uint16x8_t q14u16;
|
||||
int16x8_t q0s16, q1s16, q2s16, q3s16;
|
||||
int16x8_t q11s16, q12s16, q13s16, q14s16, q15s16, qEmptys16;
|
||||
int32x4_t q9s32, q10s32, q11s32, q12s32;
|
||||
int16x8x2_t v2tmp0, v2tmp1;
|
||||
int32x4x2_t v2tmp2, v2tmp3;
|
||||
|
||||
d16s16 = vdup_n_s16(5352);
|
||||
d17s16 = vdup_n_s16(2217);
|
||||
q9s32 = vdupq_n_s32(14500);
|
||||
q10s32 = vdupq_n_s32(7500);
|
||||
|
||||
// Part one
|
||||
pitch >>= 1;
|
||||
q0s16 = vld1q_s16(input);
|
||||
input += pitch;
|
||||
q1s16 = vld1q_s16(input);
|
||||
input += pitch;
|
||||
q2s16 = vld1q_s16(input);
|
||||
input += pitch;
|
||||
q3s16 = vld1q_s16(input);
|
||||
|
||||
v2tmp2 =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(q0s16), vreinterpretq_s32_s16(q2s16));
|
||||
v2tmp3 =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(q1s16), vreinterpretq_s32_s16(q3s16));
|
||||
v2tmp0 = vtrnq_s16(vreinterpretq_s16_s32(v2tmp2.val[0]), // q0
|
||||
vreinterpretq_s16_s32(v2tmp3.val[0])); // q1
|
||||
v2tmp1 = vtrnq_s16(vreinterpretq_s16_s32(v2tmp2.val[1]), // q2
|
||||
vreinterpretq_s16_s32(v2tmp3.val[1])); // q3
|
||||
|
||||
q11s16 = vaddq_s16(v2tmp0.val[0], v2tmp1.val[1]);
|
||||
q12s16 = vaddq_s16(v2tmp0.val[1], v2tmp1.val[0]);
|
||||
q13s16 = vsubq_s16(v2tmp0.val[1], v2tmp1.val[0]);
|
||||
q14s16 = vsubq_s16(v2tmp0.val[0], v2tmp1.val[1]);
|
||||
|
||||
q11s16 = vshlq_n_s16(q11s16, 3);
|
||||
q12s16 = vshlq_n_s16(q12s16, 3);
|
||||
q13s16 = vshlq_n_s16(q13s16, 3);
|
||||
q14s16 = vshlq_n_s16(q14s16, 3);
|
||||
|
||||
q0s16 = vaddq_s16(q11s16, q12s16);
|
||||
q2s16 = vsubq_s16(q11s16, q12s16);
|
||||
|
||||
q11s32 = q9s32;
|
||||
q12s32 = q10s32;
|
||||
|
||||
d26s16 = vget_low_s16(q13s16);
|
||||
d27s16 = vget_high_s16(q13s16);
|
||||
d28s16 = vget_low_s16(q14s16);
|
||||
d29s16 = vget_high_s16(q14s16);
|
||||
|
||||
q9s32 = vmlal_s16(q9s32, d28s16, d16s16);
|
||||
q10s32 = vmlal_s16(q10s32, d28s16, d17s16);
|
||||
q11s32 = vmlal_s16(q11s32, d29s16, d16s16);
|
||||
q12s32 = vmlal_s16(q12s32, d29s16, d17s16);
|
||||
|
||||
q9s32 = vmlal_s16(q9s32, d26s16, d17s16);
|
||||
q10s32 = vmlsl_s16(q10s32, d26s16, d16s16);
|
||||
q11s32 = vmlal_s16(q11s32, d27s16, d17s16);
|
||||
q12s32 = vmlsl_s16(q12s32, d27s16, d16s16);
|
||||
|
||||
d2s16 = vshrn_n_s32(q9s32, 12);
|
||||
d6s16 = vshrn_n_s32(q10s32, 12);
|
||||
d3s16 = vshrn_n_s32(q11s32, 12);
|
||||
d7s16 = vshrn_n_s32(q12s32, 12);
|
||||
q1s16 = vcombine_s16(d2s16, d3s16);
|
||||
q3s16 = vcombine_s16(d6s16, d7s16);
|
||||
|
||||
// Part two
|
||||
q9s32 = vdupq_n_s32(12000);
|
||||
q10s32 = vdupq_n_s32(51000);
|
||||
|
||||
v2tmp2 =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(q0s16), vreinterpretq_s32_s16(q2s16));
|
||||
v2tmp3 =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(q1s16), vreinterpretq_s32_s16(q3s16));
|
||||
v2tmp0 = vtrnq_s16(vreinterpretq_s16_s32(v2tmp2.val[0]), // q0
|
||||
vreinterpretq_s16_s32(v2tmp3.val[0])); // q1
|
||||
v2tmp1 = vtrnq_s16(vreinterpretq_s16_s32(v2tmp2.val[1]), // q2
|
||||
vreinterpretq_s16_s32(v2tmp3.val[1])); // q3
|
||||
|
||||
q11s16 = vaddq_s16(v2tmp0.val[0], v2tmp1.val[1]);
|
||||
q12s16 = vaddq_s16(v2tmp0.val[1], v2tmp1.val[0]);
|
||||
q13s16 = vsubq_s16(v2tmp0.val[1], v2tmp1.val[0]);
|
||||
q14s16 = vsubq_s16(v2tmp0.val[0], v2tmp1.val[1]);
|
||||
|
||||
q15s16 = vdupq_n_s16(7);
|
||||
q11s16 = vaddq_s16(q11s16, q15s16);
|
||||
q0s16 = vaddq_s16(q11s16, q12s16);
|
||||
q1s16 = vsubq_s16(q11s16, q12s16);
|
||||
|
||||
q11s32 = q9s32;
|
||||
q12s32 = q10s32;
|
||||
|
||||
d0s16 = vget_low_s16(q0s16);
|
||||
d1s16 = vget_high_s16(q0s16);
|
||||
d2s16 = vget_low_s16(q1s16);
|
||||
d3s16 = vget_high_s16(q1s16);
|
||||
|
||||
d0s16 = vshr_n_s16(d0s16, 4);
|
||||
d4s16 = vshr_n_s16(d1s16, 4);
|
||||
d2s16 = vshr_n_s16(d2s16, 4);
|
||||
d6s16 = vshr_n_s16(d3s16, 4);
|
||||
|
||||
d26s16 = vget_low_s16(q13s16);
|
||||
d27s16 = vget_high_s16(q13s16);
|
||||
d28s16 = vget_low_s16(q14s16);
|
||||
d29s16 = vget_high_s16(q14s16);
|
||||
|
||||
q9s32 = vmlal_s16(q9s32, d28s16, d16s16);
|
||||
q10s32 = vmlal_s16(q10s32, d28s16, d17s16);
|
||||
q11s32 = vmlal_s16(q11s32, d29s16, d16s16);
|
||||
q12s32 = vmlal_s16(q12s32, d29s16, d17s16);
|
||||
|
||||
q9s32 = vmlal_s16(q9s32, d26s16, d17s16);
|
||||
q10s32 = vmlsl_s16(q10s32, d26s16, d16s16);
|
||||
q11s32 = vmlal_s16(q11s32, d27s16, d17s16);
|
||||
q12s32 = vmlsl_s16(q12s32, d27s16, d16s16);
|
||||
|
||||
d1s16 = vshrn_n_s32(q9s32, 16);
|
||||
d3s16 = vshrn_n_s32(q10s32, 16);
|
||||
d5s16 = vshrn_n_s32(q11s32, 16);
|
||||
d7s16 = vshrn_n_s32(q12s32, 16);
|
||||
|
||||
qEmptys16 = vdupq_n_s16(0);
|
||||
q14u16 = vceqq_s16(q14s16, qEmptys16);
|
||||
q14u16 = vmvnq_u16(q14u16);
|
||||
|
||||
d28u16 = vget_low_u16(q14u16);
|
||||
d29u16 = vget_high_u16(q14u16);
|
||||
d1s16 = vsub_s16(d1s16, vreinterpret_s16_u16(d28u16));
|
||||
d5s16 = vsub_s16(d5s16, vreinterpret_s16_u16(d29u16));
|
||||
|
||||
q0s16 = vcombine_s16(d0s16, d1s16);
|
||||
q1s16 = vcombine_s16(d2s16, d3s16);
|
||||
q2s16 = vcombine_s16(d4s16, d5s16);
|
||||
q3s16 = vcombine_s16(d6s16, d7s16);
|
||||
|
||||
vst1q_s16(output, q0s16);
|
||||
vst1q_s16(output + 8, q1s16);
|
||||
vst1q_s16(output + 16, q2s16);
|
||||
vst1q_s16(output + 24, q3s16);
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "vpx_ports/arm.h"
|
||||
|
||||
#ifdef VPX_INCOMPATIBLE_GCC
|
||||
#include "./vp8_rtcd.h"
|
||||
void vp8_short_walsh4x4_neon(int16_t *input, int16_t *output, int pitch) {
|
||||
vp8_short_walsh4x4_c(input, output, pitch);
|
||||
}
|
||||
#else
|
||||
void vp8_short_walsh4x4_neon(int16_t *input, int16_t *output, int pitch) {
|
||||
uint16x4_t d16u16;
|
||||
int16x8_t q0s16, q1s16;
|
||||
int16x4_t dEmptys16, d0s16, d1s16, d2s16, d3s16, d4s16, d5s16, d6s16, d7s16;
|
||||
int32x4_t qEmptys32, q0s32, q1s32, q2s32, q3s32, q8s32;
|
||||
int32x4_t q9s32, q10s32, q11s32, q15s32;
|
||||
uint32x4_t q8u32, q9u32, q10u32, q11u32;
|
||||
int16x4x2_t v2tmp0, v2tmp1;
|
||||
int32x2x2_t v2tmp2, v2tmp3;
|
||||
|
||||
dEmptys16 = vdup_n_s16(0);
|
||||
qEmptys32 = vdupq_n_s32(0);
|
||||
q15s32 = vdupq_n_s32(3);
|
||||
|
||||
d0s16 = vld1_s16(input);
|
||||
input += pitch / 2;
|
||||
d1s16 = vld1_s16(input);
|
||||
input += pitch / 2;
|
||||
d2s16 = vld1_s16(input);
|
||||
input += pitch / 2;
|
||||
d3s16 = vld1_s16(input);
|
||||
|
||||
v2tmp2 = vtrn_s32(vreinterpret_s32_s16(d0s16), vreinterpret_s32_s16(d2s16));
|
||||
v2tmp3 = vtrn_s32(vreinterpret_s32_s16(d1s16), vreinterpret_s32_s16(d3s16));
|
||||
v2tmp0 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[0]), // d0
|
||||
vreinterpret_s16_s32(v2tmp3.val[0])); // d1
|
||||
v2tmp1 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[1]), // d2
|
||||
vreinterpret_s16_s32(v2tmp3.val[1])); // d3
|
||||
|
||||
d4s16 = vadd_s16(v2tmp0.val[0], v2tmp1.val[0]);
|
||||
d5s16 = vadd_s16(v2tmp0.val[1], v2tmp1.val[1]);
|
||||
d6s16 = vsub_s16(v2tmp0.val[1], v2tmp1.val[1]);
|
||||
d7s16 = vsub_s16(v2tmp0.val[0], v2tmp1.val[0]);
|
||||
|
||||
d4s16 = vshl_n_s16(d4s16, 2);
|
||||
d5s16 = vshl_n_s16(d5s16, 2);
|
||||
d6s16 = vshl_n_s16(d6s16, 2);
|
||||
d7s16 = vshl_n_s16(d7s16, 2);
|
||||
|
||||
d16u16 = vceq_s16(d4s16, dEmptys16);
|
||||
d16u16 = vmvn_u16(d16u16);
|
||||
|
||||
d0s16 = vadd_s16(d4s16, d5s16);
|
||||
d3s16 = vsub_s16(d4s16, d5s16);
|
||||
d1s16 = vadd_s16(d7s16, d6s16);
|
||||
d2s16 = vsub_s16(d7s16, d6s16);
|
||||
|
||||
d0s16 = vsub_s16(d0s16, vreinterpret_s16_u16(d16u16));
|
||||
|
||||
// Second for-loop
|
||||
v2tmp2 = vtrn_s32(vreinterpret_s32_s16(d1s16), vreinterpret_s32_s16(d3s16));
|
||||
v2tmp3 = vtrn_s32(vreinterpret_s32_s16(d0s16), vreinterpret_s32_s16(d2s16));
|
||||
v2tmp0 = vtrn_s16(vreinterpret_s16_s32(v2tmp3.val[1]), // d2
|
||||
vreinterpret_s16_s32(v2tmp2.val[1])); // d3
|
||||
v2tmp1 = vtrn_s16(vreinterpret_s16_s32(v2tmp3.val[0]), // d0
|
||||
vreinterpret_s16_s32(v2tmp2.val[0])); // d1
|
||||
|
||||
q8s32 = vaddl_s16(v2tmp1.val[0], v2tmp0.val[0]);
|
||||
q9s32 = vaddl_s16(v2tmp1.val[1], v2tmp0.val[1]);
|
||||
q10s32 = vsubl_s16(v2tmp1.val[1], v2tmp0.val[1]);
|
||||
q11s32 = vsubl_s16(v2tmp1.val[0], v2tmp0.val[0]);
|
||||
|
||||
q0s32 = vaddq_s32(q8s32, q9s32);
|
||||
q1s32 = vaddq_s32(q11s32, q10s32);
|
||||
q2s32 = vsubq_s32(q11s32, q10s32);
|
||||
q3s32 = vsubq_s32(q8s32, q9s32);
|
||||
|
||||
q8u32 = vcltq_s32(q0s32, qEmptys32);
|
||||
q9u32 = vcltq_s32(q1s32, qEmptys32);
|
||||
q10u32 = vcltq_s32(q2s32, qEmptys32);
|
||||
q11u32 = vcltq_s32(q3s32, qEmptys32);
|
||||
|
||||
q8s32 = vreinterpretq_s32_u32(q8u32);
|
||||
q9s32 = vreinterpretq_s32_u32(q9u32);
|
||||
q10s32 = vreinterpretq_s32_u32(q10u32);
|
||||
q11s32 = vreinterpretq_s32_u32(q11u32);
|
||||
|
||||
q0s32 = vsubq_s32(q0s32, q8s32);
|
||||
q1s32 = vsubq_s32(q1s32, q9s32);
|
||||
q2s32 = vsubq_s32(q2s32, q10s32);
|
||||
q3s32 = vsubq_s32(q3s32, q11s32);
|
||||
|
||||
q8s32 = vaddq_s32(q0s32, q15s32);
|
||||
q9s32 = vaddq_s32(q1s32, q15s32);
|
||||
q10s32 = vaddq_s32(q2s32, q15s32);
|
||||
q11s32 = vaddq_s32(q3s32, q15s32);
|
||||
|
||||
d0s16 = vshrn_n_s32(q8s32, 3);
|
||||
d1s16 = vshrn_n_s32(q9s32, 3);
|
||||
d2s16 = vshrn_n_s32(q10s32, 3);
|
||||
d3s16 = vshrn_n_s32(q11s32, 3);
|
||||
|
||||
q0s16 = vcombine_s16(d0s16, d1s16);
|
||||
q1s16 = vcombine_s16(d2s16, d3s16);
|
||||
|
||||
vst1q_s16(output, q0s16);
|
||||
vst1q_s16(output + 8, q1s16);
|
||||
return;
|
||||
}
|
||||
#endif // VPX_INCOMPATIBLE_GCC
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_BITSTREAM_H_
|
||||
#define VPX_VP8_ENCODER_BITSTREAM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "vp8/encoder/treewriter.h"
|
||||
#include "vp8/encoder/tokenize.h"
|
||||
|
||||
void vp8_pack_tokens(vp8_writer *w, const TOKENEXTRA *p, int xcount);
|
||||
void vp8_convert_rfct_to_prob(struct VP8_COMP *const cpi);
|
||||
void vp8_calc_ref_frame_costs(int *ref_frame_cost, int prob_intra,
|
||||
int prob_last, int prob_garf);
|
||||
int vp8_estimate_entropy_savings(struct VP8_COMP *cpi);
|
||||
void vp8_update_coef_probs(struct VP8_COMP *cpi);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_BITSTREAM_H_
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_BLOCK_H_
|
||||
#define VPX_VP8_ENCODER_BLOCK_H_
|
||||
|
||||
#include "vp8/common/onyx.h"
|
||||
#include "vp8/common/blockd.h"
|
||||
#include "vp8/common/entropymv.h"
|
||||
#include "vp8/common/entropy.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAX_MODES 20
|
||||
#define MAX_ERROR_BINS 1024
|
||||
|
||||
/* motion search site */
|
||||
typedef struct {
|
||||
MV mv;
|
||||
int offset;
|
||||
} search_site;
|
||||
|
||||
typedef struct block {
|
||||
/* 16 Y blocks, 4 U blocks, 4 V blocks each with 16 entries */
|
||||
short *src_diff;
|
||||
short *coeff;
|
||||
|
||||
/* 16 Y blocks, 4 U blocks, 4 V blocks each with 16 entries */
|
||||
short *quant;
|
||||
short *quant_fast;
|
||||
short *quant_shift;
|
||||
short *zbin;
|
||||
short *zrun_zbin_boost;
|
||||
short *round;
|
||||
|
||||
/* Zbin Over Quant value */
|
||||
short zbin_extra;
|
||||
|
||||
unsigned char **base_src;
|
||||
int src;
|
||||
int src_stride;
|
||||
} BLOCK;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
struct {
|
||||
B_PREDICTION_MODE mode;
|
||||
int_mv mv;
|
||||
} bmi[16];
|
||||
} PARTITION_INFO;
|
||||
|
||||
typedef struct macroblock {
|
||||
DECLARE_ALIGNED(16, short, src_diff[400]); /* 25 blocks Y,U,V,Y2 */
|
||||
DECLARE_ALIGNED(16, short, coeff[400]); /* 25 blocks Y,U,V,Y2 */
|
||||
DECLARE_ALIGNED(16, unsigned char, thismb[256]);
|
||||
|
||||
unsigned char *thismb_ptr;
|
||||
/* 16 Y, 4 U, 4 V, 1 DC 2nd order block */
|
||||
BLOCK block[25];
|
||||
|
||||
YV12_BUFFER_CONFIG src;
|
||||
|
||||
MACROBLOCKD e_mbd;
|
||||
PARTITION_INFO *partition_info; /* work pointer */
|
||||
PARTITION_INFO *pi; /* Corresponds to upper left visible macroblock */
|
||||
PARTITION_INFO *pip; /* Base of allocated array */
|
||||
|
||||
int ref_frame_cost[MAX_REF_FRAMES];
|
||||
|
||||
search_site *ss;
|
||||
int ss_count;
|
||||
int searches_per_step;
|
||||
|
||||
int errorperbit;
|
||||
int sadperbit16;
|
||||
int sadperbit4;
|
||||
int rddiv;
|
||||
int rdmult;
|
||||
unsigned int *mb_activity_ptr;
|
||||
int *mb_norm_activity_ptr;
|
||||
signed int act_zbin_adj;
|
||||
signed int last_act_zbin_adj;
|
||||
|
||||
int *mvcost[2];
|
||||
int *mvsadcost[2];
|
||||
int (*mbmode_cost)[MB_MODE_COUNT];
|
||||
int (*intra_uv_mode_cost)[MB_MODE_COUNT];
|
||||
int (*bmode_costs)[10][10];
|
||||
int *inter_bmode_costs;
|
||||
int (*token_costs)[COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS];
|
||||
|
||||
/* These define limits to motion vector components to prevent
|
||||
* them from extending outside the UMV borders.
|
||||
*/
|
||||
int mv_col_min;
|
||||
int mv_col_max;
|
||||
int mv_row_min;
|
||||
int mv_row_max;
|
||||
|
||||
int skip;
|
||||
|
||||
unsigned int encode_breakout;
|
||||
|
||||
signed char *gf_active_ptr;
|
||||
|
||||
unsigned char *active_ptr;
|
||||
MV_CONTEXT *mvc;
|
||||
|
||||
int optimize;
|
||||
int q_index;
|
||||
int is_skin;
|
||||
int denoise_zeromv;
|
||||
|
||||
#if CONFIG_TEMPORAL_DENOISING
|
||||
int increase_denoising;
|
||||
MB_PREDICTION_MODE best_sse_inter_mode;
|
||||
int_mv best_sse_mv;
|
||||
MV_REFERENCE_FRAME best_reference_frame;
|
||||
MV_REFERENCE_FRAME best_zeromv_reference_frame;
|
||||
unsigned char need_to_clamp_best_mvs;
|
||||
#endif
|
||||
|
||||
int skip_true_count;
|
||||
unsigned int coef_counts[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS]
|
||||
[MAX_ENTROPY_TOKENS];
|
||||
unsigned int MVcount[2][MVvals]; /* (row,col) MV cts this frame */
|
||||
int ymode_count[VP8_YMODES]; /* intra MB type cts this frame */
|
||||
int uv_mode_count[VP8_UV_MODES]; /* intra MB type cts this frame */
|
||||
int64_t prediction_error;
|
||||
int64_t intra_error;
|
||||
int count_mb_ref_frame_usage[MAX_REF_FRAMES];
|
||||
|
||||
int rd_thresh_mult[MAX_MODES];
|
||||
int rd_threshes[MAX_MODES];
|
||||
unsigned int mbs_tested_so_far;
|
||||
unsigned int mode_test_hit_counts[MAX_MODES];
|
||||
int zbin_mode_boost_enabled;
|
||||
int zbin_mode_boost;
|
||||
int last_zbin_mode_boost;
|
||||
|
||||
int last_zbin_over_quant;
|
||||
int zbin_over_quant;
|
||||
int error_bins[MAX_ERROR_BINS];
|
||||
|
||||
void (*short_fdct4x4)(short *input, short *output, int pitch);
|
||||
void (*short_fdct8x4)(short *input, short *output, int pitch);
|
||||
void (*short_walsh4x4)(short *input, short *output, int pitch);
|
||||
void (*quantize_b)(BLOCK *b, BLOCKD *d);
|
||||
|
||||
unsigned int mbs_zero_last_dot_suppress;
|
||||
int zero_last_dot_suppress;
|
||||
} MACROBLOCK;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_BLOCK_H_
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include "boolhuff.h"
|
||||
|
||||
#if defined(SECTIONBITS_OUTPUT)
|
||||
unsigned __int64 Sectionbits[500];
|
||||
|
||||
#endif
|
||||
|
||||
const unsigned int vp8_prob_cost[256] = {
|
||||
2047, 2047, 1791, 1641, 1535, 1452, 1385, 1328, 1279, 1235, 1196, 1161, 1129,
|
||||
1099, 1072, 1046, 1023, 1000, 979, 959, 940, 922, 905, 889, 873, 858,
|
||||
843, 829, 816, 803, 790, 778, 767, 755, 744, 733, 723, 713, 703,
|
||||
693, 684, 675, 666, 657, 649, 641, 633, 625, 617, 609, 602, 594,
|
||||
587, 580, 573, 567, 560, 553, 547, 541, 534, 528, 522, 516, 511,
|
||||
505, 499, 494, 488, 483, 477, 472, 467, 462, 457, 452, 447, 442,
|
||||
437, 433, 428, 424, 419, 415, 410, 406, 401, 397, 393, 389, 385,
|
||||
381, 377, 373, 369, 365, 361, 357, 353, 349, 346, 342, 338, 335,
|
||||
331, 328, 324, 321, 317, 314, 311, 307, 304, 301, 297, 294, 291,
|
||||
288, 285, 281, 278, 275, 272, 269, 266, 263, 260, 257, 255, 252,
|
||||
249, 246, 243, 240, 238, 235, 232, 229, 227, 224, 221, 219, 216,
|
||||
214, 211, 208, 206, 203, 201, 198, 196, 194, 191, 189, 186, 184,
|
||||
181, 179, 177, 174, 172, 170, 168, 165, 163, 161, 159, 156, 154,
|
||||
152, 150, 148, 145, 143, 141, 139, 137, 135, 133, 131, 129, 127,
|
||||
125, 123, 121, 119, 117, 115, 113, 111, 109, 107, 105, 103, 101,
|
||||
99, 97, 95, 93, 92, 90, 88, 86, 84, 82, 81, 79, 77,
|
||||
75, 73, 72, 70, 68, 66, 65, 63, 61, 60, 58, 56, 55,
|
||||
53, 51, 50, 48, 46, 45, 43, 41, 40, 38, 37, 35, 33,
|
||||
32, 30, 29, 27, 25, 24, 22, 21, 19, 18, 16, 15, 13,
|
||||
12, 10, 9, 7, 6, 4, 3, 1, 1
|
||||
};
|
||||
|
||||
void vp8_start_encode(BOOL_CODER *bc, unsigned char *source,
|
||||
unsigned char *source_end) {
|
||||
bc->lowvalue = 0;
|
||||
bc->range = 255;
|
||||
bc->count = -24;
|
||||
bc->buffer = source;
|
||||
bc->buffer_end = source_end;
|
||||
bc->pos = 0;
|
||||
}
|
||||
|
||||
void vp8_stop_encode(BOOL_CODER *bc) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; ++i) vp8_encode_bool(bc, 0, 128);
|
||||
}
|
||||
|
||||
void vp8_encode_value(BOOL_CODER *bc, int data, int bits) {
|
||||
int bit;
|
||||
|
||||
for (bit = bits - 1; bit >= 0; bit--) {
|
||||
vp8_encode_bool(bc, (1 & (data >> bit)), 0x80);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Module Title : boolhuff.h
|
||||
*
|
||||
* Description : Bool Coder header file.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef VPX_VP8_ENCODER_BOOLHUFF_H_
|
||||
#define VPX_VP8_ENCODER_BOOLHUFF_H_
|
||||
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx/internal/vpx_codec_internal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned int lowvalue;
|
||||
unsigned int range;
|
||||
int count;
|
||||
unsigned int pos;
|
||||
unsigned char *buffer;
|
||||
unsigned char *buffer_end;
|
||||
struct vpx_internal_error_info *error;
|
||||
} BOOL_CODER;
|
||||
|
||||
void vp8_start_encode(BOOL_CODER *bc, unsigned char *source,
|
||||
unsigned char *source_end);
|
||||
|
||||
void vp8_encode_value(BOOL_CODER *bc, int data, int bits);
|
||||
void vp8_stop_encode(BOOL_CODER *bc);
|
||||
extern const unsigned int vp8_prob_cost[256];
|
||||
|
||||
DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]);
|
||||
|
||||
static int validate_buffer(const unsigned char *start, size_t len,
|
||||
const unsigned char *end,
|
||||
struct vpx_internal_error_info *error) {
|
||||
if (start + len > start && start + len < end) {
|
||||
return 1;
|
||||
} else {
|
||||
vpx_internal_error(error, VPX_CODEC_CORRUPT_FRAME,
|
||||
"Truncated packet or corrupt partition ");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static void vp8_encode_bool(BOOL_CODER *bc, int bit, int probability) {
|
||||
unsigned int split;
|
||||
int count = bc->count;
|
||||
unsigned int range = bc->range;
|
||||
unsigned int lowvalue = bc->lowvalue;
|
||||
int shift;
|
||||
|
||||
split = 1 + (((range - 1) * probability) >> 8);
|
||||
|
||||
range = split;
|
||||
|
||||
if (bit) {
|
||||
lowvalue += split;
|
||||
range = bc->range - split;
|
||||
}
|
||||
|
||||
shift = vp8_norm[range];
|
||||
|
||||
range <<= shift;
|
||||
count += shift;
|
||||
|
||||
if (count >= 0) {
|
||||
int offset = shift - count;
|
||||
|
||||
if ((lowvalue << (offset - 1)) & 0x80000000) {
|
||||
int x = bc->pos - 1;
|
||||
|
||||
while (x >= 0 && bc->buffer[x] == 0xff) {
|
||||
bc->buffer[x] = (unsigned char)0;
|
||||
x--;
|
||||
}
|
||||
|
||||
bc->buffer[x] += 1;
|
||||
}
|
||||
|
||||
validate_buffer(bc->buffer + bc->pos, 1, bc->buffer_end, bc->error);
|
||||
bc->buffer[bc->pos++] = (lowvalue >> (24 - offset) & 0xff);
|
||||
|
||||
lowvalue <<= offset;
|
||||
shift = count;
|
||||
lowvalue &= 0xffffff;
|
||||
count -= 8;
|
||||
}
|
||||
|
||||
lowvalue <<= shift;
|
||||
bc->count = count;
|
||||
bc->lowvalue = lowvalue;
|
||||
bc->range = range;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_BOOLHUFF_H_
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
||||
/* Copy 2 macroblocks to a buffer */
|
||||
void vp8_copy32xn_c(const unsigned char *src_ptr, int src_stride,
|
||||
unsigned char *dst_ptr, int dst_stride, int height) {
|
||||
int r;
|
||||
|
||||
for (r = 0; r < height; ++r) {
|
||||
memcpy(dst_ptr, src_ptr, 32);
|
||||
|
||||
src_ptr += src_stride;
|
||||
dst_ptr += dst_stride;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
|
||||
void vp8_short_fdct4x4_c(short *input, short *output, int pitch) {
|
||||
int i;
|
||||
int a1, b1, c1, d1;
|
||||
short *ip = input;
|
||||
short *op = output;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
a1 = ((ip[0] + ip[3]) * 8);
|
||||
b1 = ((ip[1] + ip[2]) * 8);
|
||||
c1 = ((ip[1] - ip[2]) * 8);
|
||||
d1 = ((ip[0] - ip[3]) * 8);
|
||||
|
||||
op[0] = a1 + b1;
|
||||
op[2] = a1 - b1;
|
||||
|
||||
op[1] = (c1 * 2217 + d1 * 5352 + 14500) >> 12;
|
||||
op[3] = (d1 * 2217 - c1 * 5352 + 7500) >> 12;
|
||||
|
||||
ip += pitch / 2;
|
||||
op += 4;
|
||||
}
|
||||
ip = output;
|
||||
op = output;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
a1 = ip[0] + ip[12];
|
||||
b1 = ip[4] + ip[8];
|
||||
c1 = ip[4] - ip[8];
|
||||
d1 = ip[0] - ip[12];
|
||||
|
||||
op[0] = (a1 + b1 + 7) >> 4;
|
||||
op[8] = (a1 - b1 + 7) >> 4;
|
||||
|
||||
op[4] = ((c1 * 2217 + d1 * 5352 + 12000) >> 16) + (d1 != 0);
|
||||
op[12] = (d1 * 2217 - c1 * 5352 + 51000) >> 16;
|
||||
|
||||
ip++;
|
||||
op++;
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_short_fdct8x4_c(short *input, short *output, int pitch) {
|
||||
vp8_short_fdct4x4_c(input, output, pitch);
|
||||
vp8_short_fdct4x4_c(input + 4, output + 16, pitch);
|
||||
}
|
||||
|
||||
void vp8_short_walsh4x4_c(short *input, short *output, int pitch) {
|
||||
int i;
|
||||
int a1, b1, c1, d1;
|
||||
int a2, b2, c2, d2;
|
||||
short *ip = input;
|
||||
short *op = output;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
a1 = ((ip[0] + ip[2]) * 4);
|
||||
d1 = ((ip[1] + ip[3]) * 4);
|
||||
c1 = ((ip[1] - ip[3]) * 4);
|
||||
b1 = ((ip[0] - ip[2]) * 4);
|
||||
|
||||
op[0] = a1 + d1 + (a1 != 0);
|
||||
op[1] = b1 + c1;
|
||||
op[2] = b1 - c1;
|
||||
op[3] = a1 - d1;
|
||||
ip += pitch / 2;
|
||||
op += 4;
|
||||
}
|
||||
|
||||
ip = output;
|
||||
op = output;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
a1 = ip[0] + ip[8];
|
||||
d1 = ip[4] + ip[12];
|
||||
c1 = ip[4] - ip[12];
|
||||
b1 = ip[0] - ip[8];
|
||||
|
||||
a2 = a1 + d1;
|
||||
b2 = b1 + c1;
|
||||
c2 = b1 - c1;
|
||||
d2 = a1 - d1;
|
||||
|
||||
a2 += a2 < 0;
|
||||
b2 += b2 < 0;
|
||||
c2 += c2 < 0;
|
||||
d2 += d2 < 0;
|
||||
|
||||
op[0] = (a2 + 3) >> 3;
|
||||
op[4] = (b2 + 3) >> 3;
|
||||
op[8] = (c2 + 3) >> 3;
|
||||
op[12] = (d2 + 3) >> 3;
|
||||
|
||||
ip++;
|
||||
op++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_DCT_VALUE_COST_H_
|
||||
#define VPX_VP8_ENCODER_DCT_VALUE_COST_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Generated file, included by tokenize.c */
|
||||
/* Values generated by fill_value_tokens() */
|
||||
|
||||
static const short dct_value_cost[2048 * 2] = {
|
||||
8285, 8277, 8267, 8259, 8253, 8245, 8226, 8218, 8212, 8204, 8194, 8186, 8180,
|
||||
8172, 8150, 8142, 8136, 8128, 8118, 8110, 8104, 8096, 8077, 8069, 8063, 8055,
|
||||
8045, 8037, 8031, 8023, 7997, 7989, 7983, 7975, 7965, 7957, 7951, 7943, 7924,
|
||||
7916, 7910, 7902, 7892, 7884, 7878, 7870, 7848, 7840, 7834, 7826, 7816, 7808,
|
||||
7802, 7794, 7775, 7767, 7761, 7753, 7743, 7735, 7729, 7721, 7923, 7915, 7909,
|
||||
7901, 7891, 7883, 7877, 7869, 7850, 7842, 7836, 7828, 7818, 7810, 7804, 7796,
|
||||
7774, 7766, 7760, 7752, 7742, 7734, 7728, 7720, 7701, 7693, 7687, 7679, 7669,
|
||||
7661, 7655, 7647, 7621, 7613, 7607, 7599, 7589, 7581, 7575, 7567, 7548, 7540,
|
||||
7534, 7526, 7516, 7508, 7502, 7494, 7472, 7464, 7458, 7450, 7440, 7432, 7426,
|
||||
7418, 7399, 7391, 7385, 7377, 7367, 7359, 7353, 7345, 7479, 7471, 7465, 7457,
|
||||
7447, 7439, 7433, 7425, 7406, 7398, 7392, 7384, 7374, 7366, 7360, 7352, 7330,
|
||||
7322, 7316, 7308, 7298, 7290, 7284, 7276, 7257, 7249, 7243, 7235, 7225, 7217,
|
||||
7211, 7203, 7177, 7169, 7163, 7155, 7145, 7137, 7131, 7123, 7104, 7096, 7090,
|
||||
7082, 7072, 7064, 7058, 7050, 7028, 7020, 7014, 7006, 6996, 6988, 6982, 6974,
|
||||
6955, 6947, 6941, 6933, 6923, 6915, 6909, 6901, 7632, 7624, 7618, 7610, 7600,
|
||||
7592, 7586, 7578, 7559, 7551, 7545, 7537, 7527, 7519, 7513, 7505, 7483, 7475,
|
||||
7469, 7461, 7451, 7443, 7437, 7429, 7410, 7402, 7396, 7388, 7378, 7370, 7364,
|
||||
7356, 7330, 7322, 7316, 7308, 7298, 7290, 7284, 7276, 7257, 7249, 7243, 7235,
|
||||
7225, 7217, 7211, 7203, 7181, 7173, 7167, 7159, 7149, 7141, 7135, 7127, 7108,
|
||||
7100, 7094, 7086, 7076, 7068, 7062, 7054, 7188, 7180, 7174, 7166, 7156, 7148,
|
||||
7142, 7134, 7115, 7107, 7101, 7093, 7083, 7075, 7069, 7061, 7039, 7031, 7025,
|
||||
7017, 7007, 6999, 6993, 6985, 6966, 6958, 6952, 6944, 6934, 6926, 6920, 6912,
|
||||
6886, 6878, 6872, 6864, 6854, 6846, 6840, 6832, 6813, 6805, 6799, 6791, 6781,
|
||||
6773, 6767, 6759, 6737, 6729, 6723, 6715, 6705, 6697, 6691, 6683, 6664, 6656,
|
||||
6650, 6642, 6632, 6624, 6618, 6610, 6812, 6804, 6798, 6790, 6780, 6772, 6766,
|
||||
6758, 6739, 6731, 6725, 6717, 6707, 6699, 6693, 6685, 6663, 6655, 6649, 6641,
|
||||
6631, 6623, 6617, 6609, 6590, 6582, 6576, 6568, 6558, 6550, 6544, 6536, 6510,
|
||||
6502, 6496, 6488, 6478, 6470, 6464, 6456, 6437, 6429, 6423, 6415, 6405, 6397,
|
||||
6391, 6383, 6361, 6353, 6347, 6339, 6329, 6321, 6315, 6307, 6288, 6280, 6274,
|
||||
6266, 6256, 6248, 6242, 6234, 6368, 6360, 6354, 6346, 6336, 6328, 6322, 6314,
|
||||
6295, 6287, 6281, 6273, 6263, 6255, 6249, 6241, 6219, 6211, 6205, 6197, 6187,
|
||||
6179, 6173, 6165, 6146, 6138, 6132, 6124, 6114, 6106, 6100, 6092, 6066, 6058,
|
||||
6052, 6044, 6034, 6026, 6020, 6012, 5993, 5985, 5979, 5971, 5961, 5953, 5947,
|
||||
5939, 5917, 5909, 5903, 5895, 5885, 5877, 5871, 5863, 5844, 5836, 5830, 5822,
|
||||
5812, 5804, 5798, 5790, 6697, 6689, 6683, 6675, 6665, 6657, 6651, 6643, 6624,
|
||||
6616, 6610, 6602, 6592, 6584, 6578, 6570, 6548, 6540, 6534, 6526, 6516, 6508,
|
||||
6502, 6494, 6475, 6467, 6461, 6453, 6443, 6435, 6429, 6421, 6395, 6387, 6381,
|
||||
6373, 6363, 6355, 6349, 6341, 6322, 6314, 6308, 6300, 6290, 6282, 6276, 6268,
|
||||
6246, 6238, 6232, 6224, 6214, 6206, 6200, 6192, 6173, 6165, 6159, 6151, 6141,
|
||||
6133, 6127, 6119, 6253, 6245, 6239, 6231, 6221, 6213, 6207, 6199, 6180, 6172,
|
||||
6166, 6158, 6148, 6140, 6134, 6126, 6104, 6096, 6090, 6082, 6072, 6064, 6058,
|
||||
6050, 6031, 6023, 6017, 6009, 5999, 5991, 5985, 5977, 5951, 5943, 5937, 5929,
|
||||
5919, 5911, 5905, 5897, 5878, 5870, 5864, 5856, 5846, 5838, 5832, 5824, 5802,
|
||||
5794, 5788, 5780, 5770, 5762, 5756, 5748, 5729, 5721, 5715, 5707, 5697, 5689,
|
||||
5683, 5675, 5877, 5869, 5863, 5855, 5845, 5837, 5831, 5823, 5804, 5796, 5790,
|
||||
5782, 5772, 5764, 5758, 5750, 5728, 5720, 5714, 5706, 5696, 5688, 5682, 5674,
|
||||
5655, 5647, 5641, 5633, 5623, 5615, 5609, 5601, 5575, 5567, 5561, 5553, 5543,
|
||||
5535, 5529, 5521, 5502, 5494, 5488, 5480, 5470, 5462, 5456, 5448, 5426, 5418,
|
||||
5412, 5404, 5394, 5386, 5380, 5372, 5353, 5345, 5339, 5331, 5321, 5313, 5307,
|
||||
5299, 5433, 5425, 5419, 5411, 5401, 5393, 5387, 5379, 5360, 5352, 5346, 5338,
|
||||
5328, 5320, 5314, 5306, 5284, 5276, 5270, 5262, 5252, 5244, 5238, 5230, 5211,
|
||||
5203, 5197, 5189, 5179, 5171, 5165, 5157, 5131, 5123, 5117, 5109, 5099, 5091,
|
||||
5085, 5077, 5058, 5050, 5044, 5036, 5026, 5018, 5012, 5004, 4982, 4974, 4968,
|
||||
4960, 4950, 4942, 4936, 4928, 4909, 4901, 4895, 4887, 4877, 4869, 4863, 4855,
|
||||
5586, 5578, 5572, 5564, 5554, 5546, 5540, 5532, 5513, 5505, 5499, 5491, 5481,
|
||||
5473, 5467, 5459, 5437, 5429, 5423, 5415, 5405, 5397, 5391, 5383, 5364, 5356,
|
||||
5350, 5342, 5332, 5324, 5318, 5310, 5284, 5276, 5270, 5262, 5252, 5244, 5238,
|
||||
5230, 5211, 5203, 5197, 5189, 5179, 5171, 5165, 5157, 5135, 5127, 5121, 5113,
|
||||
5103, 5095, 5089, 5081, 5062, 5054, 5048, 5040, 5030, 5022, 5016, 5008, 5142,
|
||||
5134, 5128, 5120, 5110, 5102, 5096, 5088, 5069, 5061, 5055, 5047, 5037, 5029,
|
||||
5023, 5015, 4993, 4985, 4979, 4971, 4961, 4953, 4947, 4939, 4920, 4912, 4906,
|
||||
4898, 4888, 4880, 4874, 4866, 4840, 4832, 4826, 4818, 4808, 4800, 4794, 4786,
|
||||
4767, 4759, 4753, 4745, 4735, 4727, 4721, 4713, 4691, 4683, 4677, 4669, 4659,
|
||||
4651, 4645, 4637, 4618, 4610, 4604, 4596, 4586, 4578, 4572, 4564, 4766, 4758,
|
||||
4752, 4744, 4734, 4726, 4720, 4712, 4693, 4685, 4679, 4671, 4661, 4653, 4647,
|
||||
4639, 4617, 4609, 4603, 4595, 4585, 4577, 4571, 4563, 4544, 4536, 4530, 4522,
|
||||
4512, 4504, 4498, 4490, 4464, 4456, 4450, 4442, 4432, 4424, 4418, 4410, 4391,
|
||||
4383, 4377, 4369, 4359, 4351, 4345, 4337, 4315, 4307, 4301, 4293, 4283, 4275,
|
||||
4269, 4261, 4242, 4234, 4228, 4220, 4210, 4202, 4196, 4188, 4322, 4314, 4308,
|
||||
4300, 4290, 4282, 4276, 4268, 4249, 4241, 4235, 4227, 4217, 4209, 4203, 4195,
|
||||
4173, 4165, 4159, 4151, 4141, 4133, 4127, 4119, 4100, 4092, 4086, 4078, 4068,
|
||||
4060, 4054, 4046, 4020, 4012, 4006, 3998, 3988, 3980, 3974, 3966, 3947, 3939,
|
||||
3933, 3925, 3915, 3907, 3901, 3893, 3871, 3863, 3857, 3849, 3839, 3831, 3825,
|
||||
3817, 3798, 3790, 3784, 3776, 3766, 3758, 3752, 3744, 6697, 6689, 6683, 6675,
|
||||
6665, 6657, 6651, 6643, 6624, 6616, 6610, 6602, 6592, 6584, 6578, 6570, 6548,
|
||||
6540, 6534, 6526, 6516, 6508, 6502, 6494, 6475, 6467, 6461, 6453, 6443, 6435,
|
||||
6429, 6421, 6395, 6387, 6381, 6373, 6363, 6355, 6349, 6341, 6322, 6314, 6308,
|
||||
6300, 6290, 6282, 6276, 6268, 6246, 6238, 6232, 6224, 6214, 6206, 6200, 6192,
|
||||
6173, 6165, 6159, 6151, 6141, 6133, 6127, 6119, 6253, 6245, 6239, 6231, 6221,
|
||||
6213, 6207, 6199, 6180, 6172, 6166, 6158, 6148, 6140, 6134, 6126, 6104, 6096,
|
||||
6090, 6082, 6072, 6064, 6058, 6050, 6031, 6023, 6017, 6009, 5999, 5991, 5985,
|
||||
5977, 5951, 5943, 5937, 5929, 5919, 5911, 5905, 5897, 5878, 5870, 5864, 5856,
|
||||
5846, 5838, 5832, 5824, 5802, 5794, 5788, 5780, 5770, 5762, 5756, 5748, 5729,
|
||||
5721, 5715, 5707, 5697, 5689, 5683, 5675, 5877, 5869, 5863, 5855, 5845, 5837,
|
||||
5831, 5823, 5804, 5796, 5790, 5782, 5772, 5764, 5758, 5750, 5728, 5720, 5714,
|
||||
5706, 5696, 5688, 5682, 5674, 5655, 5647, 5641, 5633, 5623, 5615, 5609, 5601,
|
||||
5575, 5567, 5561, 5553, 5543, 5535, 5529, 5521, 5502, 5494, 5488, 5480, 5470,
|
||||
5462, 5456, 5448, 5426, 5418, 5412, 5404, 5394, 5386, 5380, 5372, 5353, 5345,
|
||||
5339, 5331, 5321, 5313, 5307, 5299, 5433, 5425, 5419, 5411, 5401, 5393, 5387,
|
||||
5379, 5360, 5352, 5346, 5338, 5328, 5320, 5314, 5306, 5284, 5276, 5270, 5262,
|
||||
5252, 5244, 5238, 5230, 5211, 5203, 5197, 5189, 5179, 5171, 5165, 5157, 5131,
|
||||
5123, 5117, 5109, 5099, 5091, 5085, 5077, 5058, 5050, 5044, 5036, 5026, 5018,
|
||||
5012, 5004, 4982, 4974, 4968, 4960, 4950, 4942, 4936, 4928, 4909, 4901, 4895,
|
||||
4887, 4877, 4869, 4863, 4855, 5586, 5578, 5572, 5564, 5554, 5546, 5540, 5532,
|
||||
5513, 5505, 5499, 5491, 5481, 5473, 5467, 5459, 5437, 5429, 5423, 5415, 5405,
|
||||
5397, 5391, 5383, 5364, 5356, 5350, 5342, 5332, 5324, 5318, 5310, 5284, 5276,
|
||||
5270, 5262, 5252, 5244, 5238, 5230, 5211, 5203, 5197, 5189, 5179, 5171, 5165,
|
||||
5157, 5135, 5127, 5121, 5113, 5103, 5095, 5089, 5081, 5062, 5054, 5048, 5040,
|
||||
5030, 5022, 5016, 5008, 5142, 5134, 5128, 5120, 5110, 5102, 5096, 5088, 5069,
|
||||
5061, 5055, 5047, 5037, 5029, 5023, 5015, 4993, 4985, 4979, 4971, 4961, 4953,
|
||||
4947, 4939, 4920, 4912, 4906, 4898, 4888, 4880, 4874, 4866, 4840, 4832, 4826,
|
||||
4818, 4808, 4800, 4794, 4786, 4767, 4759, 4753, 4745, 4735, 4727, 4721, 4713,
|
||||
4691, 4683, 4677, 4669, 4659, 4651, 4645, 4637, 4618, 4610, 4604, 4596, 4586,
|
||||
4578, 4572, 4564, 4766, 4758, 4752, 4744, 4734, 4726, 4720, 4712, 4693, 4685,
|
||||
4679, 4671, 4661, 4653, 4647, 4639, 4617, 4609, 4603, 4595, 4585, 4577, 4571,
|
||||
4563, 4544, 4536, 4530, 4522, 4512, 4504, 4498, 4490, 4464, 4456, 4450, 4442,
|
||||
4432, 4424, 4418, 4410, 4391, 4383, 4377, 4369, 4359, 4351, 4345, 4337, 4315,
|
||||
4307, 4301, 4293, 4283, 4275, 4269, 4261, 4242, 4234, 4228, 4220, 4210, 4202,
|
||||
4196, 4188, 4322, 4314, 4308, 4300, 4290, 4282, 4276, 4268, 4249, 4241, 4235,
|
||||
4227, 4217, 4209, 4203, 4195, 4173, 4165, 4159, 4151, 4141, 4133, 4127, 4119,
|
||||
4100, 4092, 4086, 4078, 4068, 4060, 4054, 4046, 4020, 4012, 4006, 3998, 3988,
|
||||
3980, 3974, 3966, 3947, 3939, 3933, 3925, 3915, 3907, 3901, 3893, 3871, 3863,
|
||||
3857, 3849, 3839, 3831, 3825, 3817, 3798, 3790, 3784, 3776, 3766, 3758, 3752,
|
||||
3744, 4651, 4643, 4637, 4629, 4619, 4611, 4605, 4597, 4578, 4570, 4564, 4556,
|
||||
4546, 4538, 4532, 4524, 4502, 4494, 4488, 4480, 4470, 4462, 4456, 4448, 4429,
|
||||
4421, 4415, 4407, 4397, 4389, 4383, 4375, 4349, 4341, 4335, 4327, 4317, 4309,
|
||||
4303, 4295, 4276, 4268, 4262, 4254, 4244, 4236, 4230, 4222, 4200, 4192, 4186,
|
||||
4178, 4168, 4160, 4154, 4146, 4127, 4119, 4113, 4105, 4095, 4087, 4081, 4073,
|
||||
4207, 4199, 4193, 4185, 4175, 4167, 4161, 4153, 4134, 4126, 4120, 4112, 4102,
|
||||
4094, 4088, 4080, 4058, 4050, 4044, 4036, 4026, 4018, 4012, 4004, 3985, 3977,
|
||||
3971, 3963, 3953, 3945, 3939, 3931, 3905, 3897, 3891, 3883, 3873, 3865, 3859,
|
||||
3851, 3832, 3824, 3818, 3810, 3800, 3792, 3786, 3778, 3756, 3748, 3742, 3734,
|
||||
3724, 3716, 3710, 3702, 3683, 3675, 3669, 3661, 3651, 3643, 3637, 3629, 3831,
|
||||
3823, 3817, 3809, 3799, 3791, 3785, 3777, 3758, 3750, 3744, 3736, 3726, 3718,
|
||||
3712, 3704, 3682, 3674, 3668, 3660, 3650, 3642, 3636, 3628, 3609, 3601, 3595,
|
||||
3587, 3577, 3569, 3563, 3555, 3529, 3521, 3515, 3507, 3497, 3489, 3483, 3475,
|
||||
3456, 3448, 3442, 3434, 3424, 3416, 3410, 3402, 3380, 3372, 3366, 3358, 3348,
|
||||
3340, 3334, 3326, 3307, 3299, 3293, 3285, 3275, 3267, 3261, 3253, 3387, 3379,
|
||||
3373, 3365, 3355, 3347, 3341, 3333, 3314, 3306, 3300, 3292, 3282, 3274, 3268,
|
||||
3260, 3238, 3230, 3224, 3216, 3206, 3198, 3192, 3184, 3165, 3157, 3151, 3143,
|
||||
3133, 3125, 3119, 3111, 3085, 3077, 3071, 3063, 3053, 3045, 3039, 3031, 3012,
|
||||
3004, 2998, 2990, 2980, 2972, 2966, 2958, 2936, 2928, 2922, 2914, 2904, 2896,
|
||||
2890, 2882, 2863, 2855, 2849, 2841, 2831, 2823, 2817, 2809, 3540, 3532, 3526,
|
||||
3518, 3508, 3500, 3494, 3486, 3467, 3459, 3453, 3445, 3435, 3427, 3421, 3413,
|
||||
3391, 3383, 3377, 3369, 3359, 3351, 3345, 3337, 3318, 3310, 3304, 3296, 3286,
|
||||
3278, 3272, 3264, 3238, 3230, 3224, 3216, 3206, 3198, 3192, 3184, 3165, 3157,
|
||||
3151, 3143, 3133, 3125, 3119, 3111, 3089, 3081, 3075, 3067, 3057, 3049, 3043,
|
||||
3035, 3016, 3008, 3002, 2994, 2984, 2976, 2970, 2962, 3096, 3088, 3082, 3074,
|
||||
3064, 3056, 3050, 3042, 3023, 3015, 3009, 3001, 2991, 2983, 2977, 2969, 2947,
|
||||
2939, 2933, 2925, 2915, 2907, 2901, 2893, 2874, 2866, 2860, 2852, 2842, 2834,
|
||||
2828, 2820, 2794, 2786, 2780, 2772, 2762, 2754, 2748, 2740, 2721, 2713, 2707,
|
||||
2699, 2689, 2681, 2675, 2667, 2645, 2637, 2631, 2623, 2613, 2605, 2599, 2591,
|
||||
2572, 2564, 2558, 2550, 2540, 2532, 2526, 2518, 2720, 2712, 2706, 2698, 2688,
|
||||
2680, 2674, 2666, 2647, 2639, 2633, 2625, 2615, 2607, 2601, 2593, 2571, 2563,
|
||||
2557, 2549, 2539, 2531, 2525, 2517, 2498, 2490, 2484, 2476, 2466, 2458, 2452,
|
||||
2444, 2418, 2410, 2404, 2396, 2386, 2378, 2372, 2364, 2345, 2337, 2331, 2323,
|
||||
2313, 2305, 2299, 2291, 2269, 2261, 2255, 2247, 2237, 2229, 2223, 2215, 2196,
|
||||
2188, 2182, 2174, 2164, 2156, 2150, 2142, 2276, 2268, 2262, 2254, 2244, 2236,
|
||||
2230, 2222, 2203, 2195, 2189, 2181, 2171, 2163, 2157, 2149, 2127, 2119, 2113,
|
||||
2105, 2095, 2087, 2081, 2073, 2054, 2046, 2040, 2032, 2022, 2014, 2008, 2000,
|
||||
1974, 1966, 1960, 1952, 1942, 1934, 1928, 1920, 1901, 1893, 1887, 1879, 1869,
|
||||
1861, 1855, 1847, 1825, 1817, 1811, 1803, 1793, 1785, 1779, 1771, 1752, 1744,
|
||||
1738, 1730, 1720, 1712, 1706, 1698, 1897, 1883, 1860, 1846, 1819, 1805, 1782,
|
||||
1768, 1723, 1709, 1686, 1672, 1645, 1631, 1608, 1594, 1574, 1560, 1537, 1523,
|
||||
1496, 1482, 1459, 1445, 1400, 1386, 1363, 1349, 1322, 1308, 1285, 1271, 1608,
|
||||
1565, 1535, 1492, 1446, 1403, 1373, 1330, 1312, 1269, 1239, 1196, 1150, 1107,
|
||||
1077, 1034, 1291, 1218, 1171, 1098, 1015, 942, 895, 822, 953, 850, 729,
|
||||
626, 618, 431, 257, 257, 257, 257, 0, 255, 255, 255, 255, 429,
|
||||
616, 624, 727, 848, 951, 820, 893, 940, 1013, 1096, 1169, 1216, 1289,
|
||||
1032, 1075, 1105, 1148, 1194, 1237, 1267, 1310, 1328, 1371, 1401, 1444, 1490,
|
||||
1533, 1563, 1606, 1269, 1283, 1306, 1320, 1347, 1361, 1384, 1398, 1443, 1457,
|
||||
1480, 1494, 1521, 1535, 1558, 1572, 1592, 1606, 1629, 1643, 1670, 1684, 1707,
|
||||
1721, 1766, 1780, 1803, 1817, 1844, 1858, 1881, 1895, 1696, 1704, 1710, 1718,
|
||||
1728, 1736, 1742, 1750, 1769, 1777, 1783, 1791, 1801, 1809, 1815, 1823, 1845,
|
||||
1853, 1859, 1867, 1877, 1885, 1891, 1899, 1918, 1926, 1932, 1940, 1950, 1958,
|
||||
1964, 1972, 1998, 2006, 2012, 2020, 2030, 2038, 2044, 2052, 2071, 2079, 2085,
|
||||
2093, 2103, 2111, 2117, 2125, 2147, 2155, 2161, 2169, 2179, 2187, 2193, 2201,
|
||||
2220, 2228, 2234, 2242, 2252, 2260, 2266, 2274, 2140, 2148, 2154, 2162, 2172,
|
||||
2180, 2186, 2194, 2213, 2221, 2227, 2235, 2245, 2253, 2259, 2267, 2289, 2297,
|
||||
2303, 2311, 2321, 2329, 2335, 2343, 2362, 2370, 2376, 2384, 2394, 2402, 2408,
|
||||
2416, 2442, 2450, 2456, 2464, 2474, 2482, 2488, 2496, 2515, 2523, 2529, 2537,
|
||||
2547, 2555, 2561, 2569, 2591, 2599, 2605, 2613, 2623, 2631, 2637, 2645, 2664,
|
||||
2672, 2678, 2686, 2696, 2704, 2710, 2718, 2516, 2524, 2530, 2538, 2548, 2556,
|
||||
2562, 2570, 2589, 2597, 2603, 2611, 2621, 2629, 2635, 2643, 2665, 2673, 2679,
|
||||
2687, 2697, 2705, 2711, 2719, 2738, 2746, 2752, 2760, 2770, 2778, 2784, 2792,
|
||||
2818, 2826, 2832, 2840, 2850, 2858, 2864, 2872, 2891, 2899, 2905, 2913, 2923,
|
||||
2931, 2937, 2945, 2967, 2975, 2981, 2989, 2999, 3007, 3013, 3021, 3040, 3048,
|
||||
3054, 3062, 3072, 3080, 3086, 3094, 2960, 2968, 2974, 2982, 2992, 3000, 3006,
|
||||
3014, 3033, 3041, 3047, 3055, 3065, 3073, 3079, 3087, 3109, 3117, 3123, 3131,
|
||||
3141, 3149, 3155, 3163, 3182, 3190, 3196, 3204, 3214, 3222, 3228, 3236, 3262,
|
||||
3270, 3276, 3284, 3294, 3302, 3308, 3316, 3335, 3343, 3349, 3357, 3367, 3375,
|
||||
3381, 3389, 3411, 3419, 3425, 3433, 3443, 3451, 3457, 3465, 3484, 3492, 3498,
|
||||
3506, 3516, 3524, 3530, 3538, 2807, 2815, 2821, 2829, 2839, 2847, 2853, 2861,
|
||||
2880, 2888, 2894, 2902, 2912, 2920, 2926, 2934, 2956, 2964, 2970, 2978, 2988,
|
||||
2996, 3002, 3010, 3029, 3037, 3043, 3051, 3061, 3069, 3075, 3083, 3109, 3117,
|
||||
3123, 3131, 3141, 3149, 3155, 3163, 3182, 3190, 3196, 3204, 3214, 3222, 3228,
|
||||
3236, 3258, 3266, 3272, 3280, 3290, 3298, 3304, 3312, 3331, 3339, 3345, 3353,
|
||||
3363, 3371, 3377, 3385, 3251, 3259, 3265, 3273, 3283, 3291, 3297, 3305, 3324,
|
||||
3332, 3338, 3346, 3356, 3364, 3370, 3378, 3400, 3408, 3414, 3422, 3432, 3440,
|
||||
3446, 3454, 3473, 3481, 3487, 3495, 3505, 3513, 3519, 3527, 3553, 3561, 3567,
|
||||
3575, 3585, 3593, 3599, 3607, 3626, 3634, 3640, 3648, 3658, 3666, 3672, 3680,
|
||||
3702, 3710, 3716, 3724, 3734, 3742, 3748, 3756, 3775, 3783, 3789, 3797, 3807,
|
||||
3815, 3821, 3829, 3627, 3635, 3641, 3649, 3659, 3667, 3673, 3681, 3700, 3708,
|
||||
3714, 3722, 3732, 3740, 3746, 3754, 3776, 3784, 3790, 3798, 3808, 3816, 3822,
|
||||
3830, 3849, 3857, 3863, 3871, 3881, 3889, 3895, 3903, 3929, 3937, 3943, 3951,
|
||||
3961, 3969, 3975, 3983, 4002, 4010, 4016, 4024, 4034, 4042, 4048, 4056, 4078,
|
||||
4086, 4092, 4100, 4110, 4118, 4124, 4132, 4151, 4159, 4165, 4173, 4183, 4191,
|
||||
4197, 4205, 4071, 4079, 4085, 4093, 4103, 4111, 4117, 4125, 4144, 4152, 4158,
|
||||
4166, 4176, 4184, 4190, 4198, 4220, 4228, 4234, 4242, 4252, 4260, 4266, 4274,
|
||||
4293, 4301, 4307, 4315, 4325, 4333, 4339, 4347, 4373, 4381, 4387, 4395, 4405,
|
||||
4413, 4419, 4427, 4446, 4454, 4460, 4468, 4478, 4486, 4492, 4500, 4522, 4530,
|
||||
4536, 4544, 4554, 4562, 4568, 4576, 4595, 4603, 4609, 4617, 4627, 4635, 4641,
|
||||
4649, 3742, 3750, 3756, 3764, 3774, 3782, 3788, 3796, 3815, 3823, 3829, 3837,
|
||||
3847, 3855, 3861, 3869, 3891, 3899, 3905, 3913, 3923, 3931, 3937, 3945, 3964,
|
||||
3972, 3978, 3986, 3996, 4004, 4010, 4018, 4044, 4052, 4058, 4066, 4076, 4084,
|
||||
4090, 4098, 4117, 4125, 4131, 4139, 4149, 4157, 4163, 4171, 4193, 4201, 4207,
|
||||
4215, 4225, 4233, 4239, 4247, 4266, 4274, 4280, 4288, 4298, 4306, 4312, 4320,
|
||||
4186, 4194, 4200, 4208, 4218, 4226, 4232, 4240, 4259, 4267, 4273, 4281, 4291,
|
||||
4299, 4305, 4313, 4335, 4343, 4349, 4357, 4367, 4375, 4381, 4389, 4408, 4416,
|
||||
4422, 4430, 4440, 4448, 4454, 4462, 4488, 4496, 4502, 4510, 4520, 4528, 4534,
|
||||
4542, 4561, 4569, 4575, 4583, 4593, 4601, 4607, 4615, 4637, 4645, 4651, 4659,
|
||||
4669, 4677, 4683, 4691, 4710, 4718, 4724, 4732, 4742, 4750, 4756, 4764, 4562,
|
||||
4570, 4576, 4584, 4594, 4602, 4608, 4616, 4635, 4643, 4649, 4657, 4667, 4675,
|
||||
4681, 4689, 4711, 4719, 4725, 4733, 4743, 4751, 4757, 4765, 4784, 4792, 4798,
|
||||
4806, 4816, 4824, 4830, 4838, 4864, 4872, 4878, 4886, 4896, 4904, 4910, 4918,
|
||||
4937, 4945, 4951, 4959, 4969, 4977, 4983, 4991, 5013, 5021, 5027, 5035, 5045,
|
||||
5053, 5059, 5067, 5086, 5094, 5100, 5108, 5118, 5126, 5132, 5140, 5006, 5014,
|
||||
5020, 5028, 5038, 5046, 5052, 5060, 5079, 5087, 5093, 5101, 5111, 5119, 5125,
|
||||
5133, 5155, 5163, 5169, 5177, 5187, 5195, 5201, 5209, 5228, 5236, 5242, 5250,
|
||||
5260, 5268, 5274, 5282, 5308, 5316, 5322, 5330, 5340, 5348, 5354, 5362, 5381,
|
||||
5389, 5395, 5403, 5413, 5421, 5427, 5435, 5457, 5465, 5471, 5479, 5489, 5497,
|
||||
5503, 5511, 5530, 5538, 5544, 5552, 5562, 5570, 5576, 5584, 4853, 4861, 4867,
|
||||
4875, 4885, 4893, 4899, 4907, 4926, 4934, 4940, 4948, 4958, 4966, 4972, 4980,
|
||||
5002, 5010, 5016, 5024, 5034, 5042, 5048, 5056, 5075, 5083, 5089, 5097, 5107,
|
||||
5115, 5121, 5129, 5155, 5163, 5169, 5177, 5187, 5195, 5201, 5209, 5228, 5236,
|
||||
5242, 5250, 5260, 5268, 5274, 5282, 5304, 5312, 5318, 5326, 5336, 5344, 5350,
|
||||
5358, 5377, 5385, 5391, 5399, 5409, 5417, 5423, 5431, 5297, 5305, 5311, 5319,
|
||||
5329, 5337, 5343, 5351, 5370, 5378, 5384, 5392, 5402, 5410, 5416, 5424, 5446,
|
||||
5454, 5460, 5468, 5478, 5486, 5492, 5500, 5519, 5527, 5533, 5541, 5551, 5559,
|
||||
5565, 5573, 5599, 5607, 5613, 5621, 5631, 5639, 5645, 5653, 5672, 5680, 5686,
|
||||
5694, 5704, 5712, 5718, 5726, 5748, 5756, 5762, 5770, 5780, 5788, 5794, 5802,
|
||||
5821, 5829, 5835, 5843, 5853, 5861, 5867, 5875, 5673, 5681, 5687, 5695, 5705,
|
||||
5713, 5719, 5727, 5746, 5754, 5760, 5768, 5778, 5786, 5792, 5800, 5822, 5830,
|
||||
5836, 5844, 5854, 5862, 5868, 5876, 5895, 5903, 5909, 5917, 5927, 5935, 5941,
|
||||
5949, 5975, 5983, 5989, 5997, 6007, 6015, 6021, 6029, 6048, 6056, 6062, 6070,
|
||||
6080, 6088, 6094, 6102, 6124, 6132, 6138, 6146, 6156, 6164, 6170, 6178, 6197,
|
||||
6205, 6211, 6219, 6229, 6237, 6243, 6251, 6117, 6125, 6131, 6139, 6149, 6157,
|
||||
6163, 6171, 6190, 6198, 6204, 6212, 6222, 6230, 6236, 6244, 6266, 6274, 6280,
|
||||
6288, 6298, 6306, 6312, 6320, 6339, 6347, 6353, 6361, 6371, 6379, 6385, 6393,
|
||||
6419, 6427, 6433, 6441, 6451, 6459, 6465, 6473, 6492, 6500, 6506, 6514, 6524,
|
||||
6532, 6538, 6546, 6568, 6576, 6582, 6590, 6600, 6608, 6614, 6622, 6641, 6649,
|
||||
6655, 6663, 6673, 6681, 6687, 6695, 3742, 3750, 3756, 3764, 3774, 3782, 3788,
|
||||
3796, 3815, 3823, 3829, 3837, 3847, 3855, 3861, 3869, 3891, 3899, 3905, 3913,
|
||||
3923, 3931, 3937, 3945, 3964, 3972, 3978, 3986, 3996, 4004, 4010, 4018, 4044,
|
||||
4052, 4058, 4066, 4076, 4084, 4090, 4098, 4117, 4125, 4131, 4139, 4149, 4157,
|
||||
4163, 4171, 4193, 4201, 4207, 4215, 4225, 4233, 4239, 4247, 4266, 4274, 4280,
|
||||
4288, 4298, 4306, 4312, 4320, 4186, 4194, 4200, 4208, 4218, 4226, 4232, 4240,
|
||||
4259, 4267, 4273, 4281, 4291, 4299, 4305, 4313, 4335, 4343, 4349, 4357, 4367,
|
||||
4375, 4381, 4389, 4408, 4416, 4422, 4430, 4440, 4448, 4454, 4462, 4488, 4496,
|
||||
4502, 4510, 4520, 4528, 4534, 4542, 4561, 4569, 4575, 4583, 4593, 4601, 4607,
|
||||
4615, 4637, 4645, 4651, 4659, 4669, 4677, 4683, 4691, 4710, 4718, 4724, 4732,
|
||||
4742, 4750, 4756, 4764, 4562, 4570, 4576, 4584, 4594, 4602, 4608, 4616, 4635,
|
||||
4643, 4649, 4657, 4667, 4675, 4681, 4689, 4711, 4719, 4725, 4733, 4743, 4751,
|
||||
4757, 4765, 4784, 4792, 4798, 4806, 4816, 4824, 4830, 4838, 4864, 4872, 4878,
|
||||
4886, 4896, 4904, 4910, 4918, 4937, 4945, 4951, 4959, 4969, 4977, 4983, 4991,
|
||||
5013, 5021, 5027, 5035, 5045, 5053, 5059, 5067, 5086, 5094, 5100, 5108, 5118,
|
||||
5126, 5132, 5140, 5006, 5014, 5020, 5028, 5038, 5046, 5052, 5060, 5079, 5087,
|
||||
5093, 5101, 5111, 5119, 5125, 5133, 5155, 5163, 5169, 5177, 5187, 5195, 5201,
|
||||
5209, 5228, 5236, 5242, 5250, 5260, 5268, 5274, 5282, 5308, 5316, 5322, 5330,
|
||||
5340, 5348, 5354, 5362, 5381, 5389, 5395, 5403, 5413, 5421, 5427, 5435, 5457,
|
||||
5465, 5471, 5479, 5489, 5497, 5503, 5511, 5530, 5538, 5544, 5552, 5562, 5570,
|
||||
5576, 5584, 4853, 4861, 4867, 4875, 4885, 4893, 4899, 4907, 4926, 4934, 4940,
|
||||
4948, 4958, 4966, 4972, 4980, 5002, 5010, 5016, 5024, 5034, 5042, 5048, 5056,
|
||||
5075, 5083, 5089, 5097, 5107, 5115, 5121, 5129, 5155, 5163, 5169, 5177, 5187,
|
||||
5195, 5201, 5209, 5228, 5236, 5242, 5250, 5260, 5268, 5274, 5282, 5304, 5312,
|
||||
5318, 5326, 5336, 5344, 5350, 5358, 5377, 5385, 5391, 5399, 5409, 5417, 5423,
|
||||
5431, 5297, 5305, 5311, 5319, 5329, 5337, 5343, 5351, 5370, 5378, 5384, 5392,
|
||||
5402, 5410, 5416, 5424, 5446, 5454, 5460, 5468, 5478, 5486, 5492, 5500, 5519,
|
||||
5527, 5533, 5541, 5551, 5559, 5565, 5573, 5599, 5607, 5613, 5621, 5631, 5639,
|
||||
5645, 5653, 5672, 5680, 5686, 5694, 5704, 5712, 5718, 5726, 5748, 5756, 5762,
|
||||
5770, 5780, 5788, 5794, 5802, 5821, 5829, 5835, 5843, 5853, 5861, 5867, 5875,
|
||||
5673, 5681, 5687, 5695, 5705, 5713, 5719, 5727, 5746, 5754, 5760, 5768, 5778,
|
||||
5786, 5792, 5800, 5822, 5830, 5836, 5844, 5854, 5862, 5868, 5876, 5895, 5903,
|
||||
5909, 5917, 5927, 5935, 5941, 5949, 5975, 5983, 5989, 5997, 6007, 6015, 6021,
|
||||
6029, 6048, 6056, 6062, 6070, 6080, 6088, 6094, 6102, 6124, 6132, 6138, 6146,
|
||||
6156, 6164, 6170, 6178, 6197, 6205, 6211, 6219, 6229, 6237, 6243, 6251, 6117,
|
||||
6125, 6131, 6139, 6149, 6157, 6163, 6171, 6190, 6198, 6204, 6212, 6222, 6230,
|
||||
6236, 6244, 6266, 6274, 6280, 6288, 6298, 6306, 6312, 6320, 6339, 6347, 6353,
|
||||
6361, 6371, 6379, 6385, 6393, 6419, 6427, 6433, 6441, 6451, 6459, 6465, 6473,
|
||||
6492, 6500, 6506, 6514, 6524, 6532, 6538, 6546, 6568, 6576, 6582, 6590, 6600,
|
||||
6608, 6614, 6622, 6641, 6649, 6655, 6663, 6673, 6681, 6687, 6695, 5788, 5796,
|
||||
5802, 5810, 5820, 5828, 5834, 5842, 5861, 5869, 5875, 5883, 5893, 5901, 5907,
|
||||
5915, 5937, 5945, 5951, 5959, 5969, 5977, 5983, 5991, 6010, 6018, 6024, 6032,
|
||||
6042, 6050, 6056, 6064, 6090, 6098, 6104, 6112, 6122, 6130, 6136, 6144, 6163,
|
||||
6171, 6177, 6185, 6195, 6203, 6209, 6217, 6239, 6247, 6253, 6261, 6271, 6279,
|
||||
6285, 6293, 6312, 6320, 6326, 6334, 6344, 6352, 6358, 6366, 6232, 6240, 6246,
|
||||
6254, 6264, 6272, 6278, 6286, 6305, 6313, 6319, 6327, 6337, 6345, 6351, 6359,
|
||||
6381, 6389, 6395, 6403, 6413, 6421, 6427, 6435, 6454, 6462, 6468, 6476, 6486,
|
||||
6494, 6500, 6508, 6534, 6542, 6548, 6556, 6566, 6574, 6580, 6588, 6607, 6615,
|
||||
6621, 6629, 6639, 6647, 6653, 6661, 6683, 6691, 6697, 6705, 6715, 6723, 6729,
|
||||
6737, 6756, 6764, 6770, 6778, 6788, 6796, 6802, 6810, 6608, 6616, 6622, 6630,
|
||||
6640, 6648, 6654, 6662, 6681, 6689, 6695, 6703, 6713, 6721, 6727, 6735, 6757,
|
||||
6765, 6771, 6779, 6789, 6797, 6803, 6811, 6830, 6838, 6844, 6852, 6862, 6870,
|
||||
6876, 6884, 6910, 6918, 6924, 6932, 6942, 6950, 6956, 6964, 6983, 6991, 6997,
|
||||
7005, 7015, 7023, 7029, 7037, 7059, 7067, 7073, 7081, 7091, 7099, 7105, 7113,
|
||||
7132, 7140, 7146, 7154, 7164, 7172, 7178, 7186, 7052, 7060, 7066, 7074, 7084,
|
||||
7092, 7098, 7106, 7125, 7133, 7139, 7147, 7157, 7165, 7171, 7179, 7201, 7209,
|
||||
7215, 7223, 7233, 7241, 7247, 7255, 7274, 7282, 7288, 7296, 7306, 7314, 7320,
|
||||
7328, 7354, 7362, 7368, 7376, 7386, 7394, 7400, 7408, 7427, 7435, 7441, 7449,
|
||||
7459, 7467, 7473, 7481, 7503, 7511, 7517, 7525, 7535, 7543, 7549, 7557, 7576,
|
||||
7584, 7590, 7598, 7608, 7616, 7622, 7630, 6899, 6907, 6913, 6921, 6931, 6939,
|
||||
6945, 6953, 6972, 6980, 6986, 6994, 7004, 7012, 7018, 7026, 7048, 7056, 7062,
|
||||
7070, 7080, 7088, 7094, 7102, 7121, 7129, 7135, 7143, 7153, 7161, 7167, 7175,
|
||||
7201, 7209, 7215, 7223, 7233, 7241, 7247, 7255, 7274, 7282, 7288, 7296, 7306,
|
||||
7314, 7320, 7328, 7350, 7358, 7364, 7372, 7382, 7390, 7396, 7404, 7423, 7431,
|
||||
7437, 7445, 7455, 7463, 7469, 7477, 7343, 7351, 7357, 7365, 7375, 7383, 7389,
|
||||
7397, 7416, 7424, 7430, 7438, 7448, 7456, 7462, 7470, 7492, 7500, 7506, 7514,
|
||||
7524, 7532, 7538, 7546, 7565, 7573, 7579, 7587, 7597, 7605, 7611, 7619, 7645,
|
||||
7653, 7659, 7667, 7677, 7685, 7691, 7699, 7718, 7726, 7732, 7740, 7750, 7758,
|
||||
7764, 7772, 7794, 7802, 7808, 7816, 7826, 7834, 7840, 7848, 7867, 7875, 7881,
|
||||
7889, 7899, 7907, 7913, 7921, 7719, 7727, 7733, 7741, 7751, 7759, 7765, 7773,
|
||||
7792, 7800, 7806, 7814, 7824, 7832, 7838, 7846, 7868, 7876, 7882, 7890, 7900,
|
||||
7908, 7914, 7922, 7941, 7949, 7955, 7963, 7973, 7981, 7987, 7995, 8021, 8029,
|
||||
8035, 8043, 8053, 8061, 8067, 8075, 8094, 8102, 8108, 8116, 8126, 8134, 8140,
|
||||
8148, 8170, 8178, 8184, 8192, 8202, 8210, 8216, 8224, 8243, 8251, 8257, 8265,
|
||||
8275
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_DCT_VALUE_COST_H_
|
||||
@@ -0,0 +1,848 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_DCT_VALUE_TOKENS_H_
|
||||
#define VPX_VP8_ENCODER_DCT_VALUE_TOKENS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Generated file, included by tokenize.c */
|
||||
/* Values generated by fill_value_tokens() */
|
||||
|
||||
static const TOKENVALUE dct_value_tokens[2048 * 2] = {
|
||||
{ 10, 3963 }, { 10, 3961 }, { 10, 3959 }, { 10, 3957 }, { 10, 3955 },
|
||||
{ 10, 3953 }, { 10, 3951 }, { 10, 3949 }, { 10, 3947 }, { 10, 3945 },
|
||||
{ 10, 3943 }, { 10, 3941 }, { 10, 3939 }, { 10, 3937 }, { 10, 3935 },
|
||||
{ 10, 3933 }, { 10, 3931 }, { 10, 3929 }, { 10, 3927 }, { 10, 3925 },
|
||||
{ 10, 3923 }, { 10, 3921 }, { 10, 3919 }, { 10, 3917 }, { 10, 3915 },
|
||||
{ 10, 3913 }, { 10, 3911 }, { 10, 3909 }, { 10, 3907 }, { 10, 3905 },
|
||||
{ 10, 3903 }, { 10, 3901 }, { 10, 3899 }, { 10, 3897 }, { 10, 3895 },
|
||||
{ 10, 3893 }, { 10, 3891 }, { 10, 3889 }, { 10, 3887 }, { 10, 3885 },
|
||||
{ 10, 3883 }, { 10, 3881 }, { 10, 3879 }, { 10, 3877 }, { 10, 3875 },
|
||||
{ 10, 3873 }, { 10, 3871 }, { 10, 3869 }, { 10, 3867 }, { 10, 3865 },
|
||||
{ 10, 3863 }, { 10, 3861 }, { 10, 3859 }, { 10, 3857 }, { 10, 3855 },
|
||||
{ 10, 3853 }, { 10, 3851 }, { 10, 3849 }, { 10, 3847 }, { 10, 3845 },
|
||||
{ 10, 3843 }, { 10, 3841 }, { 10, 3839 }, { 10, 3837 }, { 10, 3835 },
|
||||
{ 10, 3833 }, { 10, 3831 }, { 10, 3829 }, { 10, 3827 }, { 10, 3825 },
|
||||
{ 10, 3823 }, { 10, 3821 }, { 10, 3819 }, { 10, 3817 }, { 10, 3815 },
|
||||
{ 10, 3813 }, { 10, 3811 }, { 10, 3809 }, { 10, 3807 }, { 10, 3805 },
|
||||
{ 10, 3803 }, { 10, 3801 }, { 10, 3799 }, { 10, 3797 }, { 10, 3795 },
|
||||
{ 10, 3793 }, { 10, 3791 }, { 10, 3789 }, { 10, 3787 }, { 10, 3785 },
|
||||
{ 10, 3783 }, { 10, 3781 }, { 10, 3779 }, { 10, 3777 }, { 10, 3775 },
|
||||
{ 10, 3773 }, { 10, 3771 }, { 10, 3769 }, { 10, 3767 }, { 10, 3765 },
|
||||
{ 10, 3763 }, { 10, 3761 }, { 10, 3759 }, { 10, 3757 }, { 10, 3755 },
|
||||
{ 10, 3753 }, { 10, 3751 }, { 10, 3749 }, { 10, 3747 }, { 10, 3745 },
|
||||
{ 10, 3743 }, { 10, 3741 }, { 10, 3739 }, { 10, 3737 }, { 10, 3735 },
|
||||
{ 10, 3733 }, { 10, 3731 }, { 10, 3729 }, { 10, 3727 }, { 10, 3725 },
|
||||
{ 10, 3723 }, { 10, 3721 }, { 10, 3719 }, { 10, 3717 }, { 10, 3715 },
|
||||
{ 10, 3713 }, { 10, 3711 }, { 10, 3709 }, { 10, 3707 }, { 10, 3705 },
|
||||
{ 10, 3703 }, { 10, 3701 }, { 10, 3699 }, { 10, 3697 }, { 10, 3695 },
|
||||
{ 10, 3693 }, { 10, 3691 }, { 10, 3689 }, { 10, 3687 }, { 10, 3685 },
|
||||
{ 10, 3683 }, { 10, 3681 }, { 10, 3679 }, { 10, 3677 }, { 10, 3675 },
|
||||
{ 10, 3673 }, { 10, 3671 }, { 10, 3669 }, { 10, 3667 }, { 10, 3665 },
|
||||
{ 10, 3663 }, { 10, 3661 }, { 10, 3659 }, { 10, 3657 }, { 10, 3655 },
|
||||
{ 10, 3653 }, { 10, 3651 }, { 10, 3649 }, { 10, 3647 }, { 10, 3645 },
|
||||
{ 10, 3643 }, { 10, 3641 }, { 10, 3639 }, { 10, 3637 }, { 10, 3635 },
|
||||
{ 10, 3633 }, { 10, 3631 }, { 10, 3629 }, { 10, 3627 }, { 10, 3625 },
|
||||
{ 10, 3623 }, { 10, 3621 }, { 10, 3619 }, { 10, 3617 }, { 10, 3615 },
|
||||
{ 10, 3613 }, { 10, 3611 }, { 10, 3609 }, { 10, 3607 }, { 10, 3605 },
|
||||
{ 10, 3603 }, { 10, 3601 }, { 10, 3599 }, { 10, 3597 }, { 10, 3595 },
|
||||
{ 10, 3593 }, { 10, 3591 }, { 10, 3589 }, { 10, 3587 }, { 10, 3585 },
|
||||
{ 10, 3583 }, { 10, 3581 }, { 10, 3579 }, { 10, 3577 }, { 10, 3575 },
|
||||
{ 10, 3573 }, { 10, 3571 }, { 10, 3569 }, { 10, 3567 }, { 10, 3565 },
|
||||
{ 10, 3563 }, { 10, 3561 }, { 10, 3559 }, { 10, 3557 }, { 10, 3555 },
|
||||
{ 10, 3553 }, { 10, 3551 }, { 10, 3549 }, { 10, 3547 }, { 10, 3545 },
|
||||
{ 10, 3543 }, { 10, 3541 }, { 10, 3539 }, { 10, 3537 }, { 10, 3535 },
|
||||
{ 10, 3533 }, { 10, 3531 }, { 10, 3529 }, { 10, 3527 }, { 10, 3525 },
|
||||
{ 10, 3523 }, { 10, 3521 }, { 10, 3519 }, { 10, 3517 }, { 10, 3515 },
|
||||
{ 10, 3513 }, { 10, 3511 }, { 10, 3509 }, { 10, 3507 }, { 10, 3505 },
|
||||
{ 10, 3503 }, { 10, 3501 }, { 10, 3499 }, { 10, 3497 }, { 10, 3495 },
|
||||
{ 10, 3493 }, { 10, 3491 }, { 10, 3489 }, { 10, 3487 }, { 10, 3485 },
|
||||
{ 10, 3483 }, { 10, 3481 }, { 10, 3479 }, { 10, 3477 }, { 10, 3475 },
|
||||
{ 10, 3473 }, { 10, 3471 }, { 10, 3469 }, { 10, 3467 }, { 10, 3465 },
|
||||
{ 10, 3463 }, { 10, 3461 }, { 10, 3459 }, { 10, 3457 }, { 10, 3455 },
|
||||
{ 10, 3453 }, { 10, 3451 }, { 10, 3449 }, { 10, 3447 }, { 10, 3445 },
|
||||
{ 10, 3443 }, { 10, 3441 }, { 10, 3439 }, { 10, 3437 }, { 10, 3435 },
|
||||
{ 10, 3433 }, { 10, 3431 }, { 10, 3429 }, { 10, 3427 }, { 10, 3425 },
|
||||
{ 10, 3423 }, { 10, 3421 }, { 10, 3419 }, { 10, 3417 }, { 10, 3415 },
|
||||
{ 10, 3413 }, { 10, 3411 }, { 10, 3409 }, { 10, 3407 }, { 10, 3405 },
|
||||
{ 10, 3403 }, { 10, 3401 }, { 10, 3399 }, { 10, 3397 }, { 10, 3395 },
|
||||
{ 10, 3393 }, { 10, 3391 }, { 10, 3389 }, { 10, 3387 }, { 10, 3385 },
|
||||
{ 10, 3383 }, { 10, 3381 }, { 10, 3379 }, { 10, 3377 }, { 10, 3375 },
|
||||
{ 10, 3373 }, { 10, 3371 }, { 10, 3369 }, { 10, 3367 }, { 10, 3365 },
|
||||
{ 10, 3363 }, { 10, 3361 }, { 10, 3359 }, { 10, 3357 }, { 10, 3355 },
|
||||
{ 10, 3353 }, { 10, 3351 }, { 10, 3349 }, { 10, 3347 }, { 10, 3345 },
|
||||
{ 10, 3343 }, { 10, 3341 }, { 10, 3339 }, { 10, 3337 }, { 10, 3335 },
|
||||
{ 10, 3333 }, { 10, 3331 }, { 10, 3329 }, { 10, 3327 }, { 10, 3325 },
|
||||
{ 10, 3323 }, { 10, 3321 }, { 10, 3319 }, { 10, 3317 }, { 10, 3315 },
|
||||
{ 10, 3313 }, { 10, 3311 }, { 10, 3309 }, { 10, 3307 }, { 10, 3305 },
|
||||
{ 10, 3303 }, { 10, 3301 }, { 10, 3299 }, { 10, 3297 }, { 10, 3295 },
|
||||
{ 10, 3293 }, { 10, 3291 }, { 10, 3289 }, { 10, 3287 }, { 10, 3285 },
|
||||
{ 10, 3283 }, { 10, 3281 }, { 10, 3279 }, { 10, 3277 }, { 10, 3275 },
|
||||
{ 10, 3273 }, { 10, 3271 }, { 10, 3269 }, { 10, 3267 }, { 10, 3265 },
|
||||
{ 10, 3263 }, { 10, 3261 }, { 10, 3259 }, { 10, 3257 }, { 10, 3255 },
|
||||
{ 10, 3253 }, { 10, 3251 }, { 10, 3249 }, { 10, 3247 }, { 10, 3245 },
|
||||
{ 10, 3243 }, { 10, 3241 }, { 10, 3239 }, { 10, 3237 }, { 10, 3235 },
|
||||
{ 10, 3233 }, { 10, 3231 }, { 10, 3229 }, { 10, 3227 }, { 10, 3225 },
|
||||
{ 10, 3223 }, { 10, 3221 }, { 10, 3219 }, { 10, 3217 }, { 10, 3215 },
|
||||
{ 10, 3213 }, { 10, 3211 }, { 10, 3209 }, { 10, 3207 }, { 10, 3205 },
|
||||
{ 10, 3203 }, { 10, 3201 }, { 10, 3199 }, { 10, 3197 }, { 10, 3195 },
|
||||
{ 10, 3193 }, { 10, 3191 }, { 10, 3189 }, { 10, 3187 }, { 10, 3185 },
|
||||
{ 10, 3183 }, { 10, 3181 }, { 10, 3179 }, { 10, 3177 }, { 10, 3175 },
|
||||
{ 10, 3173 }, { 10, 3171 }, { 10, 3169 }, { 10, 3167 }, { 10, 3165 },
|
||||
{ 10, 3163 }, { 10, 3161 }, { 10, 3159 }, { 10, 3157 }, { 10, 3155 },
|
||||
{ 10, 3153 }, { 10, 3151 }, { 10, 3149 }, { 10, 3147 }, { 10, 3145 },
|
||||
{ 10, 3143 }, { 10, 3141 }, { 10, 3139 }, { 10, 3137 }, { 10, 3135 },
|
||||
{ 10, 3133 }, { 10, 3131 }, { 10, 3129 }, { 10, 3127 }, { 10, 3125 },
|
||||
{ 10, 3123 }, { 10, 3121 }, { 10, 3119 }, { 10, 3117 }, { 10, 3115 },
|
||||
{ 10, 3113 }, { 10, 3111 }, { 10, 3109 }, { 10, 3107 }, { 10, 3105 },
|
||||
{ 10, 3103 }, { 10, 3101 }, { 10, 3099 }, { 10, 3097 }, { 10, 3095 },
|
||||
{ 10, 3093 }, { 10, 3091 }, { 10, 3089 }, { 10, 3087 }, { 10, 3085 },
|
||||
{ 10, 3083 }, { 10, 3081 }, { 10, 3079 }, { 10, 3077 }, { 10, 3075 },
|
||||
{ 10, 3073 }, { 10, 3071 }, { 10, 3069 }, { 10, 3067 }, { 10, 3065 },
|
||||
{ 10, 3063 }, { 10, 3061 }, { 10, 3059 }, { 10, 3057 }, { 10, 3055 },
|
||||
{ 10, 3053 }, { 10, 3051 }, { 10, 3049 }, { 10, 3047 }, { 10, 3045 },
|
||||
{ 10, 3043 }, { 10, 3041 }, { 10, 3039 }, { 10, 3037 }, { 10, 3035 },
|
||||
{ 10, 3033 }, { 10, 3031 }, { 10, 3029 }, { 10, 3027 }, { 10, 3025 },
|
||||
{ 10, 3023 }, { 10, 3021 }, { 10, 3019 }, { 10, 3017 }, { 10, 3015 },
|
||||
{ 10, 3013 }, { 10, 3011 }, { 10, 3009 }, { 10, 3007 }, { 10, 3005 },
|
||||
{ 10, 3003 }, { 10, 3001 }, { 10, 2999 }, { 10, 2997 }, { 10, 2995 },
|
||||
{ 10, 2993 }, { 10, 2991 }, { 10, 2989 }, { 10, 2987 }, { 10, 2985 },
|
||||
{ 10, 2983 }, { 10, 2981 }, { 10, 2979 }, { 10, 2977 }, { 10, 2975 },
|
||||
{ 10, 2973 }, { 10, 2971 }, { 10, 2969 }, { 10, 2967 }, { 10, 2965 },
|
||||
{ 10, 2963 }, { 10, 2961 }, { 10, 2959 }, { 10, 2957 }, { 10, 2955 },
|
||||
{ 10, 2953 }, { 10, 2951 }, { 10, 2949 }, { 10, 2947 }, { 10, 2945 },
|
||||
{ 10, 2943 }, { 10, 2941 }, { 10, 2939 }, { 10, 2937 }, { 10, 2935 },
|
||||
{ 10, 2933 }, { 10, 2931 }, { 10, 2929 }, { 10, 2927 }, { 10, 2925 },
|
||||
{ 10, 2923 }, { 10, 2921 }, { 10, 2919 }, { 10, 2917 }, { 10, 2915 },
|
||||
{ 10, 2913 }, { 10, 2911 }, { 10, 2909 }, { 10, 2907 }, { 10, 2905 },
|
||||
{ 10, 2903 }, { 10, 2901 }, { 10, 2899 }, { 10, 2897 }, { 10, 2895 },
|
||||
{ 10, 2893 }, { 10, 2891 }, { 10, 2889 }, { 10, 2887 }, { 10, 2885 },
|
||||
{ 10, 2883 }, { 10, 2881 }, { 10, 2879 }, { 10, 2877 }, { 10, 2875 },
|
||||
{ 10, 2873 }, { 10, 2871 }, { 10, 2869 }, { 10, 2867 }, { 10, 2865 },
|
||||
{ 10, 2863 }, { 10, 2861 }, { 10, 2859 }, { 10, 2857 }, { 10, 2855 },
|
||||
{ 10, 2853 }, { 10, 2851 }, { 10, 2849 }, { 10, 2847 }, { 10, 2845 },
|
||||
{ 10, 2843 }, { 10, 2841 }, { 10, 2839 }, { 10, 2837 }, { 10, 2835 },
|
||||
{ 10, 2833 }, { 10, 2831 }, { 10, 2829 }, { 10, 2827 }, { 10, 2825 },
|
||||
{ 10, 2823 }, { 10, 2821 }, { 10, 2819 }, { 10, 2817 }, { 10, 2815 },
|
||||
{ 10, 2813 }, { 10, 2811 }, { 10, 2809 }, { 10, 2807 }, { 10, 2805 },
|
||||
{ 10, 2803 }, { 10, 2801 }, { 10, 2799 }, { 10, 2797 }, { 10, 2795 },
|
||||
{ 10, 2793 }, { 10, 2791 }, { 10, 2789 }, { 10, 2787 }, { 10, 2785 },
|
||||
{ 10, 2783 }, { 10, 2781 }, { 10, 2779 }, { 10, 2777 }, { 10, 2775 },
|
||||
{ 10, 2773 }, { 10, 2771 }, { 10, 2769 }, { 10, 2767 }, { 10, 2765 },
|
||||
{ 10, 2763 }, { 10, 2761 }, { 10, 2759 }, { 10, 2757 }, { 10, 2755 },
|
||||
{ 10, 2753 }, { 10, 2751 }, { 10, 2749 }, { 10, 2747 }, { 10, 2745 },
|
||||
{ 10, 2743 }, { 10, 2741 }, { 10, 2739 }, { 10, 2737 }, { 10, 2735 },
|
||||
{ 10, 2733 }, { 10, 2731 }, { 10, 2729 }, { 10, 2727 }, { 10, 2725 },
|
||||
{ 10, 2723 }, { 10, 2721 }, { 10, 2719 }, { 10, 2717 }, { 10, 2715 },
|
||||
{ 10, 2713 }, { 10, 2711 }, { 10, 2709 }, { 10, 2707 }, { 10, 2705 },
|
||||
{ 10, 2703 }, { 10, 2701 }, { 10, 2699 }, { 10, 2697 }, { 10, 2695 },
|
||||
{ 10, 2693 }, { 10, 2691 }, { 10, 2689 }, { 10, 2687 }, { 10, 2685 },
|
||||
{ 10, 2683 }, { 10, 2681 }, { 10, 2679 }, { 10, 2677 }, { 10, 2675 },
|
||||
{ 10, 2673 }, { 10, 2671 }, { 10, 2669 }, { 10, 2667 }, { 10, 2665 },
|
||||
{ 10, 2663 }, { 10, 2661 }, { 10, 2659 }, { 10, 2657 }, { 10, 2655 },
|
||||
{ 10, 2653 }, { 10, 2651 }, { 10, 2649 }, { 10, 2647 }, { 10, 2645 },
|
||||
{ 10, 2643 }, { 10, 2641 }, { 10, 2639 }, { 10, 2637 }, { 10, 2635 },
|
||||
{ 10, 2633 }, { 10, 2631 }, { 10, 2629 }, { 10, 2627 }, { 10, 2625 },
|
||||
{ 10, 2623 }, { 10, 2621 }, { 10, 2619 }, { 10, 2617 }, { 10, 2615 },
|
||||
{ 10, 2613 }, { 10, 2611 }, { 10, 2609 }, { 10, 2607 }, { 10, 2605 },
|
||||
{ 10, 2603 }, { 10, 2601 }, { 10, 2599 }, { 10, 2597 }, { 10, 2595 },
|
||||
{ 10, 2593 }, { 10, 2591 }, { 10, 2589 }, { 10, 2587 }, { 10, 2585 },
|
||||
{ 10, 2583 }, { 10, 2581 }, { 10, 2579 }, { 10, 2577 }, { 10, 2575 },
|
||||
{ 10, 2573 }, { 10, 2571 }, { 10, 2569 }, { 10, 2567 }, { 10, 2565 },
|
||||
{ 10, 2563 }, { 10, 2561 }, { 10, 2559 }, { 10, 2557 }, { 10, 2555 },
|
||||
{ 10, 2553 }, { 10, 2551 }, { 10, 2549 }, { 10, 2547 }, { 10, 2545 },
|
||||
{ 10, 2543 }, { 10, 2541 }, { 10, 2539 }, { 10, 2537 }, { 10, 2535 },
|
||||
{ 10, 2533 }, { 10, 2531 }, { 10, 2529 }, { 10, 2527 }, { 10, 2525 },
|
||||
{ 10, 2523 }, { 10, 2521 }, { 10, 2519 }, { 10, 2517 }, { 10, 2515 },
|
||||
{ 10, 2513 }, { 10, 2511 }, { 10, 2509 }, { 10, 2507 }, { 10, 2505 },
|
||||
{ 10, 2503 }, { 10, 2501 }, { 10, 2499 }, { 10, 2497 }, { 10, 2495 },
|
||||
{ 10, 2493 }, { 10, 2491 }, { 10, 2489 }, { 10, 2487 }, { 10, 2485 },
|
||||
{ 10, 2483 }, { 10, 2481 }, { 10, 2479 }, { 10, 2477 }, { 10, 2475 },
|
||||
{ 10, 2473 }, { 10, 2471 }, { 10, 2469 }, { 10, 2467 }, { 10, 2465 },
|
||||
{ 10, 2463 }, { 10, 2461 }, { 10, 2459 }, { 10, 2457 }, { 10, 2455 },
|
||||
{ 10, 2453 }, { 10, 2451 }, { 10, 2449 }, { 10, 2447 }, { 10, 2445 },
|
||||
{ 10, 2443 }, { 10, 2441 }, { 10, 2439 }, { 10, 2437 }, { 10, 2435 },
|
||||
{ 10, 2433 }, { 10, 2431 }, { 10, 2429 }, { 10, 2427 }, { 10, 2425 },
|
||||
{ 10, 2423 }, { 10, 2421 }, { 10, 2419 }, { 10, 2417 }, { 10, 2415 },
|
||||
{ 10, 2413 }, { 10, 2411 }, { 10, 2409 }, { 10, 2407 }, { 10, 2405 },
|
||||
{ 10, 2403 }, { 10, 2401 }, { 10, 2399 }, { 10, 2397 }, { 10, 2395 },
|
||||
{ 10, 2393 }, { 10, 2391 }, { 10, 2389 }, { 10, 2387 }, { 10, 2385 },
|
||||
{ 10, 2383 }, { 10, 2381 }, { 10, 2379 }, { 10, 2377 }, { 10, 2375 },
|
||||
{ 10, 2373 }, { 10, 2371 }, { 10, 2369 }, { 10, 2367 }, { 10, 2365 },
|
||||
{ 10, 2363 }, { 10, 2361 }, { 10, 2359 }, { 10, 2357 }, { 10, 2355 },
|
||||
{ 10, 2353 }, { 10, 2351 }, { 10, 2349 }, { 10, 2347 }, { 10, 2345 },
|
||||
{ 10, 2343 }, { 10, 2341 }, { 10, 2339 }, { 10, 2337 }, { 10, 2335 },
|
||||
{ 10, 2333 }, { 10, 2331 }, { 10, 2329 }, { 10, 2327 }, { 10, 2325 },
|
||||
{ 10, 2323 }, { 10, 2321 }, { 10, 2319 }, { 10, 2317 }, { 10, 2315 },
|
||||
{ 10, 2313 }, { 10, 2311 }, { 10, 2309 }, { 10, 2307 }, { 10, 2305 },
|
||||
{ 10, 2303 }, { 10, 2301 }, { 10, 2299 }, { 10, 2297 }, { 10, 2295 },
|
||||
{ 10, 2293 }, { 10, 2291 }, { 10, 2289 }, { 10, 2287 }, { 10, 2285 },
|
||||
{ 10, 2283 }, { 10, 2281 }, { 10, 2279 }, { 10, 2277 }, { 10, 2275 },
|
||||
{ 10, 2273 }, { 10, 2271 }, { 10, 2269 }, { 10, 2267 }, { 10, 2265 },
|
||||
{ 10, 2263 }, { 10, 2261 }, { 10, 2259 }, { 10, 2257 }, { 10, 2255 },
|
||||
{ 10, 2253 }, { 10, 2251 }, { 10, 2249 }, { 10, 2247 }, { 10, 2245 },
|
||||
{ 10, 2243 }, { 10, 2241 }, { 10, 2239 }, { 10, 2237 }, { 10, 2235 },
|
||||
{ 10, 2233 }, { 10, 2231 }, { 10, 2229 }, { 10, 2227 }, { 10, 2225 },
|
||||
{ 10, 2223 }, { 10, 2221 }, { 10, 2219 }, { 10, 2217 }, { 10, 2215 },
|
||||
{ 10, 2213 }, { 10, 2211 }, { 10, 2209 }, { 10, 2207 }, { 10, 2205 },
|
||||
{ 10, 2203 }, { 10, 2201 }, { 10, 2199 }, { 10, 2197 }, { 10, 2195 },
|
||||
{ 10, 2193 }, { 10, 2191 }, { 10, 2189 }, { 10, 2187 }, { 10, 2185 },
|
||||
{ 10, 2183 }, { 10, 2181 }, { 10, 2179 }, { 10, 2177 }, { 10, 2175 },
|
||||
{ 10, 2173 }, { 10, 2171 }, { 10, 2169 }, { 10, 2167 }, { 10, 2165 },
|
||||
{ 10, 2163 }, { 10, 2161 }, { 10, 2159 }, { 10, 2157 }, { 10, 2155 },
|
||||
{ 10, 2153 }, { 10, 2151 }, { 10, 2149 }, { 10, 2147 }, { 10, 2145 },
|
||||
{ 10, 2143 }, { 10, 2141 }, { 10, 2139 }, { 10, 2137 }, { 10, 2135 },
|
||||
{ 10, 2133 }, { 10, 2131 }, { 10, 2129 }, { 10, 2127 }, { 10, 2125 },
|
||||
{ 10, 2123 }, { 10, 2121 }, { 10, 2119 }, { 10, 2117 }, { 10, 2115 },
|
||||
{ 10, 2113 }, { 10, 2111 }, { 10, 2109 }, { 10, 2107 }, { 10, 2105 },
|
||||
{ 10, 2103 }, { 10, 2101 }, { 10, 2099 }, { 10, 2097 }, { 10, 2095 },
|
||||
{ 10, 2093 }, { 10, 2091 }, { 10, 2089 }, { 10, 2087 }, { 10, 2085 },
|
||||
{ 10, 2083 }, { 10, 2081 }, { 10, 2079 }, { 10, 2077 }, { 10, 2075 },
|
||||
{ 10, 2073 }, { 10, 2071 }, { 10, 2069 }, { 10, 2067 }, { 10, 2065 },
|
||||
{ 10, 2063 }, { 10, 2061 }, { 10, 2059 }, { 10, 2057 }, { 10, 2055 },
|
||||
{ 10, 2053 }, { 10, 2051 }, { 10, 2049 }, { 10, 2047 }, { 10, 2045 },
|
||||
{ 10, 2043 }, { 10, 2041 }, { 10, 2039 }, { 10, 2037 }, { 10, 2035 },
|
||||
{ 10, 2033 }, { 10, 2031 }, { 10, 2029 }, { 10, 2027 }, { 10, 2025 },
|
||||
{ 10, 2023 }, { 10, 2021 }, { 10, 2019 }, { 10, 2017 }, { 10, 2015 },
|
||||
{ 10, 2013 }, { 10, 2011 }, { 10, 2009 }, { 10, 2007 }, { 10, 2005 },
|
||||
{ 10, 2003 }, { 10, 2001 }, { 10, 1999 }, { 10, 1997 }, { 10, 1995 },
|
||||
{ 10, 1993 }, { 10, 1991 }, { 10, 1989 }, { 10, 1987 }, { 10, 1985 },
|
||||
{ 10, 1983 }, { 10, 1981 }, { 10, 1979 }, { 10, 1977 }, { 10, 1975 },
|
||||
{ 10, 1973 }, { 10, 1971 }, { 10, 1969 }, { 10, 1967 }, { 10, 1965 },
|
||||
{ 10, 1963 }, { 10, 1961 }, { 10, 1959 }, { 10, 1957 }, { 10, 1955 },
|
||||
{ 10, 1953 }, { 10, 1951 }, { 10, 1949 }, { 10, 1947 }, { 10, 1945 },
|
||||
{ 10, 1943 }, { 10, 1941 }, { 10, 1939 }, { 10, 1937 }, { 10, 1935 },
|
||||
{ 10, 1933 }, { 10, 1931 }, { 10, 1929 }, { 10, 1927 }, { 10, 1925 },
|
||||
{ 10, 1923 }, { 10, 1921 }, { 10, 1919 }, { 10, 1917 }, { 10, 1915 },
|
||||
{ 10, 1913 }, { 10, 1911 }, { 10, 1909 }, { 10, 1907 }, { 10, 1905 },
|
||||
{ 10, 1903 }, { 10, 1901 }, { 10, 1899 }, { 10, 1897 }, { 10, 1895 },
|
||||
{ 10, 1893 }, { 10, 1891 }, { 10, 1889 }, { 10, 1887 }, { 10, 1885 },
|
||||
{ 10, 1883 }, { 10, 1881 }, { 10, 1879 }, { 10, 1877 }, { 10, 1875 },
|
||||
{ 10, 1873 }, { 10, 1871 }, { 10, 1869 }, { 10, 1867 }, { 10, 1865 },
|
||||
{ 10, 1863 }, { 10, 1861 }, { 10, 1859 }, { 10, 1857 }, { 10, 1855 },
|
||||
{ 10, 1853 }, { 10, 1851 }, { 10, 1849 }, { 10, 1847 }, { 10, 1845 },
|
||||
{ 10, 1843 }, { 10, 1841 }, { 10, 1839 }, { 10, 1837 }, { 10, 1835 },
|
||||
{ 10, 1833 }, { 10, 1831 }, { 10, 1829 }, { 10, 1827 }, { 10, 1825 },
|
||||
{ 10, 1823 }, { 10, 1821 }, { 10, 1819 }, { 10, 1817 }, { 10, 1815 },
|
||||
{ 10, 1813 }, { 10, 1811 }, { 10, 1809 }, { 10, 1807 }, { 10, 1805 },
|
||||
{ 10, 1803 }, { 10, 1801 }, { 10, 1799 }, { 10, 1797 }, { 10, 1795 },
|
||||
{ 10, 1793 }, { 10, 1791 }, { 10, 1789 }, { 10, 1787 }, { 10, 1785 },
|
||||
{ 10, 1783 }, { 10, 1781 }, { 10, 1779 }, { 10, 1777 }, { 10, 1775 },
|
||||
{ 10, 1773 }, { 10, 1771 }, { 10, 1769 }, { 10, 1767 }, { 10, 1765 },
|
||||
{ 10, 1763 }, { 10, 1761 }, { 10, 1759 }, { 10, 1757 }, { 10, 1755 },
|
||||
{ 10, 1753 }, { 10, 1751 }, { 10, 1749 }, { 10, 1747 }, { 10, 1745 },
|
||||
{ 10, 1743 }, { 10, 1741 }, { 10, 1739 }, { 10, 1737 }, { 10, 1735 },
|
||||
{ 10, 1733 }, { 10, 1731 }, { 10, 1729 }, { 10, 1727 }, { 10, 1725 },
|
||||
{ 10, 1723 }, { 10, 1721 }, { 10, 1719 }, { 10, 1717 }, { 10, 1715 },
|
||||
{ 10, 1713 }, { 10, 1711 }, { 10, 1709 }, { 10, 1707 }, { 10, 1705 },
|
||||
{ 10, 1703 }, { 10, 1701 }, { 10, 1699 }, { 10, 1697 }, { 10, 1695 },
|
||||
{ 10, 1693 }, { 10, 1691 }, { 10, 1689 }, { 10, 1687 }, { 10, 1685 },
|
||||
{ 10, 1683 }, { 10, 1681 }, { 10, 1679 }, { 10, 1677 }, { 10, 1675 },
|
||||
{ 10, 1673 }, { 10, 1671 }, { 10, 1669 }, { 10, 1667 }, { 10, 1665 },
|
||||
{ 10, 1663 }, { 10, 1661 }, { 10, 1659 }, { 10, 1657 }, { 10, 1655 },
|
||||
{ 10, 1653 }, { 10, 1651 }, { 10, 1649 }, { 10, 1647 }, { 10, 1645 },
|
||||
{ 10, 1643 }, { 10, 1641 }, { 10, 1639 }, { 10, 1637 }, { 10, 1635 },
|
||||
{ 10, 1633 }, { 10, 1631 }, { 10, 1629 }, { 10, 1627 }, { 10, 1625 },
|
||||
{ 10, 1623 }, { 10, 1621 }, { 10, 1619 }, { 10, 1617 }, { 10, 1615 },
|
||||
{ 10, 1613 }, { 10, 1611 }, { 10, 1609 }, { 10, 1607 }, { 10, 1605 },
|
||||
{ 10, 1603 }, { 10, 1601 }, { 10, 1599 }, { 10, 1597 }, { 10, 1595 },
|
||||
{ 10, 1593 }, { 10, 1591 }, { 10, 1589 }, { 10, 1587 }, { 10, 1585 },
|
||||
{ 10, 1583 }, { 10, 1581 }, { 10, 1579 }, { 10, 1577 }, { 10, 1575 },
|
||||
{ 10, 1573 }, { 10, 1571 }, { 10, 1569 }, { 10, 1567 }, { 10, 1565 },
|
||||
{ 10, 1563 }, { 10, 1561 }, { 10, 1559 }, { 10, 1557 }, { 10, 1555 },
|
||||
{ 10, 1553 }, { 10, 1551 }, { 10, 1549 }, { 10, 1547 }, { 10, 1545 },
|
||||
{ 10, 1543 }, { 10, 1541 }, { 10, 1539 }, { 10, 1537 }, { 10, 1535 },
|
||||
{ 10, 1533 }, { 10, 1531 }, { 10, 1529 }, { 10, 1527 }, { 10, 1525 },
|
||||
{ 10, 1523 }, { 10, 1521 }, { 10, 1519 }, { 10, 1517 }, { 10, 1515 },
|
||||
{ 10, 1513 }, { 10, 1511 }, { 10, 1509 }, { 10, 1507 }, { 10, 1505 },
|
||||
{ 10, 1503 }, { 10, 1501 }, { 10, 1499 }, { 10, 1497 }, { 10, 1495 },
|
||||
{ 10, 1493 }, { 10, 1491 }, { 10, 1489 }, { 10, 1487 }, { 10, 1485 },
|
||||
{ 10, 1483 }, { 10, 1481 }, { 10, 1479 }, { 10, 1477 }, { 10, 1475 },
|
||||
{ 10, 1473 }, { 10, 1471 }, { 10, 1469 }, { 10, 1467 }, { 10, 1465 },
|
||||
{ 10, 1463 }, { 10, 1461 }, { 10, 1459 }, { 10, 1457 }, { 10, 1455 },
|
||||
{ 10, 1453 }, { 10, 1451 }, { 10, 1449 }, { 10, 1447 }, { 10, 1445 },
|
||||
{ 10, 1443 }, { 10, 1441 }, { 10, 1439 }, { 10, 1437 }, { 10, 1435 },
|
||||
{ 10, 1433 }, { 10, 1431 }, { 10, 1429 }, { 10, 1427 }, { 10, 1425 },
|
||||
{ 10, 1423 }, { 10, 1421 }, { 10, 1419 }, { 10, 1417 }, { 10, 1415 },
|
||||
{ 10, 1413 }, { 10, 1411 }, { 10, 1409 }, { 10, 1407 }, { 10, 1405 },
|
||||
{ 10, 1403 }, { 10, 1401 }, { 10, 1399 }, { 10, 1397 }, { 10, 1395 },
|
||||
{ 10, 1393 }, { 10, 1391 }, { 10, 1389 }, { 10, 1387 }, { 10, 1385 },
|
||||
{ 10, 1383 }, { 10, 1381 }, { 10, 1379 }, { 10, 1377 }, { 10, 1375 },
|
||||
{ 10, 1373 }, { 10, 1371 }, { 10, 1369 }, { 10, 1367 }, { 10, 1365 },
|
||||
{ 10, 1363 }, { 10, 1361 }, { 10, 1359 }, { 10, 1357 }, { 10, 1355 },
|
||||
{ 10, 1353 }, { 10, 1351 }, { 10, 1349 }, { 10, 1347 }, { 10, 1345 },
|
||||
{ 10, 1343 }, { 10, 1341 }, { 10, 1339 }, { 10, 1337 }, { 10, 1335 },
|
||||
{ 10, 1333 }, { 10, 1331 }, { 10, 1329 }, { 10, 1327 }, { 10, 1325 },
|
||||
{ 10, 1323 }, { 10, 1321 }, { 10, 1319 }, { 10, 1317 }, { 10, 1315 },
|
||||
{ 10, 1313 }, { 10, 1311 }, { 10, 1309 }, { 10, 1307 }, { 10, 1305 },
|
||||
{ 10, 1303 }, { 10, 1301 }, { 10, 1299 }, { 10, 1297 }, { 10, 1295 },
|
||||
{ 10, 1293 }, { 10, 1291 }, { 10, 1289 }, { 10, 1287 }, { 10, 1285 },
|
||||
{ 10, 1283 }, { 10, 1281 }, { 10, 1279 }, { 10, 1277 }, { 10, 1275 },
|
||||
{ 10, 1273 }, { 10, 1271 }, { 10, 1269 }, { 10, 1267 }, { 10, 1265 },
|
||||
{ 10, 1263 }, { 10, 1261 }, { 10, 1259 }, { 10, 1257 }, { 10, 1255 },
|
||||
{ 10, 1253 }, { 10, 1251 }, { 10, 1249 }, { 10, 1247 }, { 10, 1245 },
|
||||
{ 10, 1243 }, { 10, 1241 }, { 10, 1239 }, { 10, 1237 }, { 10, 1235 },
|
||||
{ 10, 1233 }, { 10, 1231 }, { 10, 1229 }, { 10, 1227 }, { 10, 1225 },
|
||||
{ 10, 1223 }, { 10, 1221 }, { 10, 1219 }, { 10, 1217 }, { 10, 1215 },
|
||||
{ 10, 1213 }, { 10, 1211 }, { 10, 1209 }, { 10, 1207 }, { 10, 1205 },
|
||||
{ 10, 1203 }, { 10, 1201 }, { 10, 1199 }, { 10, 1197 }, { 10, 1195 },
|
||||
{ 10, 1193 }, { 10, 1191 }, { 10, 1189 }, { 10, 1187 }, { 10, 1185 },
|
||||
{ 10, 1183 }, { 10, 1181 }, { 10, 1179 }, { 10, 1177 }, { 10, 1175 },
|
||||
{ 10, 1173 }, { 10, 1171 }, { 10, 1169 }, { 10, 1167 }, { 10, 1165 },
|
||||
{ 10, 1163 }, { 10, 1161 }, { 10, 1159 }, { 10, 1157 }, { 10, 1155 },
|
||||
{ 10, 1153 }, { 10, 1151 }, { 10, 1149 }, { 10, 1147 }, { 10, 1145 },
|
||||
{ 10, 1143 }, { 10, 1141 }, { 10, 1139 }, { 10, 1137 }, { 10, 1135 },
|
||||
{ 10, 1133 }, { 10, 1131 }, { 10, 1129 }, { 10, 1127 }, { 10, 1125 },
|
||||
{ 10, 1123 }, { 10, 1121 }, { 10, 1119 }, { 10, 1117 }, { 10, 1115 },
|
||||
{ 10, 1113 }, { 10, 1111 }, { 10, 1109 }, { 10, 1107 }, { 10, 1105 },
|
||||
{ 10, 1103 }, { 10, 1101 }, { 10, 1099 }, { 10, 1097 }, { 10, 1095 },
|
||||
{ 10, 1093 }, { 10, 1091 }, { 10, 1089 }, { 10, 1087 }, { 10, 1085 },
|
||||
{ 10, 1083 }, { 10, 1081 }, { 10, 1079 }, { 10, 1077 }, { 10, 1075 },
|
||||
{ 10, 1073 }, { 10, 1071 }, { 10, 1069 }, { 10, 1067 }, { 10, 1065 },
|
||||
{ 10, 1063 }, { 10, 1061 }, { 10, 1059 }, { 10, 1057 }, { 10, 1055 },
|
||||
{ 10, 1053 }, { 10, 1051 }, { 10, 1049 }, { 10, 1047 }, { 10, 1045 },
|
||||
{ 10, 1043 }, { 10, 1041 }, { 10, 1039 }, { 10, 1037 }, { 10, 1035 },
|
||||
{ 10, 1033 }, { 10, 1031 }, { 10, 1029 }, { 10, 1027 }, { 10, 1025 },
|
||||
{ 10, 1023 }, { 10, 1021 }, { 10, 1019 }, { 10, 1017 }, { 10, 1015 },
|
||||
{ 10, 1013 }, { 10, 1011 }, { 10, 1009 }, { 10, 1007 }, { 10, 1005 },
|
||||
{ 10, 1003 }, { 10, 1001 }, { 10, 999 }, { 10, 997 }, { 10, 995 },
|
||||
{ 10, 993 }, { 10, 991 }, { 10, 989 }, { 10, 987 }, { 10, 985 },
|
||||
{ 10, 983 }, { 10, 981 }, { 10, 979 }, { 10, 977 }, { 10, 975 },
|
||||
{ 10, 973 }, { 10, 971 }, { 10, 969 }, { 10, 967 }, { 10, 965 },
|
||||
{ 10, 963 }, { 10, 961 }, { 10, 959 }, { 10, 957 }, { 10, 955 },
|
||||
{ 10, 953 }, { 10, 951 }, { 10, 949 }, { 10, 947 }, { 10, 945 },
|
||||
{ 10, 943 }, { 10, 941 }, { 10, 939 }, { 10, 937 }, { 10, 935 },
|
||||
{ 10, 933 }, { 10, 931 }, { 10, 929 }, { 10, 927 }, { 10, 925 },
|
||||
{ 10, 923 }, { 10, 921 }, { 10, 919 }, { 10, 917 }, { 10, 915 },
|
||||
{ 10, 913 }, { 10, 911 }, { 10, 909 }, { 10, 907 }, { 10, 905 },
|
||||
{ 10, 903 }, { 10, 901 }, { 10, 899 }, { 10, 897 }, { 10, 895 },
|
||||
{ 10, 893 }, { 10, 891 }, { 10, 889 }, { 10, 887 }, { 10, 885 },
|
||||
{ 10, 883 }, { 10, 881 }, { 10, 879 }, { 10, 877 }, { 10, 875 },
|
||||
{ 10, 873 }, { 10, 871 }, { 10, 869 }, { 10, 867 }, { 10, 865 },
|
||||
{ 10, 863 }, { 10, 861 }, { 10, 859 }, { 10, 857 }, { 10, 855 },
|
||||
{ 10, 853 }, { 10, 851 }, { 10, 849 }, { 10, 847 }, { 10, 845 },
|
||||
{ 10, 843 }, { 10, 841 }, { 10, 839 }, { 10, 837 }, { 10, 835 },
|
||||
{ 10, 833 }, { 10, 831 }, { 10, 829 }, { 10, 827 }, { 10, 825 },
|
||||
{ 10, 823 }, { 10, 821 }, { 10, 819 }, { 10, 817 }, { 10, 815 },
|
||||
{ 10, 813 }, { 10, 811 }, { 10, 809 }, { 10, 807 }, { 10, 805 },
|
||||
{ 10, 803 }, { 10, 801 }, { 10, 799 }, { 10, 797 }, { 10, 795 },
|
||||
{ 10, 793 }, { 10, 791 }, { 10, 789 }, { 10, 787 }, { 10, 785 },
|
||||
{ 10, 783 }, { 10, 781 }, { 10, 779 }, { 10, 777 }, { 10, 775 },
|
||||
{ 10, 773 }, { 10, 771 }, { 10, 769 }, { 10, 767 }, { 10, 765 },
|
||||
{ 10, 763 }, { 10, 761 }, { 10, 759 }, { 10, 757 }, { 10, 755 },
|
||||
{ 10, 753 }, { 10, 751 }, { 10, 749 }, { 10, 747 }, { 10, 745 },
|
||||
{ 10, 743 }, { 10, 741 }, { 10, 739 }, { 10, 737 }, { 10, 735 },
|
||||
{ 10, 733 }, { 10, 731 }, { 10, 729 }, { 10, 727 }, { 10, 725 },
|
||||
{ 10, 723 }, { 10, 721 }, { 10, 719 }, { 10, 717 }, { 10, 715 },
|
||||
{ 10, 713 }, { 10, 711 }, { 10, 709 }, { 10, 707 }, { 10, 705 },
|
||||
{ 10, 703 }, { 10, 701 }, { 10, 699 }, { 10, 697 }, { 10, 695 },
|
||||
{ 10, 693 }, { 10, 691 }, { 10, 689 }, { 10, 687 }, { 10, 685 },
|
||||
{ 10, 683 }, { 10, 681 }, { 10, 679 }, { 10, 677 }, { 10, 675 },
|
||||
{ 10, 673 }, { 10, 671 }, { 10, 669 }, { 10, 667 }, { 10, 665 },
|
||||
{ 10, 663 }, { 10, 661 }, { 10, 659 }, { 10, 657 }, { 10, 655 },
|
||||
{ 10, 653 }, { 10, 651 }, { 10, 649 }, { 10, 647 }, { 10, 645 },
|
||||
{ 10, 643 }, { 10, 641 }, { 10, 639 }, { 10, 637 }, { 10, 635 },
|
||||
{ 10, 633 }, { 10, 631 }, { 10, 629 }, { 10, 627 }, { 10, 625 },
|
||||
{ 10, 623 }, { 10, 621 }, { 10, 619 }, { 10, 617 }, { 10, 615 },
|
||||
{ 10, 613 }, { 10, 611 }, { 10, 609 }, { 10, 607 }, { 10, 605 },
|
||||
{ 10, 603 }, { 10, 601 }, { 10, 599 }, { 10, 597 }, { 10, 595 },
|
||||
{ 10, 593 }, { 10, 591 }, { 10, 589 }, { 10, 587 }, { 10, 585 },
|
||||
{ 10, 583 }, { 10, 581 }, { 10, 579 }, { 10, 577 }, { 10, 575 },
|
||||
{ 10, 573 }, { 10, 571 }, { 10, 569 }, { 10, 567 }, { 10, 565 },
|
||||
{ 10, 563 }, { 10, 561 }, { 10, 559 }, { 10, 557 }, { 10, 555 },
|
||||
{ 10, 553 }, { 10, 551 }, { 10, 549 }, { 10, 547 }, { 10, 545 },
|
||||
{ 10, 543 }, { 10, 541 }, { 10, 539 }, { 10, 537 }, { 10, 535 },
|
||||
{ 10, 533 }, { 10, 531 }, { 10, 529 }, { 10, 527 }, { 10, 525 },
|
||||
{ 10, 523 }, { 10, 521 }, { 10, 519 }, { 10, 517 }, { 10, 515 },
|
||||
{ 10, 513 }, { 10, 511 }, { 10, 509 }, { 10, 507 }, { 10, 505 },
|
||||
{ 10, 503 }, { 10, 501 }, { 10, 499 }, { 10, 497 }, { 10, 495 },
|
||||
{ 10, 493 }, { 10, 491 }, { 10, 489 }, { 10, 487 }, { 10, 485 },
|
||||
{ 10, 483 }, { 10, 481 }, { 10, 479 }, { 10, 477 }, { 10, 475 },
|
||||
{ 10, 473 }, { 10, 471 }, { 10, 469 }, { 10, 467 }, { 10, 465 },
|
||||
{ 10, 463 }, { 10, 461 }, { 10, 459 }, { 10, 457 }, { 10, 455 },
|
||||
{ 10, 453 }, { 10, 451 }, { 10, 449 }, { 10, 447 }, { 10, 445 },
|
||||
{ 10, 443 }, { 10, 441 }, { 10, 439 }, { 10, 437 }, { 10, 435 },
|
||||
{ 10, 433 }, { 10, 431 }, { 10, 429 }, { 10, 427 }, { 10, 425 },
|
||||
{ 10, 423 }, { 10, 421 }, { 10, 419 }, { 10, 417 }, { 10, 415 },
|
||||
{ 10, 413 }, { 10, 411 }, { 10, 409 }, { 10, 407 }, { 10, 405 },
|
||||
{ 10, 403 }, { 10, 401 }, { 10, 399 }, { 10, 397 }, { 10, 395 },
|
||||
{ 10, 393 }, { 10, 391 }, { 10, 389 }, { 10, 387 }, { 10, 385 },
|
||||
{ 10, 383 }, { 10, 381 }, { 10, 379 }, { 10, 377 }, { 10, 375 },
|
||||
{ 10, 373 }, { 10, 371 }, { 10, 369 }, { 10, 367 }, { 10, 365 },
|
||||
{ 10, 363 }, { 10, 361 }, { 10, 359 }, { 10, 357 }, { 10, 355 },
|
||||
{ 10, 353 }, { 10, 351 }, { 10, 349 }, { 10, 347 }, { 10, 345 },
|
||||
{ 10, 343 }, { 10, 341 }, { 10, 339 }, { 10, 337 }, { 10, 335 },
|
||||
{ 10, 333 }, { 10, 331 }, { 10, 329 }, { 10, 327 }, { 10, 325 },
|
||||
{ 10, 323 }, { 10, 321 }, { 10, 319 }, { 10, 317 }, { 10, 315 },
|
||||
{ 10, 313 }, { 10, 311 }, { 10, 309 }, { 10, 307 }, { 10, 305 },
|
||||
{ 10, 303 }, { 10, 301 }, { 10, 299 }, { 10, 297 }, { 10, 295 },
|
||||
{ 10, 293 }, { 10, 291 }, { 10, 289 }, { 10, 287 }, { 10, 285 },
|
||||
{ 10, 283 }, { 10, 281 }, { 10, 279 }, { 10, 277 }, { 10, 275 },
|
||||
{ 10, 273 }, { 10, 271 }, { 10, 269 }, { 10, 267 }, { 10, 265 },
|
||||
{ 10, 263 }, { 10, 261 }, { 10, 259 }, { 10, 257 }, { 10, 255 },
|
||||
{ 10, 253 }, { 10, 251 }, { 10, 249 }, { 10, 247 }, { 10, 245 },
|
||||
{ 10, 243 }, { 10, 241 }, { 10, 239 }, { 10, 237 }, { 10, 235 },
|
||||
{ 10, 233 }, { 10, 231 }, { 10, 229 }, { 10, 227 }, { 10, 225 },
|
||||
{ 10, 223 }, { 10, 221 }, { 10, 219 }, { 10, 217 }, { 10, 215 },
|
||||
{ 10, 213 }, { 10, 211 }, { 10, 209 }, { 10, 207 }, { 10, 205 },
|
||||
{ 10, 203 }, { 10, 201 }, { 10, 199 }, { 10, 197 }, { 10, 195 },
|
||||
{ 10, 193 }, { 10, 191 }, { 10, 189 }, { 10, 187 }, { 10, 185 },
|
||||
{ 10, 183 }, { 10, 181 }, { 10, 179 }, { 10, 177 }, { 10, 175 },
|
||||
{ 10, 173 }, { 10, 171 }, { 10, 169 }, { 10, 167 }, { 10, 165 },
|
||||
{ 10, 163 }, { 10, 161 }, { 10, 159 }, { 10, 157 }, { 10, 155 },
|
||||
{ 10, 153 }, { 10, 151 }, { 10, 149 }, { 10, 147 }, { 10, 145 },
|
||||
{ 10, 143 }, { 10, 141 }, { 10, 139 }, { 10, 137 }, { 10, 135 },
|
||||
{ 10, 133 }, { 10, 131 }, { 10, 129 }, { 10, 127 }, { 10, 125 },
|
||||
{ 10, 123 }, { 10, 121 }, { 10, 119 }, { 10, 117 }, { 10, 115 },
|
||||
{ 10, 113 }, { 10, 111 }, { 10, 109 }, { 10, 107 }, { 10, 105 },
|
||||
{ 10, 103 }, { 10, 101 }, { 10, 99 }, { 10, 97 }, { 10, 95 },
|
||||
{ 10, 93 }, { 10, 91 }, { 10, 89 }, { 10, 87 }, { 10, 85 },
|
||||
{ 10, 83 }, { 10, 81 }, { 10, 79 }, { 10, 77 }, { 10, 75 },
|
||||
{ 10, 73 }, { 10, 71 }, { 10, 69 }, { 10, 67 }, { 10, 65 },
|
||||
{ 10, 63 }, { 10, 61 }, { 10, 59 }, { 10, 57 }, { 10, 55 },
|
||||
{ 10, 53 }, { 10, 51 }, { 10, 49 }, { 10, 47 }, { 10, 45 },
|
||||
{ 10, 43 }, { 10, 41 }, { 10, 39 }, { 10, 37 }, { 10, 35 },
|
||||
{ 10, 33 }, { 10, 31 }, { 10, 29 }, { 10, 27 }, { 10, 25 },
|
||||
{ 10, 23 }, { 10, 21 }, { 10, 19 }, { 10, 17 }, { 10, 15 },
|
||||
{ 10, 13 }, { 10, 11 }, { 10, 9 }, { 10, 7 }, { 10, 5 },
|
||||
{ 10, 3 }, { 10, 1 }, { 9, 63 }, { 9, 61 }, { 9, 59 },
|
||||
{ 9, 57 }, { 9, 55 }, { 9, 53 }, { 9, 51 }, { 9, 49 },
|
||||
{ 9, 47 }, { 9, 45 }, { 9, 43 }, { 9, 41 }, { 9, 39 },
|
||||
{ 9, 37 }, { 9, 35 }, { 9, 33 }, { 9, 31 }, { 9, 29 },
|
||||
{ 9, 27 }, { 9, 25 }, { 9, 23 }, { 9, 21 }, { 9, 19 },
|
||||
{ 9, 17 }, { 9, 15 }, { 9, 13 }, { 9, 11 }, { 9, 9 },
|
||||
{ 9, 7 }, { 9, 5 }, { 9, 3 }, { 9, 1 }, { 8, 31 },
|
||||
{ 8, 29 }, { 8, 27 }, { 8, 25 }, { 8, 23 }, { 8, 21 },
|
||||
{ 8, 19 }, { 8, 17 }, { 8, 15 }, { 8, 13 }, { 8, 11 },
|
||||
{ 8, 9 }, { 8, 7 }, { 8, 5 }, { 8, 3 }, { 8, 1 },
|
||||
{ 7, 15 }, { 7, 13 }, { 7, 11 }, { 7, 9 }, { 7, 7 },
|
||||
{ 7, 5 }, { 7, 3 }, { 7, 1 }, { 6, 7 }, { 6, 5 },
|
||||
{ 6, 3 }, { 6, 1 }, { 5, 3 }, { 5, 1 }, { 4, 1 },
|
||||
{ 3, 1 }, { 2, 1 }, { 1, 1 }, { 0, 0 }, { 1, 0 },
|
||||
{ 2, 0 }, { 3, 0 }, { 4, 0 }, { 5, 0 }, { 5, 2 },
|
||||
{ 6, 0 }, { 6, 2 }, { 6, 4 }, { 6, 6 }, { 7, 0 },
|
||||
{ 7, 2 }, { 7, 4 }, { 7, 6 }, { 7, 8 }, { 7, 10 },
|
||||
{ 7, 12 }, { 7, 14 }, { 8, 0 }, { 8, 2 }, { 8, 4 },
|
||||
{ 8, 6 }, { 8, 8 }, { 8, 10 }, { 8, 12 }, { 8, 14 },
|
||||
{ 8, 16 }, { 8, 18 }, { 8, 20 }, { 8, 22 }, { 8, 24 },
|
||||
{ 8, 26 }, { 8, 28 }, { 8, 30 }, { 9, 0 }, { 9, 2 },
|
||||
{ 9, 4 }, { 9, 6 }, { 9, 8 }, { 9, 10 }, { 9, 12 },
|
||||
{ 9, 14 }, { 9, 16 }, { 9, 18 }, { 9, 20 }, { 9, 22 },
|
||||
{ 9, 24 }, { 9, 26 }, { 9, 28 }, { 9, 30 }, { 9, 32 },
|
||||
{ 9, 34 }, { 9, 36 }, { 9, 38 }, { 9, 40 }, { 9, 42 },
|
||||
{ 9, 44 }, { 9, 46 }, { 9, 48 }, { 9, 50 }, { 9, 52 },
|
||||
{ 9, 54 }, { 9, 56 }, { 9, 58 }, { 9, 60 }, { 9, 62 },
|
||||
{ 10, 0 }, { 10, 2 }, { 10, 4 }, { 10, 6 }, { 10, 8 },
|
||||
{ 10, 10 }, { 10, 12 }, { 10, 14 }, { 10, 16 }, { 10, 18 },
|
||||
{ 10, 20 }, { 10, 22 }, { 10, 24 }, { 10, 26 }, { 10, 28 },
|
||||
{ 10, 30 }, { 10, 32 }, { 10, 34 }, { 10, 36 }, { 10, 38 },
|
||||
{ 10, 40 }, { 10, 42 }, { 10, 44 }, { 10, 46 }, { 10, 48 },
|
||||
{ 10, 50 }, { 10, 52 }, { 10, 54 }, { 10, 56 }, { 10, 58 },
|
||||
{ 10, 60 }, { 10, 62 }, { 10, 64 }, { 10, 66 }, { 10, 68 },
|
||||
{ 10, 70 }, { 10, 72 }, { 10, 74 }, { 10, 76 }, { 10, 78 },
|
||||
{ 10, 80 }, { 10, 82 }, { 10, 84 }, { 10, 86 }, { 10, 88 },
|
||||
{ 10, 90 }, { 10, 92 }, { 10, 94 }, { 10, 96 }, { 10, 98 },
|
||||
{ 10, 100 }, { 10, 102 }, { 10, 104 }, { 10, 106 }, { 10, 108 },
|
||||
{ 10, 110 }, { 10, 112 }, { 10, 114 }, { 10, 116 }, { 10, 118 },
|
||||
{ 10, 120 }, { 10, 122 }, { 10, 124 }, { 10, 126 }, { 10, 128 },
|
||||
{ 10, 130 }, { 10, 132 }, { 10, 134 }, { 10, 136 }, { 10, 138 },
|
||||
{ 10, 140 }, { 10, 142 }, { 10, 144 }, { 10, 146 }, { 10, 148 },
|
||||
{ 10, 150 }, { 10, 152 }, { 10, 154 }, { 10, 156 }, { 10, 158 },
|
||||
{ 10, 160 }, { 10, 162 }, { 10, 164 }, { 10, 166 }, { 10, 168 },
|
||||
{ 10, 170 }, { 10, 172 }, { 10, 174 }, { 10, 176 }, { 10, 178 },
|
||||
{ 10, 180 }, { 10, 182 }, { 10, 184 }, { 10, 186 }, { 10, 188 },
|
||||
{ 10, 190 }, { 10, 192 }, { 10, 194 }, { 10, 196 }, { 10, 198 },
|
||||
{ 10, 200 }, { 10, 202 }, { 10, 204 }, { 10, 206 }, { 10, 208 },
|
||||
{ 10, 210 }, { 10, 212 }, { 10, 214 }, { 10, 216 }, { 10, 218 },
|
||||
{ 10, 220 }, { 10, 222 }, { 10, 224 }, { 10, 226 }, { 10, 228 },
|
||||
{ 10, 230 }, { 10, 232 }, { 10, 234 }, { 10, 236 }, { 10, 238 },
|
||||
{ 10, 240 }, { 10, 242 }, { 10, 244 }, { 10, 246 }, { 10, 248 },
|
||||
{ 10, 250 }, { 10, 252 }, { 10, 254 }, { 10, 256 }, { 10, 258 },
|
||||
{ 10, 260 }, { 10, 262 }, { 10, 264 }, { 10, 266 }, { 10, 268 },
|
||||
{ 10, 270 }, { 10, 272 }, { 10, 274 }, { 10, 276 }, { 10, 278 },
|
||||
{ 10, 280 }, { 10, 282 }, { 10, 284 }, { 10, 286 }, { 10, 288 },
|
||||
{ 10, 290 }, { 10, 292 }, { 10, 294 }, { 10, 296 }, { 10, 298 },
|
||||
{ 10, 300 }, { 10, 302 }, { 10, 304 }, { 10, 306 }, { 10, 308 },
|
||||
{ 10, 310 }, { 10, 312 }, { 10, 314 }, { 10, 316 }, { 10, 318 },
|
||||
{ 10, 320 }, { 10, 322 }, { 10, 324 }, { 10, 326 }, { 10, 328 },
|
||||
{ 10, 330 }, { 10, 332 }, { 10, 334 }, { 10, 336 }, { 10, 338 },
|
||||
{ 10, 340 }, { 10, 342 }, { 10, 344 }, { 10, 346 }, { 10, 348 },
|
||||
{ 10, 350 }, { 10, 352 }, { 10, 354 }, { 10, 356 }, { 10, 358 },
|
||||
{ 10, 360 }, { 10, 362 }, { 10, 364 }, { 10, 366 }, { 10, 368 },
|
||||
{ 10, 370 }, { 10, 372 }, { 10, 374 }, { 10, 376 }, { 10, 378 },
|
||||
{ 10, 380 }, { 10, 382 }, { 10, 384 }, { 10, 386 }, { 10, 388 },
|
||||
{ 10, 390 }, { 10, 392 }, { 10, 394 }, { 10, 396 }, { 10, 398 },
|
||||
{ 10, 400 }, { 10, 402 }, { 10, 404 }, { 10, 406 }, { 10, 408 },
|
||||
{ 10, 410 }, { 10, 412 }, { 10, 414 }, { 10, 416 }, { 10, 418 },
|
||||
{ 10, 420 }, { 10, 422 }, { 10, 424 }, { 10, 426 }, { 10, 428 },
|
||||
{ 10, 430 }, { 10, 432 }, { 10, 434 }, { 10, 436 }, { 10, 438 },
|
||||
{ 10, 440 }, { 10, 442 }, { 10, 444 }, { 10, 446 }, { 10, 448 },
|
||||
{ 10, 450 }, { 10, 452 }, { 10, 454 }, { 10, 456 }, { 10, 458 },
|
||||
{ 10, 460 }, { 10, 462 }, { 10, 464 }, { 10, 466 }, { 10, 468 },
|
||||
{ 10, 470 }, { 10, 472 }, { 10, 474 }, { 10, 476 }, { 10, 478 },
|
||||
{ 10, 480 }, { 10, 482 }, { 10, 484 }, { 10, 486 }, { 10, 488 },
|
||||
{ 10, 490 }, { 10, 492 }, { 10, 494 }, { 10, 496 }, { 10, 498 },
|
||||
{ 10, 500 }, { 10, 502 }, { 10, 504 }, { 10, 506 }, { 10, 508 },
|
||||
{ 10, 510 }, { 10, 512 }, { 10, 514 }, { 10, 516 }, { 10, 518 },
|
||||
{ 10, 520 }, { 10, 522 }, { 10, 524 }, { 10, 526 }, { 10, 528 },
|
||||
{ 10, 530 }, { 10, 532 }, { 10, 534 }, { 10, 536 }, { 10, 538 },
|
||||
{ 10, 540 }, { 10, 542 }, { 10, 544 }, { 10, 546 }, { 10, 548 },
|
||||
{ 10, 550 }, { 10, 552 }, { 10, 554 }, { 10, 556 }, { 10, 558 },
|
||||
{ 10, 560 }, { 10, 562 }, { 10, 564 }, { 10, 566 }, { 10, 568 },
|
||||
{ 10, 570 }, { 10, 572 }, { 10, 574 }, { 10, 576 }, { 10, 578 },
|
||||
{ 10, 580 }, { 10, 582 }, { 10, 584 }, { 10, 586 }, { 10, 588 },
|
||||
{ 10, 590 }, { 10, 592 }, { 10, 594 }, { 10, 596 }, { 10, 598 },
|
||||
{ 10, 600 }, { 10, 602 }, { 10, 604 }, { 10, 606 }, { 10, 608 },
|
||||
{ 10, 610 }, { 10, 612 }, { 10, 614 }, { 10, 616 }, { 10, 618 },
|
||||
{ 10, 620 }, { 10, 622 }, { 10, 624 }, { 10, 626 }, { 10, 628 },
|
||||
{ 10, 630 }, { 10, 632 }, { 10, 634 }, { 10, 636 }, { 10, 638 },
|
||||
{ 10, 640 }, { 10, 642 }, { 10, 644 }, { 10, 646 }, { 10, 648 },
|
||||
{ 10, 650 }, { 10, 652 }, { 10, 654 }, { 10, 656 }, { 10, 658 },
|
||||
{ 10, 660 }, { 10, 662 }, { 10, 664 }, { 10, 666 }, { 10, 668 },
|
||||
{ 10, 670 }, { 10, 672 }, { 10, 674 }, { 10, 676 }, { 10, 678 },
|
||||
{ 10, 680 }, { 10, 682 }, { 10, 684 }, { 10, 686 }, { 10, 688 },
|
||||
{ 10, 690 }, { 10, 692 }, { 10, 694 }, { 10, 696 }, { 10, 698 },
|
||||
{ 10, 700 }, { 10, 702 }, { 10, 704 }, { 10, 706 }, { 10, 708 },
|
||||
{ 10, 710 }, { 10, 712 }, { 10, 714 }, { 10, 716 }, { 10, 718 },
|
||||
{ 10, 720 }, { 10, 722 }, { 10, 724 }, { 10, 726 }, { 10, 728 },
|
||||
{ 10, 730 }, { 10, 732 }, { 10, 734 }, { 10, 736 }, { 10, 738 },
|
||||
{ 10, 740 }, { 10, 742 }, { 10, 744 }, { 10, 746 }, { 10, 748 },
|
||||
{ 10, 750 }, { 10, 752 }, { 10, 754 }, { 10, 756 }, { 10, 758 },
|
||||
{ 10, 760 }, { 10, 762 }, { 10, 764 }, { 10, 766 }, { 10, 768 },
|
||||
{ 10, 770 }, { 10, 772 }, { 10, 774 }, { 10, 776 }, { 10, 778 },
|
||||
{ 10, 780 }, { 10, 782 }, { 10, 784 }, { 10, 786 }, { 10, 788 },
|
||||
{ 10, 790 }, { 10, 792 }, { 10, 794 }, { 10, 796 }, { 10, 798 },
|
||||
{ 10, 800 }, { 10, 802 }, { 10, 804 }, { 10, 806 }, { 10, 808 },
|
||||
{ 10, 810 }, { 10, 812 }, { 10, 814 }, { 10, 816 }, { 10, 818 },
|
||||
{ 10, 820 }, { 10, 822 }, { 10, 824 }, { 10, 826 }, { 10, 828 },
|
||||
{ 10, 830 }, { 10, 832 }, { 10, 834 }, { 10, 836 }, { 10, 838 },
|
||||
{ 10, 840 }, { 10, 842 }, { 10, 844 }, { 10, 846 }, { 10, 848 },
|
||||
{ 10, 850 }, { 10, 852 }, { 10, 854 }, { 10, 856 }, { 10, 858 },
|
||||
{ 10, 860 }, { 10, 862 }, { 10, 864 }, { 10, 866 }, { 10, 868 },
|
||||
{ 10, 870 }, { 10, 872 }, { 10, 874 }, { 10, 876 }, { 10, 878 },
|
||||
{ 10, 880 }, { 10, 882 }, { 10, 884 }, { 10, 886 }, { 10, 888 },
|
||||
{ 10, 890 }, { 10, 892 }, { 10, 894 }, { 10, 896 }, { 10, 898 },
|
||||
{ 10, 900 }, { 10, 902 }, { 10, 904 }, { 10, 906 }, { 10, 908 },
|
||||
{ 10, 910 }, { 10, 912 }, { 10, 914 }, { 10, 916 }, { 10, 918 },
|
||||
{ 10, 920 }, { 10, 922 }, { 10, 924 }, { 10, 926 }, { 10, 928 },
|
||||
{ 10, 930 }, { 10, 932 }, { 10, 934 }, { 10, 936 }, { 10, 938 },
|
||||
{ 10, 940 }, { 10, 942 }, { 10, 944 }, { 10, 946 }, { 10, 948 },
|
||||
{ 10, 950 }, { 10, 952 }, { 10, 954 }, { 10, 956 }, { 10, 958 },
|
||||
{ 10, 960 }, { 10, 962 }, { 10, 964 }, { 10, 966 }, { 10, 968 },
|
||||
{ 10, 970 }, { 10, 972 }, { 10, 974 }, { 10, 976 }, { 10, 978 },
|
||||
{ 10, 980 }, { 10, 982 }, { 10, 984 }, { 10, 986 }, { 10, 988 },
|
||||
{ 10, 990 }, { 10, 992 }, { 10, 994 }, { 10, 996 }, { 10, 998 },
|
||||
{ 10, 1000 }, { 10, 1002 }, { 10, 1004 }, { 10, 1006 }, { 10, 1008 },
|
||||
{ 10, 1010 }, { 10, 1012 }, { 10, 1014 }, { 10, 1016 }, { 10, 1018 },
|
||||
{ 10, 1020 }, { 10, 1022 }, { 10, 1024 }, { 10, 1026 }, { 10, 1028 },
|
||||
{ 10, 1030 }, { 10, 1032 }, { 10, 1034 }, { 10, 1036 }, { 10, 1038 },
|
||||
{ 10, 1040 }, { 10, 1042 }, { 10, 1044 }, { 10, 1046 }, { 10, 1048 },
|
||||
{ 10, 1050 }, { 10, 1052 }, { 10, 1054 }, { 10, 1056 }, { 10, 1058 },
|
||||
{ 10, 1060 }, { 10, 1062 }, { 10, 1064 }, { 10, 1066 }, { 10, 1068 },
|
||||
{ 10, 1070 }, { 10, 1072 }, { 10, 1074 }, { 10, 1076 }, { 10, 1078 },
|
||||
{ 10, 1080 }, { 10, 1082 }, { 10, 1084 }, { 10, 1086 }, { 10, 1088 },
|
||||
{ 10, 1090 }, { 10, 1092 }, { 10, 1094 }, { 10, 1096 }, { 10, 1098 },
|
||||
{ 10, 1100 }, { 10, 1102 }, { 10, 1104 }, { 10, 1106 }, { 10, 1108 },
|
||||
{ 10, 1110 }, { 10, 1112 }, { 10, 1114 }, { 10, 1116 }, { 10, 1118 },
|
||||
{ 10, 1120 }, { 10, 1122 }, { 10, 1124 }, { 10, 1126 }, { 10, 1128 },
|
||||
{ 10, 1130 }, { 10, 1132 }, { 10, 1134 }, { 10, 1136 }, { 10, 1138 },
|
||||
{ 10, 1140 }, { 10, 1142 }, { 10, 1144 }, { 10, 1146 }, { 10, 1148 },
|
||||
{ 10, 1150 }, { 10, 1152 }, { 10, 1154 }, { 10, 1156 }, { 10, 1158 },
|
||||
{ 10, 1160 }, { 10, 1162 }, { 10, 1164 }, { 10, 1166 }, { 10, 1168 },
|
||||
{ 10, 1170 }, { 10, 1172 }, { 10, 1174 }, { 10, 1176 }, { 10, 1178 },
|
||||
{ 10, 1180 }, { 10, 1182 }, { 10, 1184 }, { 10, 1186 }, { 10, 1188 },
|
||||
{ 10, 1190 }, { 10, 1192 }, { 10, 1194 }, { 10, 1196 }, { 10, 1198 },
|
||||
{ 10, 1200 }, { 10, 1202 }, { 10, 1204 }, { 10, 1206 }, { 10, 1208 },
|
||||
{ 10, 1210 }, { 10, 1212 }, { 10, 1214 }, { 10, 1216 }, { 10, 1218 },
|
||||
{ 10, 1220 }, { 10, 1222 }, { 10, 1224 }, { 10, 1226 }, { 10, 1228 },
|
||||
{ 10, 1230 }, { 10, 1232 }, { 10, 1234 }, { 10, 1236 }, { 10, 1238 },
|
||||
{ 10, 1240 }, { 10, 1242 }, { 10, 1244 }, { 10, 1246 }, { 10, 1248 },
|
||||
{ 10, 1250 }, { 10, 1252 }, { 10, 1254 }, { 10, 1256 }, { 10, 1258 },
|
||||
{ 10, 1260 }, { 10, 1262 }, { 10, 1264 }, { 10, 1266 }, { 10, 1268 },
|
||||
{ 10, 1270 }, { 10, 1272 }, { 10, 1274 }, { 10, 1276 }, { 10, 1278 },
|
||||
{ 10, 1280 }, { 10, 1282 }, { 10, 1284 }, { 10, 1286 }, { 10, 1288 },
|
||||
{ 10, 1290 }, { 10, 1292 }, { 10, 1294 }, { 10, 1296 }, { 10, 1298 },
|
||||
{ 10, 1300 }, { 10, 1302 }, { 10, 1304 }, { 10, 1306 }, { 10, 1308 },
|
||||
{ 10, 1310 }, { 10, 1312 }, { 10, 1314 }, { 10, 1316 }, { 10, 1318 },
|
||||
{ 10, 1320 }, { 10, 1322 }, { 10, 1324 }, { 10, 1326 }, { 10, 1328 },
|
||||
{ 10, 1330 }, { 10, 1332 }, { 10, 1334 }, { 10, 1336 }, { 10, 1338 },
|
||||
{ 10, 1340 }, { 10, 1342 }, { 10, 1344 }, { 10, 1346 }, { 10, 1348 },
|
||||
{ 10, 1350 }, { 10, 1352 }, { 10, 1354 }, { 10, 1356 }, { 10, 1358 },
|
||||
{ 10, 1360 }, { 10, 1362 }, { 10, 1364 }, { 10, 1366 }, { 10, 1368 },
|
||||
{ 10, 1370 }, { 10, 1372 }, { 10, 1374 }, { 10, 1376 }, { 10, 1378 },
|
||||
{ 10, 1380 }, { 10, 1382 }, { 10, 1384 }, { 10, 1386 }, { 10, 1388 },
|
||||
{ 10, 1390 }, { 10, 1392 }, { 10, 1394 }, { 10, 1396 }, { 10, 1398 },
|
||||
{ 10, 1400 }, { 10, 1402 }, { 10, 1404 }, { 10, 1406 }, { 10, 1408 },
|
||||
{ 10, 1410 }, { 10, 1412 }, { 10, 1414 }, { 10, 1416 }, { 10, 1418 },
|
||||
{ 10, 1420 }, { 10, 1422 }, { 10, 1424 }, { 10, 1426 }, { 10, 1428 },
|
||||
{ 10, 1430 }, { 10, 1432 }, { 10, 1434 }, { 10, 1436 }, { 10, 1438 },
|
||||
{ 10, 1440 }, { 10, 1442 }, { 10, 1444 }, { 10, 1446 }, { 10, 1448 },
|
||||
{ 10, 1450 }, { 10, 1452 }, { 10, 1454 }, { 10, 1456 }, { 10, 1458 },
|
||||
{ 10, 1460 }, { 10, 1462 }, { 10, 1464 }, { 10, 1466 }, { 10, 1468 },
|
||||
{ 10, 1470 }, { 10, 1472 }, { 10, 1474 }, { 10, 1476 }, { 10, 1478 },
|
||||
{ 10, 1480 }, { 10, 1482 }, { 10, 1484 }, { 10, 1486 }, { 10, 1488 },
|
||||
{ 10, 1490 }, { 10, 1492 }, { 10, 1494 }, { 10, 1496 }, { 10, 1498 },
|
||||
{ 10, 1500 }, { 10, 1502 }, { 10, 1504 }, { 10, 1506 }, { 10, 1508 },
|
||||
{ 10, 1510 }, { 10, 1512 }, { 10, 1514 }, { 10, 1516 }, { 10, 1518 },
|
||||
{ 10, 1520 }, { 10, 1522 }, { 10, 1524 }, { 10, 1526 }, { 10, 1528 },
|
||||
{ 10, 1530 }, { 10, 1532 }, { 10, 1534 }, { 10, 1536 }, { 10, 1538 },
|
||||
{ 10, 1540 }, { 10, 1542 }, { 10, 1544 }, { 10, 1546 }, { 10, 1548 },
|
||||
{ 10, 1550 }, { 10, 1552 }, { 10, 1554 }, { 10, 1556 }, { 10, 1558 },
|
||||
{ 10, 1560 }, { 10, 1562 }, { 10, 1564 }, { 10, 1566 }, { 10, 1568 },
|
||||
{ 10, 1570 }, { 10, 1572 }, { 10, 1574 }, { 10, 1576 }, { 10, 1578 },
|
||||
{ 10, 1580 }, { 10, 1582 }, { 10, 1584 }, { 10, 1586 }, { 10, 1588 },
|
||||
{ 10, 1590 }, { 10, 1592 }, { 10, 1594 }, { 10, 1596 }, { 10, 1598 },
|
||||
{ 10, 1600 }, { 10, 1602 }, { 10, 1604 }, { 10, 1606 }, { 10, 1608 },
|
||||
{ 10, 1610 }, { 10, 1612 }, { 10, 1614 }, { 10, 1616 }, { 10, 1618 },
|
||||
{ 10, 1620 }, { 10, 1622 }, { 10, 1624 }, { 10, 1626 }, { 10, 1628 },
|
||||
{ 10, 1630 }, { 10, 1632 }, { 10, 1634 }, { 10, 1636 }, { 10, 1638 },
|
||||
{ 10, 1640 }, { 10, 1642 }, { 10, 1644 }, { 10, 1646 }, { 10, 1648 },
|
||||
{ 10, 1650 }, { 10, 1652 }, { 10, 1654 }, { 10, 1656 }, { 10, 1658 },
|
||||
{ 10, 1660 }, { 10, 1662 }, { 10, 1664 }, { 10, 1666 }, { 10, 1668 },
|
||||
{ 10, 1670 }, { 10, 1672 }, { 10, 1674 }, { 10, 1676 }, { 10, 1678 },
|
||||
{ 10, 1680 }, { 10, 1682 }, { 10, 1684 }, { 10, 1686 }, { 10, 1688 },
|
||||
{ 10, 1690 }, { 10, 1692 }, { 10, 1694 }, { 10, 1696 }, { 10, 1698 },
|
||||
{ 10, 1700 }, { 10, 1702 }, { 10, 1704 }, { 10, 1706 }, { 10, 1708 },
|
||||
{ 10, 1710 }, { 10, 1712 }, { 10, 1714 }, { 10, 1716 }, { 10, 1718 },
|
||||
{ 10, 1720 }, { 10, 1722 }, { 10, 1724 }, { 10, 1726 }, { 10, 1728 },
|
||||
{ 10, 1730 }, { 10, 1732 }, { 10, 1734 }, { 10, 1736 }, { 10, 1738 },
|
||||
{ 10, 1740 }, { 10, 1742 }, { 10, 1744 }, { 10, 1746 }, { 10, 1748 },
|
||||
{ 10, 1750 }, { 10, 1752 }, { 10, 1754 }, { 10, 1756 }, { 10, 1758 },
|
||||
{ 10, 1760 }, { 10, 1762 }, { 10, 1764 }, { 10, 1766 }, { 10, 1768 },
|
||||
{ 10, 1770 }, { 10, 1772 }, { 10, 1774 }, { 10, 1776 }, { 10, 1778 },
|
||||
{ 10, 1780 }, { 10, 1782 }, { 10, 1784 }, { 10, 1786 }, { 10, 1788 },
|
||||
{ 10, 1790 }, { 10, 1792 }, { 10, 1794 }, { 10, 1796 }, { 10, 1798 },
|
||||
{ 10, 1800 }, { 10, 1802 }, { 10, 1804 }, { 10, 1806 }, { 10, 1808 },
|
||||
{ 10, 1810 }, { 10, 1812 }, { 10, 1814 }, { 10, 1816 }, { 10, 1818 },
|
||||
{ 10, 1820 }, { 10, 1822 }, { 10, 1824 }, { 10, 1826 }, { 10, 1828 },
|
||||
{ 10, 1830 }, { 10, 1832 }, { 10, 1834 }, { 10, 1836 }, { 10, 1838 },
|
||||
{ 10, 1840 }, { 10, 1842 }, { 10, 1844 }, { 10, 1846 }, { 10, 1848 },
|
||||
{ 10, 1850 }, { 10, 1852 }, { 10, 1854 }, { 10, 1856 }, { 10, 1858 },
|
||||
{ 10, 1860 }, { 10, 1862 }, { 10, 1864 }, { 10, 1866 }, { 10, 1868 },
|
||||
{ 10, 1870 }, { 10, 1872 }, { 10, 1874 }, { 10, 1876 }, { 10, 1878 },
|
||||
{ 10, 1880 }, { 10, 1882 }, { 10, 1884 }, { 10, 1886 }, { 10, 1888 },
|
||||
{ 10, 1890 }, { 10, 1892 }, { 10, 1894 }, { 10, 1896 }, { 10, 1898 },
|
||||
{ 10, 1900 }, { 10, 1902 }, { 10, 1904 }, { 10, 1906 }, { 10, 1908 },
|
||||
{ 10, 1910 }, { 10, 1912 }, { 10, 1914 }, { 10, 1916 }, { 10, 1918 },
|
||||
{ 10, 1920 }, { 10, 1922 }, { 10, 1924 }, { 10, 1926 }, { 10, 1928 },
|
||||
{ 10, 1930 }, { 10, 1932 }, { 10, 1934 }, { 10, 1936 }, { 10, 1938 },
|
||||
{ 10, 1940 }, { 10, 1942 }, { 10, 1944 }, { 10, 1946 }, { 10, 1948 },
|
||||
{ 10, 1950 }, { 10, 1952 }, { 10, 1954 }, { 10, 1956 }, { 10, 1958 },
|
||||
{ 10, 1960 }, { 10, 1962 }, { 10, 1964 }, { 10, 1966 }, { 10, 1968 },
|
||||
{ 10, 1970 }, { 10, 1972 }, { 10, 1974 }, { 10, 1976 }, { 10, 1978 },
|
||||
{ 10, 1980 }, { 10, 1982 }, { 10, 1984 }, { 10, 1986 }, { 10, 1988 },
|
||||
{ 10, 1990 }, { 10, 1992 }, { 10, 1994 }, { 10, 1996 }, { 10, 1998 },
|
||||
{ 10, 2000 }, { 10, 2002 }, { 10, 2004 }, { 10, 2006 }, { 10, 2008 },
|
||||
{ 10, 2010 }, { 10, 2012 }, { 10, 2014 }, { 10, 2016 }, { 10, 2018 },
|
||||
{ 10, 2020 }, { 10, 2022 }, { 10, 2024 }, { 10, 2026 }, { 10, 2028 },
|
||||
{ 10, 2030 }, { 10, 2032 }, { 10, 2034 }, { 10, 2036 }, { 10, 2038 },
|
||||
{ 10, 2040 }, { 10, 2042 }, { 10, 2044 }, { 10, 2046 }, { 10, 2048 },
|
||||
{ 10, 2050 }, { 10, 2052 }, { 10, 2054 }, { 10, 2056 }, { 10, 2058 },
|
||||
{ 10, 2060 }, { 10, 2062 }, { 10, 2064 }, { 10, 2066 }, { 10, 2068 },
|
||||
{ 10, 2070 }, { 10, 2072 }, { 10, 2074 }, { 10, 2076 }, { 10, 2078 },
|
||||
{ 10, 2080 }, { 10, 2082 }, { 10, 2084 }, { 10, 2086 }, { 10, 2088 },
|
||||
{ 10, 2090 }, { 10, 2092 }, { 10, 2094 }, { 10, 2096 }, { 10, 2098 },
|
||||
{ 10, 2100 }, { 10, 2102 }, { 10, 2104 }, { 10, 2106 }, { 10, 2108 },
|
||||
{ 10, 2110 }, { 10, 2112 }, { 10, 2114 }, { 10, 2116 }, { 10, 2118 },
|
||||
{ 10, 2120 }, { 10, 2122 }, { 10, 2124 }, { 10, 2126 }, { 10, 2128 },
|
||||
{ 10, 2130 }, { 10, 2132 }, { 10, 2134 }, { 10, 2136 }, { 10, 2138 },
|
||||
{ 10, 2140 }, { 10, 2142 }, { 10, 2144 }, { 10, 2146 }, { 10, 2148 },
|
||||
{ 10, 2150 }, { 10, 2152 }, { 10, 2154 }, { 10, 2156 }, { 10, 2158 },
|
||||
{ 10, 2160 }, { 10, 2162 }, { 10, 2164 }, { 10, 2166 }, { 10, 2168 },
|
||||
{ 10, 2170 }, { 10, 2172 }, { 10, 2174 }, { 10, 2176 }, { 10, 2178 },
|
||||
{ 10, 2180 }, { 10, 2182 }, { 10, 2184 }, { 10, 2186 }, { 10, 2188 },
|
||||
{ 10, 2190 }, { 10, 2192 }, { 10, 2194 }, { 10, 2196 }, { 10, 2198 },
|
||||
{ 10, 2200 }, { 10, 2202 }, { 10, 2204 }, { 10, 2206 }, { 10, 2208 },
|
||||
{ 10, 2210 }, { 10, 2212 }, { 10, 2214 }, { 10, 2216 }, { 10, 2218 },
|
||||
{ 10, 2220 }, { 10, 2222 }, { 10, 2224 }, { 10, 2226 }, { 10, 2228 },
|
||||
{ 10, 2230 }, { 10, 2232 }, { 10, 2234 }, { 10, 2236 }, { 10, 2238 },
|
||||
{ 10, 2240 }, { 10, 2242 }, { 10, 2244 }, { 10, 2246 }, { 10, 2248 },
|
||||
{ 10, 2250 }, { 10, 2252 }, { 10, 2254 }, { 10, 2256 }, { 10, 2258 },
|
||||
{ 10, 2260 }, { 10, 2262 }, { 10, 2264 }, { 10, 2266 }, { 10, 2268 },
|
||||
{ 10, 2270 }, { 10, 2272 }, { 10, 2274 }, { 10, 2276 }, { 10, 2278 },
|
||||
{ 10, 2280 }, { 10, 2282 }, { 10, 2284 }, { 10, 2286 }, { 10, 2288 },
|
||||
{ 10, 2290 }, { 10, 2292 }, { 10, 2294 }, { 10, 2296 }, { 10, 2298 },
|
||||
{ 10, 2300 }, { 10, 2302 }, { 10, 2304 }, { 10, 2306 }, { 10, 2308 },
|
||||
{ 10, 2310 }, { 10, 2312 }, { 10, 2314 }, { 10, 2316 }, { 10, 2318 },
|
||||
{ 10, 2320 }, { 10, 2322 }, { 10, 2324 }, { 10, 2326 }, { 10, 2328 },
|
||||
{ 10, 2330 }, { 10, 2332 }, { 10, 2334 }, { 10, 2336 }, { 10, 2338 },
|
||||
{ 10, 2340 }, { 10, 2342 }, { 10, 2344 }, { 10, 2346 }, { 10, 2348 },
|
||||
{ 10, 2350 }, { 10, 2352 }, { 10, 2354 }, { 10, 2356 }, { 10, 2358 },
|
||||
{ 10, 2360 }, { 10, 2362 }, { 10, 2364 }, { 10, 2366 }, { 10, 2368 },
|
||||
{ 10, 2370 }, { 10, 2372 }, { 10, 2374 }, { 10, 2376 }, { 10, 2378 },
|
||||
{ 10, 2380 }, { 10, 2382 }, { 10, 2384 }, { 10, 2386 }, { 10, 2388 },
|
||||
{ 10, 2390 }, { 10, 2392 }, { 10, 2394 }, { 10, 2396 }, { 10, 2398 },
|
||||
{ 10, 2400 }, { 10, 2402 }, { 10, 2404 }, { 10, 2406 }, { 10, 2408 },
|
||||
{ 10, 2410 }, { 10, 2412 }, { 10, 2414 }, { 10, 2416 }, { 10, 2418 },
|
||||
{ 10, 2420 }, { 10, 2422 }, { 10, 2424 }, { 10, 2426 }, { 10, 2428 },
|
||||
{ 10, 2430 }, { 10, 2432 }, { 10, 2434 }, { 10, 2436 }, { 10, 2438 },
|
||||
{ 10, 2440 }, { 10, 2442 }, { 10, 2444 }, { 10, 2446 }, { 10, 2448 },
|
||||
{ 10, 2450 }, { 10, 2452 }, { 10, 2454 }, { 10, 2456 }, { 10, 2458 },
|
||||
{ 10, 2460 }, { 10, 2462 }, { 10, 2464 }, { 10, 2466 }, { 10, 2468 },
|
||||
{ 10, 2470 }, { 10, 2472 }, { 10, 2474 }, { 10, 2476 }, { 10, 2478 },
|
||||
{ 10, 2480 }, { 10, 2482 }, { 10, 2484 }, { 10, 2486 }, { 10, 2488 },
|
||||
{ 10, 2490 }, { 10, 2492 }, { 10, 2494 }, { 10, 2496 }, { 10, 2498 },
|
||||
{ 10, 2500 }, { 10, 2502 }, { 10, 2504 }, { 10, 2506 }, { 10, 2508 },
|
||||
{ 10, 2510 }, { 10, 2512 }, { 10, 2514 }, { 10, 2516 }, { 10, 2518 },
|
||||
{ 10, 2520 }, { 10, 2522 }, { 10, 2524 }, { 10, 2526 }, { 10, 2528 },
|
||||
{ 10, 2530 }, { 10, 2532 }, { 10, 2534 }, { 10, 2536 }, { 10, 2538 },
|
||||
{ 10, 2540 }, { 10, 2542 }, { 10, 2544 }, { 10, 2546 }, { 10, 2548 },
|
||||
{ 10, 2550 }, { 10, 2552 }, { 10, 2554 }, { 10, 2556 }, { 10, 2558 },
|
||||
{ 10, 2560 }, { 10, 2562 }, { 10, 2564 }, { 10, 2566 }, { 10, 2568 },
|
||||
{ 10, 2570 }, { 10, 2572 }, { 10, 2574 }, { 10, 2576 }, { 10, 2578 },
|
||||
{ 10, 2580 }, { 10, 2582 }, { 10, 2584 }, { 10, 2586 }, { 10, 2588 },
|
||||
{ 10, 2590 }, { 10, 2592 }, { 10, 2594 }, { 10, 2596 }, { 10, 2598 },
|
||||
{ 10, 2600 }, { 10, 2602 }, { 10, 2604 }, { 10, 2606 }, { 10, 2608 },
|
||||
{ 10, 2610 }, { 10, 2612 }, { 10, 2614 }, { 10, 2616 }, { 10, 2618 },
|
||||
{ 10, 2620 }, { 10, 2622 }, { 10, 2624 }, { 10, 2626 }, { 10, 2628 },
|
||||
{ 10, 2630 }, { 10, 2632 }, { 10, 2634 }, { 10, 2636 }, { 10, 2638 },
|
||||
{ 10, 2640 }, { 10, 2642 }, { 10, 2644 }, { 10, 2646 }, { 10, 2648 },
|
||||
{ 10, 2650 }, { 10, 2652 }, { 10, 2654 }, { 10, 2656 }, { 10, 2658 },
|
||||
{ 10, 2660 }, { 10, 2662 }, { 10, 2664 }, { 10, 2666 }, { 10, 2668 },
|
||||
{ 10, 2670 }, { 10, 2672 }, { 10, 2674 }, { 10, 2676 }, { 10, 2678 },
|
||||
{ 10, 2680 }, { 10, 2682 }, { 10, 2684 }, { 10, 2686 }, { 10, 2688 },
|
||||
{ 10, 2690 }, { 10, 2692 }, { 10, 2694 }, { 10, 2696 }, { 10, 2698 },
|
||||
{ 10, 2700 }, { 10, 2702 }, { 10, 2704 }, { 10, 2706 }, { 10, 2708 },
|
||||
{ 10, 2710 }, { 10, 2712 }, { 10, 2714 }, { 10, 2716 }, { 10, 2718 },
|
||||
{ 10, 2720 }, { 10, 2722 }, { 10, 2724 }, { 10, 2726 }, { 10, 2728 },
|
||||
{ 10, 2730 }, { 10, 2732 }, { 10, 2734 }, { 10, 2736 }, { 10, 2738 },
|
||||
{ 10, 2740 }, { 10, 2742 }, { 10, 2744 }, { 10, 2746 }, { 10, 2748 },
|
||||
{ 10, 2750 }, { 10, 2752 }, { 10, 2754 }, { 10, 2756 }, { 10, 2758 },
|
||||
{ 10, 2760 }, { 10, 2762 }, { 10, 2764 }, { 10, 2766 }, { 10, 2768 },
|
||||
{ 10, 2770 }, { 10, 2772 }, { 10, 2774 }, { 10, 2776 }, { 10, 2778 },
|
||||
{ 10, 2780 }, { 10, 2782 }, { 10, 2784 }, { 10, 2786 }, { 10, 2788 },
|
||||
{ 10, 2790 }, { 10, 2792 }, { 10, 2794 }, { 10, 2796 }, { 10, 2798 },
|
||||
{ 10, 2800 }, { 10, 2802 }, { 10, 2804 }, { 10, 2806 }, { 10, 2808 },
|
||||
{ 10, 2810 }, { 10, 2812 }, { 10, 2814 }, { 10, 2816 }, { 10, 2818 },
|
||||
{ 10, 2820 }, { 10, 2822 }, { 10, 2824 }, { 10, 2826 }, { 10, 2828 },
|
||||
{ 10, 2830 }, { 10, 2832 }, { 10, 2834 }, { 10, 2836 }, { 10, 2838 },
|
||||
{ 10, 2840 }, { 10, 2842 }, { 10, 2844 }, { 10, 2846 }, { 10, 2848 },
|
||||
{ 10, 2850 }, { 10, 2852 }, { 10, 2854 }, { 10, 2856 }, { 10, 2858 },
|
||||
{ 10, 2860 }, { 10, 2862 }, { 10, 2864 }, { 10, 2866 }, { 10, 2868 },
|
||||
{ 10, 2870 }, { 10, 2872 }, { 10, 2874 }, { 10, 2876 }, { 10, 2878 },
|
||||
{ 10, 2880 }, { 10, 2882 }, { 10, 2884 }, { 10, 2886 }, { 10, 2888 },
|
||||
{ 10, 2890 }, { 10, 2892 }, { 10, 2894 }, { 10, 2896 }, { 10, 2898 },
|
||||
{ 10, 2900 }, { 10, 2902 }, { 10, 2904 }, { 10, 2906 }, { 10, 2908 },
|
||||
{ 10, 2910 }, { 10, 2912 }, { 10, 2914 }, { 10, 2916 }, { 10, 2918 },
|
||||
{ 10, 2920 }, { 10, 2922 }, { 10, 2924 }, { 10, 2926 }, { 10, 2928 },
|
||||
{ 10, 2930 }, { 10, 2932 }, { 10, 2934 }, { 10, 2936 }, { 10, 2938 },
|
||||
{ 10, 2940 }, { 10, 2942 }, { 10, 2944 }, { 10, 2946 }, { 10, 2948 },
|
||||
{ 10, 2950 }, { 10, 2952 }, { 10, 2954 }, { 10, 2956 }, { 10, 2958 },
|
||||
{ 10, 2960 }, { 10, 2962 }, { 10, 2964 }, { 10, 2966 }, { 10, 2968 },
|
||||
{ 10, 2970 }, { 10, 2972 }, { 10, 2974 }, { 10, 2976 }, { 10, 2978 },
|
||||
{ 10, 2980 }, { 10, 2982 }, { 10, 2984 }, { 10, 2986 }, { 10, 2988 },
|
||||
{ 10, 2990 }, { 10, 2992 }, { 10, 2994 }, { 10, 2996 }, { 10, 2998 },
|
||||
{ 10, 3000 }, { 10, 3002 }, { 10, 3004 }, { 10, 3006 }, { 10, 3008 },
|
||||
{ 10, 3010 }, { 10, 3012 }, { 10, 3014 }, { 10, 3016 }, { 10, 3018 },
|
||||
{ 10, 3020 }, { 10, 3022 }, { 10, 3024 }, { 10, 3026 }, { 10, 3028 },
|
||||
{ 10, 3030 }, { 10, 3032 }, { 10, 3034 }, { 10, 3036 }, { 10, 3038 },
|
||||
{ 10, 3040 }, { 10, 3042 }, { 10, 3044 }, { 10, 3046 }, { 10, 3048 },
|
||||
{ 10, 3050 }, { 10, 3052 }, { 10, 3054 }, { 10, 3056 }, { 10, 3058 },
|
||||
{ 10, 3060 }, { 10, 3062 }, { 10, 3064 }, { 10, 3066 }, { 10, 3068 },
|
||||
{ 10, 3070 }, { 10, 3072 }, { 10, 3074 }, { 10, 3076 }, { 10, 3078 },
|
||||
{ 10, 3080 }, { 10, 3082 }, { 10, 3084 }, { 10, 3086 }, { 10, 3088 },
|
||||
{ 10, 3090 }, { 10, 3092 }, { 10, 3094 }, { 10, 3096 }, { 10, 3098 },
|
||||
{ 10, 3100 }, { 10, 3102 }, { 10, 3104 }, { 10, 3106 }, { 10, 3108 },
|
||||
{ 10, 3110 }, { 10, 3112 }, { 10, 3114 }, { 10, 3116 }, { 10, 3118 },
|
||||
{ 10, 3120 }, { 10, 3122 }, { 10, 3124 }, { 10, 3126 }, { 10, 3128 },
|
||||
{ 10, 3130 }, { 10, 3132 }, { 10, 3134 }, { 10, 3136 }, { 10, 3138 },
|
||||
{ 10, 3140 }, { 10, 3142 }, { 10, 3144 }, { 10, 3146 }, { 10, 3148 },
|
||||
{ 10, 3150 }, { 10, 3152 }, { 10, 3154 }, { 10, 3156 }, { 10, 3158 },
|
||||
{ 10, 3160 }, { 10, 3162 }, { 10, 3164 }, { 10, 3166 }, { 10, 3168 },
|
||||
{ 10, 3170 }, { 10, 3172 }, { 10, 3174 }, { 10, 3176 }, { 10, 3178 },
|
||||
{ 10, 3180 }, { 10, 3182 }, { 10, 3184 }, { 10, 3186 }, { 10, 3188 },
|
||||
{ 10, 3190 }, { 10, 3192 }, { 10, 3194 }, { 10, 3196 }, { 10, 3198 },
|
||||
{ 10, 3200 }, { 10, 3202 }, { 10, 3204 }, { 10, 3206 }, { 10, 3208 },
|
||||
{ 10, 3210 }, { 10, 3212 }, { 10, 3214 }, { 10, 3216 }, { 10, 3218 },
|
||||
{ 10, 3220 }, { 10, 3222 }, { 10, 3224 }, { 10, 3226 }, { 10, 3228 },
|
||||
{ 10, 3230 }, { 10, 3232 }, { 10, 3234 }, { 10, 3236 }, { 10, 3238 },
|
||||
{ 10, 3240 }, { 10, 3242 }, { 10, 3244 }, { 10, 3246 }, { 10, 3248 },
|
||||
{ 10, 3250 }, { 10, 3252 }, { 10, 3254 }, { 10, 3256 }, { 10, 3258 },
|
||||
{ 10, 3260 }, { 10, 3262 }, { 10, 3264 }, { 10, 3266 }, { 10, 3268 },
|
||||
{ 10, 3270 }, { 10, 3272 }, { 10, 3274 }, { 10, 3276 }, { 10, 3278 },
|
||||
{ 10, 3280 }, { 10, 3282 }, { 10, 3284 }, { 10, 3286 }, { 10, 3288 },
|
||||
{ 10, 3290 }, { 10, 3292 }, { 10, 3294 }, { 10, 3296 }, { 10, 3298 },
|
||||
{ 10, 3300 }, { 10, 3302 }, { 10, 3304 }, { 10, 3306 }, { 10, 3308 },
|
||||
{ 10, 3310 }, { 10, 3312 }, { 10, 3314 }, { 10, 3316 }, { 10, 3318 },
|
||||
{ 10, 3320 }, { 10, 3322 }, { 10, 3324 }, { 10, 3326 }, { 10, 3328 },
|
||||
{ 10, 3330 }, { 10, 3332 }, { 10, 3334 }, { 10, 3336 }, { 10, 3338 },
|
||||
{ 10, 3340 }, { 10, 3342 }, { 10, 3344 }, { 10, 3346 }, { 10, 3348 },
|
||||
{ 10, 3350 }, { 10, 3352 }, { 10, 3354 }, { 10, 3356 }, { 10, 3358 },
|
||||
{ 10, 3360 }, { 10, 3362 }, { 10, 3364 }, { 10, 3366 }, { 10, 3368 },
|
||||
{ 10, 3370 }, { 10, 3372 }, { 10, 3374 }, { 10, 3376 }, { 10, 3378 },
|
||||
{ 10, 3380 }, { 10, 3382 }, { 10, 3384 }, { 10, 3386 }, { 10, 3388 },
|
||||
{ 10, 3390 }, { 10, 3392 }, { 10, 3394 }, { 10, 3396 }, { 10, 3398 },
|
||||
{ 10, 3400 }, { 10, 3402 }, { 10, 3404 }, { 10, 3406 }, { 10, 3408 },
|
||||
{ 10, 3410 }, { 10, 3412 }, { 10, 3414 }, { 10, 3416 }, { 10, 3418 },
|
||||
{ 10, 3420 }, { 10, 3422 }, { 10, 3424 }, { 10, 3426 }, { 10, 3428 },
|
||||
{ 10, 3430 }, { 10, 3432 }, { 10, 3434 }, { 10, 3436 }, { 10, 3438 },
|
||||
{ 10, 3440 }, { 10, 3442 }, { 10, 3444 }, { 10, 3446 }, { 10, 3448 },
|
||||
{ 10, 3450 }, { 10, 3452 }, { 10, 3454 }, { 10, 3456 }, { 10, 3458 },
|
||||
{ 10, 3460 }, { 10, 3462 }, { 10, 3464 }, { 10, 3466 }, { 10, 3468 },
|
||||
{ 10, 3470 }, { 10, 3472 }, { 10, 3474 }, { 10, 3476 }, { 10, 3478 },
|
||||
{ 10, 3480 }, { 10, 3482 }, { 10, 3484 }, { 10, 3486 }, { 10, 3488 },
|
||||
{ 10, 3490 }, { 10, 3492 }, { 10, 3494 }, { 10, 3496 }, { 10, 3498 },
|
||||
{ 10, 3500 }, { 10, 3502 }, { 10, 3504 }, { 10, 3506 }, { 10, 3508 },
|
||||
{ 10, 3510 }, { 10, 3512 }, { 10, 3514 }, { 10, 3516 }, { 10, 3518 },
|
||||
{ 10, 3520 }, { 10, 3522 }, { 10, 3524 }, { 10, 3526 }, { 10, 3528 },
|
||||
{ 10, 3530 }, { 10, 3532 }, { 10, 3534 }, { 10, 3536 }, { 10, 3538 },
|
||||
{ 10, 3540 }, { 10, 3542 }, { 10, 3544 }, { 10, 3546 }, { 10, 3548 },
|
||||
{ 10, 3550 }, { 10, 3552 }, { 10, 3554 }, { 10, 3556 }, { 10, 3558 },
|
||||
{ 10, 3560 }, { 10, 3562 }, { 10, 3564 }, { 10, 3566 }, { 10, 3568 },
|
||||
{ 10, 3570 }, { 10, 3572 }, { 10, 3574 }, { 10, 3576 }, { 10, 3578 },
|
||||
{ 10, 3580 }, { 10, 3582 }, { 10, 3584 }, { 10, 3586 }, { 10, 3588 },
|
||||
{ 10, 3590 }, { 10, 3592 }, { 10, 3594 }, { 10, 3596 }, { 10, 3598 },
|
||||
{ 10, 3600 }, { 10, 3602 }, { 10, 3604 }, { 10, 3606 }, { 10, 3608 },
|
||||
{ 10, 3610 }, { 10, 3612 }, { 10, 3614 }, { 10, 3616 }, { 10, 3618 },
|
||||
{ 10, 3620 }, { 10, 3622 }, { 10, 3624 }, { 10, 3626 }, { 10, 3628 },
|
||||
{ 10, 3630 }, { 10, 3632 }, { 10, 3634 }, { 10, 3636 }, { 10, 3638 },
|
||||
{ 10, 3640 }, { 10, 3642 }, { 10, 3644 }, { 10, 3646 }, { 10, 3648 },
|
||||
{ 10, 3650 }, { 10, 3652 }, { 10, 3654 }, { 10, 3656 }, { 10, 3658 },
|
||||
{ 10, 3660 }, { 10, 3662 }, { 10, 3664 }, { 10, 3666 }, { 10, 3668 },
|
||||
{ 10, 3670 }, { 10, 3672 }, { 10, 3674 }, { 10, 3676 }, { 10, 3678 },
|
||||
{ 10, 3680 }, { 10, 3682 }, { 10, 3684 }, { 10, 3686 }, { 10, 3688 },
|
||||
{ 10, 3690 }, { 10, 3692 }, { 10, 3694 }, { 10, 3696 }, { 10, 3698 },
|
||||
{ 10, 3700 }, { 10, 3702 }, { 10, 3704 }, { 10, 3706 }, { 10, 3708 },
|
||||
{ 10, 3710 }, { 10, 3712 }, { 10, 3714 }, { 10, 3716 }, { 10, 3718 },
|
||||
{ 10, 3720 }, { 10, 3722 }, { 10, 3724 }, { 10, 3726 }, { 10, 3728 },
|
||||
{ 10, 3730 }, { 10, 3732 }, { 10, 3734 }, { 10, 3736 }, { 10, 3738 },
|
||||
{ 10, 3740 }, { 10, 3742 }, { 10, 3744 }, { 10, 3746 }, { 10, 3748 },
|
||||
{ 10, 3750 }, { 10, 3752 }, { 10, 3754 }, { 10, 3756 }, { 10, 3758 },
|
||||
{ 10, 3760 }, { 10, 3762 }, { 10, 3764 }, { 10, 3766 }, { 10, 3768 },
|
||||
{ 10, 3770 }, { 10, 3772 }, { 10, 3774 }, { 10, 3776 }, { 10, 3778 },
|
||||
{ 10, 3780 }, { 10, 3782 }, { 10, 3784 }, { 10, 3786 }, { 10, 3788 },
|
||||
{ 10, 3790 }, { 10, 3792 }, { 10, 3794 }, { 10, 3796 }, { 10, 3798 },
|
||||
{ 10, 3800 }, { 10, 3802 }, { 10, 3804 }, { 10, 3806 }, { 10, 3808 },
|
||||
{ 10, 3810 }, { 10, 3812 }, { 10, 3814 }, { 10, 3816 }, { 10, 3818 },
|
||||
{ 10, 3820 }, { 10, 3822 }, { 10, 3824 }, { 10, 3826 }, { 10, 3828 },
|
||||
{ 10, 3830 }, { 10, 3832 }, { 10, 3834 }, { 10, 3836 }, { 10, 3838 },
|
||||
{ 10, 3840 }, { 10, 3842 }, { 10, 3844 }, { 10, 3846 }, { 10, 3848 },
|
||||
{ 10, 3850 }, { 10, 3852 }, { 10, 3854 }, { 10, 3856 }, { 10, 3858 },
|
||||
{ 10, 3860 }, { 10, 3862 }, { 10, 3864 }, { 10, 3866 }, { 10, 3868 },
|
||||
{ 10, 3870 }, { 10, 3872 }, { 10, 3874 }, { 10, 3876 }, { 10, 3878 },
|
||||
{ 10, 3880 }, { 10, 3882 }, { 10, 3884 }, { 10, 3886 }, { 10, 3888 },
|
||||
{ 10, 3890 }, { 10, 3892 }, { 10, 3894 }, { 10, 3896 }, { 10, 3898 },
|
||||
{ 10, 3900 }, { 10, 3902 }, { 10, 3904 }, { 10, 3906 }, { 10, 3908 },
|
||||
{ 10, 3910 }, { 10, 3912 }, { 10, 3914 }, { 10, 3916 }, { 10, 3918 },
|
||||
{ 10, 3920 }, { 10, 3922 }, { 10, 3924 }, { 10, 3926 }, { 10, 3928 },
|
||||
{ 10, 3930 }, { 10, 3932 }, { 10, 3934 }, { 10, 3936 }, { 10, 3938 },
|
||||
{ 10, 3940 }, { 10, 3942 }, { 10, 3944 }, { 10, 3946 }, { 10, 3948 },
|
||||
{ 10, 3950 }, { 10, 3952 }, { 10, 3954 }, { 10, 3956 }, { 10, 3958 },
|
||||
{ 10, 3960 }
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_DCT_VALUE_TOKENS_H_
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_DEFAULTCOEFCOUNTS_H_
|
||||
#define VPX_VP8_ENCODER_DEFAULTCOEFCOUNTS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Generated file, included by entropy.c */
|
||||
|
||||
static const unsigned int default_coef_counts
|
||||
[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS] = {
|
||||
|
||||
{
|
||||
/* Block Type ( 0 ) */
|
||||
{
|
||||
/* Coeff Band ( 0 ) */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 1 ) */
|
||||
{ 30190, 26544, 225, 24, 4, 0, 0, 0, 0, 0, 0, 4171593 },
|
||||
{ 26846, 25157, 1241, 130, 26, 6, 1, 0, 0, 0, 0, 149987 },
|
||||
{ 10484, 9538, 1006, 160, 36, 18, 0, 0, 0, 0, 0, 15104 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 2 ) */
|
||||
{ 25842, 40456, 1126, 83, 11, 2, 0, 0, 0, 0, 0, 0 },
|
||||
{ 9338, 8010, 512, 73, 7, 3, 2, 0, 0, 0, 0, 43294 },
|
||||
{ 1047, 751, 149, 31, 13, 6, 1, 0, 0, 0, 0, 879 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 3 ) */
|
||||
{ 26136, 9826, 252, 13, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 8134, 5574, 191, 14, 2, 0, 0, 0, 0, 0, 0, 35302 },
|
||||
{ 605, 677, 116, 9, 1, 0, 0, 0, 0, 0, 0, 611 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 4 ) */
|
||||
{ 10263, 15463, 283, 17, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 2773, 2191, 128, 9, 2, 2, 0, 0, 0, 0, 0, 10073 },
|
||||
{ 134, 125, 32, 4, 0, 2, 0, 0, 0, 0, 0, 50 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 5 ) */
|
||||
{ 10483, 2663, 23, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 2137, 1251, 27, 1, 1, 0, 0, 0, 0, 0, 0, 14362 },
|
||||
{ 116, 156, 14, 2, 1, 0, 0, 0, 0, 0, 0, 190 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 6 ) */
|
||||
{ 40977, 27614, 412, 28, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 6113, 5213, 261, 22, 3, 0, 0, 0, 0, 0, 0, 26164 },
|
||||
{ 382, 312, 50, 14, 2, 0, 0, 0, 0, 0, 0, 345 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 7 ) */
|
||||
{ 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 },
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Block Type ( 1 ) */
|
||||
{
|
||||
/* Coeff Band ( 0 ) */
|
||||
{ 3268, 19382, 1043, 250, 93, 82, 49, 26, 17, 8, 25, 82289 },
|
||||
{ 8758, 32110, 5436, 1832, 827, 668, 420, 153, 24, 0, 3, 52914 },
|
||||
{ 9337, 23725, 8487, 3954, 2107, 1836, 1069, 399, 59, 0, 0,
|
||||
18620 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 1 ) */
|
||||
{ 12419, 8420, 452, 62, 9, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ 11715, 8705, 693, 92, 15, 7, 2, 0, 0, 0, 0, 53988 },
|
||||
{ 7603, 8585, 2306, 778, 270, 145, 39, 5, 0, 0, 0, 9136 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 2 ) */
|
||||
{ 15938, 14335, 1207, 184, 55, 13, 4, 1, 0, 0, 0, 0 },
|
||||
{ 7415, 6829, 1138, 244, 71, 26, 7, 0, 0, 0, 0, 9980 },
|
||||
{ 1580, 1824, 655, 241, 89, 46, 10, 2, 0, 0, 0, 429 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 3 ) */
|
||||
{ 19453, 5260, 201, 19, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 9173, 3758, 213, 22, 1, 1, 0, 0, 0, 0, 0, 9820 },
|
||||
{ 1689, 1277, 276, 51, 17, 4, 0, 0, 0, 0, 0, 679 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 4 ) */
|
||||
{ 12076, 10667, 620, 85, 19, 9, 5, 0, 0, 0, 0, 0 },
|
||||
{ 4665, 3625, 423, 55, 19, 9, 0, 0, 0, 0, 0, 5127 },
|
||||
{ 415, 440, 143, 34, 20, 7, 2, 0, 0, 0, 0, 101 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 5 ) */
|
||||
{ 12183, 4846, 115, 11, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 4226, 3149, 177, 21, 2, 0, 0, 0, 0, 0, 0, 7157 },
|
||||
{ 375, 621, 189, 51, 11, 4, 1, 0, 0, 0, 0, 198 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 6 ) */
|
||||
{ 61658, 37743, 1203, 94, 10, 3, 0, 0, 0, 0, 0, 0 },
|
||||
{ 15514, 11563, 903, 111, 14, 5, 0, 0, 0, 0, 0, 25195 },
|
||||
{ 929, 1077, 291, 78, 14, 7, 1, 0, 0, 0, 0, 507 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 7 ) */
|
||||
{ 0, 990, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 412, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1641 },
|
||||
{ 0, 18, 7, 1, 0, 0, 0, 0, 0, 0, 0, 30 },
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Block Type ( 2 ) */
|
||||
{
|
||||
/* Coeff Band ( 0 ) */
|
||||
{ 953, 24519, 628, 120, 28, 12, 4, 0, 0, 0, 0, 2248798 },
|
||||
{ 1525, 25654, 2647, 617, 239, 143, 42, 5, 0, 0, 0, 66837 },
|
||||
{ 1180, 11011, 3001, 1237, 532, 448, 239, 54, 5, 0, 0, 7122 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 1 ) */
|
||||
{ 1356, 2220, 67, 10, 4, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ 1450, 2544, 102, 18, 4, 3, 0, 0, 0, 0, 0, 57063 },
|
||||
{ 1182, 2110, 470, 130, 41, 21, 0, 0, 0, 0, 0, 6047 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 2 ) */
|
||||
{ 370, 3378, 200, 30, 5, 4, 1, 0, 0, 0, 0, 0 },
|
||||
{ 293, 1006, 131, 29, 11, 0, 0, 0, 0, 0, 0, 5404 },
|
||||
{ 114, 387, 98, 23, 4, 8, 1, 0, 0, 0, 0, 236 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 3 ) */
|
||||
{ 579, 194, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 395, 213, 5, 1, 0, 0, 0, 0, 0, 0, 0, 4157 },
|
||||
{ 119, 122, 4, 0, 0, 0, 0, 0, 0, 0, 0, 300 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 4 ) */
|
||||
{ 38, 557, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 21, 114, 12, 1, 0, 0, 0, 0, 0, 0, 0, 427 },
|
||||
{ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 5 ) */
|
||||
{ 52, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 18, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 652 },
|
||||
{ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 6 ) */
|
||||
{ 640, 569, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 25, 77, 2, 0, 0, 0, 0, 0, 0, 0, 0, 517 },
|
||||
{ 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 7 ) */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Block Type ( 3 ) */
|
||||
{
|
||||
/* Coeff Band ( 0 ) */
|
||||
{ 2506, 20161, 2707, 767, 261, 178, 107, 30, 14, 3, 0, 100694 },
|
||||
{ 8806, 36478, 8817, 3268, 1280, 850, 401, 114, 42, 0, 0, 58572 },
|
||||
{ 11003, 27214, 11798, 5716, 2482, 2072, 1048, 175, 32, 0, 0,
|
||||
19284 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 1 ) */
|
||||
{ 9738, 11313, 959, 205, 70, 18, 11, 1, 0, 0, 0, 0 },
|
||||
{ 12628, 15085, 1507, 273, 52, 19, 9, 0, 0, 0, 0, 54280 },
|
||||
{ 10701, 15846, 5561, 1926, 813, 570, 249, 36, 0, 0, 0, 6460 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 2 ) */
|
||||
{ 6781, 22539, 2784, 634, 182, 123, 20, 4, 0, 0, 0, 0 },
|
||||
{ 6263, 11544, 2649, 790, 259, 168, 27, 5, 0, 0, 0, 20539 },
|
||||
{ 3109, 4075, 2031, 896, 457, 386, 158, 29, 0, 0, 0, 1138 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 3 ) */
|
||||
{ 11515, 4079, 465, 73, 5, 14, 2, 0, 0, 0, 0, 0 },
|
||||
{ 9361, 5834, 650, 96, 24, 8, 4, 0, 0, 0, 0, 22181 },
|
||||
{ 4343, 3974, 1360, 415, 132, 96, 14, 1, 0, 0, 0, 1267 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 4 ) */
|
||||
{ 4787, 9297, 823, 168, 44, 12, 4, 0, 0, 0, 0, 0 },
|
||||
{ 3619, 4472, 719, 198, 60, 31, 3, 0, 0, 0, 0, 8401 },
|
||||
{ 1157, 1175, 483, 182, 88, 31, 8, 0, 0, 0, 0, 268 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 5 ) */
|
||||
{ 8299, 1226, 32, 5, 1, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 3502, 1568, 57, 4, 1, 1, 0, 0, 0, 0, 0, 9811 },
|
||||
{ 1055, 1070, 166, 29, 6, 1, 0, 0, 0, 0, 0, 527 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 6 ) */
|
||||
{ 27414, 27927, 1989, 347, 69, 26, 0, 0, 0, 0, 0, 0 },
|
||||
{ 5876, 10074, 1574, 341, 91, 24, 4, 0, 0, 0, 0, 21954 },
|
||||
{ 1571, 2171, 778, 324, 124, 65, 16, 0, 0, 0, 0, 979 },
|
||||
},
|
||||
{
|
||||
/* Coeff Band ( 7 ) */
|
||||
{ 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 459 },
|
||||
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13 },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_DEFAULTCOEFCOUNTS_H_
|
||||
@@ -0,0 +1,725 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "denoising.h"
|
||||
|
||||
#include "vp8/common/reconinter.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vp8_rtcd.h"
|
||||
|
||||
static const unsigned int NOISE_MOTION_THRESHOLD = 25 * 25;
|
||||
/* SSE_DIFF_THRESHOLD is selected as ~95% confidence assuming
|
||||
* var(noise) ~= 100.
|
||||
*/
|
||||
static const unsigned int SSE_DIFF_THRESHOLD = 16 * 16 * 20;
|
||||
static const unsigned int SSE_THRESHOLD = 16 * 16 * 40;
|
||||
static const unsigned int SSE_THRESHOLD_HIGH = 16 * 16 * 80;
|
||||
|
||||
/*
|
||||
* The filter function was modified to reduce the computational complexity.
|
||||
* Step 1:
|
||||
* Instead of applying tap coefficients for each pixel, we calculated the
|
||||
* pixel adjustments vs. pixel diff value ahead of time.
|
||||
* adjustment = filtered_value - current_raw
|
||||
* = (filter_coefficient * diff + 128) >> 8
|
||||
* where
|
||||
* filter_coefficient = (255 << 8) / (256 + ((absdiff * 330) >> 3));
|
||||
* filter_coefficient += filter_coefficient /
|
||||
* (3 + motion_magnitude_adjustment);
|
||||
* filter_coefficient is clamped to 0 ~ 255.
|
||||
*
|
||||
* Step 2:
|
||||
* The adjustment vs. diff curve becomes flat very quick when diff increases.
|
||||
* This allowed us to use only several levels to approximate the curve without
|
||||
* changing the filtering algorithm too much.
|
||||
* The adjustments were further corrected by checking the motion magnitude.
|
||||
* The levels used are:
|
||||
* diff adjustment w/o motion correction adjustment w/ motion correction
|
||||
* [-255, -16] -6 -7
|
||||
* [-15, -8] -4 -5
|
||||
* [-7, -4] -3 -4
|
||||
* [-3, 3] diff diff
|
||||
* [4, 7] 3 4
|
||||
* [8, 15] 4 5
|
||||
* [16, 255] 6 7
|
||||
*/
|
||||
|
||||
int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride,
|
||||
unsigned char *running_avg_y, int avg_y_stride,
|
||||
unsigned char *sig, int sig_stride,
|
||||
unsigned int motion_magnitude,
|
||||
int increase_denoising) {
|
||||
unsigned char *running_avg_y_start = running_avg_y;
|
||||
unsigned char *sig_start = sig;
|
||||
int sum_diff_thresh;
|
||||
int r, c;
|
||||
int sum_diff = 0;
|
||||
int adj_val[3] = { 3, 4, 6 };
|
||||
int shift_inc1 = 0;
|
||||
int shift_inc2 = 1;
|
||||
int col_sum[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
/* If motion_magnitude is small, making the denoiser more aggressive by
|
||||
* increasing the adjustment for each level. Add another increment for
|
||||
* blocks that are labeled for increase denoising. */
|
||||
if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) {
|
||||
if (increase_denoising) {
|
||||
shift_inc1 = 1;
|
||||
shift_inc2 = 2;
|
||||
}
|
||||
adj_val[0] += shift_inc2;
|
||||
adj_val[1] += shift_inc2;
|
||||
adj_val[2] += shift_inc2;
|
||||
}
|
||||
|
||||
for (r = 0; r < 16; ++r) {
|
||||
for (c = 0; c < 16; ++c) {
|
||||
int diff = 0;
|
||||
int adjustment = 0;
|
||||
int absdiff = 0;
|
||||
|
||||
diff = mc_running_avg_y[c] - sig[c];
|
||||
absdiff = abs(diff);
|
||||
|
||||
// When |diff| <= |3 + shift_inc1|, use pixel value from
|
||||
// last denoised raw.
|
||||
if (absdiff <= 3 + shift_inc1) {
|
||||
running_avg_y[c] = mc_running_avg_y[c];
|
||||
col_sum[c] += diff;
|
||||
} else {
|
||||
if (absdiff >= 4 + shift_inc1 && absdiff <= 7) {
|
||||
adjustment = adj_val[0];
|
||||
} else if (absdiff >= 8 && absdiff <= 15) {
|
||||
adjustment = adj_val[1];
|
||||
} else {
|
||||
adjustment = adj_val[2];
|
||||
}
|
||||
|
||||
if (diff > 0) {
|
||||
if ((sig[c] + adjustment) > 255) {
|
||||
running_avg_y[c] = 255;
|
||||
} else {
|
||||
running_avg_y[c] = sig[c] + adjustment;
|
||||
}
|
||||
|
||||
col_sum[c] += adjustment;
|
||||
} else {
|
||||
if ((sig[c] - adjustment) < 0) {
|
||||
running_avg_y[c] = 0;
|
||||
} else {
|
||||
running_avg_y[c] = sig[c] - adjustment;
|
||||
}
|
||||
|
||||
col_sum[c] -= adjustment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update pointers for next iteration. */
|
||||
sig += sig_stride;
|
||||
mc_running_avg_y += mc_avg_y_stride;
|
||||
running_avg_y += avg_y_stride;
|
||||
}
|
||||
|
||||
for (c = 0; c < 16; ++c) {
|
||||
// Below we clip the value in the same way which SSE code use.
|
||||
// When adopting aggressive denoiser, the adj_val for each pixel
|
||||
// could be at most 8 (this is current max adjustment of the map).
|
||||
// In SSE code, we calculate the sum of adj_val for
|
||||
// the columns, so the sum could be upto 128(16 rows). However,
|
||||
// the range of the value is -128 ~ 127 in SSE code, that's why
|
||||
// we do this change in C code.
|
||||
// We don't do this for UV denoiser, since there are only 8 rows,
|
||||
// and max adjustments <= 8, so the sum of the columns will not
|
||||
// exceed 64.
|
||||
if (col_sum[c] >= 128) {
|
||||
col_sum[c] = 127;
|
||||
}
|
||||
sum_diff += col_sum[c];
|
||||
}
|
||||
|
||||
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
|
||||
// accceptable range given by sum_diff_thresh.
|
||||
|
||||
// The delta is set by the excess of absolute pixel diff over threshold.
|
||||
int delta = ((abs(sum_diff) - sum_diff_thresh) >> 8) + 1;
|
||||
// Only apply the adjustment for max delta up to 3.
|
||||
if (delta < 4) {
|
||||
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) {
|
||||
for (c = 0; c < 16; ++c) {
|
||||
int diff = mc_running_avg_y[c] - sig[c];
|
||||
int adjustment = abs(diff);
|
||||
if (adjustment > delta) adjustment = delta;
|
||||
if (diff > 0) {
|
||||
// Bring denoised signal down.
|
||||
if (running_avg_y[c] - adjustment < 0) {
|
||||
running_avg_y[c] = 0;
|
||||
} else {
|
||||
running_avg_y[c] = running_avg_y[c] - adjustment;
|
||||
}
|
||||
col_sum[c] -= adjustment;
|
||||
} else if (diff < 0) {
|
||||
// Bring denoised signal up.
|
||||
if (running_avg_y[c] + adjustment > 255) {
|
||||
running_avg_y[c] = 255;
|
||||
} else {
|
||||
running_avg_y[c] = running_avg_y[c] + adjustment;
|
||||
}
|
||||
col_sum[c] += adjustment;
|
||||
}
|
||||
}
|
||||
// TODO(marpan): Check here if abs(sum_diff) has gone below the
|
||||
// threshold sum_diff_thresh, and if so, we can exit the row loop.
|
||||
sig += sig_stride;
|
||||
mc_running_avg_y += mc_avg_y_stride;
|
||||
running_avg_y += avg_y_stride;
|
||||
}
|
||||
|
||||
sum_diff = 0;
|
||||
for (c = 0; c < 16; ++c) {
|
||||
if (col_sum[c] >= 128) {
|
||||
col_sum[c] = 127;
|
||||
}
|
||||
sum_diff += col_sum[c];
|
||||
}
|
||||
|
||||
if (abs(sum_diff) > sum_diff_thresh) return COPY_BLOCK;
|
||||
} else {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
vp8_copy_mem16x16(running_avg_y_start, avg_y_stride, sig_start, sig_stride);
|
||||
return FILTER_BLOCK;
|
||||
}
|
||||
|
||||
int vp8_denoiser_filter_uv_c(unsigned char *mc_running_avg, int mc_avg_stride,
|
||||
unsigned char *running_avg, int avg_stride,
|
||||
unsigned char *sig, int sig_stride,
|
||||
unsigned int motion_magnitude,
|
||||
int increase_denoising) {
|
||||
unsigned char *running_avg_start = running_avg;
|
||||
unsigned char *sig_start = sig;
|
||||
int sum_diff_thresh;
|
||||
int r, c;
|
||||
int sum_diff = 0;
|
||||
int sum_block = 0;
|
||||
int adj_val[3] = { 3, 4, 6 };
|
||||
int shift_inc1 = 0;
|
||||
int shift_inc2 = 1;
|
||||
/* If motion_magnitude is small, making the denoiser more aggressive by
|
||||
* increasing the adjustment for each level. Add another increment for
|
||||
* blocks that are labeled for increase denoising. */
|
||||
if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD_UV) {
|
||||
if (increase_denoising) {
|
||||
shift_inc1 = 1;
|
||||
shift_inc2 = 2;
|
||||
}
|
||||
adj_val[0] += shift_inc2;
|
||||
adj_val[1] += shift_inc2;
|
||||
adj_val[2] += shift_inc2;
|
||||
}
|
||||
|
||||
// Avoid denoising color signal if its close to average level.
|
||||
for (r = 0; r < 8; ++r) {
|
||||
for (c = 0; c < 8; ++c) {
|
||||
sum_block += sig[c];
|
||||
}
|
||||
sig += sig_stride;
|
||||
}
|
||||
if (abs(sum_block - (128 * 8 * 8)) < SUM_DIFF_FROM_AVG_THRESH_UV) {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
|
||||
sig -= sig_stride * 8;
|
||||
for (r = 0; r < 8; ++r) {
|
||||
for (c = 0; c < 8; ++c) {
|
||||
int diff = 0;
|
||||
int adjustment = 0;
|
||||
int absdiff = 0;
|
||||
|
||||
diff = mc_running_avg[c] - sig[c];
|
||||
absdiff = abs(diff);
|
||||
|
||||
// When |diff| <= |3 + shift_inc1|, use pixel value from
|
||||
// last denoised raw.
|
||||
if (absdiff <= 3 + shift_inc1) {
|
||||
running_avg[c] = mc_running_avg[c];
|
||||
sum_diff += diff;
|
||||
} else {
|
||||
if (absdiff >= 4 && absdiff <= 7) {
|
||||
adjustment = adj_val[0];
|
||||
} else if (absdiff >= 8 && absdiff <= 15) {
|
||||
adjustment = adj_val[1];
|
||||
} else {
|
||||
adjustment = adj_val[2];
|
||||
}
|
||||
if (diff > 0) {
|
||||
if ((sig[c] + adjustment) > 255) {
|
||||
running_avg[c] = 255;
|
||||
} else {
|
||||
running_avg[c] = sig[c] + adjustment;
|
||||
}
|
||||
sum_diff += adjustment;
|
||||
} else {
|
||||
if ((sig[c] - adjustment) < 0) {
|
||||
running_avg[c] = 0;
|
||||
} else {
|
||||
running_avg[c] = sig[c] - adjustment;
|
||||
}
|
||||
sum_diff -= adjustment;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Update pointers for next iteration. */
|
||||
sig += sig_stride;
|
||||
mc_running_avg += mc_avg_stride;
|
||||
running_avg += avg_stride;
|
||||
}
|
||||
|
||||
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
|
||||
// accceptable range given by sum_diff_thresh.
|
||||
|
||||
// The delta is set by the excess of absolute pixel diff over threshold.
|
||||
int delta = ((abs(sum_diff) - sum_diff_thresh) >> 8) + 1;
|
||||
// Only apply the adjustment for max delta up to 3.
|
||||
if (delta < 4) {
|
||||
sig -= sig_stride * 8;
|
||||
mc_running_avg -= mc_avg_stride * 8;
|
||||
running_avg -= avg_stride * 8;
|
||||
for (r = 0; r < 8; ++r) {
|
||||
for (c = 0; c < 8; ++c) {
|
||||
int diff = mc_running_avg[c] - sig[c];
|
||||
int adjustment = abs(diff);
|
||||
if (adjustment > delta) adjustment = delta;
|
||||
if (diff > 0) {
|
||||
// Bring denoised signal down.
|
||||
if (running_avg[c] - adjustment < 0) {
|
||||
running_avg[c] = 0;
|
||||
} else {
|
||||
running_avg[c] = running_avg[c] - adjustment;
|
||||
}
|
||||
sum_diff -= adjustment;
|
||||
} else if (diff < 0) {
|
||||
// Bring denoised signal up.
|
||||
if (running_avg[c] + adjustment > 255) {
|
||||
running_avg[c] = 255;
|
||||
} else {
|
||||
running_avg[c] = running_avg[c] + adjustment;
|
||||
}
|
||||
sum_diff += adjustment;
|
||||
}
|
||||
}
|
||||
// TODO(marpan): Check here if abs(sum_diff) has gone below the
|
||||
// threshold sum_diff_thresh, and if so, we can exit the row loop.
|
||||
sig += sig_stride;
|
||||
mc_running_avg += mc_avg_stride;
|
||||
running_avg += avg_stride;
|
||||
}
|
||||
if (abs(sum_diff) > sum_diff_thresh) return COPY_BLOCK;
|
||||
} else {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
vp8_copy_mem8x8(running_avg_start, avg_stride, sig_start, sig_stride);
|
||||
return FILTER_BLOCK;
|
||||
}
|
||||
|
||||
void vp8_denoiser_set_parameters(VP8_DENOISER *denoiser, int mode) {
|
||||
assert(mode > 0); // Denoiser is allocated only if mode > 0.
|
||||
if (mode == 1) {
|
||||
denoiser->denoiser_mode = kDenoiserOnYOnly;
|
||||
} else if (mode == 2) {
|
||||
denoiser->denoiser_mode = kDenoiserOnYUV;
|
||||
} else if (mode == 3) {
|
||||
denoiser->denoiser_mode = kDenoiserOnYUVAggressive;
|
||||
} else {
|
||||
denoiser->denoiser_mode = kDenoiserOnYUV;
|
||||
}
|
||||
if (denoiser->denoiser_mode != kDenoiserOnYUVAggressive) {
|
||||
denoiser->denoise_pars.scale_sse_thresh = 1;
|
||||
denoiser->denoise_pars.scale_motion_thresh = 8;
|
||||
denoiser->denoise_pars.scale_increase_filter = 0;
|
||||
denoiser->denoise_pars.denoise_mv_bias = 95;
|
||||
denoiser->denoise_pars.pickmode_mv_bias = 100;
|
||||
denoiser->denoise_pars.qp_thresh = 0;
|
||||
denoiser->denoise_pars.consec_zerolast = UINT_MAX;
|
||||
denoiser->denoise_pars.spatial_blur = 0;
|
||||
} else {
|
||||
denoiser->denoise_pars.scale_sse_thresh = 2;
|
||||
denoiser->denoise_pars.scale_motion_thresh = 16;
|
||||
denoiser->denoise_pars.scale_increase_filter = 1;
|
||||
denoiser->denoise_pars.denoise_mv_bias = 60;
|
||||
denoiser->denoise_pars.pickmode_mv_bias = 75;
|
||||
denoiser->denoise_pars.qp_thresh = 80;
|
||||
denoiser->denoise_pars.consec_zerolast = 15;
|
||||
denoiser->denoise_pars.spatial_blur = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height,
|
||||
int num_mb_rows, int num_mb_cols, int mode) {
|
||||
int i;
|
||||
assert(denoiser);
|
||||
denoiser->num_mb_cols = num_mb_cols;
|
||||
|
||||
for (i = 0; i < MAX_REF_FRAMES; ++i) {
|
||||
denoiser->yv12_running_avg[i].flags = 0;
|
||||
|
||||
if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_running_avg[i]), width,
|
||||
height, VP8BORDERINPIXELS) < 0) {
|
||||
vp8_denoiser_free(denoiser);
|
||||
return 1;
|
||||
}
|
||||
memset(denoiser->yv12_running_avg[i].buffer_alloc, 0,
|
||||
denoiser->yv12_running_avg[i].frame_size);
|
||||
}
|
||||
denoiser->yv12_mc_running_avg.flags = 0;
|
||||
|
||||
if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_mc_running_avg), width,
|
||||
height, VP8BORDERINPIXELS) < 0) {
|
||||
vp8_denoiser_free(denoiser);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(denoiser->yv12_mc_running_avg.buffer_alloc, 0,
|
||||
denoiser->yv12_mc_running_avg.frame_size);
|
||||
|
||||
if (vp8_yv12_alloc_frame_buffer(&denoiser->yv12_last_source, width, height,
|
||||
VP8BORDERINPIXELS) < 0) {
|
||||
vp8_denoiser_free(denoiser);
|
||||
return 1;
|
||||
}
|
||||
memset(denoiser->yv12_last_source.buffer_alloc, 0,
|
||||
denoiser->yv12_last_source.frame_size);
|
||||
|
||||
denoiser->denoise_state = vpx_calloc((num_mb_rows * num_mb_cols), 1);
|
||||
if (!denoiser->denoise_state) {
|
||||
vp8_denoiser_free(denoiser);
|
||||
return 1;
|
||||
}
|
||||
memset(denoiser->denoise_state, 0, (num_mb_rows * num_mb_cols));
|
||||
vp8_denoiser_set_parameters(denoiser, mode);
|
||||
denoiser->nmse_source_diff = 0;
|
||||
denoiser->nmse_source_diff_count = 0;
|
||||
denoiser->qp_avg = 0;
|
||||
// QP threshold below which we can go up to aggressive mode.
|
||||
denoiser->qp_threshold_up = 80;
|
||||
// QP threshold above which we can go back down to normal mode.
|
||||
// For now keep this second threshold high, so not used currently.
|
||||
denoiser->qp_threshold_down = 128;
|
||||
// Bitrate thresholds and noise metric (nmse) thresholds for switching to
|
||||
// aggressive mode.
|
||||
// TODO(marpan): Adjust thresholds, including effect on resolution.
|
||||
denoiser->bitrate_threshold = 400000; // (bits/sec).
|
||||
denoiser->threshold_aggressive_mode = 80;
|
||||
if (width * height > 1280 * 720) {
|
||||
denoiser->bitrate_threshold = 3000000;
|
||||
denoiser->threshold_aggressive_mode = 200;
|
||||
} else if (width * height > 960 * 540) {
|
||||
denoiser->bitrate_threshold = 1200000;
|
||||
denoiser->threshold_aggressive_mode = 120;
|
||||
} else if (width * height > 640 * 480) {
|
||||
denoiser->bitrate_threshold = 600000;
|
||||
denoiser->threshold_aggressive_mode = 100;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vp8_denoiser_free(VP8_DENOISER *denoiser) {
|
||||
int i;
|
||||
assert(denoiser);
|
||||
|
||||
for (i = 0; i < MAX_REF_FRAMES; ++i) {
|
||||
vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_running_avg[i]);
|
||||
}
|
||||
vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_mc_running_avg);
|
||||
vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_last_source);
|
||||
vpx_free(denoiser->denoise_state);
|
||||
}
|
||||
|
||||
void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, MACROBLOCK *x,
|
||||
unsigned int best_sse, unsigned int zero_mv_sse,
|
||||
int recon_yoffset, int recon_uvoffset,
|
||||
loop_filter_info_n *lfi_n, int mb_row, int mb_col,
|
||||
int block_index, int consec_zero_last)
|
||||
|
||||
{
|
||||
int mv_row;
|
||||
int mv_col;
|
||||
unsigned int motion_threshold;
|
||||
unsigned int motion_magnitude2;
|
||||
unsigned int sse_thresh;
|
||||
int sse_diff_thresh = 0;
|
||||
// Spatial loop filter: only applied selectively based on
|
||||
// temporal filter state of block relative to top/left neighbors.
|
||||
int apply_spatial_loop_filter = 1;
|
||||
MV_REFERENCE_FRAME frame = x->best_reference_frame;
|
||||
MV_REFERENCE_FRAME zero_frame = x->best_zeromv_reference_frame;
|
||||
|
||||
enum vp8_denoiser_decision decision = FILTER_BLOCK;
|
||||
enum vp8_denoiser_decision decision_u = COPY_BLOCK;
|
||||
enum vp8_denoiser_decision decision_v = COPY_BLOCK;
|
||||
|
||||
if (zero_frame) {
|
||||
YV12_BUFFER_CONFIG *src = &denoiser->yv12_running_avg[frame];
|
||||
YV12_BUFFER_CONFIG *dst = &denoiser->yv12_mc_running_avg;
|
||||
YV12_BUFFER_CONFIG saved_pre, saved_dst;
|
||||
MB_MODE_INFO saved_mbmi;
|
||||
MACROBLOCKD *filter_xd = &x->e_mbd;
|
||||
MB_MODE_INFO *mbmi = &filter_xd->mode_info_context->mbmi;
|
||||
int sse_diff = 0;
|
||||
// Bias on zero motion vector sse.
|
||||
const int zero_bias = denoiser->denoise_pars.denoise_mv_bias;
|
||||
zero_mv_sse = (unsigned int)((int64_t)zero_mv_sse * zero_bias / 100);
|
||||
sse_diff = (int)zero_mv_sse - (int)best_sse;
|
||||
|
||||
saved_mbmi = *mbmi;
|
||||
|
||||
/* Use the best MV for the compensation. */
|
||||
mbmi->ref_frame = x->best_reference_frame;
|
||||
mbmi->mode = x->best_sse_inter_mode;
|
||||
mbmi->mv = x->best_sse_mv;
|
||||
mbmi->need_to_clamp_mvs = x->need_to_clamp_best_mvs;
|
||||
mv_col = x->best_sse_mv.as_mv.col;
|
||||
mv_row = x->best_sse_mv.as_mv.row;
|
||||
// Bias to zero_mv if small amount of motion.
|
||||
// Note sse_diff_thresh is intialized to zero, so this ensures
|
||||
// we will always choose zero_mv for denoising if
|
||||
// zero_mv_see <= best_sse (i.e., sse_diff <= 0).
|
||||
if ((unsigned int)(mv_row * mv_row + mv_col * mv_col) <=
|
||||
NOISE_MOTION_THRESHOLD) {
|
||||
sse_diff_thresh = (int)SSE_DIFF_THRESHOLD;
|
||||
}
|
||||
|
||||
if (frame == INTRA_FRAME || sse_diff <= sse_diff_thresh) {
|
||||
/*
|
||||
* Handle intra blocks as referring to last frame with zero motion
|
||||
* and let the absolute pixel difference affect the filter factor.
|
||||
* Also consider small amount of motion as being random walk due
|
||||
* to noise, if it doesn't mean that we get a much bigger error.
|
||||
* Note that any changes to the mode info only affects the
|
||||
* denoising.
|
||||
*/
|
||||
x->denoise_zeromv = 1;
|
||||
mbmi->ref_frame = x->best_zeromv_reference_frame;
|
||||
|
||||
src = &denoiser->yv12_running_avg[zero_frame];
|
||||
|
||||
mbmi->mode = ZEROMV;
|
||||
mbmi->mv.as_int = 0;
|
||||
x->best_sse_inter_mode = ZEROMV;
|
||||
x->best_sse_mv.as_int = 0;
|
||||
best_sse = zero_mv_sse;
|
||||
}
|
||||
|
||||
mv_row = x->best_sse_mv.as_mv.row;
|
||||
mv_col = x->best_sse_mv.as_mv.col;
|
||||
motion_magnitude2 = mv_row * mv_row + mv_col * mv_col;
|
||||
motion_threshold =
|
||||
denoiser->denoise_pars.scale_motion_thresh * NOISE_MOTION_THRESHOLD;
|
||||
|
||||
if (motion_magnitude2 <
|
||||
denoiser->denoise_pars.scale_increase_filter * NOISE_MOTION_THRESHOLD) {
|
||||
x->increase_denoising = 1;
|
||||
}
|
||||
|
||||
sse_thresh = denoiser->denoise_pars.scale_sse_thresh * SSE_THRESHOLD;
|
||||
if (x->increase_denoising) {
|
||||
sse_thresh = denoiser->denoise_pars.scale_sse_thresh * SSE_THRESHOLD_HIGH;
|
||||
}
|
||||
|
||||
if (best_sse > sse_thresh || motion_magnitude2 > motion_threshold) {
|
||||
decision = COPY_BLOCK;
|
||||
}
|
||||
|
||||
// If block is considered skin, don't denoise if the block
|
||||
// (1) is selected as non-zero motion for current frame, or
|
||||
// (2) has not been selected as ZERO_LAST mode at least x past frames
|
||||
// in a row.
|
||||
// TODO(marpan): Parameter "x" should be varied with framerate.
|
||||
// In particualar, should be reduced for layers (base layer/LAST).
|
||||
if (x->is_skin && (consec_zero_last < 2 || motion_magnitude2 > 0)) {
|
||||
decision = COPY_BLOCK;
|
||||
}
|
||||
|
||||
if (decision == FILTER_BLOCK) {
|
||||
saved_pre = filter_xd->pre;
|
||||
saved_dst = filter_xd->dst;
|
||||
|
||||
/* Compensate the running average. */
|
||||
filter_xd->pre.y_buffer = src->y_buffer + recon_yoffset;
|
||||
filter_xd->pre.u_buffer = src->u_buffer + recon_uvoffset;
|
||||
filter_xd->pre.v_buffer = src->v_buffer + recon_uvoffset;
|
||||
/* Write the compensated running average to the destination buffer. */
|
||||
filter_xd->dst.y_buffer = dst->y_buffer + recon_yoffset;
|
||||
filter_xd->dst.u_buffer = dst->u_buffer + recon_uvoffset;
|
||||
filter_xd->dst.v_buffer = dst->v_buffer + recon_uvoffset;
|
||||
|
||||
if (!x->skip) {
|
||||
vp8_build_inter_predictors_mb(filter_xd);
|
||||
} else {
|
||||
vp8_build_inter16x16_predictors_mb(
|
||||
filter_xd, filter_xd->dst.y_buffer, filter_xd->dst.u_buffer,
|
||||
filter_xd->dst.v_buffer, filter_xd->dst.y_stride,
|
||||
filter_xd->dst.uv_stride);
|
||||
}
|
||||
filter_xd->pre = saved_pre;
|
||||
filter_xd->dst = saved_dst;
|
||||
*mbmi = saved_mbmi;
|
||||
}
|
||||
} else {
|
||||
// zero_frame should always be 1 for real-time mode, as the
|
||||
// ZEROMV mode is always checked, so we should never go into this branch.
|
||||
// If case ZEROMV is not checked, then we will force no denoise (COPY).
|
||||
decision = COPY_BLOCK;
|
||||
}
|
||||
|
||||
if (decision == FILTER_BLOCK) {
|
||||
unsigned char *mc_running_avg_y =
|
||||
denoiser->yv12_mc_running_avg.y_buffer + recon_yoffset;
|
||||
int mc_avg_y_stride = denoiser->yv12_mc_running_avg.y_stride;
|
||||
unsigned char *running_avg_y =
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset;
|
||||
int avg_y_stride = denoiser->yv12_running_avg[INTRA_FRAME].y_stride;
|
||||
|
||||
/* Filter. */
|
||||
decision = vp8_denoiser_filter(mc_running_avg_y, mc_avg_y_stride,
|
||||
running_avg_y, avg_y_stride, x->thismb, 16,
|
||||
motion_magnitude2, x->increase_denoising);
|
||||
denoiser->denoise_state[block_index] =
|
||||
motion_magnitude2 > 0 ? kFilterNonZeroMV : kFilterZeroMV;
|
||||
// Only denoise UV for zero motion, and if y channel was denoised.
|
||||
if (denoiser->denoiser_mode != kDenoiserOnYOnly && motion_magnitude2 == 0 &&
|
||||
decision == FILTER_BLOCK) {
|
||||
unsigned char *mc_running_avg_u =
|
||||
denoiser->yv12_mc_running_avg.u_buffer + recon_uvoffset;
|
||||
unsigned char *running_avg_u =
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].u_buffer + recon_uvoffset;
|
||||
unsigned char *mc_running_avg_v =
|
||||
denoiser->yv12_mc_running_avg.v_buffer + recon_uvoffset;
|
||||
unsigned char *running_avg_v =
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].v_buffer + recon_uvoffset;
|
||||
int mc_avg_uv_stride = denoiser->yv12_mc_running_avg.uv_stride;
|
||||
int avg_uv_stride = denoiser->yv12_running_avg[INTRA_FRAME].uv_stride;
|
||||
int signal_stride = x->block[16].src_stride;
|
||||
decision_u = vp8_denoiser_filter_uv(
|
||||
mc_running_avg_u, mc_avg_uv_stride, running_avg_u, avg_uv_stride,
|
||||
x->block[16].src + *x->block[16].base_src, signal_stride,
|
||||
motion_magnitude2, 0);
|
||||
decision_v = vp8_denoiser_filter_uv(
|
||||
mc_running_avg_v, mc_avg_uv_stride, running_avg_v, avg_uv_stride,
|
||||
x->block[20].src + *x->block[20].base_src, signal_stride,
|
||||
motion_magnitude2, 0);
|
||||
}
|
||||
}
|
||||
if (decision == COPY_BLOCK) {
|
||||
/* No filtering of this block; it differs too much from the predictor,
|
||||
* or the motion vector magnitude is considered too big.
|
||||
*/
|
||||
x->denoise_zeromv = 0;
|
||||
vp8_copy_mem16x16(
|
||||
x->thismb, 16,
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset,
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].y_stride);
|
||||
denoiser->denoise_state[block_index] = kNoFilter;
|
||||
}
|
||||
if (denoiser->denoiser_mode != kDenoiserOnYOnly) {
|
||||
if (decision_u == COPY_BLOCK) {
|
||||
vp8_copy_mem8x8(
|
||||
x->block[16].src + *x->block[16].base_src, x->block[16].src_stride,
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].u_buffer + recon_uvoffset,
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].uv_stride);
|
||||
}
|
||||
if (decision_v == COPY_BLOCK) {
|
||||
vp8_copy_mem8x8(
|
||||
x->block[20].src + *x->block[20].base_src, x->block[16].src_stride,
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].v_buffer + recon_uvoffset,
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].uv_stride);
|
||||
}
|
||||
}
|
||||
// Option to selectively deblock the denoised signal, for y channel only.
|
||||
if (apply_spatial_loop_filter) {
|
||||
loop_filter_info lfi;
|
||||
int apply_filter_col = 0;
|
||||
int apply_filter_row = 0;
|
||||
int apply_filter = 0;
|
||||
int y_stride = denoiser->yv12_running_avg[INTRA_FRAME].y_stride;
|
||||
int uv_stride = denoiser->yv12_running_avg[INTRA_FRAME].uv_stride;
|
||||
|
||||
// Fix filter level to some nominal value for now.
|
||||
int filter_level = 48;
|
||||
|
||||
int hev_index = lfi_n->hev_thr_lut[INTER_FRAME][filter_level];
|
||||
lfi.mblim = lfi_n->mblim[filter_level];
|
||||
lfi.blim = lfi_n->blim[filter_level];
|
||||
lfi.lim = lfi_n->lim[filter_level];
|
||||
lfi.hev_thr = lfi_n->hev_thr[hev_index];
|
||||
|
||||
// Apply filter if there is a difference in the denoiser filter state
|
||||
// between the current and left/top block, or if non-zero motion vector
|
||||
// is used for the motion-compensated filtering.
|
||||
if (mb_col > 0) {
|
||||
apply_filter_col =
|
||||
!((denoiser->denoise_state[block_index] ==
|
||||
denoiser->denoise_state[block_index - 1]) &&
|
||||
denoiser->denoise_state[block_index] != kFilterNonZeroMV);
|
||||
if (apply_filter_col) {
|
||||
// Filter left vertical edge.
|
||||
apply_filter = 1;
|
||||
vp8_loop_filter_mbv(
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset,
|
||||
NULL, NULL, y_stride, uv_stride, &lfi);
|
||||
}
|
||||
}
|
||||
if (mb_row > 0) {
|
||||
apply_filter_row =
|
||||
!((denoiser->denoise_state[block_index] ==
|
||||
denoiser->denoise_state[block_index - denoiser->num_mb_cols]) &&
|
||||
denoiser->denoise_state[block_index] != kFilterNonZeroMV);
|
||||
if (apply_filter_row) {
|
||||
// Filter top horizontal edge.
|
||||
apply_filter = 1;
|
||||
vp8_loop_filter_mbh(
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset,
|
||||
NULL, NULL, y_stride, uv_stride, &lfi);
|
||||
}
|
||||
}
|
||||
if (apply_filter) {
|
||||
// Update the signal block |x|. Pixel changes are only to top and/or
|
||||
// left boundary pixels: can we avoid full block copy here.
|
||||
vp8_copy_mem16x16(
|
||||
denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset,
|
||||
y_stride, x->thismb, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_DENOISING_H_
|
||||
#define VPX_VP8_ENCODER_DENOISING_H_
|
||||
|
||||
#include "block.h"
|
||||
#include "vp8/common/loopfilter.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SUM_DIFF_THRESHOLD 512
|
||||
#define SUM_DIFF_THRESHOLD_HIGH 600
|
||||
#define MOTION_MAGNITUDE_THRESHOLD (8 * 3)
|
||||
|
||||
#define SUM_DIFF_THRESHOLD_UV (96) // (8 * 8 * 1.5)
|
||||
#define SUM_DIFF_THRESHOLD_HIGH_UV (8 * 8 * 2)
|
||||
#define SUM_DIFF_FROM_AVG_THRESH_UV (8 * 8 * 8)
|
||||
#define MOTION_MAGNITUDE_THRESHOLD_UV (8 * 3)
|
||||
|
||||
#define MAX_GF_ARF_DENOISE_RANGE (8)
|
||||
|
||||
enum vp8_denoiser_decision { COPY_BLOCK, FILTER_BLOCK };
|
||||
|
||||
enum vp8_denoiser_filter_state { kNoFilter, kFilterZeroMV, kFilterNonZeroMV };
|
||||
|
||||
enum vp8_denoiser_mode {
|
||||
kDenoiserOff,
|
||||
kDenoiserOnYOnly,
|
||||
kDenoiserOnYUV,
|
||||
kDenoiserOnYUVAggressive,
|
||||
kDenoiserOnAdaptive
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
// Scale factor on sse threshold above which no denoising is done.
|
||||
unsigned int scale_sse_thresh;
|
||||
// Scale factor on motion magnitude threshold above which no
|
||||
// denoising is done.
|
||||
unsigned int scale_motion_thresh;
|
||||
// Scale factor on motion magnitude below which we increase the strength of
|
||||
// the temporal filter (in function vp8_denoiser_filter).
|
||||
unsigned int scale_increase_filter;
|
||||
// Scale factor to bias to ZEROMV for denoising.
|
||||
unsigned int denoise_mv_bias;
|
||||
// Scale factor to bias to ZEROMV for coding mode selection.
|
||||
unsigned int pickmode_mv_bias;
|
||||
// Quantizer threshold below which we use the segmentation map to switch off
|
||||
// loop filter for blocks that have been coded as ZEROMV-LAST a certain number
|
||||
// (consec_zerolast) of consecutive frames. Note that the delta-QP is set to
|
||||
// 0 when segmentation map is used for shutting off loop filter.
|
||||
unsigned int qp_thresh;
|
||||
// Threshold for number of consecutive frames for blocks coded as ZEROMV-LAST.
|
||||
unsigned int consec_zerolast;
|
||||
// Threshold for amount of spatial blur on Y channel. 0 means no spatial blur.
|
||||
unsigned int spatial_blur;
|
||||
} denoise_params;
|
||||
|
||||
typedef struct vp8_denoiser {
|
||||
YV12_BUFFER_CONFIG yv12_running_avg[MAX_REF_FRAMES];
|
||||
YV12_BUFFER_CONFIG yv12_mc_running_avg;
|
||||
// TODO(marpan): Should remove yv12_last_source and use vp8_lookahead_peak.
|
||||
YV12_BUFFER_CONFIG yv12_last_source;
|
||||
unsigned char *denoise_state;
|
||||
int num_mb_cols;
|
||||
int denoiser_mode;
|
||||
int threshold_aggressive_mode;
|
||||
int nmse_source_diff;
|
||||
int nmse_source_diff_count;
|
||||
int qp_avg;
|
||||
int qp_threshold_up;
|
||||
int qp_threshold_down;
|
||||
int bitrate_threshold;
|
||||
denoise_params denoise_pars;
|
||||
} VP8_DENOISER;
|
||||
|
||||
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height,
|
||||
int num_mb_rows, int num_mb_cols, int mode);
|
||||
|
||||
void vp8_denoiser_free(VP8_DENOISER *denoiser);
|
||||
|
||||
void vp8_denoiser_set_parameters(VP8_DENOISER *denoiser, int mode);
|
||||
|
||||
void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, MACROBLOCK *x,
|
||||
unsigned int best_sse, unsigned int zero_mv_sse,
|
||||
int recon_yoffset, int recon_uvoffset,
|
||||
loop_filter_info_n *lfi_n, int mb_row, int mb_col,
|
||||
int block_index, int consec_zero_last);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_DENOISING_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef VPX_VP8_ENCODER_ENCODEFRAME_H_
|
||||
#define VPX_VP8_ENCODER_ENCODEFRAME_H_
|
||||
|
||||
#include "vp8/encoder/tokenize.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct VP8_COMP;
|
||||
struct macroblock;
|
||||
|
||||
void vp8_activity_masking(struct VP8_COMP *cpi, MACROBLOCK *x);
|
||||
|
||||
void vp8_build_block_offsets(struct macroblock *x);
|
||||
|
||||
void vp8_setup_block_ptrs(struct macroblock *x);
|
||||
|
||||
void vp8_encode_frame(struct VP8_COMP *cpi);
|
||||
|
||||
int vp8cx_encode_inter_macroblock(struct VP8_COMP *cpi, struct macroblock *x,
|
||||
TOKENEXTRA **t, int recon_yoffset,
|
||||
int recon_uvoffset, int mb_row, int mb_col);
|
||||
|
||||
int vp8cx_encode_intra_macroblock(struct VP8_COMP *cpi, struct macroblock *x,
|
||||
TOKENEXTRA **t);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_ENCODEFRAME_H_
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include "vpx_config.h"
|
||||
#include "vp8_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vp8/encoder/quantize.h"
|
||||
#include "vp8/common/reconintra.h"
|
||||
#include "vp8/common/reconintra4x4.h"
|
||||
#include "encodemb.h"
|
||||
#include "vp8/common/invtrans.h"
|
||||
#include "encodeintra.h"
|
||||
|
||||
int vp8_encode_intra(VP8_COMP *cpi, MACROBLOCK *x, int use_dc_pred) {
|
||||
int i;
|
||||
int intra_pred_var = 0;
|
||||
(void)cpi;
|
||||
|
||||
if (use_dc_pred) {
|
||||
x->e_mbd.mode_info_context->mbmi.mode = DC_PRED;
|
||||
x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
|
||||
x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
|
||||
|
||||
vp8_encode_intra16x16mby(x);
|
||||
|
||||
vp8_inverse_transform_mby(&x->e_mbd);
|
||||
} else {
|
||||
for (i = 0; i < 16; ++i) {
|
||||
x->e_mbd.block[i].bmi.as_mode = B_DC_PRED;
|
||||
vp8_encode_intra4x4block(x, i);
|
||||
}
|
||||
}
|
||||
|
||||
intra_pred_var = vpx_get_mb_ss(x->src_diff);
|
||||
|
||||
return intra_pred_var;
|
||||
}
|
||||
|
||||
void vp8_encode_intra4x4block(MACROBLOCK *x, int ib) {
|
||||
BLOCKD *b = &x->e_mbd.block[ib];
|
||||
BLOCK *be = &x->block[ib];
|
||||
int dst_stride = x->e_mbd.dst.y_stride;
|
||||
unsigned char *dst = x->e_mbd.dst.y_buffer + b->offset;
|
||||
unsigned char *Above = dst - dst_stride;
|
||||
unsigned char *yleft = dst - 1;
|
||||
unsigned char top_left = Above[-1];
|
||||
|
||||
vp8_intra4x4_predict(Above, yleft, dst_stride, b->bmi.as_mode, b->predictor,
|
||||
16, top_left);
|
||||
|
||||
vp8_subtract_b(be, b, 16);
|
||||
|
||||
x->short_fdct4x4(be->src_diff, be->coeff, 32);
|
||||
|
||||
x->quantize_b(be, b);
|
||||
|
||||
if (*b->eob > 1) {
|
||||
vp8_short_idct4x4llm(b->dqcoeff, b->predictor, 16, dst, dst_stride);
|
||||
} else {
|
||||
vp8_dc_only_idct_add(b->dqcoeff[0], b->predictor, 16, dst, dst_stride);
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_encode_intra4x4mby(MACROBLOCK *mb) {
|
||||
int i;
|
||||
|
||||
MACROBLOCKD *xd = &mb->e_mbd;
|
||||
intra_prediction_down_copy(xd, xd->dst.y_buffer - xd->dst.y_stride + 16);
|
||||
|
||||
for (i = 0; i < 16; ++i) vp8_encode_intra4x4block(mb, i);
|
||||
return;
|
||||
}
|
||||
|
||||
void vp8_encode_intra16x16mby(MACROBLOCK *x) {
|
||||
BLOCK *b = &x->block[0];
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
|
||||
vp8_build_intra_predictors_mby_s(xd, xd->dst.y_buffer - xd->dst.y_stride,
|
||||
xd->dst.y_buffer - 1, xd->dst.y_stride,
|
||||
xd->dst.y_buffer, xd->dst.y_stride);
|
||||
|
||||
vp8_subtract_mby(x->src_diff, *(b->base_src), b->src_stride, xd->dst.y_buffer,
|
||||
xd->dst.y_stride);
|
||||
|
||||
vp8_transform_intra_mby(x);
|
||||
|
||||
vp8_quantize_mby(x);
|
||||
|
||||
if (x->optimize) vp8_optimize_mby(x);
|
||||
}
|
||||
|
||||
void vp8_encode_intra16x16mbuv(MACROBLOCK *x) {
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
|
||||
vp8_build_intra_predictors_mbuv_s(xd, xd->dst.u_buffer - xd->dst.uv_stride,
|
||||
xd->dst.v_buffer - xd->dst.uv_stride,
|
||||
xd->dst.u_buffer - 1, xd->dst.v_buffer - 1,
|
||||
xd->dst.uv_stride, xd->dst.u_buffer,
|
||||
xd->dst.v_buffer, xd->dst.uv_stride);
|
||||
|
||||
vp8_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
|
||||
x->src.uv_stride, xd->dst.u_buffer, xd->dst.v_buffer,
|
||||
xd->dst.uv_stride);
|
||||
|
||||
vp8_transform_mbuv(x);
|
||||
|
||||
vp8_quantize_mbuv(x);
|
||||
|
||||
if (x->optimize) vp8_optimize_mbuv(x);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_ENCODEINTRA_H_
|
||||
#define VPX_VP8_ENCODER_ENCODEINTRA_H_
|
||||
#include "onyx_int.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int vp8_encode_intra(VP8_COMP *cpi, MACROBLOCK *x, int use_dc_pred);
|
||||
void vp8_encode_intra16x16mby(MACROBLOCK *x);
|
||||
void vp8_encode_intra16x16mbuv(MACROBLOCK *x);
|
||||
void vp8_encode_intra4x4mby(MACROBLOCK *mb);
|
||||
void vp8_encode_intra4x4block(MACROBLOCK *x, int ib);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_ENCODEINTRA_H_
|
||||
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
|
||||
#include "vpx_config.h"
|
||||
#include "vp8_rtcd.h"
|
||||
#include "encodemb.h"
|
||||
#include "vp8/common/reconinter.h"
|
||||
#include "vp8/encoder/quantize.h"
|
||||
#include "tokenize.h"
|
||||
#include "vp8/common/invtrans.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "rdopt.h"
|
||||
|
||||
void vp8_subtract_b(BLOCK *be, BLOCKD *bd, int pitch) {
|
||||
unsigned char *src_ptr = (*(be->base_src) + be->src);
|
||||
short *diff_ptr = be->src_diff;
|
||||
unsigned char *pred_ptr = bd->predictor;
|
||||
int src_stride = be->src_stride;
|
||||
|
||||
vpx_subtract_block(4, 4, diff_ptr, pitch, src_ptr, src_stride, pred_ptr,
|
||||
pitch);
|
||||
}
|
||||
|
||||
void vp8_subtract_mbuv(short *diff, unsigned char *usrc, unsigned char *vsrc,
|
||||
int src_stride, unsigned char *upred,
|
||||
unsigned char *vpred, int pred_stride) {
|
||||
short *udiff = diff + 256;
|
||||
short *vdiff = diff + 320;
|
||||
|
||||
vpx_subtract_block(8, 8, udiff, 8, usrc, src_stride, upred, pred_stride);
|
||||
vpx_subtract_block(8, 8, vdiff, 8, vsrc, src_stride, vpred, pred_stride);
|
||||
}
|
||||
|
||||
void vp8_subtract_mby(short *diff, unsigned char *src, int src_stride,
|
||||
unsigned char *pred, int pred_stride) {
|
||||
vpx_subtract_block(16, 16, diff, 16, src, src_stride, pred, pred_stride);
|
||||
}
|
||||
|
||||
static void vp8_subtract_mb(MACROBLOCK *x) {
|
||||
BLOCK *b = &x->block[0];
|
||||
|
||||
vp8_subtract_mby(x->src_diff, *(b->base_src), b->src_stride,
|
||||
x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride);
|
||||
vp8_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
|
||||
x->src.uv_stride, x->e_mbd.dst.u_buffer,
|
||||
x->e_mbd.dst.v_buffer, x->e_mbd.dst.uv_stride);
|
||||
}
|
||||
|
||||
static void build_dcblock(MACROBLOCK *x) {
|
||||
short *src_diff_ptr = &x->src_diff[384];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
src_diff_ptr[i] = x->coeff[i * 16];
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_transform_mbuv(MACROBLOCK *x) {
|
||||
int i;
|
||||
|
||||
for (i = 16; i < 24; i += 2) {
|
||||
x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16);
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_transform_intra_mby(MACROBLOCK *x) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
|
||||
}
|
||||
|
||||
/* build dc block from 16 y dc values */
|
||||
build_dcblock(x);
|
||||
|
||||
/* do 2nd order transform on the dc block */
|
||||
x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
|
||||
}
|
||||
|
||||
static void transform_mb(MACROBLOCK *x) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
|
||||
}
|
||||
|
||||
/* build dc block from 16 y dc values */
|
||||
if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) build_dcblock(x);
|
||||
|
||||
for (i = 16; i < 24; i += 2) {
|
||||
x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16);
|
||||
}
|
||||
|
||||
/* do 2nd order transform on the dc block */
|
||||
if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) {
|
||||
x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
|
||||
}
|
||||
}
|
||||
|
||||
static void transform_mby(MACROBLOCK *x) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
|
||||
}
|
||||
|
||||
/* build dc block from 16 y dc values */
|
||||
if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) {
|
||||
build_dcblock(x);
|
||||
x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
|
||||
}
|
||||
}
|
||||
|
||||
#define RDTRUNC(RM, DM, R, D) ((128 + (R) * (RM)) & 0xFF)
|
||||
|
||||
typedef struct vp8_token_state vp8_token_state;
|
||||
|
||||
struct vp8_token_state {
|
||||
int rate;
|
||||
int error;
|
||||
signed char next;
|
||||
signed char token;
|
||||
short qc;
|
||||
};
|
||||
|
||||
/* TODO: experiments to find optimal multiple numbers */
|
||||
#define Y1_RD_MULT 4
|
||||
#define UV_RD_MULT 2
|
||||
#define Y2_RD_MULT 16
|
||||
|
||||
static const int plane_rd_mult[4] = { Y1_RD_MULT, Y2_RD_MULT, UV_RD_MULT,
|
||||
Y1_RD_MULT };
|
||||
|
||||
static void optimize_b(MACROBLOCK *mb, int ib, int type, ENTROPY_CONTEXT *a,
|
||||
ENTROPY_CONTEXT *l) {
|
||||
BLOCK *b;
|
||||
BLOCKD *d;
|
||||
vp8_token_state tokens[17][2];
|
||||
unsigned best_mask[2];
|
||||
const short *dequant_ptr;
|
||||
const short *coeff_ptr;
|
||||
short *qcoeff_ptr;
|
||||
short *dqcoeff_ptr;
|
||||
int eob;
|
||||
int i0;
|
||||
int rc;
|
||||
int x;
|
||||
int sz = 0;
|
||||
int next;
|
||||
int rdmult;
|
||||
int rddiv;
|
||||
int final_eob;
|
||||
int rd_cost0;
|
||||
int rd_cost1;
|
||||
int rate0;
|
||||
int rate1;
|
||||
int error0;
|
||||
int error1;
|
||||
int t0;
|
||||
int t1;
|
||||
int best;
|
||||
int band;
|
||||
int pt;
|
||||
int i;
|
||||
int err_mult = plane_rd_mult[type];
|
||||
|
||||
b = &mb->block[ib];
|
||||
d = &mb->e_mbd.block[ib];
|
||||
|
||||
dequant_ptr = d->dequant;
|
||||
coeff_ptr = b->coeff;
|
||||
qcoeff_ptr = d->qcoeff;
|
||||
dqcoeff_ptr = d->dqcoeff;
|
||||
i0 = !type;
|
||||
eob = *d->eob;
|
||||
|
||||
/* Now set up a Viterbi trellis to evaluate alternative roundings. */
|
||||
rdmult = mb->rdmult * err_mult;
|
||||
if (mb->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
|
||||
rdmult = (rdmult * 9) >> 4;
|
||||
}
|
||||
|
||||
rddiv = mb->rddiv;
|
||||
best_mask[0] = best_mask[1] = 0;
|
||||
/* Initialize the sentinel node of the trellis. */
|
||||
tokens[eob][0].rate = 0;
|
||||
tokens[eob][0].error = 0;
|
||||
tokens[eob][0].next = 16;
|
||||
tokens[eob][0].token = DCT_EOB_TOKEN;
|
||||
tokens[eob][0].qc = 0;
|
||||
*(tokens[eob] + 1) = *(tokens[eob] + 0);
|
||||
next = eob;
|
||||
for (i = eob; i-- > i0;) {
|
||||
int base_bits;
|
||||
int d2;
|
||||
int dx;
|
||||
|
||||
rc = vp8_default_zig_zag1d[i];
|
||||
x = qcoeff_ptr[rc];
|
||||
/* Only add a trellis state for non-zero coefficients. */
|
||||
if (x) {
|
||||
int shortcut = 0;
|
||||
error0 = tokens[next][0].error;
|
||||
error1 = tokens[next][1].error;
|
||||
/* Evaluate the first possibility for this state. */
|
||||
rate0 = tokens[next][0].rate;
|
||||
rate1 = tokens[next][1].rate;
|
||||
t0 = (vp8_dct_value_tokens_ptr + x)->Token;
|
||||
/* Consider both possible successor states. */
|
||||
if (next < 16) {
|
||||
band = vp8_coef_bands[i + 1];
|
||||
pt = vp8_prev_token_class[t0];
|
||||
rate0 += mb->token_costs[type][band][pt][tokens[next][0].token];
|
||||
rate1 += mb->token_costs[type][band][pt][tokens[next][1].token];
|
||||
}
|
||||
rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
|
||||
rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
|
||||
if (rd_cost0 == rd_cost1) {
|
||||
rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
|
||||
rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
|
||||
}
|
||||
/* And pick the best. */
|
||||
best = rd_cost1 < rd_cost0;
|
||||
base_bits = *(vp8_dct_value_cost_ptr + x);
|
||||
dx = dqcoeff_ptr[rc] - coeff_ptr[rc];
|
||||
d2 = dx * dx;
|
||||
tokens[i][0].rate = base_bits + (best ? rate1 : rate0);
|
||||
tokens[i][0].error = d2 + (best ? error1 : error0);
|
||||
tokens[i][0].next = next;
|
||||
tokens[i][0].token = t0;
|
||||
tokens[i][0].qc = x;
|
||||
best_mask[0] |= best << i;
|
||||
/* Evaluate the second possibility for this state. */
|
||||
rate0 = tokens[next][0].rate;
|
||||
rate1 = tokens[next][1].rate;
|
||||
|
||||
if ((abs(x) * dequant_ptr[rc] > abs(coeff_ptr[rc])) &&
|
||||
(abs(x) * dequant_ptr[rc] < abs(coeff_ptr[rc]) + dequant_ptr[rc])) {
|
||||
shortcut = 1;
|
||||
} else {
|
||||
shortcut = 0;
|
||||
}
|
||||
|
||||
if (shortcut) {
|
||||
sz = -(x < 0);
|
||||
x -= 2 * sz + 1;
|
||||
}
|
||||
|
||||
/* Consider both possible successor states. */
|
||||
if (!x) {
|
||||
/* If we reduced this coefficient to zero, check to see if
|
||||
* we need to move the EOB back here.
|
||||
*/
|
||||
t0 =
|
||||
tokens[next][0].token == DCT_EOB_TOKEN ? DCT_EOB_TOKEN : ZERO_TOKEN;
|
||||
t1 =
|
||||
tokens[next][1].token == DCT_EOB_TOKEN ? DCT_EOB_TOKEN : ZERO_TOKEN;
|
||||
} else {
|
||||
t0 = t1 = (vp8_dct_value_tokens_ptr + x)->Token;
|
||||
}
|
||||
if (next < 16) {
|
||||
band = vp8_coef_bands[i + 1];
|
||||
if (t0 != DCT_EOB_TOKEN) {
|
||||
pt = vp8_prev_token_class[t0];
|
||||
rate0 += mb->token_costs[type][band][pt][tokens[next][0].token];
|
||||
}
|
||||
if (t1 != DCT_EOB_TOKEN) {
|
||||
pt = vp8_prev_token_class[t1];
|
||||
rate1 += mb->token_costs[type][band][pt][tokens[next][1].token];
|
||||
}
|
||||
}
|
||||
|
||||
rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
|
||||
rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
|
||||
if (rd_cost0 == rd_cost1) {
|
||||
rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
|
||||
rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
|
||||
}
|
||||
/* And pick the best. */
|
||||
best = rd_cost1 < rd_cost0;
|
||||
base_bits = *(vp8_dct_value_cost_ptr + x);
|
||||
|
||||
if (shortcut) {
|
||||
dx -= (dequant_ptr[rc] + sz) ^ sz;
|
||||
d2 = dx * dx;
|
||||
}
|
||||
tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
|
||||
tokens[i][1].error = d2 + (best ? error1 : error0);
|
||||
tokens[i][1].next = next;
|
||||
tokens[i][1].token = best ? t1 : t0;
|
||||
tokens[i][1].qc = x;
|
||||
best_mask[1] |= best << i;
|
||||
/* Finally, make this the new head of the trellis. */
|
||||
next = i;
|
||||
}
|
||||
/* There's no choice to make for a zero coefficient, so we don't
|
||||
* add a new trellis node, but we do need to update the costs.
|
||||
*/
|
||||
else {
|
||||
band = vp8_coef_bands[i + 1];
|
||||
t0 = tokens[next][0].token;
|
||||
t1 = tokens[next][1].token;
|
||||
/* Update the cost of each path if we're past the EOB token. */
|
||||
if (t0 != DCT_EOB_TOKEN) {
|
||||
tokens[next][0].rate += mb->token_costs[type][band][0][t0];
|
||||
tokens[next][0].token = ZERO_TOKEN;
|
||||
}
|
||||
if (t1 != DCT_EOB_TOKEN) {
|
||||
tokens[next][1].rate += mb->token_costs[type][band][0][t1];
|
||||
tokens[next][1].token = ZERO_TOKEN;
|
||||
}
|
||||
/* Don't update next, because we didn't add a new node. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Now pick the best path through the whole trellis. */
|
||||
band = vp8_coef_bands[i + 1];
|
||||
VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
|
||||
rate0 = tokens[next][0].rate;
|
||||
rate1 = tokens[next][1].rate;
|
||||
error0 = tokens[next][0].error;
|
||||
error1 = tokens[next][1].error;
|
||||
t0 = tokens[next][0].token;
|
||||
t1 = tokens[next][1].token;
|
||||
rate0 += mb->token_costs[type][band][pt][t0];
|
||||
rate1 += mb->token_costs[type][band][pt][t1];
|
||||
rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
|
||||
rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
|
||||
if (rd_cost0 == rd_cost1) {
|
||||
rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
|
||||
rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
|
||||
}
|
||||
best = rd_cost1 < rd_cost0;
|
||||
final_eob = i0 - 1;
|
||||
for (i = next; i < eob; i = next) {
|
||||
x = tokens[i][best].qc;
|
||||
if (x) final_eob = i;
|
||||
rc = vp8_default_zig_zag1d[i];
|
||||
qcoeff_ptr[rc] = x;
|
||||
dqcoeff_ptr[rc] = x * dequant_ptr[rc];
|
||||
next = tokens[i][best].next;
|
||||
best = (best_mask[best] >> i) & 1;
|
||||
}
|
||||
final_eob++;
|
||||
|
||||
*a = *l = (final_eob != !type);
|
||||
*d->eob = (char)final_eob;
|
||||
}
|
||||
static void check_reset_2nd_coeffs(MACROBLOCKD *x, int type, ENTROPY_CONTEXT *a,
|
||||
ENTROPY_CONTEXT *l) {
|
||||
int sum = 0;
|
||||
int i;
|
||||
BLOCKD *bd = &x->block[24];
|
||||
|
||||
if (bd->dequant[0] >= 35 && bd->dequant[1] >= 35) return;
|
||||
|
||||
for (i = 0; i < (*bd->eob); ++i) {
|
||||
int coef = bd->dqcoeff[vp8_default_zig_zag1d[i]];
|
||||
sum += (coef >= 0) ? coef : -coef;
|
||||
if (sum >= 35) return;
|
||||
}
|
||||
/**************************************************************************
|
||||
our inverse hadamard transform effectively is weighted sum of all 16 inputs
|
||||
with weight either 1 or -1. It has a last stage scaling of (sum+3)>>3. And
|
||||
dc only idct is (dc+4)>>3. So if all the sums are between -35 and 29, the
|
||||
output after inverse wht and idct will be all zero. A sum of absolute value
|
||||
smaller than 35 guarantees all 16 different (+1/-1) weighted sums in wht
|
||||
fall between -35 and +35.
|
||||
**************************************************************************/
|
||||
if (sum < 35) {
|
||||
for (i = 0; i < (*bd->eob); ++i) {
|
||||
int rc = vp8_default_zig_zag1d[i];
|
||||
bd->qcoeff[rc] = 0;
|
||||
bd->dqcoeff[rc] = 0;
|
||||
}
|
||||
*bd->eob = 0;
|
||||
*a = *l = (*bd->eob != !type);
|
||||
}
|
||||
}
|
||||
|
||||
static void optimize_mb(MACROBLOCK *x) {
|
||||
int b;
|
||||
int type;
|
||||
int has_2nd_order;
|
||||
|
||||
ENTROPY_CONTEXT_PLANES t_above, t_left;
|
||||
ENTROPY_CONTEXT *ta;
|
||||
ENTROPY_CONTEXT *tl;
|
||||
|
||||
memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
|
||||
ta = (ENTROPY_CONTEXT *)&t_above;
|
||||
tl = (ENTROPY_CONTEXT *)&t_left;
|
||||
|
||||
has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&
|
||||
x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
|
||||
type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
|
||||
|
||||
for (b = 0; b < 16; ++b) {
|
||||
optimize_b(x, b, type, ta + vp8_block2above[b], tl + vp8_block2left[b]);
|
||||
}
|
||||
|
||||
for (b = 16; b < 24; ++b) {
|
||||
optimize_b(x, b, PLANE_TYPE_UV, ta + vp8_block2above[b],
|
||||
tl + vp8_block2left[b]);
|
||||
}
|
||||
|
||||
if (has_2nd_order) {
|
||||
b = 24;
|
||||
optimize_b(x, b, PLANE_TYPE_Y2, ta + vp8_block2above[b],
|
||||
tl + vp8_block2left[b]);
|
||||
check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2, ta + vp8_block2above[b],
|
||||
tl + vp8_block2left[b]);
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_optimize_mby(MACROBLOCK *x) {
|
||||
int b;
|
||||
int type;
|
||||
int has_2nd_order;
|
||||
|
||||
ENTROPY_CONTEXT_PLANES t_above, t_left;
|
||||
ENTROPY_CONTEXT *ta;
|
||||
ENTROPY_CONTEXT *tl;
|
||||
|
||||
if (!x->e_mbd.above_context) return;
|
||||
|
||||
if (!x->e_mbd.left_context) return;
|
||||
|
||||
memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
|
||||
ta = (ENTROPY_CONTEXT *)&t_above;
|
||||
tl = (ENTROPY_CONTEXT *)&t_left;
|
||||
|
||||
has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&
|
||||
x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
|
||||
type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
|
||||
|
||||
for (b = 0; b < 16; ++b) {
|
||||
optimize_b(x, b, type, ta + vp8_block2above[b], tl + vp8_block2left[b]);
|
||||
}
|
||||
|
||||
if (has_2nd_order) {
|
||||
b = 24;
|
||||
optimize_b(x, b, PLANE_TYPE_Y2, ta + vp8_block2above[b],
|
||||
tl + vp8_block2left[b]);
|
||||
check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2, ta + vp8_block2above[b],
|
||||
tl + vp8_block2left[b]);
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_optimize_mbuv(MACROBLOCK *x) {
|
||||
int b;
|
||||
ENTROPY_CONTEXT_PLANES t_above, t_left;
|
||||
ENTROPY_CONTEXT *ta;
|
||||
ENTROPY_CONTEXT *tl;
|
||||
|
||||
if (!x->e_mbd.above_context) return;
|
||||
|
||||
if (!x->e_mbd.left_context) return;
|
||||
|
||||
memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
|
||||
ta = (ENTROPY_CONTEXT *)&t_above;
|
||||
tl = (ENTROPY_CONTEXT *)&t_left;
|
||||
|
||||
for (b = 16; b < 24; ++b) {
|
||||
optimize_b(x, b, PLANE_TYPE_UV, ta + vp8_block2above[b],
|
||||
tl + vp8_block2left[b]);
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_encode_inter16x16(MACROBLOCK *x) {
|
||||
vp8_build_inter_predictors_mb(&x->e_mbd);
|
||||
|
||||
vp8_subtract_mb(x);
|
||||
|
||||
transform_mb(x);
|
||||
|
||||
vp8_quantize_mb(x);
|
||||
|
||||
if (x->optimize) optimize_mb(x);
|
||||
}
|
||||
|
||||
/* this funciton is used by first pass only */
|
||||
void vp8_encode_inter16x16y(MACROBLOCK *x) {
|
||||
BLOCK *b = &x->block[0];
|
||||
|
||||
vp8_build_inter16x16_predictors_mby(&x->e_mbd, x->e_mbd.dst.y_buffer,
|
||||
x->e_mbd.dst.y_stride);
|
||||
|
||||
vp8_subtract_mby(x->src_diff, *(b->base_src), b->src_stride,
|
||||
x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride);
|
||||
|
||||
transform_mby(x);
|
||||
|
||||
vp8_quantize_mby(x);
|
||||
|
||||
vp8_inverse_transform_mby(&x->e_mbd);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_ENCODEMB_H_
|
||||
#define VPX_VP8_ENCODER_ENCODEMB_H_
|
||||
|
||||
#include "onyx_int.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void vp8_encode_inter16x16(MACROBLOCK *x);
|
||||
|
||||
void vp8_subtract_b(BLOCK *be, BLOCKD *bd, int pitch);
|
||||
void vp8_subtract_mbuv(short *diff, unsigned char *usrc, unsigned char *vsrc,
|
||||
int src_stride, unsigned char *upred,
|
||||
unsigned char *vpred, int pred_stride);
|
||||
void vp8_subtract_mby(short *diff, unsigned char *src, int src_stride,
|
||||
unsigned char *pred, int pred_stride);
|
||||
|
||||
void vp8_build_dcblock(MACROBLOCK *b);
|
||||
void vp8_transform_mb(MACROBLOCK *mb);
|
||||
void vp8_transform_mbuv(MACROBLOCK *x);
|
||||
void vp8_transform_intra_mby(MACROBLOCK *x);
|
||||
|
||||
void vp8_optimize_mby(MACROBLOCK *x);
|
||||
void vp8_optimize_mbuv(MACROBLOCK *x);
|
||||
void vp8_encode_inter16x16y(MACROBLOCK *x);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_ENCODEMB_H_
|
||||
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include "vp8/common/common.h"
|
||||
#include "encodemv.h"
|
||||
#include "vp8/common/entropymode.h"
|
||||
#include "vp8/common/systemdependent.h"
|
||||
#include "vpx_ports/system_state.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
static void encode_mvcomponent(vp8_writer *const w, const int v,
|
||||
const struct mv_context *mvc) {
|
||||
const vp8_prob *p = mvc->prob;
|
||||
const int x = v < 0 ? -v : v;
|
||||
|
||||
if (x < mvnum_short) { /* Small */
|
||||
vp8_write(w, 0, p[mvpis_short]);
|
||||
vp8_treed_write(w, vp8_small_mvtree, p + MVPshort, x, 3);
|
||||
|
||||
if (!x) return; /* no sign bit */
|
||||
} else { /* Large */
|
||||
int i = 0;
|
||||
|
||||
vp8_write(w, 1, p[mvpis_short]);
|
||||
|
||||
do
|
||||
vp8_write(w, (x >> i) & 1, p[MVPbits + i]);
|
||||
|
||||
while (++i < 3);
|
||||
|
||||
i = mvlong_width - 1; /* Skip bit 3, which is sometimes implicit */
|
||||
|
||||
do
|
||||
vp8_write(w, (x >> i) & 1, p[MVPbits + i]);
|
||||
|
||||
while (--i > 3);
|
||||
|
||||
if (x & 0xFFF0) vp8_write(w, (x >> 3) & 1, p[MVPbits + 3]);
|
||||
}
|
||||
|
||||
vp8_write(w, v < 0, p[MVPsign]);
|
||||
}
|
||||
#if 0
|
||||
static int max_mv_r = 0;
|
||||
static int max_mv_c = 0;
|
||||
#endif
|
||||
void vp8_encode_motion_vector(vp8_writer *w, const MV *mv,
|
||||
const MV_CONTEXT *mvc) {
|
||||
#if 0
|
||||
{
|
||||
if (abs(mv->row >> 1) > max_mv_r)
|
||||
{
|
||||
FILE *f = fopen("maxmv.stt", "a");
|
||||
max_mv_r = abs(mv->row >> 1);
|
||||
fprintf(f, "New Mv Row Max %6d\n", (mv->row >> 1));
|
||||
|
||||
if ((abs(mv->row) / 2) != max_mv_r)
|
||||
fprintf(f, "MV Row conversion error %6d\n", abs(mv->row) / 2);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
if (abs(mv->col >> 1) > max_mv_c)
|
||||
{
|
||||
FILE *f = fopen("maxmv.stt", "a");
|
||||
fprintf(f, "New Mv Col Max %6d\n", (mv->col >> 1));
|
||||
max_mv_c = abs(mv->col >> 1);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
encode_mvcomponent(w, mv->row >> 1, &mvc[0]);
|
||||
encode_mvcomponent(w, mv->col >> 1, &mvc[1]);
|
||||
}
|
||||
|
||||
static unsigned int cost_mvcomponent(const int v,
|
||||
const struct mv_context *mvc) {
|
||||
const vp8_prob *p = mvc->prob;
|
||||
const int x = v;
|
||||
unsigned int cost;
|
||||
|
||||
if (x < mvnum_short) {
|
||||
cost = vp8_cost_zero(p[mvpis_short]) +
|
||||
vp8_treed_cost(vp8_small_mvtree, p + MVPshort, x, 3);
|
||||
|
||||
if (!x) return cost;
|
||||
} else {
|
||||
int i = 0;
|
||||
cost = vp8_cost_one(p[mvpis_short]);
|
||||
|
||||
do {
|
||||
cost += vp8_cost_bit(p[MVPbits + i], (x >> i) & 1);
|
||||
|
||||
} while (++i < 3);
|
||||
|
||||
i = mvlong_width - 1; /* Skip bit 3, which is sometimes implicit */
|
||||
|
||||
do {
|
||||
cost += vp8_cost_bit(p[MVPbits + i], (x >> i) & 1);
|
||||
|
||||
} while (--i > 3);
|
||||
|
||||
if (x & 0xFFF0) cost += vp8_cost_bit(p[MVPbits + 3], (x >> 3) & 1);
|
||||
}
|
||||
|
||||
return cost; /* + vp8_cost_bit( p [MVPsign], v < 0); */
|
||||
}
|
||||
|
||||
void vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc,
|
||||
int mvc_flag[2]) {
|
||||
int i = 1;
|
||||
unsigned int cost0 = 0;
|
||||
unsigned int cost1 = 0;
|
||||
|
||||
vpx_clear_system_state();
|
||||
|
||||
i = 1;
|
||||
|
||||
if (mvc_flag[0]) {
|
||||
mvcost[0][0] = cost_mvcomponent(0, &mvc[0]);
|
||||
|
||||
do {
|
||||
cost0 = cost_mvcomponent(i, &mvc[0]);
|
||||
|
||||
mvcost[0][i] = cost0 + vp8_cost_zero(mvc[0].prob[MVPsign]);
|
||||
mvcost[0][-i] = cost0 + vp8_cost_one(mvc[0].prob[MVPsign]);
|
||||
} while (++i <= mv_max);
|
||||
}
|
||||
|
||||
i = 1;
|
||||
|
||||
if (mvc_flag[1]) {
|
||||
mvcost[1][0] = cost_mvcomponent(0, &mvc[1]);
|
||||
|
||||
do {
|
||||
cost1 = cost_mvcomponent(i, &mvc[1]);
|
||||
|
||||
mvcost[1][i] = cost1 + vp8_cost_zero(mvc[1].prob[MVPsign]);
|
||||
mvcost[1][-i] = cost1 + vp8_cost_one(mvc[1].prob[MVPsign]);
|
||||
} while (++i <= mv_max);
|
||||
}
|
||||
}
|
||||
|
||||
/* Motion vector probability table update depends on benefit.
|
||||
* Small correction allows for the fact that an update to an MV probability
|
||||
* may have benefit in subsequent frames as well as the current one.
|
||||
*/
|
||||
#define MV_PROB_UPDATE_CORRECTION -1
|
||||
|
||||
static void calc_prob(vp8_prob *p, const unsigned int ct[2]) {
|
||||
const unsigned int tot = ct[0] + ct[1];
|
||||
|
||||
if (tot) {
|
||||
const vp8_prob x = ((ct[0] * 255) / tot) & -2;
|
||||
*p = x ? x : 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void update(vp8_writer *const w, const unsigned int ct[2],
|
||||
vp8_prob *const cur_p, const vp8_prob new_p,
|
||||
const vp8_prob update_p, int *updated) {
|
||||
const int cur_b = vp8_cost_branch(ct, *cur_p);
|
||||
const int new_b = vp8_cost_branch(ct, new_p);
|
||||
const int cost =
|
||||
7 + MV_PROB_UPDATE_CORRECTION +
|
||||
((vp8_cost_one(update_p) - vp8_cost_zero(update_p) + 128) >> 8);
|
||||
|
||||
if (cur_b - new_b > cost) {
|
||||
*cur_p = new_p;
|
||||
vp8_write(w, 1, update_p);
|
||||
vp8_write_literal(w, new_p >> 1, 7);
|
||||
*updated = 1;
|
||||
|
||||
} else
|
||||
vp8_write(w, 0, update_p);
|
||||
}
|
||||
|
||||
static void write_component_probs(vp8_writer *const w,
|
||||
struct mv_context *cur_mvc,
|
||||
const struct mv_context *default_mvc_,
|
||||
const struct mv_context *update_mvc,
|
||||
const unsigned int events[MVvals],
|
||||
unsigned int rc, int *updated) {
|
||||
vp8_prob *Pcur = cur_mvc->prob;
|
||||
const vp8_prob *default_mvc = default_mvc_->prob;
|
||||
const vp8_prob *Pupdate = update_mvc->prob;
|
||||
unsigned int is_short_ct[2], sign_ct[2];
|
||||
|
||||
unsigned int bit_ct[mvlong_width][2];
|
||||
|
||||
unsigned int short_ct[mvnum_short];
|
||||
unsigned int short_bct[mvnum_short - 1][2];
|
||||
|
||||
vp8_prob Pnew[MVPcount];
|
||||
|
||||
(void)rc;
|
||||
vp8_copy_array(Pnew, default_mvc, MVPcount);
|
||||
|
||||
vp8_zero(is_short_ct) vp8_zero(sign_ct) vp8_zero(bit_ct) vp8_zero(short_ct)
|
||||
vp8_zero(short_bct)
|
||||
|
||||
/* j=0 */
|
||||
{
|
||||
const int c = events[mv_max];
|
||||
|
||||
is_short_ct[0] += c; /* Short vector */
|
||||
short_ct[0] += c; /* Magnitude distribution */
|
||||
}
|
||||
|
||||
/* j: 1 ~ mv_max (1023) */
|
||||
{
|
||||
int j = 1;
|
||||
|
||||
do {
|
||||
const int c1 = events[mv_max + j]; /* positive */
|
||||
const int c2 = events[mv_max - j]; /* negative */
|
||||
const int c = c1 + c2;
|
||||
int a = j;
|
||||
|
||||
sign_ct[0] += c1;
|
||||
sign_ct[1] += c2;
|
||||
|
||||
if (a < mvnum_short) {
|
||||
is_short_ct[0] += c; /* Short vector */
|
||||
short_ct[a] += c; /* Magnitude distribution */
|
||||
} else {
|
||||
int k = mvlong_width - 1;
|
||||
is_short_ct[1] += c; /* Long vector */
|
||||
|
||||
/* bit 3 not always encoded. */
|
||||
do {
|
||||
bit_ct[k][(a >> k) & 1] += c;
|
||||
|
||||
} while (--k >= 0);
|
||||
}
|
||||
} while (++j <= mv_max);
|
||||
}
|
||||
|
||||
calc_prob(Pnew + mvpis_short, is_short_ct);
|
||||
|
||||
calc_prob(Pnew + MVPsign, sign_ct);
|
||||
|
||||
{
|
||||
vp8_prob p[mvnum_short - 1]; /* actually only need branch ct */
|
||||
int j = 0;
|
||||
|
||||
vp8_tree_probs_from_distribution(8, vp8_small_mvencodings, vp8_small_mvtree,
|
||||
p, short_bct, short_ct, 256, 1);
|
||||
|
||||
do {
|
||||
calc_prob(Pnew + MVPshort + j, short_bct[j]);
|
||||
|
||||
} while (++j < mvnum_short - 1);
|
||||
}
|
||||
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
do {
|
||||
calc_prob(Pnew + MVPbits + j, bit_ct[j]);
|
||||
|
||||
} while (++j < mvlong_width);
|
||||
}
|
||||
|
||||
update(w, is_short_ct, Pcur + mvpis_short, Pnew[mvpis_short], *Pupdate++,
|
||||
updated);
|
||||
|
||||
update(w, sign_ct, Pcur + MVPsign, Pnew[MVPsign], *Pupdate++, updated);
|
||||
|
||||
{
|
||||
const vp8_prob *const new_p = Pnew + MVPshort;
|
||||
vp8_prob *const cur_p = Pcur + MVPshort;
|
||||
|
||||
int j = 0;
|
||||
|
||||
do {
|
||||
update(w, short_bct[j], cur_p + j, new_p[j], *Pupdate++, updated);
|
||||
|
||||
} while (++j < mvnum_short - 1);
|
||||
}
|
||||
|
||||
{
|
||||
const vp8_prob *const new_p = Pnew + MVPbits;
|
||||
vp8_prob *const cur_p = Pcur + MVPbits;
|
||||
|
||||
int j = 0;
|
||||
|
||||
do {
|
||||
update(w, bit_ct[j], cur_p + j, new_p[j], *Pupdate++, updated);
|
||||
|
||||
} while (++j < mvlong_width);
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_write_mvprobs(VP8_COMP *cpi) {
|
||||
vp8_writer *const w = cpi->bc;
|
||||
MV_CONTEXT *mvc = cpi->common.fc.mvc;
|
||||
int flags[2] = { 0, 0 };
|
||||
write_component_probs(w, &mvc[0], &vp8_default_mv_context[0],
|
||||
&vp8_mv_update_probs[0], cpi->mb.MVcount[0], 0,
|
||||
&flags[0]);
|
||||
write_component_probs(w, &mvc[1], &vp8_default_mv_context[1],
|
||||
&vp8_mv_update_probs[1], cpi->mb.MVcount[1], 1,
|
||||
&flags[1]);
|
||||
|
||||
if (flags[0] || flags[1]) {
|
||||
vp8_build_component_cost_table(
|
||||
cpi->mb.mvcost, (const MV_CONTEXT *)cpi->common.fc.mvc, flags);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_ENCODEMV_H_
|
||||
#define VPX_VP8_ENCODER_ENCODEMV_H_
|
||||
|
||||
#include "onyx_int.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void vp8_write_mvprobs(VP8_COMP *);
|
||||
void vp8_encode_motion_vector(vp8_writer *, const MV *, const MV_CONTEXT *);
|
||||
void vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc,
|
||||
int mvc_flag[2]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_ENCODEMV_H_
|
||||
@@ -0,0 +1,639 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include "onyx_int.h"
|
||||
#include "vp8/common/threading.h"
|
||||
#include "vp8/common/common.h"
|
||||
#include "vp8/common/extend.h"
|
||||
#include "bitstream.h"
|
||||
#include "encodeframe.h"
|
||||
#include "ethreading.h"
|
||||
|
||||
#if CONFIG_MULTITHREAD
|
||||
|
||||
extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x,
|
||||
int ok_to_skip);
|
||||
|
||||
static THREAD_FUNCTION thread_loopfilter(void *p_data) {
|
||||
VP8_COMP *cpi = (VP8_COMP *)(((LPFTHREAD_DATA *)p_data)->ptr1);
|
||||
VP8_COMMON *cm = &cpi->common;
|
||||
|
||||
while (1) {
|
||||
if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) == 0) break;
|
||||
|
||||
if (sem_wait(&cpi->h_event_start_lpf) == 0) {
|
||||
/* we're shutting down */
|
||||
if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) == 0) break;
|
||||
|
||||
vp8_loopfilter_frame(cpi, cm);
|
||||
|
||||
sem_post(&cpi->h_event_end_lpf);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static THREAD_FUNCTION thread_encoding_proc(void *p_data) {
|
||||
int ithread = ((ENCODETHREAD_DATA *)p_data)->ithread;
|
||||
VP8_COMP *cpi = (VP8_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr1);
|
||||
MB_ROW_COMP *mbri = (MB_ROW_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr2);
|
||||
ENTROPY_CONTEXT_PLANES mb_row_left_context;
|
||||
|
||||
while (1) {
|
||||
if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) == 0) break;
|
||||
|
||||
if (sem_wait(&cpi->h_event_start_encoding[ithread]) == 0) {
|
||||
const int nsync = cpi->mt_sync_range;
|
||||
VP8_COMMON *cm = &cpi->common;
|
||||
int mb_row;
|
||||
MACROBLOCK *x = &mbri->mb;
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
TOKENEXTRA *tp;
|
||||
#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
|
||||
TOKENEXTRA *tp_start = cpi->tok + (1 + ithread) * (16 * 24);
|
||||
const int num_part = (1 << cm->multi_token_partition);
|
||||
#endif
|
||||
|
||||
int *segment_counts = mbri->segment_counts;
|
||||
int *totalrate = &mbri->totalrate;
|
||||
|
||||
/* we're shutting down */
|
||||
if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) == 0) break;
|
||||
|
||||
xd->mode_info_context = cm->mi + cm->mode_info_stride * (ithread + 1);
|
||||
xd->mode_info_stride = cm->mode_info_stride;
|
||||
|
||||
for (mb_row = ithread + 1; mb_row < cm->mb_rows;
|
||||
mb_row += (cpi->encoding_thread_count + 1)) {
|
||||
int recon_yoffset, recon_uvoffset;
|
||||
int mb_col;
|
||||
int ref_fb_idx = cm->lst_fb_idx;
|
||||
int dst_fb_idx = cm->new_fb_idx;
|
||||
int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
|
||||
int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
|
||||
int map_index = (mb_row * cm->mb_cols);
|
||||
const vpx_atomic_int *last_row_current_mb_col;
|
||||
vpx_atomic_int *current_mb_col = &cpi->mt_current_mb_col[mb_row];
|
||||
|
||||
#if (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
|
||||
vp8_writer *w = &cpi->bc[1 + (mb_row % num_part)];
|
||||
#else
|
||||
tp = cpi->tok + (mb_row * (cm->mb_cols * 16 * 24));
|
||||
cpi->tplist[mb_row].start = tp;
|
||||
#endif
|
||||
|
||||
last_row_current_mb_col = &cpi->mt_current_mb_col[mb_row - 1];
|
||||
|
||||
/* reset above block coeffs */
|
||||
xd->above_context = cm->above_context;
|
||||
xd->left_context = &mb_row_left_context;
|
||||
|
||||
vp8_zero(mb_row_left_context);
|
||||
|
||||
xd->up_available = (mb_row != 0);
|
||||
recon_yoffset = (mb_row * recon_y_stride * 16);
|
||||
recon_uvoffset = (mb_row * recon_uv_stride * 8);
|
||||
|
||||
/* Set the mb activity pointer to the start of the row. */
|
||||
x->mb_activity_ptr = &cpi->mb_activity_map[map_index];
|
||||
|
||||
/* for each macroblock col in image */
|
||||
for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
|
||||
if (((mb_col - 1) % nsync) == 0) {
|
||||
vpx_atomic_store_release(current_mb_col, mb_col - 1);
|
||||
}
|
||||
|
||||
if (mb_row && !(mb_col & (nsync - 1))) {
|
||||
vp8_atomic_spin_wait(mb_col, last_row_current_mb_col, nsync);
|
||||
}
|
||||
|
||||
#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
|
||||
tp = tp_start;
|
||||
#endif
|
||||
|
||||
/* Distance of Mb to the various image edges.
|
||||
* These specified to 8th pel as they are always compared
|
||||
* to values that are in 1/8th pel units
|
||||
*/
|
||||
xd->mb_to_left_edge = -((mb_col * 16) << 3);
|
||||
xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
|
||||
xd->mb_to_top_edge = -((mb_row * 16) << 3);
|
||||
xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
|
||||
|
||||
/* Set up limit values for motion vectors used to prevent
|
||||
* them extending outside the UMV borders
|
||||
*/
|
||||
x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
|
||||
x->mv_col_max =
|
||||
((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16);
|
||||
x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
|
||||
x->mv_row_max =
|
||||
((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16);
|
||||
|
||||
xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
|
||||
xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
|
||||
xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
|
||||
xd->left_available = (mb_col != 0);
|
||||
|
||||
x->rddiv = cpi->RDDIV;
|
||||
x->rdmult = cpi->RDMULT;
|
||||
|
||||
/* Copy current mb to a buffer */
|
||||
vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
|
||||
|
||||
if (cpi->oxcf.tuning == VP8_TUNE_SSIM) vp8_activity_masking(cpi, x);
|
||||
|
||||
/* Is segmentation enabled */
|
||||
/* MB level adjustment to quantizer */
|
||||
if (xd->segmentation_enabled) {
|
||||
/* Code to set segment id in xd->mbmi.segment_id for
|
||||
* current MB (with range checking)
|
||||
*/
|
||||
if (cpi->segmentation_map[map_index + mb_col] <= 3) {
|
||||
xd->mode_info_context->mbmi.segment_id =
|
||||
cpi->segmentation_map[map_index + mb_col];
|
||||
} else {
|
||||
xd->mode_info_context->mbmi.segment_id = 0;
|
||||
}
|
||||
|
||||
vp8cx_mb_init_quantizer(cpi, x, 1);
|
||||
} else {
|
||||
/* Set to Segment 0 by default */
|
||||
xd->mode_info_context->mbmi.segment_id = 0;
|
||||
}
|
||||
|
||||
x->active_ptr = cpi->active_map + map_index + mb_col;
|
||||
|
||||
if (cm->frame_type == KEY_FRAME) {
|
||||
*totalrate += vp8cx_encode_intra_macroblock(cpi, x, &tp);
|
||||
#ifdef MODE_STATS
|
||||
y_modes[xd->mbmi.mode]++;
|
||||
#endif
|
||||
} else {
|
||||
*totalrate += vp8cx_encode_inter_macroblock(
|
||||
cpi, x, &tp, recon_yoffset, recon_uvoffset, mb_row, mb_col);
|
||||
|
||||
#ifdef MODE_STATS
|
||||
inter_y_modes[xd->mbmi.mode]++;
|
||||
|
||||
if (xd->mbmi.mode == SPLITMV) {
|
||||
int b;
|
||||
|
||||
for (b = 0; b < xd->mbmi.partition_count; ++b) {
|
||||
inter_b_modes[x->partition->bmi[b].mode]++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
// Keep track of how many (consecutive) times a block
|
||||
// is coded as ZEROMV_LASTREF, for base layer frames.
|
||||
// Reset to 0 if its coded as anything else.
|
||||
if (cpi->current_layer == 0) {
|
||||
if (xd->mode_info_context->mbmi.mode == ZEROMV &&
|
||||
xd->mode_info_context->mbmi.ref_frame == LAST_FRAME) {
|
||||
// Increment, check for wrap-around.
|
||||
if (cpi->consec_zero_last[map_index + mb_col] < 255) {
|
||||
cpi->consec_zero_last[map_index + mb_col] += 1;
|
||||
}
|
||||
if (cpi->consec_zero_last_mvbias[map_index + mb_col] < 255) {
|
||||
cpi->consec_zero_last_mvbias[map_index + mb_col] += 1;
|
||||
}
|
||||
} else {
|
||||
cpi->consec_zero_last[map_index + mb_col] = 0;
|
||||
cpi->consec_zero_last_mvbias[map_index + mb_col] = 0;
|
||||
}
|
||||
if (x->zero_last_dot_suppress) {
|
||||
cpi->consec_zero_last_mvbias[map_index + mb_col] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Special case code for cyclic refresh
|
||||
* If cyclic update enabled then copy
|
||||
* xd->mbmi.segment_id; (which may have been updated
|
||||
* based on mode during
|
||||
* vp8cx_encode_inter_macroblock()) back into the
|
||||
* global segmentation map
|
||||
*/
|
||||
if ((cpi->current_layer == 0) &&
|
||||
(cpi->cyclic_refresh_mode_enabled &&
|
||||
xd->segmentation_enabled)) {
|
||||
const MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
|
||||
cpi->segmentation_map[map_index + mb_col] = mbmi->segment_id;
|
||||
|
||||
/* If the block has been refreshed mark it as clean
|
||||
* (the magnitude of the -ve influences how long it
|
||||
* will be before we consider another refresh):
|
||||
* Else if it was coded (last frame 0,0) and has
|
||||
* not already been refreshed then mark it as a
|
||||
* candidate for cleanup next time (marked 0) else
|
||||
* mark it as dirty (1).
|
||||
*/
|
||||
if (mbmi->segment_id) {
|
||||
cpi->cyclic_refresh_map[map_index + mb_col] = -1;
|
||||
} else if ((mbmi->mode == ZEROMV) &&
|
||||
(mbmi->ref_frame == LAST_FRAME)) {
|
||||
if (cpi->cyclic_refresh_map[map_index + mb_col] == 1) {
|
||||
cpi->cyclic_refresh_map[map_index + mb_col] = 0;
|
||||
}
|
||||
} else {
|
||||
cpi->cyclic_refresh_map[map_index + mb_col] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
|
||||
/* pack tokens for this MB */
|
||||
{
|
||||
int tok_count = tp - tp_start;
|
||||
vp8_pack_tokens(w, tp_start, tok_count);
|
||||
}
|
||||
#else
|
||||
cpi->tplist[mb_row].stop = tp;
|
||||
#endif
|
||||
/* Increment pointer into gf usage flags structure. */
|
||||
x->gf_active_ptr++;
|
||||
|
||||
/* Increment the activity mask pointers. */
|
||||
x->mb_activity_ptr++;
|
||||
|
||||
/* adjust to the next column of macroblocks */
|
||||
x->src.y_buffer += 16;
|
||||
x->src.u_buffer += 8;
|
||||
x->src.v_buffer += 8;
|
||||
|
||||
recon_yoffset += 16;
|
||||
recon_uvoffset += 8;
|
||||
|
||||
/* Keep track of segment usage */
|
||||
segment_counts[xd->mode_info_context->mbmi.segment_id]++;
|
||||
|
||||
/* skip to next mb */
|
||||
xd->mode_info_context++;
|
||||
x->partition_info++;
|
||||
xd->above_context++;
|
||||
}
|
||||
|
||||
vp8_extend_mb_row(&cm->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16,
|
||||
xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
|
||||
|
||||
vpx_atomic_store_release(current_mb_col, mb_col + nsync);
|
||||
|
||||
/* this is to account for the border */
|
||||
xd->mode_info_context++;
|
||||
x->partition_info++;
|
||||
|
||||
x->src.y_buffer +=
|
||||
16 * x->src.y_stride * (cpi->encoding_thread_count + 1) -
|
||||
16 * cm->mb_cols;
|
||||
x->src.u_buffer +=
|
||||
8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) -
|
||||
8 * cm->mb_cols;
|
||||
x->src.v_buffer +=
|
||||
8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) -
|
||||
8 * cm->mb_cols;
|
||||
|
||||
xd->mode_info_context +=
|
||||
xd->mode_info_stride * cpi->encoding_thread_count;
|
||||
x->partition_info += xd->mode_info_stride * cpi->encoding_thread_count;
|
||||
x->gf_active_ptr += cm->mb_cols * cpi->encoding_thread_count;
|
||||
}
|
||||
/* Signal that this thread has completed processing its rows. */
|
||||
sem_post(&cpi->h_event_end_encoding[ithread]);
|
||||
}
|
||||
}
|
||||
|
||||
/* printf("exit thread %d\n", ithread); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_mbby_copy(MACROBLOCK *mbdst, MACROBLOCK *mbsrc) {
|
||||
MACROBLOCK *x = mbsrc;
|
||||
MACROBLOCK *z = mbdst;
|
||||
int i;
|
||||
|
||||
z->ss = x->ss;
|
||||
z->ss_count = x->ss_count;
|
||||
z->searches_per_step = x->searches_per_step;
|
||||
z->errorperbit = x->errorperbit;
|
||||
|
||||
z->sadperbit16 = x->sadperbit16;
|
||||
z->sadperbit4 = x->sadperbit4;
|
||||
|
||||
/*
|
||||
z->mv_col_min = x->mv_col_min;
|
||||
z->mv_col_max = x->mv_col_max;
|
||||
z->mv_row_min = x->mv_row_min;
|
||||
z->mv_row_max = x->mv_row_max;
|
||||
*/
|
||||
|
||||
z->short_fdct4x4 = x->short_fdct4x4;
|
||||
z->short_fdct8x4 = x->short_fdct8x4;
|
||||
z->short_walsh4x4 = x->short_walsh4x4;
|
||||
z->quantize_b = x->quantize_b;
|
||||
z->optimize = x->optimize;
|
||||
|
||||
/*
|
||||
z->mvc = x->mvc;
|
||||
z->src.y_buffer = x->src.y_buffer;
|
||||
z->src.u_buffer = x->src.u_buffer;
|
||||
z->src.v_buffer = x->src.v_buffer;
|
||||
*/
|
||||
|
||||
z->mvcost[0] = x->mvcost[0];
|
||||
z->mvcost[1] = x->mvcost[1];
|
||||
z->mvsadcost[0] = x->mvsadcost[0];
|
||||
z->mvsadcost[1] = x->mvsadcost[1];
|
||||
|
||||
z->token_costs = x->token_costs;
|
||||
z->inter_bmode_costs = x->inter_bmode_costs;
|
||||
z->mbmode_cost = x->mbmode_cost;
|
||||
z->intra_uv_mode_cost = x->intra_uv_mode_cost;
|
||||
z->bmode_costs = x->bmode_costs;
|
||||
|
||||
for (i = 0; i < 25; ++i) {
|
||||
z->block[i].quant = x->block[i].quant;
|
||||
z->block[i].quant_fast = x->block[i].quant_fast;
|
||||
z->block[i].quant_shift = x->block[i].quant_shift;
|
||||
z->block[i].zbin = x->block[i].zbin;
|
||||
z->block[i].zrun_zbin_boost = x->block[i].zrun_zbin_boost;
|
||||
z->block[i].round = x->block[i].round;
|
||||
z->block[i].src_stride = x->block[i].src_stride;
|
||||
}
|
||||
|
||||
z->q_index = x->q_index;
|
||||
z->act_zbin_adj = x->act_zbin_adj;
|
||||
z->last_act_zbin_adj = x->last_act_zbin_adj;
|
||||
|
||||
{
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
MACROBLOCKD *zd = &z->e_mbd;
|
||||
|
||||
/*
|
||||
zd->mode_info_context = xd->mode_info_context;
|
||||
zd->mode_info = xd->mode_info;
|
||||
|
||||
zd->mode_info_stride = xd->mode_info_stride;
|
||||
zd->frame_type = xd->frame_type;
|
||||
zd->up_available = xd->up_available ;
|
||||
zd->left_available = xd->left_available;
|
||||
zd->left_context = xd->left_context;
|
||||
zd->last_frame_dc = xd->last_frame_dc;
|
||||
zd->last_frame_dccons = xd->last_frame_dccons;
|
||||
zd->gold_frame_dc = xd->gold_frame_dc;
|
||||
zd->gold_frame_dccons = xd->gold_frame_dccons;
|
||||
zd->mb_to_left_edge = xd->mb_to_left_edge;
|
||||
zd->mb_to_right_edge = xd->mb_to_right_edge;
|
||||
zd->mb_to_top_edge = xd->mb_to_top_edge ;
|
||||
zd->mb_to_bottom_edge = xd->mb_to_bottom_edge;
|
||||
zd->gf_active_ptr = xd->gf_active_ptr;
|
||||
zd->frames_since_golden = xd->frames_since_golden;
|
||||
zd->frames_till_alt_ref_frame = xd->frames_till_alt_ref_frame;
|
||||
*/
|
||||
zd->subpixel_predict = xd->subpixel_predict;
|
||||
zd->subpixel_predict8x4 = xd->subpixel_predict8x4;
|
||||
zd->subpixel_predict8x8 = xd->subpixel_predict8x8;
|
||||
zd->subpixel_predict16x16 = xd->subpixel_predict16x16;
|
||||
zd->segmentation_enabled = xd->segmentation_enabled;
|
||||
zd->mb_segement_abs_delta = xd->mb_segement_abs_delta;
|
||||
memcpy(zd->segment_feature_data, xd->segment_feature_data,
|
||||
sizeof(xd->segment_feature_data));
|
||||
|
||||
memcpy(zd->dequant_y1_dc, xd->dequant_y1_dc, sizeof(xd->dequant_y1_dc));
|
||||
memcpy(zd->dequant_y1, xd->dequant_y1, sizeof(xd->dequant_y1));
|
||||
memcpy(zd->dequant_y2, xd->dequant_y2, sizeof(xd->dequant_y2));
|
||||
memcpy(zd->dequant_uv, xd->dequant_uv, sizeof(xd->dequant_uv));
|
||||
|
||||
#if 1
|
||||
/*TODO: Remove dequant from BLOCKD. This is a temporary solution until
|
||||
* the quantizer code uses a passed in pointer to the dequant constants.
|
||||
* This will also require modifications to the x86 and neon assembly.
|
||||
* */
|
||||
for (i = 0; i < 16; ++i) zd->block[i].dequant = zd->dequant_y1;
|
||||
for (i = 16; i < 24; ++i) zd->block[i].dequant = zd->dequant_uv;
|
||||
zd->block[24].dequant = zd->dequant_y2;
|
||||
#endif
|
||||
|
||||
memcpy(z->rd_threshes, x->rd_threshes, sizeof(x->rd_threshes));
|
||||
memcpy(z->rd_thresh_mult, x->rd_thresh_mult, sizeof(x->rd_thresh_mult));
|
||||
|
||||
z->zbin_over_quant = x->zbin_over_quant;
|
||||
z->zbin_mode_boost_enabled = x->zbin_mode_boost_enabled;
|
||||
z->zbin_mode_boost = x->zbin_mode_boost;
|
||||
|
||||
memset(z->error_bins, 0, sizeof(z->error_bins));
|
||||
}
|
||||
}
|
||||
|
||||
void vp8cx_init_mbrthread_data(VP8_COMP *cpi, MACROBLOCK *x,
|
||||
MB_ROW_COMP *mbr_ei, int count) {
|
||||
VP8_COMMON *const cm = &cpi->common;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
MACROBLOCK *mb = &mbr_ei[i].mb;
|
||||
MACROBLOCKD *mbd = &mb->e_mbd;
|
||||
|
||||
mbd->subpixel_predict = xd->subpixel_predict;
|
||||
mbd->subpixel_predict8x4 = xd->subpixel_predict8x4;
|
||||
mbd->subpixel_predict8x8 = xd->subpixel_predict8x8;
|
||||
mbd->subpixel_predict16x16 = xd->subpixel_predict16x16;
|
||||
mb->gf_active_ptr = x->gf_active_ptr;
|
||||
|
||||
memset(mbr_ei[i].segment_counts, 0, sizeof(mbr_ei[i].segment_counts));
|
||||
mbr_ei[i].totalrate = 0;
|
||||
|
||||
mb->partition_info = x->pi + x->e_mbd.mode_info_stride * (i + 1);
|
||||
|
||||
mbd->frame_type = cm->frame_type;
|
||||
|
||||
mb->src = *cpi->Source;
|
||||
mbd->pre = cm->yv12_fb[cm->lst_fb_idx];
|
||||
mbd->dst = cm->yv12_fb[cm->new_fb_idx];
|
||||
|
||||
mb->src.y_buffer += 16 * x->src.y_stride * (i + 1);
|
||||
mb->src.u_buffer += 8 * x->src.uv_stride * (i + 1);
|
||||
mb->src.v_buffer += 8 * x->src.uv_stride * (i + 1);
|
||||
|
||||
vp8_build_block_offsets(mb);
|
||||
|
||||
mbd->left_context = &cm->left_context;
|
||||
mb->mvc = cm->fc.mvc;
|
||||
|
||||
setup_mbby_copy(&mbr_ei[i].mb, x);
|
||||
|
||||
mbd->fullpixel_mask = 0xffffffff;
|
||||
if (cm->full_pixel) mbd->fullpixel_mask = 0xfffffff8;
|
||||
|
||||
vp8_zero(mb->coef_counts);
|
||||
vp8_zero(x->ymode_count);
|
||||
mb->skip_true_count = 0;
|
||||
vp8_zero(mb->MVcount);
|
||||
mb->prediction_error = 0;
|
||||
mb->intra_error = 0;
|
||||
vp8_zero(mb->count_mb_ref_frame_usage);
|
||||
mb->mbs_tested_so_far = 0;
|
||||
mb->mbs_zero_last_dot_suppress = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int vp8cx_create_encoder_threads(VP8_COMP *cpi) {
|
||||
const VP8_COMMON *cm = &cpi->common;
|
||||
|
||||
vpx_atomic_init(&cpi->b_multi_threaded, 0);
|
||||
cpi->encoding_thread_count = 0;
|
||||
cpi->b_lpf_running = 0;
|
||||
|
||||
if (cm->processor_core_count > 1 && cpi->oxcf.multi_threaded > 1) {
|
||||
int ithread;
|
||||
int th_count = cpi->oxcf.multi_threaded - 1;
|
||||
int rc = 0;
|
||||
|
||||
/* don't allocate more threads than cores available */
|
||||
if (cpi->oxcf.multi_threaded > cm->processor_core_count) {
|
||||
th_count = cm->processor_core_count - 1;
|
||||
}
|
||||
|
||||
/* we have th_count + 1 (main) threads processing one row each */
|
||||
/* no point to have more threads than the sync range allows */
|
||||
if (th_count > ((cm->mb_cols / cpi->mt_sync_range) - 1)) {
|
||||
th_count = (cm->mb_cols / cpi->mt_sync_range) - 1;
|
||||
}
|
||||
|
||||
if (th_count == 0) return 0;
|
||||
|
||||
CHECK_MEM_ERROR(cpi->h_encoding_thread,
|
||||
vpx_malloc(sizeof(pthread_t) * th_count));
|
||||
CHECK_MEM_ERROR(cpi->h_event_start_encoding,
|
||||
vpx_malloc(sizeof(sem_t) * th_count));
|
||||
CHECK_MEM_ERROR(cpi->h_event_end_encoding,
|
||||
vpx_malloc(sizeof(sem_t) * th_count));
|
||||
CHECK_MEM_ERROR(cpi->mb_row_ei,
|
||||
vpx_memalign(32, sizeof(MB_ROW_COMP) * th_count));
|
||||
memset(cpi->mb_row_ei, 0, sizeof(MB_ROW_COMP) * th_count);
|
||||
CHECK_MEM_ERROR(cpi->en_thread_data,
|
||||
vpx_malloc(sizeof(ENCODETHREAD_DATA) * th_count));
|
||||
|
||||
vpx_atomic_store_release(&cpi->b_multi_threaded, 1);
|
||||
cpi->encoding_thread_count = th_count;
|
||||
|
||||
/*
|
||||
printf("[VP8:] multi_threaded encoding is enabled with %d threads\n\n",
|
||||
(cpi->encoding_thread_count +1));
|
||||
*/
|
||||
|
||||
for (ithread = 0; ithread < th_count; ++ithread) {
|
||||
ENCODETHREAD_DATA *ethd = &cpi->en_thread_data[ithread];
|
||||
|
||||
/* Setup block ptrs and offsets */
|
||||
vp8_setup_block_ptrs(&cpi->mb_row_ei[ithread].mb);
|
||||
vp8_setup_block_dptrs(&cpi->mb_row_ei[ithread].mb.e_mbd);
|
||||
|
||||
sem_init(&cpi->h_event_start_encoding[ithread], 0, 0);
|
||||
sem_init(&cpi->h_event_end_encoding[ithread], 0, 0);
|
||||
|
||||
ethd->ithread = ithread;
|
||||
ethd->ptr1 = (void *)cpi;
|
||||
ethd->ptr2 = (void *)&cpi->mb_row_ei[ithread];
|
||||
|
||||
rc = pthread_create(&cpi->h_encoding_thread[ithread], 0,
|
||||
thread_encoding_proc, ethd);
|
||||
if (rc) break;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
/* shutdown other threads */
|
||||
vpx_atomic_store_release(&cpi->b_multi_threaded, 0);
|
||||
for (--ithread; ithread >= 0; ithread--) {
|
||||
pthread_join(cpi->h_encoding_thread[ithread], 0);
|
||||
sem_destroy(&cpi->h_event_start_encoding[ithread]);
|
||||
sem_destroy(&cpi->h_event_end_encoding[ithread]);
|
||||
}
|
||||
|
||||
/* free thread related resources */
|
||||
vpx_free(cpi->h_event_start_encoding);
|
||||
vpx_free(cpi->h_event_end_encoding);
|
||||
vpx_free(cpi->h_encoding_thread);
|
||||
vpx_free(cpi->mb_row_ei);
|
||||
vpx_free(cpi->en_thread_data);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
LPFTHREAD_DATA *lpfthd = &cpi->lpf_thread_data;
|
||||
|
||||
sem_init(&cpi->h_event_start_lpf, 0, 0);
|
||||
sem_init(&cpi->h_event_end_lpf, 0, 0);
|
||||
|
||||
lpfthd->ptr1 = (void *)cpi;
|
||||
rc = pthread_create(&cpi->h_filter_thread, 0, thread_loopfilter, lpfthd);
|
||||
|
||||
if (rc) {
|
||||
/* shutdown other threads */
|
||||
vpx_atomic_store_release(&cpi->b_multi_threaded, 0);
|
||||
for (--ithread; ithread >= 0; ithread--) {
|
||||
sem_post(&cpi->h_event_start_encoding[ithread]);
|
||||
sem_post(&cpi->h_event_end_encoding[ithread]);
|
||||
pthread_join(cpi->h_encoding_thread[ithread], 0);
|
||||
sem_destroy(&cpi->h_event_start_encoding[ithread]);
|
||||
sem_destroy(&cpi->h_event_end_encoding[ithread]);
|
||||
}
|
||||
sem_destroy(&cpi->h_event_end_lpf);
|
||||
sem_destroy(&cpi->h_event_start_lpf);
|
||||
|
||||
/* free thread related resources */
|
||||
vpx_free(cpi->h_event_start_encoding);
|
||||
vpx_free(cpi->h_event_end_encoding);
|
||||
vpx_free(cpi->h_encoding_thread);
|
||||
vpx_free(cpi->mb_row_ei);
|
||||
vpx_free(cpi->en_thread_data);
|
||||
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vp8cx_remove_encoder_threads(VP8_COMP *cpi) {
|
||||
if (vpx_atomic_load_acquire(&cpi->b_multi_threaded)) {
|
||||
/* shutdown other threads */
|
||||
vpx_atomic_store_release(&cpi->b_multi_threaded, 0);
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cpi->encoding_thread_count; ++i) {
|
||||
sem_post(&cpi->h_event_start_encoding[i]);
|
||||
sem_post(&cpi->h_event_end_encoding[i]);
|
||||
|
||||
pthread_join(cpi->h_encoding_thread[i], 0);
|
||||
|
||||
sem_destroy(&cpi->h_event_start_encoding[i]);
|
||||
sem_destroy(&cpi->h_event_end_encoding[i]);
|
||||
}
|
||||
|
||||
sem_post(&cpi->h_event_start_lpf);
|
||||
pthread_join(cpi->h_filter_thread, 0);
|
||||
}
|
||||
|
||||
sem_destroy(&cpi->h_event_end_lpf);
|
||||
sem_destroy(&cpi->h_event_start_lpf);
|
||||
|
||||
/* free thread related resources */
|
||||
vpx_free(cpi->h_event_start_encoding);
|
||||
vpx_free(cpi->h_event_end_encoding);
|
||||
vpx_free(cpi->h_encoding_thread);
|
||||
vpx_free(cpi->mb_row_ei);
|
||||
vpx_free(cpi->en_thread_data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_ETHREADING_H_
|
||||
#define VPX_VP8_ENCODER_ETHREADING_H_
|
||||
|
||||
#include "vp8/encoder/onyx_int.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct VP8_COMP;
|
||||
struct macroblock;
|
||||
|
||||
void vp8cx_init_mbrthread_data(struct VP8_COMP *cpi, struct macroblock *x,
|
||||
MB_ROW_COMP *mbr_ei, int count);
|
||||
int vp8cx_create_encoder_threads(struct VP8_COMP *cpi);
|
||||
void vp8cx_remove_encoder_threads(struct VP8_COMP *cpi);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_ETHREADING_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_FIRSTPASS_H_
|
||||
#define VPX_VP8_ENCODER_FIRSTPASS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void vp8_init_first_pass(VP8_COMP *cpi);
|
||||
extern void vp8_first_pass(VP8_COMP *cpi);
|
||||
extern void vp8_end_first_pass(VP8_COMP *cpi);
|
||||
|
||||
extern void vp8_init_second_pass(VP8_COMP *cpi);
|
||||
extern void vp8_second_pass(VP8_COMP *cpi);
|
||||
extern void vp8_end_second_pass(VP8_COMP *cpi);
|
||||
|
||||
extern size_t vp8_firstpass_stats_sz(unsigned int mb_count);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_FIRSTPASS_H_
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (c) 2011 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.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "vpx_config.h"
|
||||
#include "lookahead.h"
|
||||
#include "vp8/common/extend.h"
|
||||
|
||||
#define MAX_LAG_BUFFERS (CONFIG_REALTIME_ONLY ? 1 : 25)
|
||||
|
||||
struct lookahead_ctx {
|
||||
unsigned int max_sz; /* Absolute size of the queue */
|
||||
unsigned int sz; /* Number of buffers currently in the queue */
|
||||
unsigned int read_idx; /* Read index */
|
||||
unsigned int write_idx; /* Write index */
|
||||
struct lookahead_entry *buf; /* Buffer list */
|
||||
};
|
||||
|
||||
/* Return the buffer at the given absolute index and increment the index */
|
||||
static struct lookahead_entry *pop(struct lookahead_ctx *ctx,
|
||||
unsigned int *idx) {
|
||||
unsigned int index = *idx;
|
||||
struct lookahead_entry *buf = ctx->buf + index;
|
||||
|
||||
assert(index < ctx->max_sz);
|
||||
if (++index >= ctx->max_sz) index -= ctx->max_sz;
|
||||
*idx = index;
|
||||
return buf;
|
||||
}
|
||||
|
||||
void vp8_lookahead_destroy(struct lookahead_ctx *ctx) {
|
||||
if (ctx) {
|
||||
if (ctx->buf) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ctx->max_sz; ++i) {
|
||||
vp8_yv12_de_alloc_frame_buffer(&ctx->buf[i].img);
|
||||
}
|
||||
free(ctx->buf);
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
struct lookahead_ctx *vp8_lookahead_init(unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int depth) {
|
||||
struct lookahead_ctx *ctx = NULL;
|
||||
unsigned int i;
|
||||
|
||||
/* Clamp the lookahead queue depth */
|
||||
if (depth < 1) {
|
||||
depth = 1;
|
||||
} else if (depth > MAX_LAG_BUFFERS) {
|
||||
depth = MAX_LAG_BUFFERS;
|
||||
}
|
||||
|
||||
/* Keep last frame in lookahead buffer by increasing depth by 1.*/
|
||||
depth += 1;
|
||||
|
||||
/* Align the buffer dimensions */
|
||||
width = (width + 15) & ~15;
|
||||
height = (height + 15) & ~15;
|
||||
|
||||
/* Allocate the lookahead structures */
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if (ctx) {
|
||||
ctx->max_sz = depth;
|
||||
ctx->buf = calloc(depth, sizeof(*ctx->buf));
|
||||
if (!ctx->buf) goto bail;
|
||||
for (i = 0; i < depth; ++i) {
|
||||
if (vp8_yv12_alloc_frame_buffer(&ctx->buf[i].img, width, height,
|
||||
VP8BORDERINPIXELS)) {
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ctx;
|
||||
bail:
|
||||
vp8_lookahead_destroy(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int vp8_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src,
|
||||
int64_t ts_start, int64_t ts_end, unsigned int flags,
|
||||
unsigned char *active_map) {
|
||||
struct lookahead_entry *buf;
|
||||
int row, col, active_end;
|
||||
int mb_rows = (src->y_height + 15) >> 4;
|
||||
int mb_cols = (src->y_width + 15) >> 4;
|
||||
|
||||
if (ctx->sz + 2 > ctx->max_sz) return 1;
|
||||
ctx->sz++;
|
||||
buf = pop(ctx, &ctx->write_idx);
|
||||
|
||||
/* Only do this partial copy if the following conditions are all met:
|
||||
* 1. Lookahead queue has has size of 1.
|
||||
* 2. Active map is provided.
|
||||
* 3. This is not a key frame, golden nor altref frame.
|
||||
*/
|
||||
if (ctx->max_sz == 1 && active_map && !flags) {
|
||||
for (row = 0; row < mb_rows; ++row) {
|
||||
col = 0;
|
||||
|
||||
while (1) {
|
||||
/* Find the first active macroblock in this row. */
|
||||
for (; col < mb_cols; ++col) {
|
||||
if (active_map[col]) break;
|
||||
}
|
||||
|
||||
/* No more active macroblock in this row. */
|
||||
if (col == mb_cols) break;
|
||||
|
||||
/* Find the end of active region in this row. */
|
||||
active_end = col;
|
||||
|
||||
for (; active_end < mb_cols; ++active_end) {
|
||||
if (!active_map[active_end]) break;
|
||||
}
|
||||
|
||||
/* Only copy this active region. */
|
||||
vp8_copy_and_extend_frame_with_rect(src, &buf->img, row << 4, col << 4,
|
||||
16, (active_end - col) << 4);
|
||||
|
||||
/* Start again from the end of this active region. */
|
||||
col = active_end;
|
||||
}
|
||||
|
||||
active_map += mb_cols;
|
||||
}
|
||||
} else {
|
||||
vp8_copy_and_extend_frame(src, &buf->img);
|
||||
}
|
||||
buf->ts_start = ts_start;
|
||||
buf->ts_end = ts_end;
|
||||
buf->flags = flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lookahead_entry *vp8_lookahead_pop(struct lookahead_ctx *ctx,
|
||||
int drain) {
|
||||
struct lookahead_entry *buf = NULL;
|
||||
|
||||
assert(ctx != NULL);
|
||||
if (ctx->sz && (drain || ctx->sz == ctx->max_sz - 1)) {
|
||||
buf = pop(ctx, &ctx->read_idx);
|
||||
ctx->sz--;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
struct lookahead_entry *vp8_lookahead_peek(struct lookahead_ctx *ctx,
|
||||
unsigned int index, int direction) {
|
||||
struct lookahead_entry *buf = NULL;
|
||||
|
||||
if (direction == PEEK_FORWARD) {
|
||||
assert(index < ctx->max_sz - 1);
|
||||
if (index < ctx->sz) {
|
||||
index += ctx->read_idx;
|
||||
if (index >= ctx->max_sz) index -= ctx->max_sz;
|
||||
buf = ctx->buf + index;
|
||||
}
|
||||
} else if (direction == PEEK_BACKWARD) {
|
||||
assert(index == 1);
|
||||
|
||||
if (ctx->read_idx == 0) {
|
||||
index = ctx->max_sz - 1;
|
||||
} else {
|
||||
index = ctx->read_idx - index;
|
||||
}
|
||||
buf = ctx->buf + index;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
unsigned int vp8_lookahead_depth(struct lookahead_ctx *ctx) { return ctx->sz; }
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2011 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.
|
||||
*/
|
||||
#ifndef VPX_VP8_ENCODER_LOOKAHEAD_H_
|
||||
#define VPX_VP8_ENCODER_LOOKAHEAD_H_
|
||||
#include "vpx_scale/yv12config.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct lookahead_entry {
|
||||
YV12_BUFFER_CONFIG img;
|
||||
int64_t ts_start;
|
||||
int64_t ts_end;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct lookahead_ctx;
|
||||
|
||||
/**\brief Initializes the lookahead stage
|
||||
*
|
||||
* The lookahead stage is a queue of frame buffers on which some analysis
|
||||
* may be done when buffers are enqueued.
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct lookahead_ctx *vp8_lookahead_init(unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int depth);
|
||||
|
||||
/**\brief Destroys the lookahead stage
|
||||
*
|
||||
*/
|
||||
void vp8_lookahead_destroy(struct lookahead_ctx *ctx);
|
||||
|
||||
/**\brief Enqueue a source buffer
|
||||
*
|
||||
* This function will copy the source image into a new framebuffer with
|
||||
* the expected stride/border.
|
||||
*
|
||||
* If active_map is non-NULL and there is only one frame in the queue, then copy
|
||||
* only active macroblocks.
|
||||
*
|
||||
* \param[in] ctx Pointer to the lookahead context
|
||||
* \param[in] src Pointer to the image to enqueue
|
||||
* \param[in] ts_start Timestamp for the start of this frame
|
||||
* \param[in] ts_end Timestamp for the end of this frame
|
||||
* \param[in] flags Flags set on this frame
|
||||
* \param[in] active_map Map that specifies which macroblock is active
|
||||
*/
|
||||
int vp8_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src,
|
||||
int64_t ts_start, int64_t ts_end, unsigned int flags,
|
||||
unsigned char *active_map);
|
||||
|
||||
/**\brief Get the next source buffer to encode
|
||||
*
|
||||
*
|
||||
* \param[in] ctx Pointer to the lookahead context
|
||||
* \param[in] drain Flag indicating the buffer should be drained
|
||||
* (return a buffer regardless of the current queue depth)
|
||||
*
|
||||
* \retval NULL, if drain set and queue is empty
|
||||
* \retval NULL, if drain not set and queue not of the configured depth
|
||||
*
|
||||
*/
|
||||
struct lookahead_entry *vp8_lookahead_pop(struct lookahead_ctx *ctx, int drain);
|
||||
|
||||
#define PEEK_FORWARD 1
|
||||
#define PEEK_BACKWARD (-1)
|
||||
/**\brief Get a future source buffer to encode
|
||||
*
|
||||
* \param[in] ctx Pointer to the lookahead context
|
||||
* \param[in] index Index of the frame to be returned, 0 == next frame
|
||||
*
|
||||
* \retval NULL, if no buffer exists at the specified index
|
||||
*
|
||||
*/
|
||||
struct lookahead_entry *vp8_lookahead_peek(struct lookahead_ctx *ctx,
|
||||
unsigned int index, int direction);
|
||||
|
||||
/**\brief Get the number of frames currently in the lookahead queue
|
||||
*
|
||||
* \param[in] ctx Pointer to the lookahead context
|
||||
*/
|
||||
unsigned int vp8_lookahead_depth(struct lookahead_ctx *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_LOOKAHEAD_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_MCOMP_H_
|
||||
#define VPX_VP8_ENCODER_MCOMP_H_
|
||||
|
||||
#include "block.h"
|
||||
#include "vpx_dsp/variance.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* The maximum number of steps in a step search given the largest allowed
|
||||
* initial step
|
||||
*/
|
||||
#define MAX_MVSEARCH_STEPS 8
|
||||
|
||||
/* Max full pel mv specified in 1 pel units */
|
||||
#define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS)) - 1)
|
||||
|
||||
/* Maximum size of the first step in full pel units */
|
||||
#define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS - 1))
|
||||
|
||||
int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight);
|
||||
void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride);
|
||||
void vp8_init3smotion_compensation(MACROBLOCK *x, int stride);
|
||||
|
||||
int vp8_hex_search(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
|
||||
int_mv *best_mv, int search_param, int sad_per_bit,
|
||||
const vp8_variance_fn_ptr_t *vfp, int *mvsadcost[2],
|
||||
int_mv *center_mv);
|
||||
|
||||
typedef int(fractional_mv_step_fp)(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
|
||||
int_mv *bestmv, int_mv *ref_mv,
|
||||
int error_per_bit,
|
||||
const vp8_variance_fn_ptr_t *vfp,
|
||||
int *mvcost[2], int *distortion,
|
||||
unsigned int *sse);
|
||||
|
||||
fractional_mv_step_fp vp8_find_best_sub_pixel_step_iteratively;
|
||||
fractional_mv_step_fp vp8_find_best_sub_pixel_step;
|
||||
fractional_mv_step_fp vp8_find_best_half_pixel_step;
|
||||
fractional_mv_step_fp vp8_skip_fractional_mv_step;
|
||||
|
||||
typedef int (*vp8_full_search_fn_t)(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
|
||||
int_mv *ref_mv, int sad_per_bit,
|
||||
int distance, vp8_variance_fn_ptr_t *fn_ptr,
|
||||
int *mvcost[2], int_mv *center_mv);
|
||||
|
||||
typedef int (*vp8_refining_search_fn_t)(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
|
||||
int_mv *ref_mv, int sad_per_bit,
|
||||
int distance,
|
||||
vp8_variance_fn_ptr_t *fn_ptr,
|
||||
int *mvcost[2], int_mv *center_mv);
|
||||
|
||||
typedef int (*vp8_diamond_search_fn_t)(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
|
||||
int_mv *ref_mv, int_mv *best_mv,
|
||||
int search_param, int sad_per_bit,
|
||||
int *num00,
|
||||
vp8_variance_fn_ptr_t *fn_ptr,
|
||||
int *mvcost[2], int_mv *center_mv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_MCOMP_H_
|
||||
@@ -0,0 +1,425 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx_ports/asmdefs_mmi.h"
|
||||
|
||||
/* clang-format off */
|
||||
/* TRANSPOSE_4H: transpose 4x4 matrix.
|
||||
Input: ftmp1,ftmp2,ftmp3,ftmp4
|
||||
Output: ftmp1,ftmp2,ftmp3,ftmp4
|
||||
Note: ftmp0 always be 0, ftmp5~9 used for temporary value.
|
||||
*/
|
||||
#define TRANSPOSE_4H \
|
||||
MMI_LI(%[tmp0], 0x93) \
|
||||
"mtc1 %[tmp0], %[ftmp10] \n\t" \
|
||||
"punpcklhw %[ftmp5], %[ftmp1], %[ftmp0] \n\t" \
|
||||
"punpcklhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \
|
||||
"pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \
|
||||
"or %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \
|
||||
"punpckhhw %[ftmp6], %[ftmp1], %[ftmp0] \n\t" \
|
||||
"punpckhhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \
|
||||
"pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \
|
||||
"or %[ftmp6], %[ftmp6], %[ftmp9] \n\t" \
|
||||
"punpcklhw %[ftmp7], %[ftmp3], %[ftmp0] \n\t" \
|
||||
"punpcklhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \
|
||||
"pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \
|
||||
"or %[ftmp7], %[ftmp7], %[ftmp9] \n\t" \
|
||||
"punpckhhw %[ftmp8], %[ftmp3], %[ftmp0] \n\t" \
|
||||
"punpckhhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \
|
||||
"pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \
|
||||
"or %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \
|
||||
"punpcklwd %[ftmp1], %[ftmp5], %[ftmp7] \n\t" \
|
||||
"punpckhwd %[ftmp2], %[ftmp5], %[ftmp7] \n\t" \
|
||||
"punpcklwd %[ftmp3], %[ftmp6], %[ftmp8] \n\t" \
|
||||
"punpckhwd %[ftmp4], %[ftmp6], %[ftmp8] \n\t"
|
||||
/* clang-format on */
|
||||
|
||||
void vp8_short_fdct4x4_mmi(int16_t *input, int16_t *output, int pitch) {
|
||||
uint64_t tmp[1];
|
||||
int16_t *ip = input;
|
||||
|
||||
#if _MIPS_SIM == _ABIO32
|
||||
register double ftmp0 asm("$f0");
|
||||
register double ftmp1 asm("$f2");
|
||||
register double ftmp2 asm("$f4");
|
||||
register double ftmp3 asm("$f6");
|
||||
register double ftmp4 asm("$f8");
|
||||
register double ftmp5 asm("$f10");
|
||||
register double ftmp6 asm("$f12");
|
||||
register double ftmp7 asm("$f14");
|
||||
register double ftmp8 asm("$f16");
|
||||
register double ftmp9 asm("$f18");
|
||||
register double ftmp10 asm("$f20");
|
||||
register double ftmp11 asm("$f22");
|
||||
register double ftmp12 asm("$f24");
|
||||
#else
|
||||
register double ftmp0 asm("$f0");
|
||||
register double ftmp1 asm("$f1");
|
||||
register double ftmp2 asm("$f2");
|
||||
register double ftmp3 asm("$f3");
|
||||
register double ftmp4 asm("$f4");
|
||||
register double ftmp5 asm("$f5");
|
||||
register double ftmp6 asm("$f6");
|
||||
register double ftmp7 asm("$f7");
|
||||
register double ftmp8 asm("$f8");
|
||||
register double ftmp9 asm("$f9");
|
||||
register double ftmp10 asm("$f10");
|
||||
register double ftmp11 asm("$f11");
|
||||
register double ftmp12 asm("$f12");
|
||||
#endif // _MIPS_SIM == _ABIO32
|
||||
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_ph_01) = { 0x0001000100010001ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_ph_07) = { 0x0007000700070007ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_pw_12000) = { 0x00002ee000002ee0ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_pw_51000) = { 0x0000c7380000c738ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_pw_14500) = { 0x000038a4000038a4ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_pw_7500) = { 0x00001d4c00001d4cULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_ph_op1) = { 0x14e808a914e808a9ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_ph_op3) = { 0xeb1808a9eb1808a9ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_pw_5352) = { 0x000014e8000014e8ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_pw_2217) = { 0x000008a9000008a9ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_ph_8) = { 0x0008000800080008ULL };
|
||||
|
||||
__asm__ volatile (
|
||||
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
|
||||
"gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t"
|
||||
"gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t"
|
||||
MMI_ADDU(%[ip], %[ip], %[pitch])
|
||||
"gsldlc1 %[ftmp2], 0x07(%[ip]) \n\t"
|
||||
"gsldrc1 %[ftmp2], 0x00(%[ip]) \n\t"
|
||||
MMI_ADDU(%[ip], %[ip], %[pitch])
|
||||
"gsldlc1 %[ftmp3], 0x07(%[ip]) \n\t"
|
||||
"gsldrc1 %[ftmp3], 0x00(%[ip]) \n\t"
|
||||
MMI_ADDU(%[ip], %[ip], %[pitch])
|
||||
"gsldlc1 %[ftmp4], 0x07(%[ip]) \n\t"
|
||||
"gsldrc1 %[ftmp4], 0x00(%[ip]) \n\t"
|
||||
MMI_ADDU(%[ip], %[ip], %[pitch])
|
||||
TRANSPOSE_4H
|
||||
|
||||
"ldc1 %[ftmp11], %[ff_ph_8] \n\t"
|
||||
// f1 + f4
|
||||
"paddh %[ftmp5], %[ftmp1], %[ftmp4] \n\t"
|
||||
// a1
|
||||
"pmullh %[ftmp5], %[ftmp5], %[ftmp11] \n\t"
|
||||
// f2 + f3
|
||||
"paddh %[ftmp6], %[ftmp2], %[ftmp3] \n\t"
|
||||
// b1
|
||||
"pmullh %[ftmp6], %[ftmp6], %[ftmp11] \n\t"
|
||||
// f2 - f3
|
||||
"psubh %[ftmp7], %[ftmp2], %[ftmp3] \n\t"
|
||||
// c1
|
||||
"pmullh %[ftmp7], %[ftmp7], %[ftmp11] \n\t"
|
||||
// f1 - f4
|
||||
"psubh %[ftmp8], %[ftmp1], %[ftmp4] \n\t"
|
||||
// d1
|
||||
"pmullh %[ftmp8], %[ftmp8], %[ftmp11] \n\t"
|
||||
// op[0] = a1 + b1
|
||||
"paddh %[ftmp1], %[ftmp5], %[ftmp6] \n\t"
|
||||
// op[2] = a1 - b1
|
||||
"psubh %[ftmp3], %[ftmp5], %[ftmp6] \n\t"
|
||||
|
||||
// op[1] = (c1 * 2217 + d1 * 5352 + 14500) >> 12
|
||||
MMI_LI(%[tmp0], 0x0c)
|
||||
"mtc1 %[tmp0], %[ftmp11] \n\t"
|
||||
"ldc1 %[ftmp12], %[ff_pw_14500] \n\t"
|
||||
"punpcklhw %[ftmp9], %[ftmp7], %[ftmp8] \n\t"
|
||||
"pmaddhw %[ftmp5], %[ftmp9], %[ff_ph_op1] \n\t"
|
||||
"punpckhhw %[ftmp9], %[ftmp7], %[ftmp8] \n\t"
|
||||
"pmaddhw %[ftmp6], %[ftmp9], %[ff_ph_op1] \n\t"
|
||||
"paddw %[ftmp5], %[ftmp5], %[ftmp12] \n\t"
|
||||
"paddw %[ftmp6], %[ftmp6], %[ftmp12] \n\t"
|
||||
"psraw %[ftmp5], %[ftmp5], %[ftmp11] \n\t"
|
||||
"psraw %[ftmp6], %[ftmp6], %[ftmp11] \n\t"
|
||||
"packsswh %[ftmp2], %[ftmp5], %[ftmp6] \n\t"
|
||||
|
||||
// op[3] = (d1 * 2217 - c1 * 5352 + 7500) >> 12
|
||||
"ldc1 %[ftmp12], %[ff_pw_7500] \n\t"
|
||||
"punpcklhw %[ftmp9], %[ftmp8], %[ftmp7] \n\t"
|
||||
"pmaddhw %[ftmp5], %[ftmp9], %[ff_ph_op3] \n\t"
|
||||
"punpckhhw %[ftmp9], %[ftmp8], %[ftmp7] \n\t"
|
||||
"pmaddhw %[ftmp6], %[ftmp9], %[ff_ph_op3] \n\t"
|
||||
"paddw %[ftmp5], %[ftmp5], %[ftmp12] \n\t"
|
||||
"paddw %[ftmp6], %[ftmp6], %[ftmp12] \n\t"
|
||||
"psraw %[ftmp5], %[ftmp5], %[ftmp11] \n\t"
|
||||
"psraw %[ftmp6], %[ftmp6], %[ftmp11] \n\t"
|
||||
"packsswh %[ftmp4], %[ftmp5], %[ftmp6] \n\t"
|
||||
TRANSPOSE_4H
|
||||
|
||||
"paddh %[ftmp5], %[ftmp1], %[ftmp4] \n\t"
|
||||
"paddh %[ftmp6], %[ftmp2], %[ftmp3] \n\t"
|
||||
"psubh %[ftmp7], %[ftmp2], %[ftmp3] \n\t"
|
||||
"psubh %[ftmp8], %[ftmp1], %[ftmp4] \n\t"
|
||||
|
||||
"pcmpeqh %[ftmp0], %[ftmp8], %[ftmp0] \n\t"
|
||||
"ldc1 %[ftmp9], %[ff_ph_01] \n\t"
|
||||
"paddh %[ftmp0], %[ftmp0], %[ftmp9] \n\t"
|
||||
|
||||
"paddh %[ftmp1], %[ftmp5], %[ftmp6] \n\t"
|
||||
"psubh %[ftmp2], %[ftmp5], %[ftmp6] \n\t"
|
||||
"ldc1 %[ftmp9], %[ff_ph_07] \n\t"
|
||||
"paddh %[ftmp1], %[ftmp1], %[ftmp9] \n\t"
|
||||
"paddh %[ftmp2], %[ftmp2], %[ftmp9] \n\t"
|
||||
MMI_LI(%[tmp0], 0x04)
|
||||
"mtc1 %[tmp0], %[ftmp9] \n\t"
|
||||
"psrah %[ftmp1], %[ftmp1], %[ftmp9] \n\t"
|
||||
"psrah %[ftmp2], %[ftmp2], %[ftmp9] \n\t"
|
||||
|
||||
MMI_LI(%[tmp0], 0x10)
|
||||
"mtc1 %[tmp0], %[ftmp9] \n\t"
|
||||
"ldc1 %[ftmp12], %[ff_pw_12000] \n\t"
|
||||
"punpcklhw %[ftmp5], %[ftmp7], %[ftmp8] \n\t"
|
||||
"pmaddhw %[ftmp10], %[ftmp5], %[ff_ph_op1] \n\t"
|
||||
"punpckhhw %[ftmp5], %[ftmp7], %[ftmp8] \n\t"
|
||||
"pmaddhw %[ftmp11], %[ftmp5], %[ff_ph_op1] \n\t"
|
||||
"paddw %[ftmp10], %[ftmp10], %[ftmp12] \n\t"
|
||||
"paddw %[ftmp11], %[ftmp11], %[ftmp12] \n\t"
|
||||
"psraw %[ftmp10], %[ftmp10], %[ftmp9] \n\t"
|
||||
"psraw %[ftmp11], %[ftmp11], %[ftmp9] \n\t"
|
||||
"packsswh %[ftmp3], %[ftmp10], %[ftmp11] \n\t"
|
||||
"paddh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
|
||||
|
||||
"ldc1 %[ftmp12], %[ff_pw_51000] \n\t"
|
||||
"punpcklhw %[ftmp5], %[ftmp8], %[ftmp7] \n\t"
|
||||
"pmaddhw %[ftmp10], %[ftmp5], %[ff_ph_op3] \n\t"
|
||||
"punpckhhw %[ftmp5], %[ftmp8], %[ftmp7] \n\t"
|
||||
"pmaddhw %[ftmp11], %[ftmp5], %[ff_ph_op3] \n\t"
|
||||
"paddw %[ftmp10], %[ftmp10], %[ftmp12] \n\t"
|
||||
"paddw %[ftmp11], %[ftmp11], %[ftmp12] \n\t"
|
||||
"psraw %[ftmp10], %[ftmp10], %[ftmp9] \n\t"
|
||||
"psraw %[ftmp11], %[ftmp11], %[ftmp9] \n\t"
|
||||
"packsswh %[ftmp4], %[ftmp10], %[ftmp11] \n\t"
|
||||
|
||||
"gssdlc1 %[ftmp1], 0x07(%[output]) \n\t"
|
||||
"gssdrc1 %[ftmp1], 0x00(%[output]) \n\t"
|
||||
"gssdlc1 %[ftmp3], 0x0f(%[output]) \n\t"
|
||||
"gssdrc1 %[ftmp3], 0x08(%[output]) \n\t"
|
||||
"gssdlc1 %[ftmp2], 0x17(%[output]) \n\t"
|
||||
"gssdrc1 %[ftmp2], 0x10(%[output]) \n\t"
|
||||
"gssdlc1 %[ftmp4], 0x1f(%[output]) \n\t"
|
||||
"gssdrc1 %[ftmp4], 0x18(%[output]) \n\t"
|
||||
|
||||
: [ftmp0] "=&f"(ftmp0), [ftmp1] "=&f"(ftmp1), [ftmp2] "=&f"(ftmp2),
|
||||
[ftmp3] "=&f"(ftmp3), [ftmp4] "=&f"(ftmp4), [ftmp5] "=&f"(ftmp5),
|
||||
[ftmp6] "=&f"(ftmp6), [ftmp7] "=&f"(ftmp7), [ftmp8] "=&f"(ftmp8),
|
||||
[ftmp9] "=&f"(ftmp9), [ftmp10] "=&f"(ftmp10), [ftmp11] "=&f"(ftmp11),
|
||||
[ftmp12] "=&f"(ftmp12), [tmp0] "=&r"(tmp[0]), [ip]"+&r"(ip)
|
||||
: [ff_ph_01] "m"(ff_ph_01), [ff_ph_07] "m"(ff_ph_07),
|
||||
[ff_ph_op1] "f"(ff_ph_op1), [ff_ph_op3] "f"(ff_ph_op3),
|
||||
[ff_pw_14500] "m"(ff_pw_14500), [ff_pw_7500] "m"(ff_pw_7500),
|
||||
[ff_pw_12000] "m"(ff_pw_12000), [ff_pw_51000] "m"(ff_pw_51000),
|
||||
[ff_pw_5352]"m"(ff_pw_5352), [ff_pw_2217]"m"(ff_pw_2217),
|
||||
[ff_ph_8]"m"(ff_ph_8), [pitch]"r"(pitch), [output] "r"(output)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
void vp8_short_fdct8x4_mmi(int16_t *input, int16_t *output, int pitch) {
|
||||
vp8_short_fdct4x4_mmi(input, output, pitch);
|
||||
vp8_short_fdct4x4_mmi(input + 4, output + 16, pitch);
|
||||
}
|
||||
|
||||
void vp8_short_walsh4x4_mmi(int16_t *input, int16_t *output, int pitch) {
|
||||
double ftmp[13];
|
||||
uint32_t tmp[1];
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_ph_01) = { 0x0001000100010001ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_pw_01) = { 0x0000000100000001ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_pw_03) = { 0x0000000300000003ULL };
|
||||
DECLARE_ALIGNED(8, const uint64_t, ff_pw_mask) = { 0x0001000000010000ULL };
|
||||
|
||||
__asm__ volatile (
|
||||
MMI_LI(%[tmp0], 0x02)
|
||||
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
|
||||
"mtc1 %[tmp0], %[ftmp11] \n\t"
|
||||
|
||||
"gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t"
|
||||
"gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t"
|
||||
MMI_ADDU(%[ip], %[ip], %[pitch])
|
||||
"gsldlc1 %[ftmp2], 0x07(%[ip]) \n\t"
|
||||
"gsldrc1 %[ftmp2], 0x00(%[ip]) \n\t"
|
||||
MMI_ADDU(%[ip], %[ip], %[pitch])
|
||||
"gsldlc1 %[ftmp3], 0x07(%[ip]) \n\t"
|
||||
"gsldrc1 %[ftmp3], 0x00(%[ip]) \n\t"
|
||||
MMI_ADDU(%[ip], %[ip], %[pitch])
|
||||
"gsldlc1 %[ftmp4], 0x07(%[ip]) \n\t"
|
||||
"gsldrc1 %[ftmp4], 0x00(%[ip]) \n\t"
|
||||
TRANSPOSE_4H
|
||||
|
||||
"psllh %[ftmp1], %[ftmp1], %[ftmp11] \n\t"
|
||||
"psllh %[ftmp2], %[ftmp2], %[ftmp11] \n\t"
|
||||
"psllh %[ftmp3], %[ftmp3], %[ftmp11] \n\t"
|
||||
"psllh %[ftmp4], %[ftmp4], %[ftmp11] \n\t"
|
||||
// a
|
||||
"paddh %[ftmp5], %[ftmp1], %[ftmp3] \n\t"
|
||||
// d
|
||||
"paddh %[ftmp6], %[ftmp2], %[ftmp4] \n\t"
|
||||
// c
|
||||
"psubh %[ftmp7], %[ftmp2], %[ftmp4] \n\t"
|
||||
// b
|
||||
"psubh %[ftmp8], %[ftmp1], %[ftmp3] \n\t"
|
||||
|
||||
// a + d
|
||||
"paddh %[ftmp1], %[ftmp5], %[ftmp6] \n\t"
|
||||
// b + c
|
||||
"paddh %[ftmp2], %[ftmp8], %[ftmp7] \n\t"
|
||||
// b - c
|
||||
"psubh %[ftmp3], %[ftmp8], %[ftmp7] \n\t"
|
||||
// a - d
|
||||
"psubh %[ftmp4], %[ftmp5], %[ftmp6] \n\t"
|
||||
|
||||
"pcmpeqh %[ftmp6], %[ftmp5], %[ftmp0] \n\t"
|
||||
"paddh %[ftmp6], %[ftmp6], %[ff_ph_01] \n\t"
|
||||
"paddh %[ftmp1], %[ftmp1], %[ftmp6] \n\t"
|
||||
TRANSPOSE_4H
|
||||
|
||||
// op[2], op[0]
|
||||
"pmaddhw %[ftmp5], %[ftmp1], %[ff_pw_01] \n\t"
|
||||
// op[3], op[1]
|
||||
"pmaddhw %[ftmp1], %[ftmp1], %[ff_pw_mask] \n\t"
|
||||
|
||||
// op[6], op[4]
|
||||
"pmaddhw %[ftmp6], %[ftmp2], %[ff_pw_01] \n\t"
|
||||
// op[7], op[5]
|
||||
"pmaddhw %[ftmp2], %[ftmp2], %[ff_pw_mask] \n\t"
|
||||
|
||||
// op[10], op[8]
|
||||
"pmaddhw %[ftmp7], %[ftmp3], %[ff_pw_01] \n\t"
|
||||
// op[11], op[9]
|
||||
"pmaddhw %[ftmp3], %[ftmp3], %[ff_pw_mask] \n\t"
|
||||
|
||||
// op[14], op[12]
|
||||
"pmaddhw %[ftmp8], %[ftmp4], %[ff_pw_01] \n\t"
|
||||
// op[15], op[13]
|
||||
"pmaddhw %[ftmp4], %[ftmp4], %[ff_pw_mask] \n\t"
|
||||
|
||||
// a1, a3
|
||||
"paddw %[ftmp9], %[ftmp5], %[ftmp7] \n\t"
|
||||
// d1, d3
|
||||
"paddw %[ftmp10], %[ftmp6], %[ftmp8] \n\t"
|
||||
// c1, c3
|
||||
"psubw %[ftmp11], %[ftmp6], %[ftmp8] \n\t"
|
||||
// b1, b3
|
||||
"psubw %[ftmp12], %[ftmp5], %[ftmp7] \n\t"
|
||||
|
||||
// a1 + d1, a3 + d3
|
||||
"paddw %[ftmp5], %[ftmp9], %[ftmp10] \n\t"
|
||||
// b1 + c1, b3 + c3
|
||||
"paddw %[ftmp6], %[ftmp12], %[ftmp11] \n\t"
|
||||
// b1 - c1, b3 - c3
|
||||
"psubw %[ftmp7], %[ftmp12], %[ftmp11] \n\t"
|
||||
// a1 - d1, a3 - d3
|
||||
"psubw %[ftmp8], %[ftmp9], %[ftmp10] \n\t"
|
||||
|
||||
// a2, a4
|
||||
"paddw %[ftmp9], %[ftmp1], %[ftmp3] \n\t"
|
||||
// d2, d4
|
||||
"paddw %[ftmp10], %[ftmp2], %[ftmp4] \n\t"
|
||||
// c2, c4
|
||||
"psubw %[ftmp11], %[ftmp2], %[ftmp4] \n\t"
|
||||
// b2, b4
|
||||
"psubw %[ftmp12], %[ftmp1], %[ftmp3] \n\t"
|
||||
|
||||
// a2 + d2, a4 + d4
|
||||
"paddw %[ftmp1], %[ftmp9], %[ftmp10] \n\t"
|
||||
// b2 + c2, b4 + c4
|
||||
"paddw %[ftmp2], %[ftmp12], %[ftmp11] \n\t"
|
||||
// b2 - c2, b4 - c4
|
||||
"psubw %[ftmp3], %[ftmp12], %[ftmp11] \n\t"
|
||||
// a2 - d2, a4 - d4
|
||||
"psubw %[ftmp4], %[ftmp9], %[ftmp10] \n\t"
|
||||
|
||||
MMI_LI(%[tmp0], 0x03)
|
||||
"mtc1 %[tmp0], %[ftmp11] \n\t"
|
||||
|
||||
"pcmpgtw %[ftmp9], %[ftmp0], %[ftmp1] \n\t"
|
||||
"and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t"
|
||||
"paddw %[ftmp1], %[ftmp1], %[ftmp9] \n\t"
|
||||
"paddw %[ftmp1], %[ftmp1], %[ff_pw_03] \n\t"
|
||||
"psraw %[ftmp1], %[ftmp1], %[ftmp11] \n\t"
|
||||
|
||||
"pcmpgtw %[ftmp9], %[ftmp0], %[ftmp2] \n\t"
|
||||
"and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t"
|
||||
"paddw %[ftmp2], %[ftmp2], %[ftmp9] \n\t"
|
||||
"paddw %[ftmp2], %[ftmp2], %[ff_pw_03] \n\t"
|
||||
"psraw %[ftmp2], %[ftmp2], %[ftmp11] \n\t"
|
||||
|
||||
"pcmpgtw %[ftmp9], %[ftmp0], %[ftmp3] \n\t"
|
||||
"and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t"
|
||||
"paddw %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
|
||||
"paddw %[ftmp3], %[ftmp3], %[ff_pw_03] \n\t"
|
||||
"psraw %[ftmp3], %[ftmp3], %[ftmp11] \n\t"
|
||||
|
||||
"pcmpgtw %[ftmp9], %[ftmp0], %[ftmp4] \n\t"
|
||||
"and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t"
|
||||
"paddw %[ftmp4], %[ftmp4], %[ftmp9] \n\t"
|
||||
"paddw %[ftmp4], %[ftmp4], %[ff_pw_03] \n\t"
|
||||
"psraw %[ftmp4], %[ftmp4], %[ftmp11] \n\t"
|
||||
|
||||
"pcmpgtw %[ftmp9], %[ftmp0], %[ftmp5] \n\t"
|
||||
"and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t"
|
||||
"paddw %[ftmp5], %[ftmp5], %[ftmp9] \n\t"
|
||||
"paddw %[ftmp5], %[ftmp5], %[ff_pw_03] \n\t"
|
||||
"psraw %[ftmp5], %[ftmp5], %[ftmp11] \n\t"
|
||||
|
||||
"pcmpgtw %[ftmp9], %[ftmp0], %[ftmp6] \n\t"
|
||||
"and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t"
|
||||
"paddw %[ftmp6], %[ftmp6], %[ftmp9] \n\t"
|
||||
"paddw %[ftmp6], %[ftmp6], %[ff_pw_03] \n\t"
|
||||
"psraw %[ftmp6], %[ftmp6], %[ftmp11] \n\t"
|
||||
|
||||
"pcmpgtw %[ftmp9], %[ftmp0], %[ftmp7] \n\t"
|
||||
"and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t"
|
||||
"paddw %[ftmp7], %[ftmp7], %[ftmp9] \n\t"
|
||||
"paddw %[ftmp7], %[ftmp7], %[ff_pw_03] \n\t"
|
||||
"psraw %[ftmp7], %[ftmp7], %[ftmp11] \n\t"
|
||||
|
||||
"pcmpgtw %[ftmp9], %[ftmp0], %[ftmp8] \n\t"
|
||||
"and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t"
|
||||
"paddw %[ftmp8], %[ftmp8], %[ftmp9] \n\t"
|
||||
"paddw %[ftmp8], %[ftmp8], %[ff_pw_03] \n\t"
|
||||
"psraw %[ftmp8], %[ftmp8], %[ftmp11] \n\t"
|
||||
|
||||
"packsswh %[ftmp1], %[ftmp1], %[ftmp5] \n\t"
|
||||
"packsswh %[ftmp2], %[ftmp2], %[ftmp6] \n\t"
|
||||
"packsswh %[ftmp3], %[ftmp3], %[ftmp7] \n\t"
|
||||
"packsswh %[ftmp4], %[ftmp4], %[ftmp8] \n\t"
|
||||
|
||||
MMI_LI(%[tmp0], 0x72)
|
||||
"mtc1 %[tmp0], %[ftmp11] \n\t"
|
||||
"pshufh %[ftmp1], %[ftmp1], %[ftmp11] \n\t"
|
||||
"pshufh %[ftmp2], %[ftmp2], %[ftmp11] \n\t"
|
||||
"pshufh %[ftmp3], %[ftmp3], %[ftmp11] \n\t"
|
||||
"pshufh %[ftmp4], %[ftmp4], %[ftmp11] \n\t"
|
||||
|
||||
"gssdlc1 %[ftmp1], 0x07(%[op]) \n\t"
|
||||
"gssdrc1 %[ftmp1], 0x00(%[op]) \n\t"
|
||||
"gssdlc1 %[ftmp2], 0x0f(%[op]) \n\t"
|
||||
"gssdrc1 %[ftmp2], 0x08(%[op]) \n\t"
|
||||
"gssdlc1 %[ftmp3], 0x17(%[op]) \n\t"
|
||||
"gssdrc1 %[ftmp3], 0x10(%[op]) \n\t"
|
||||
"gssdlc1 %[ftmp4], 0x1f(%[op]) \n\t"
|
||||
"gssdrc1 %[ftmp4], 0x18(%[op]) \n\t"
|
||||
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
|
||||
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
|
||||
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
|
||||
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
|
||||
[ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]),
|
||||
[ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]),
|
||||
[ftmp12]"=&f"(ftmp[12]),
|
||||
[tmp0]"=&r"(tmp[0]),
|
||||
[ip]"+&r"(input)
|
||||
: [op]"r"(output),
|
||||
[ff_pw_01]"f"(ff_pw_01), [pitch]"r"((mips_reg)pitch),
|
||||
[ff_pw_03]"f"(ff_pw_03), [ff_pw_mask]"f"(ff_pw_mask),
|
||||
[ff_ph_01]"f"(ff_ph_01)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/asmdefs_mmi.h"
|
||||
#include "vp8/encoder/onyx_int.h"
|
||||
#include "vp8/encoder/quantize.h"
|
||||
#include "vp8/common/quant_common.h"
|
||||
|
||||
#define REGULAR_SELECT_EOB(i, rc) \
|
||||
z = coeff_ptr[rc]; \
|
||||
sz = (z >> 31); \
|
||||
x = (z ^ sz) - sz; \
|
||||
zbin = zbin_ptr[rc] + *(zbin_boost_ptr++) + zbin_oq_value; \
|
||||
if (x >= zbin) { \
|
||||
x += round_ptr[rc]; \
|
||||
y = ((((x * quant_ptr[rc]) >> 16) + x) * quant_shift_ptr[rc]) >> 16; \
|
||||
if (y) { \
|
||||
x = (y ^ sz) - sz; \
|
||||
qcoeff_ptr[rc] = x; \
|
||||
dqcoeff_ptr[rc] = x * dequant_ptr[rc]; \
|
||||
eob = i; \
|
||||
zbin_boost_ptr = b->zrun_zbin_boost; \
|
||||
} \
|
||||
}
|
||||
|
||||
void vp8_fast_quantize_b_mmi(BLOCK *b, BLOCKD *d) {
|
||||
const int16_t *coeff_ptr = b->coeff;
|
||||
const int16_t *round_ptr = b->round;
|
||||
const int16_t *quant_ptr = b->quant_fast;
|
||||
int16_t *qcoeff_ptr = d->qcoeff;
|
||||
int16_t *dqcoeff_ptr = d->dqcoeff;
|
||||
const int16_t *dequant_ptr = d->dequant;
|
||||
const int16_t *inv_zig_zag = vp8_default_inv_zig_zag;
|
||||
|
||||
double ftmp[13];
|
||||
uint64_t tmp[1];
|
||||
DECLARE_ALIGNED(8, const uint64_t, ones) = { 0xffffffffffffffffULL };
|
||||
int eob = 0;
|
||||
|
||||
__asm__ volatile(
|
||||
// loop 0 ~ 7
|
||||
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
|
||||
"gsldlc1 %[ftmp1], 0x07(%[coeff_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp1], 0x00(%[coeff_ptr]) \n\t"
|
||||
"li %[tmp0], 0x0f \n\t"
|
||||
"mtc1 %[tmp0], %[ftmp9] \n\t"
|
||||
"gsldlc1 %[ftmp2], 0x0f(%[coeff_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp2], 0x08(%[coeff_ptr]) \n\t"
|
||||
|
||||
"psrah %[ftmp3], %[ftmp1], %[ftmp9] \n\t"
|
||||
"xor %[ftmp1], %[ftmp3], %[ftmp1] \n\t"
|
||||
"psubh %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
|
||||
"psrah %[ftmp4], %[ftmp2], %[ftmp9] \n\t"
|
||||
"xor %[ftmp2], %[ftmp4], %[ftmp2] \n\t"
|
||||
"psubh %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
|
||||
|
||||
"gsldlc1 %[ftmp5], 0x07(%[round_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp5], 0x00(%[round_ptr]) \n\t"
|
||||
"gsldlc1 %[ftmp6], 0x0f(%[round_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp6], 0x08(%[round_ptr]) \n\t"
|
||||
"paddh %[ftmp5], %[ftmp5], %[ftmp1] \n\t"
|
||||
"paddh %[ftmp6], %[ftmp6], %[ftmp2] \n\t"
|
||||
"gsldlc1 %[ftmp7], 0x07(%[quant_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp7], 0x00(%[quant_ptr]) \n\t"
|
||||
"gsldlc1 %[ftmp8], 0x0f(%[quant_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp8], 0x08(%[quant_ptr]) \n\t"
|
||||
"pmulhuh %[ftmp5], %[ftmp5], %[ftmp7] \n\t"
|
||||
"pmulhuh %[ftmp6], %[ftmp6], %[ftmp8] \n\t"
|
||||
|
||||
"xor %[ftmp7], %[ftmp5], %[ftmp3] \n\t"
|
||||
"xor %[ftmp8], %[ftmp6], %[ftmp4] \n\t"
|
||||
"psubh %[ftmp7], %[ftmp7], %[ftmp3] \n\t"
|
||||
"psubh %[ftmp8], %[ftmp8], %[ftmp4] \n\t"
|
||||
"gssdlc1 %[ftmp7], 0x07(%[qcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp7], 0x00(%[qcoeff_ptr]) \n\t"
|
||||
"gssdlc1 %[ftmp8], 0x0f(%[qcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp8], 0x08(%[qcoeff_ptr]) \n\t"
|
||||
|
||||
"gsldlc1 %[ftmp1], 0x07(%[inv_zig_zag]) \n\t"
|
||||
"gsldrc1 %[ftmp1], 0x00(%[inv_zig_zag]) \n\t"
|
||||
"gsldlc1 %[ftmp2], 0x0f(%[inv_zig_zag]) \n\t"
|
||||
"gsldrc1 %[ftmp2], 0x08(%[inv_zig_zag]) \n\t"
|
||||
"pcmpeqh %[ftmp5], %[ftmp5], %[ftmp0] \n\t"
|
||||
"pcmpeqh %[ftmp6], %[ftmp6], %[ftmp0] \n\t"
|
||||
"xor %[ftmp5], %[ftmp5], %[ones] \n\t"
|
||||
"xor %[ftmp6], %[ftmp6], %[ones] \n\t"
|
||||
"and %[ftmp5], %[ftmp5], %[ftmp1] \n\t"
|
||||
"and %[ftmp6], %[ftmp6], %[ftmp2] \n\t"
|
||||
"pmaxsh %[ftmp10], %[ftmp5], %[ftmp6] \n\t"
|
||||
|
||||
"gsldlc1 %[ftmp5], 0x07(%[dequant_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp5], 0x00(%[dequant_ptr]) \n\t"
|
||||
"gsldlc1 %[ftmp6], 0x0f(%[dequant_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp6], 0x08(%[dequant_ptr]) \n\t"
|
||||
"pmullh %[ftmp5], %[ftmp5], %[ftmp7] \n\t"
|
||||
"pmullh %[ftmp6], %[ftmp6], %[ftmp8] \n\t"
|
||||
"gssdlc1 %[ftmp5], 0x07(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp5], 0x00(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdlc1 %[ftmp6], 0x0f(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp6], 0x08(%[dqcoeff_ptr]) \n\t"
|
||||
|
||||
// loop 8 ~ 15
|
||||
"gsldlc1 %[ftmp1], 0x17(%[coeff_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp1], 0x10(%[coeff_ptr]) \n\t"
|
||||
"gsldlc1 %[ftmp2], 0x1f(%[coeff_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp2], 0x18(%[coeff_ptr]) \n\t"
|
||||
|
||||
"psrah %[ftmp3], %[ftmp1], %[ftmp9] \n\t"
|
||||
"xor %[ftmp1], %[ftmp3], %[ftmp1] \n\t"
|
||||
"psubh %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
|
||||
"psrah %[ftmp4], %[ftmp2], %[ftmp9] \n\t"
|
||||
"xor %[ftmp2], %[ftmp4], %[ftmp2] \n\t"
|
||||
"psubh %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
|
||||
|
||||
"gsldlc1 %[ftmp5], 0x17(%[round_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp5], 0x10(%[round_ptr]) \n\t"
|
||||
"gsldlc1 %[ftmp6], 0x1f(%[round_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp6], 0x18(%[round_ptr]) \n\t"
|
||||
"paddh %[ftmp5], %[ftmp5], %[ftmp1] \n\t"
|
||||
"paddh %[ftmp6], %[ftmp6], %[ftmp2] \n\t"
|
||||
"gsldlc1 %[ftmp7], 0x17(%[quant_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp7], 0x10(%[quant_ptr]) \n\t"
|
||||
"gsldlc1 %[ftmp8], 0x1f(%[quant_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp8], 0x18(%[quant_ptr]) \n\t"
|
||||
"pmulhuh %[ftmp5], %[ftmp5], %[ftmp7] \n\t"
|
||||
"pmulhuh %[ftmp6], %[ftmp6], %[ftmp8] \n\t"
|
||||
|
||||
"xor %[ftmp7], %[ftmp5], %[ftmp3] \n\t"
|
||||
"xor %[ftmp8], %[ftmp6], %[ftmp4] \n\t"
|
||||
"psubh %[ftmp7], %[ftmp7], %[ftmp3] \n\t"
|
||||
"psubh %[ftmp8], %[ftmp8], %[ftmp4] \n\t"
|
||||
"gssdlc1 %[ftmp7], 0x17(%[qcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp7], 0x10(%[qcoeff_ptr]) \n\t"
|
||||
"gssdlc1 %[ftmp8], 0x1f(%[qcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp8], 0x18(%[qcoeff_ptr]) \n\t"
|
||||
|
||||
"gsldlc1 %[ftmp1], 0x17(%[inv_zig_zag]) \n\t"
|
||||
"gsldrc1 %[ftmp1], 0x10(%[inv_zig_zag]) \n\t"
|
||||
"gsldlc1 %[ftmp2], 0x1f(%[inv_zig_zag]) \n\t"
|
||||
"gsldrc1 %[ftmp2], 0x18(%[inv_zig_zag]) \n\t"
|
||||
"pcmpeqh %[ftmp5], %[ftmp5], %[ftmp0] \n\t"
|
||||
"pcmpeqh %[ftmp6], %[ftmp6], %[ftmp0] \n\t"
|
||||
"xor %[ftmp5], %[ftmp5], %[ones] \n\t"
|
||||
"xor %[ftmp6], %[ftmp6], %[ones] \n\t"
|
||||
"and %[ftmp5], %[ftmp5], %[ftmp1] \n\t"
|
||||
"and %[ftmp6], %[ftmp6], %[ftmp2] \n\t"
|
||||
"pmaxsh %[ftmp11], %[ftmp5], %[ftmp6] \n\t"
|
||||
|
||||
"gsldlc1 %[ftmp5], 0x17(%[dequant_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp5], 0x10(%[dequant_ptr]) \n\t"
|
||||
"gsldlc1 %[ftmp6], 0x1f(%[dequant_ptr]) \n\t"
|
||||
"gsldrc1 %[ftmp6], 0x18(%[dequant_ptr]) \n\t"
|
||||
"pmullh %[ftmp5], %[ftmp5], %[ftmp7] \n\t"
|
||||
"pmullh %[ftmp6], %[ftmp6], %[ftmp8] \n\t"
|
||||
"gssdlc1 %[ftmp5], 0x17(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp5], 0x10(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdlc1 %[ftmp6], 0x1f(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp6], 0x18(%[dqcoeff_ptr]) \n\t"
|
||||
|
||||
"li %[tmp0], 0x10 \n\t"
|
||||
"mtc1 %[tmp0], %[ftmp9] \n\t"
|
||||
|
||||
"pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t"
|
||||
"psrlw %[ftmp11], %[ftmp10], %[ftmp9] \n\t"
|
||||
"pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t"
|
||||
"li %[tmp0], 0xaa \n\t"
|
||||
"mtc1 %[tmp0], %[ftmp9] \n\t"
|
||||
"pshufh %[ftmp11], %[ftmp10], %[ftmp9] \n\t"
|
||||
"pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t"
|
||||
"li %[tmp0], 0xffff \n\t"
|
||||
"mtc1 %[tmp0], %[ftmp9] \n\t"
|
||||
"and %[ftmp10], %[ftmp10], %[ftmp9] \n\t"
|
||||
"gssdlc1 %[ftmp10], 0x07(%[eob]) \n\t"
|
||||
"gssdrc1 %[ftmp10], 0x00(%[eob]) \n\t"
|
||||
: [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), [ftmp2] "=&f"(ftmp[2]),
|
||||
[ftmp3] "=&f"(ftmp[3]), [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]),
|
||||
[ftmp6] "=&f"(ftmp[6]), [ftmp7] "=&f"(ftmp[7]), [ftmp8] "=&f"(ftmp[8]),
|
||||
[ftmp9] "=&f"(ftmp[9]), [ftmp10] "=&f"(ftmp[10]),
|
||||
[ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), [tmp0] "=&r"(tmp[0])
|
||||
: [coeff_ptr] "r"((mips_reg)coeff_ptr),
|
||||
[qcoeff_ptr] "r"((mips_reg)qcoeff_ptr),
|
||||
[dequant_ptr] "r"((mips_reg)dequant_ptr),
|
||||
[round_ptr] "r"((mips_reg)round_ptr),
|
||||
[quant_ptr] "r"((mips_reg)quant_ptr),
|
||||
[dqcoeff_ptr] "r"((mips_reg)dqcoeff_ptr),
|
||||
[inv_zig_zag] "r"((mips_reg)inv_zig_zag), [eob] "r"((mips_reg)&eob),
|
||||
[ones] "f"(ones)
|
||||
: "memory");
|
||||
|
||||
*d->eob = eob;
|
||||
}
|
||||
|
||||
void vp8_regular_quantize_b_mmi(BLOCK *b, BLOCKD *d) {
|
||||
int eob = 0;
|
||||
int x, y, z, sz, zbin;
|
||||
const int16_t *zbin_boost_ptr = b->zrun_zbin_boost;
|
||||
const int16_t *coeff_ptr = b->coeff;
|
||||
const int16_t *zbin_ptr = b->zbin;
|
||||
const int16_t *round_ptr = b->round;
|
||||
const int16_t *quant_ptr = b->quant;
|
||||
const int16_t *quant_shift_ptr = b->quant_shift;
|
||||
int16_t *qcoeff_ptr = d->qcoeff;
|
||||
int16_t *dqcoeff_ptr = d->dqcoeff;
|
||||
const int16_t *dequant_ptr = d->dequant;
|
||||
const int16_t zbin_oq_value = b->zbin_extra;
|
||||
register double ftmp0 asm("$f0");
|
||||
|
||||
// memset(qcoeff_ptr, 0, 32);
|
||||
// memset(dqcoeff_ptr, 0, 32);
|
||||
/* clang-format off */
|
||||
__asm__ volatile (
|
||||
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
|
||||
"gssdlc1 %[ftmp0], 0x07(%[qcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp0], 0x00(%[qcoeff_ptr]) \n\t"
|
||||
"gssdlc1 %[ftmp0], 0x0f(%[qcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp0], 0x08(%[qcoeff_ptr]) \n\t"
|
||||
"gssdlc1 %[ftmp0], 0x17(%[qcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp0], 0x10(%[qcoeff_ptr]) \n\t"
|
||||
"gssdlc1 %[ftmp0], 0x1f(%[qcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp0], 0x18(%[qcoeff_ptr]) \n\t"
|
||||
|
||||
"gssdlc1 %[ftmp0], 0x07(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp0], 0x00(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdlc1 %[ftmp0], 0x0f(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp0], 0x08(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdlc1 %[ftmp0], 0x17(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp0], 0x10(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdlc1 %[ftmp0], 0x1f(%[dqcoeff_ptr]) \n\t"
|
||||
"gssdrc1 %[ftmp0], 0x18(%[dqcoeff_ptr]) \n\t"
|
||||
: [ftmp0]"=&f"(ftmp0)
|
||||
: [qcoeff_ptr]"r"(qcoeff_ptr), [dqcoeff_ptr]"r"(dqcoeff_ptr)
|
||||
: "memory"
|
||||
);
|
||||
/* clang-format on */
|
||||
|
||||
REGULAR_SELECT_EOB(1, 0);
|
||||
REGULAR_SELECT_EOB(2, 1);
|
||||
REGULAR_SELECT_EOB(3, 4);
|
||||
REGULAR_SELECT_EOB(4, 8);
|
||||
REGULAR_SELECT_EOB(5, 5);
|
||||
REGULAR_SELECT_EOB(6, 2);
|
||||
REGULAR_SELECT_EOB(7, 3);
|
||||
REGULAR_SELECT_EOB(8, 6);
|
||||
REGULAR_SELECT_EOB(9, 9);
|
||||
REGULAR_SELECT_EOB(10, 12);
|
||||
REGULAR_SELECT_EOB(11, 13);
|
||||
REGULAR_SELECT_EOB(12, 10);
|
||||
REGULAR_SELECT_EOB(13, 7);
|
||||
REGULAR_SELECT_EOB(14, 11);
|
||||
REGULAR_SELECT_EOB(15, 14);
|
||||
REGULAR_SELECT_EOB(16, 15);
|
||||
|
||||
*d->eob = (char)eob;
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "vp8/common/mips/msa/vp8_macros_msa.h"
|
||||
|
||||
#define TRANSPOSE4x4_H(in0, in1, in2, in3, out0, out1, out2, out3) \
|
||||
{ \
|
||||
v8i16 s0_m, s1_m, tp0_m, tp1_m, tp2_m, tp3_m; \
|
||||
\
|
||||
ILVR_H2_SH(in2, in0, in3, in1, s0_m, s1_m); \
|
||||
ILVRL_H2_SH(s1_m, s0_m, tp0_m, tp1_m); \
|
||||
ILVL_H2_SH(in2, in0, in3, in1, s0_m, s1_m); \
|
||||
ILVRL_H2_SH(s1_m, s0_m, tp2_m, tp3_m); \
|
||||
PCKEV_D2_SH(tp2_m, tp0_m, tp3_m, tp1_m, out0, out2); \
|
||||
PCKOD_D2_SH(tp2_m, tp0_m, tp3_m, tp1_m, out1, out3); \
|
||||
}
|
||||
|
||||
#define SET_DOTP_VALUES(coeff, val0, val1, val2, const1, const2) \
|
||||
{ \
|
||||
v8i16 tmp0_m; \
|
||||
\
|
||||
SPLATI_H3_SH(coeff, val0, val1, val2, tmp0_m, const1, const2); \
|
||||
ILVEV_H2_SH(tmp0_m, const1, const2, tmp0_m, const1, const2); \
|
||||
}
|
||||
|
||||
#define RET_1_IF_NZERO_H(in0) \
|
||||
({ \
|
||||
v8i16 tmp0_m; \
|
||||
v8i16 one_m = __msa_ldi_h(1); \
|
||||
\
|
||||
tmp0_m = __msa_ceqi_h(in0, 0); \
|
||||
tmp0_m = tmp0_m ^ 255; \
|
||||
tmp0_m = one_m & tmp0_m; \
|
||||
\
|
||||
tmp0_m; \
|
||||
})
|
||||
|
||||
#define RET_1_IF_NZERO_W(in0) \
|
||||
({ \
|
||||
v4i32 tmp0_m; \
|
||||
v4i32 one_m = __msa_ldi_w(1); \
|
||||
\
|
||||
tmp0_m = __msa_ceqi_w(in0, 0); \
|
||||
tmp0_m = tmp0_m ^ 255; \
|
||||
tmp0_m = one_m & tmp0_m; \
|
||||
\
|
||||
tmp0_m; \
|
||||
})
|
||||
|
||||
#define RET_1_IF_NEG_W(in0) \
|
||||
({ \
|
||||
v4i32 tmp0_m; \
|
||||
\
|
||||
v4i32 one_m = __msa_ldi_w(1); \
|
||||
tmp0_m = __msa_clti_s_w(in0, 0); \
|
||||
tmp0_m = one_m & tmp0_m; \
|
||||
\
|
||||
tmp0_m; \
|
||||
})
|
||||
|
||||
void vp8_short_fdct4x4_msa(int16_t *input, int16_t *output, int32_t pitch) {
|
||||
v8i16 in0, in1, in2, in3;
|
||||
v8i16 temp0, temp1;
|
||||
v8i16 const0, const1;
|
||||
v8i16 coeff = { 2217, 5352, -5352, 14500, 7500, 12000, 25000, 26000 };
|
||||
v4i32 out0, out1, out2, out3;
|
||||
v8i16 zero = { 0 };
|
||||
|
||||
LD_SH4(input, pitch / 2, in0, in1, in2, in3);
|
||||
TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
|
||||
BUTTERFLY_4(in0, in1, in2, in3, temp0, temp1, in1, in3);
|
||||
SLLI_4V(temp0, temp1, in1, in3, 3);
|
||||
in0 = temp0 + temp1;
|
||||
in2 = temp0 - temp1;
|
||||
SET_DOTP_VALUES(coeff, 0, 1, 2, const0, const1);
|
||||
temp0 = __msa_ilvr_h(in3, in1);
|
||||
in1 = __msa_splati_h(coeff, 3);
|
||||
out0 = (v4i32)__msa_ilvev_h(zero, in1);
|
||||
coeff = __msa_ilvl_h(zero, coeff);
|
||||
out1 = __msa_splati_w((v4i32)coeff, 0);
|
||||
DPADD_SH2_SW(temp0, temp0, const0, const1, out0, out1);
|
||||
out0 >>= 12;
|
||||
out1 >>= 12;
|
||||
PCKEV_H2_SH(out0, out0, out1, out1, in1, in3);
|
||||
TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
|
||||
BUTTERFLY_4(in0, in1, in2, in3, temp0, temp1, in1, in3);
|
||||
in0 = temp0 + temp1 + 7;
|
||||
in2 = temp0 - temp1 + 7;
|
||||
in0 >>= 4;
|
||||
in2 >>= 4;
|
||||
ILVR_H2_SW(zero, in0, zero, in2, out0, out2);
|
||||
temp1 = RET_1_IF_NZERO_H(in3);
|
||||
ILVR_H2_SH(zero, temp1, in3, in1, temp1, temp0);
|
||||
SPLATI_W2_SW(coeff, 2, out3, out1);
|
||||
out3 += out1;
|
||||
out1 = __msa_splati_w((v4i32)coeff, 1);
|
||||
DPADD_SH2_SW(temp0, temp0, const0, const1, out1, out3);
|
||||
out1 >>= 16;
|
||||
out3 >>= 16;
|
||||
out1 += (v4i32)temp1;
|
||||
PCKEV_H2_SH(out1, out0, out3, out2, in0, in2);
|
||||
ST_SH2(in0, in2, output, 8);
|
||||
}
|
||||
|
||||
void vp8_short_fdct8x4_msa(int16_t *input, int16_t *output, int32_t pitch) {
|
||||
v8i16 in0, in1, in2, in3;
|
||||
v8i16 temp0, temp1, tmp0, tmp1;
|
||||
v8i16 const0, const1, const2;
|
||||
v8i16 coeff = { 2217, 5352, -5352, 14500, 7500, 12000, 25000, 26000 };
|
||||
v8i16 zero = { 0 };
|
||||
v4i32 vec0_w, vec1_w, vec2_w, vec3_w;
|
||||
|
||||
LD_SH4(input, pitch / 2, in0, in1, in2, in3);
|
||||
TRANSPOSE4x4_H(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
|
||||
BUTTERFLY_4(in0, in1, in2, in3, temp0, temp1, in1, in3);
|
||||
SLLI_4V(temp0, temp1, in1, in3, 3);
|
||||
in0 = temp0 + temp1;
|
||||
in2 = temp0 - temp1;
|
||||
SET_DOTP_VALUES(coeff, 0, 1, 2, const1, const2);
|
||||
temp0 = __msa_splati_h(coeff, 3);
|
||||
vec1_w = (v4i32)__msa_ilvev_h(zero, temp0);
|
||||
coeff = __msa_ilvl_h(zero, coeff);
|
||||
vec3_w = __msa_splati_w((v4i32)coeff, 0);
|
||||
ILVRL_H2_SH(in3, in1, tmp1, tmp0);
|
||||
vec0_w = vec1_w;
|
||||
vec2_w = vec3_w;
|
||||
DPADD_SH4_SW(tmp1, tmp0, tmp1, tmp0, const1, const1, const2, const2, vec0_w,
|
||||
vec1_w, vec2_w, vec3_w);
|
||||
SRA_4V(vec1_w, vec0_w, vec3_w, vec2_w, 12);
|
||||
PCKEV_H2_SH(vec1_w, vec0_w, vec3_w, vec2_w, in1, in3);
|
||||
TRANSPOSE4x4_H(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
|
||||
BUTTERFLY_4(in0, in1, in2, in3, temp0, temp1, in1, in3);
|
||||
in0 = temp0 + temp1 + 7;
|
||||
in2 = temp0 - temp1 + 7;
|
||||
in0 >>= 4;
|
||||
in2 >>= 4;
|
||||
SPLATI_W2_SW(coeff, 2, vec3_w, vec1_w);
|
||||
vec3_w += vec1_w;
|
||||
vec1_w = __msa_splati_w((v4i32)coeff, 1);
|
||||
const0 = RET_1_IF_NZERO_H(in3);
|
||||
ILVRL_H2_SH(in3, in1, tmp1, tmp0);
|
||||
vec0_w = vec1_w;
|
||||
vec2_w = vec3_w;
|
||||
DPADD_SH4_SW(tmp1, tmp0, tmp1, tmp0, const1, const1, const2, const2, vec0_w,
|
||||
vec1_w, vec2_w, vec3_w);
|
||||
SRA_4V(vec1_w, vec0_w, vec3_w, vec2_w, 16);
|
||||
PCKEV_H2_SH(vec1_w, vec0_w, vec3_w, vec2_w, in1, in3);
|
||||
in1 += const0;
|
||||
PCKEV_D2_SH(in1, in0, in3, in2, temp0, temp1);
|
||||
ST_SH2(temp0, temp1, output, 8);
|
||||
|
||||
PCKOD_D2_SH(in1, in0, in3, in2, in0, in2);
|
||||
ST_SH2(in0, in2, output + 16, 8);
|
||||
}
|
||||
|
||||
void vp8_short_walsh4x4_msa(int16_t *input, int16_t *output, int32_t pitch) {
|
||||
v8i16 in0_h, in1_h, in2_h, in3_h;
|
||||
v4i32 in0_w, in1_w, in2_w, in3_w, temp0, temp1, temp2, temp3;
|
||||
|
||||
LD_SH4(input, pitch / 2, in0_h, in1_h, in2_h, in3_h);
|
||||
TRANSPOSE4x4_SH_SH(in0_h, in1_h, in2_h, in3_h, in0_h, in1_h, in2_h, in3_h);
|
||||
|
||||
UNPCK_R_SH_SW(in0_h, in0_w);
|
||||
UNPCK_R_SH_SW(in1_h, in1_w);
|
||||
UNPCK_R_SH_SW(in2_h, in2_w);
|
||||
UNPCK_R_SH_SW(in3_h, in3_w);
|
||||
BUTTERFLY_4(in0_w, in1_w, in3_w, in2_w, temp0, temp3, temp2, temp1);
|
||||
SLLI_4V(temp0, temp1, temp2, temp3, 2);
|
||||
BUTTERFLY_4(temp0, temp1, temp2, temp3, in0_w, in1_w, in2_w, in3_w);
|
||||
temp0 = RET_1_IF_NZERO_W(temp0);
|
||||
in0_w += temp0;
|
||||
TRANSPOSE4x4_SW_SW(in0_w, in1_w, in2_w, in3_w, in0_w, in1_w, in2_w, in3_w);
|
||||
|
||||
BUTTERFLY_4(in0_w, in1_w, in3_w, in2_w, temp0, temp3, temp2, temp1);
|
||||
BUTTERFLY_4(temp0, temp1, temp2, temp3, in0_w, in1_w, in2_w, in3_w);
|
||||
in0_w += RET_1_IF_NEG_W(in0_w);
|
||||
in1_w += RET_1_IF_NEG_W(in1_w);
|
||||
in2_w += RET_1_IF_NEG_W(in2_w);
|
||||
in3_w += RET_1_IF_NEG_W(in3_w);
|
||||
ADD4(in0_w, 3, in1_w, 3, in2_w, 3, in3_w, 3, in0_w, in1_w, in2_w, in3_w);
|
||||
SRA_4V(in0_w, in1_w, in2_w, in3_w, 3);
|
||||
PCKEV_H2_SH(in1_w, in0_w, in3_w, in2_w, in0_h, in1_h);
|
||||
ST_SH2(in0_h, in1_h, output, 8);
|
||||
}
|
||||
@@ -0,0 +1,568 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "vp8/common/mips/msa/vp8_macros_msa.h"
|
||||
#include "vp8/encoder/denoising.h"
|
||||
|
||||
int32_t vp8_denoiser_filter_msa(uint8_t *mc_running_avg_y_ptr,
|
||||
int32_t mc_avg_y_stride,
|
||||
uint8_t *running_avg_y_ptr,
|
||||
int32_t avg_y_stride, uint8_t *sig_ptr,
|
||||
int32_t sig_stride, uint32_t motion_magnitude,
|
||||
int32_t increase_denoising) {
|
||||
uint8_t *running_avg_y_start = running_avg_y_ptr;
|
||||
uint8_t *sig_start = sig_ptr;
|
||||
int32_t cnt = 0;
|
||||
int32_t sum_diff = 0;
|
||||
int32_t shift_inc1 = 3;
|
||||
int32_t delta = 0;
|
||||
int32_t sum_diff_thresh;
|
||||
v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
|
||||
v16u8 src8, src9, src10, src11, src12, src13, src14, src15;
|
||||
v16u8 mc_running_avg_y0, running_avg_y, sig0;
|
||||
v16u8 mc_running_avg_y1, running_avg_y1, sig1;
|
||||
v16u8 coeff0, coeff1;
|
||||
v8i16 diff0, diff1, abs_diff0, abs_diff1, abs_diff_neg0, abs_diff_neg1;
|
||||
v8i16 adjust0, adjust1, adjust2, adjust3;
|
||||
v8i16 shift_inc1_vec = { 0 };
|
||||
v8i16 col_sum0 = { 0 };
|
||||
v8i16 col_sum1 = { 0 };
|
||||
v8i16 col_sum2 = { 0 };
|
||||
v8i16 col_sum3 = { 0 };
|
||||
v8i16 temp0_h, temp1_h, temp2_h, temp3_h, cmp, delta_vec;
|
||||
v4i32 temp0_w;
|
||||
v2i64 temp0_d, temp1_d;
|
||||
v8i16 zero = { 0 };
|
||||
v8i16 one = __msa_ldi_h(1);
|
||||
v8i16 four = __msa_ldi_h(4);
|
||||
v8i16 val_127 = __msa_ldi_h(127);
|
||||
v8i16 adj_val = { 6, 4, 3, 0, -6, -4, -3, 0 };
|
||||
|
||||
if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) {
|
||||
adj_val = __msa_add_a_h(adj_val, one);
|
||||
if (increase_denoising) {
|
||||
adj_val = __msa_add_a_h(adj_val, one);
|
||||
shift_inc1 = 4;
|
||||
}
|
||||
|
||||
temp0_h = zero - adj_val;
|
||||
adj_val = (v8i16)__msa_ilvev_d((v2i64)temp0_h, (v2i64)adj_val);
|
||||
}
|
||||
|
||||
adj_val = __msa_insert_h(adj_val, 3, cnt);
|
||||
adj_val = __msa_insert_h(adj_val, 7, cnt);
|
||||
shift_inc1_vec = __msa_fill_h(shift_inc1);
|
||||
|
||||
for (cnt = 8; cnt--;) {
|
||||
v8i16 mask0 = { 0 };
|
||||
v8i16 mask1 = { 0 };
|
||||
|
||||
mc_running_avg_y0 = LD_UB(mc_running_avg_y_ptr);
|
||||
sig0 = LD_UB(sig_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
mc_running_avg_y_ptr += mc_avg_y_stride;
|
||||
|
||||
mc_running_avg_y1 = LD_UB(mc_running_avg_y_ptr);
|
||||
sig1 = LD_UB(sig_ptr);
|
||||
|
||||
ILVRL_B2_UB(mc_running_avg_y0, sig0, coeff0, coeff1);
|
||||
HSUB_UB2_SH(coeff0, coeff1, diff0, diff1);
|
||||
abs_diff0 = __msa_add_a_h(diff0, zero);
|
||||
abs_diff1 = __msa_add_a_h(diff1, zero);
|
||||
cmp = __msa_clei_s_h(abs_diff0, 15);
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
cmp = __msa_clei_s_h(abs_diff0, 7);
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
cmp = abs_diff0 < shift_inc1_vec;
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
cmp = __msa_clei_s_h(abs_diff1, 15);
|
||||
cmp = cmp & one;
|
||||
mask1 += cmp;
|
||||
cmp = __msa_clei_s_h(abs_diff1, 7);
|
||||
cmp = cmp & one;
|
||||
mask1 += cmp;
|
||||
cmp = abs_diff1 < shift_inc1_vec;
|
||||
cmp = cmp & one;
|
||||
mask1 += cmp;
|
||||
temp0_h = __msa_clei_s_h(diff0, 0);
|
||||
temp0_h = temp0_h & four;
|
||||
mask0 += temp0_h;
|
||||
temp1_h = __msa_clei_s_h(diff1, 0);
|
||||
temp1_h = temp1_h & four;
|
||||
mask1 += temp1_h;
|
||||
VSHF_H2_SH(adj_val, adj_val, adj_val, adj_val, mask0, mask1, adjust0,
|
||||
adjust1);
|
||||
temp2_h = __msa_ceqi_h(adjust0, 0);
|
||||
temp3_h = __msa_ceqi_h(adjust1, 0);
|
||||
adjust0 = (v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)diff0, (v16u8)temp2_h);
|
||||
adjust1 = (v8i16)__msa_bmnz_v((v16u8)adjust1, (v16u8)diff1, (v16u8)temp3_h);
|
||||
ADD2(col_sum0, adjust0, col_sum1, adjust1, col_sum0, col_sum1);
|
||||
UNPCK_UB_SH(sig0, temp0_h, temp1_h);
|
||||
ADD2(temp0_h, adjust0, temp1_h, adjust1, temp0_h, temp1_h);
|
||||
MAXI_SH2_SH(temp0_h, temp1_h, 0);
|
||||
SAT_UH2_SH(temp0_h, temp1_h, 7);
|
||||
temp2_h = (v8i16)__msa_pckev_b((v16i8)temp3_h, (v16i8)temp2_h);
|
||||
running_avg_y = (v16u8)__msa_pckev_b((v16i8)temp1_h, (v16i8)temp0_h);
|
||||
running_avg_y =
|
||||
__msa_bmnz_v(running_avg_y, mc_running_avg_y0, (v16u8)temp2_h);
|
||||
ST_UB(running_avg_y, running_avg_y_ptr);
|
||||
running_avg_y_ptr += avg_y_stride;
|
||||
|
||||
mask0 = zero;
|
||||
mask1 = zero;
|
||||
ILVRL_B2_UB(mc_running_avg_y1, sig1, coeff0, coeff1);
|
||||
HSUB_UB2_SH(coeff0, coeff1, diff0, diff1);
|
||||
abs_diff0 = __msa_add_a_h(diff0, zero);
|
||||
abs_diff1 = __msa_add_a_h(diff1, zero);
|
||||
cmp = __msa_clei_s_h(abs_diff0, 15);
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
cmp = __msa_clei_s_h(abs_diff0, 7);
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
cmp = abs_diff0 < shift_inc1_vec;
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
cmp = __msa_clei_s_h(abs_diff1, 15);
|
||||
cmp = cmp & one;
|
||||
mask1 += cmp;
|
||||
cmp = __msa_clei_s_h(abs_diff1, 7);
|
||||
cmp = cmp & one;
|
||||
mask1 += cmp;
|
||||
cmp = abs_diff1 < shift_inc1_vec;
|
||||
cmp = cmp & one;
|
||||
mask1 += cmp;
|
||||
temp0_h = __msa_clei_s_h(diff0, 0);
|
||||
temp0_h = temp0_h & four;
|
||||
mask0 += temp0_h;
|
||||
temp1_h = __msa_clei_s_h(diff1, 0);
|
||||
temp1_h = temp1_h & four;
|
||||
mask1 += temp1_h;
|
||||
VSHF_H2_SH(adj_val, adj_val, adj_val, adj_val, mask0, mask1, adjust0,
|
||||
adjust1);
|
||||
temp2_h = __msa_ceqi_h(adjust0, 0);
|
||||
temp3_h = __msa_ceqi_h(adjust1, 0);
|
||||
adjust0 = (v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)diff0, (v16u8)temp2_h);
|
||||
adjust1 = (v8i16)__msa_bmnz_v((v16u8)adjust1, (v16u8)diff1, (v16u8)temp3_h);
|
||||
ADD2(col_sum0, adjust0, col_sum1, adjust1, col_sum0, col_sum1);
|
||||
UNPCK_UB_SH(sig1, temp0_h, temp1_h);
|
||||
ADD2(temp0_h, adjust0, temp1_h, adjust1, temp0_h, temp1_h);
|
||||
MAXI_SH2_SH(temp0_h, temp1_h, 0);
|
||||
SAT_UH2_SH(temp0_h, temp1_h, 7);
|
||||
temp2_h = (v8i16)__msa_pckev_b((v16i8)temp3_h, (v16i8)temp2_h);
|
||||
running_avg_y = (v16u8)__msa_pckev_b((v16i8)temp1_h, (v16i8)temp0_h);
|
||||
running_avg_y =
|
||||
__msa_bmnz_v(running_avg_y, mc_running_avg_y1, (v16u8)temp2_h);
|
||||
ST_UB(running_avg_y, running_avg_y_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
mc_running_avg_y_ptr += mc_avg_y_stride;
|
||||
running_avg_y_ptr += avg_y_stride;
|
||||
}
|
||||
|
||||
col_sum0 = __msa_min_s_h(col_sum0, val_127);
|
||||
col_sum1 = __msa_min_s_h(col_sum1, val_127);
|
||||
temp0_h = col_sum0 + col_sum1;
|
||||
temp0_w = __msa_hadd_s_w(temp0_h, temp0_h);
|
||||
temp0_d = __msa_hadd_s_d(temp0_w, temp0_w);
|
||||
temp1_d = __msa_splati_d(temp0_d, 1);
|
||||
temp0_d += temp1_d;
|
||||
sum_diff = __msa_copy_s_w((v4i32)temp0_d, 0);
|
||||
sig_ptr -= sig_stride * 16;
|
||||
mc_running_avg_y_ptr -= mc_avg_y_stride * 16;
|
||||
running_avg_y_ptr -= avg_y_stride * 16;
|
||||
|
||||
if (increase_denoising) {
|
||||
sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH;
|
||||
}
|
||||
|
||||
if (abs(sum_diff) > sum_diff_thresh) {
|
||||
delta = ((abs(sum_diff) - sum_diff_thresh) >> 8) + 1;
|
||||
delta_vec = __msa_fill_h(delta);
|
||||
if (delta < 4) {
|
||||
for (cnt = 8; cnt--;) {
|
||||
running_avg_y = LD_UB(running_avg_y_ptr);
|
||||
mc_running_avg_y0 = LD_UB(mc_running_avg_y_ptr);
|
||||
sig0 = LD_UB(sig_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
mc_running_avg_y_ptr += mc_avg_y_stride;
|
||||
running_avg_y_ptr += avg_y_stride;
|
||||
mc_running_avg_y1 = LD_UB(mc_running_avg_y_ptr);
|
||||
sig1 = LD_UB(sig_ptr);
|
||||
running_avg_y1 = LD_UB(running_avg_y_ptr);
|
||||
ILVRL_B2_UB(mc_running_avg_y0, sig0, coeff0, coeff1);
|
||||
HSUB_UB2_SH(coeff0, coeff1, diff0, diff1);
|
||||
abs_diff0 = __msa_add_a_h(diff0, zero);
|
||||
abs_diff1 = __msa_add_a_h(diff1, zero);
|
||||
temp0_h = abs_diff0 < delta_vec;
|
||||
temp1_h = abs_diff1 < delta_vec;
|
||||
abs_diff0 = (v8i16)__msa_bmz_v((v16u8)abs_diff0, (v16u8)delta_vec,
|
||||
(v16u8)temp0_h);
|
||||
abs_diff1 = (v8i16)__msa_bmz_v((v16u8)abs_diff1, (v16u8)delta_vec,
|
||||
(v16u8)temp1_h);
|
||||
SUB2(zero, abs_diff0, zero, abs_diff1, abs_diff_neg0, abs_diff_neg1);
|
||||
abs_diff_neg0 = zero - abs_diff0;
|
||||
abs_diff_neg1 = zero - abs_diff1;
|
||||
temp0_h = __msa_clei_s_h(diff0, 0);
|
||||
temp1_h = __msa_clei_s_h(diff1, 0);
|
||||
adjust0 = (v8i16)__msa_bmnz_v((v16u8)abs_diff0, (v16u8)abs_diff_neg0,
|
||||
(v16u8)temp0_h);
|
||||
adjust1 = (v8i16)__msa_bmnz_v((v16u8)abs_diff1, (v16u8)abs_diff_neg1,
|
||||
(v16u8)temp1_h);
|
||||
ILVRL_B2_SH(zero, running_avg_y, temp2_h, temp3_h);
|
||||
ADD2(temp2_h, adjust0, temp3_h, adjust1, adjust2, adjust3);
|
||||
MAXI_SH2_SH(adjust2, adjust3, 0);
|
||||
SAT_UH2_SH(adjust2, adjust3, 7);
|
||||
temp0_h = __msa_ceqi_h(diff0, 0);
|
||||
temp1_h = __msa_ceqi_h(diff1, 0);
|
||||
adjust2 =
|
||||
(v8i16)__msa_bmz_v((v16u8)adjust2, (v16u8)temp2_h, (v16u8)temp0_h);
|
||||
adjust3 =
|
||||
(v8i16)__msa_bmz_v((v16u8)adjust3, (v16u8)temp3_h, (v16u8)temp1_h);
|
||||
adjust0 =
|
||||
(v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)zero, (v16u8)temp0_h);
|
||||
adjust1 =
|
||||
(v8i16)__msa_bmnz_v((v16u8)adjust1, (v16u8)zero, (v16u8)temp1_h);
|
||||
ADD2(col_sum2, adjust0, col_sum3, adjust1, col_sum2, col_sum3);
|
||||
running_avg_y = (v16u8)__msa_pckev_b((v16i8)adjust3, (v16i8)adjust2);
|
||||
ST_UB(running_avg_y, running_avg_y_ptr - avg_y_stride);
|
||||
ILVRL_B2_UB(mc_running_avg_y1, sig1, coeff0, coeff1);
|
||||
HSUB_UB2_SH(coeff0, coeff1, diff0, diff1);
|
||||
abs_diff0 = __msa_add_a_h(diff0, zero);
|
||||
abs_diff1 = __msa_add_a_h(diff1, zero);
|
||||
temp0_h = abs_diff0 < delta_vec;
|
||||
temp1_h = abs_diff1 < delta_vec;
|
||||
abs_diff0 = (v8i16)__msa_bmz_v((v16u8)abs_diff0, (v16u8)delta_vec,
|
||||
(v16u8)temp0_h);
|
||||
abs_diff1 = (v8i16)__msa_bmz_v((v16u8)abs_diff1, (v16u8)delta_vec,
|
||||
(v16u8)temp1_h);
|
||||
SUB2(zero, abs_diff0, zero, abs_diff1, abs_diff_neg0, abs_diff_neg1);
|
||||
temp0_h = __msa_clei_s_h(diff0, 0);
|
||||
temp1_h = __msa_clei_s_h(diff1, 0);
|
||||
adjust0 = (v8i16)__msa_bmnz_v((v16u8)abs_diff0, (v16u8)abs_diff_neg0,
|
||||
(v16u8)temp0_h);
|
||||
adjust1 = (v8i16)__msa_bmnz_v((v16u8)abs_diff1, (v16u8)abs_diff_neg1,
|
||||
(v16u8)temp1_h);
|
||||
ILVRL_H2_SH(zero, running_avg_y1, temp2_h, temp3_h);
|
||||
ADD2(temp2_h, adjust0, temp3_h, adjust1, adjust2, adjust3);
|
||||
MAXI_SH2_SH(adjust2, adjust3, 0);
|
||||
SAT_UH2_SH(adjust2, adjust3, 7);
|
||||
temp0_h = __msa_ceqi_h(diff0, 0);
|
||||
temp1_h = __msa_ceqi_h(diff1, 0);
|
||||
adjust2 =
|
||||
(v8i16)__msa_bmz_v((v16u8)adjust2, (v16u8)temp2_h, (v16u8)temp0_h);
|
||||
adjust3 =
|
||||
(v8i16)__msa_bmz_v((v16u8)adjust3, (v16u8)temp3_h, (v16u8)temp1_h);
|
||||
adjust0 =
|
||||
(v8i16)__msa_bmz_v((v16u8)adjust0, (v16u8)zero, (v16u8)temp0_h);
|
||||
adjust1 =
|
||||
(v8i16)__msa_bmz_v((v16u8)adjust1, (v16u8)zero, (v16u8)temp1_h);
|
||||
ADD2(col_sum2, adjust0, col_sum3, adjust1, col_sum2, col_sum3);
|
||||
running_avg_y = (v16u8)__msa_pckev_b((v16i8)adjust3, (v16i8)adjust2);
|
||||
ST_UB(running_avg_y, running_avg_y_ptr);
|
||||
running_avg_y_ptr += avg_y_stride;
|
||||
}
|
||||
|
||||
col_sum2 = __msa_min_s_h(col_sum2, val_127);
|
||||
col_sum3 = __msa_min_s_h(col_sum3, val_127);
|
||||
temp0_h = col_sum2 + col_sum3;
|
||||
temp0_w = __msa_hadd_s_w(temp0_h, temp0_h);
|
||||
temp0_d = __msa_hadd_s_d(temp0_w, temp0_w);
|
||||
temp1_d = __msa_splati_d(temp0_d, 1);
|
||||
temp0_d += (v2i64)temp1_d;
|
||||
sum_diff = __msa_copy_s_w((v4i32)temp0_d, 0);
|
||||
if (abs(sum_diff) > SUM_DIFF_THRESHOLD) {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
} else {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
LD_UB8(sig_start, sig_stride, src0, src1, src2, src3, src4, src5, src6, src7);
|
||||
sig_start += (8 * sig_stride);
|
||||
LD_UB8(sig_start, sig_stride, src8, src9, src10, src11, src12, src13, src14,
|
||||
src15);
|
||||
|
||||
ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, running_avg_y_start,
|
||||
avg_y_stride);
|
||||
running_avg_y_start += (8 * avg_y_stride);
|
||||
ST_UB8(src8, src9, src10, src11, src12, src13, src14, src15,
|
||||
running_avg_y_start, avg_y_stride);
|
||||
|
||||
return FILTER_BLOCK;
|
||||
}
|
||||
|
||||
int32_t vp8_denoiser_filter_uv_msa(
|
||||
uint8_t *mc_running_avg_y_ptr, int32_t mc_avg_y_stride,
|
||||
uint8_t *running_avg_y_ptr, int32_t avg_y_stride, uint8_t *sig_ptr,
|
||||
int32_t sig_stride, uint32_t motion_magnitude, int32_t increase_denoising) {
|
||||
uint8_t *running_avg_y_start = running_avg_y_ptr;
|
||||
uint8_t *sig_start = sig_ptr;
|
||||
int32_t cnt = 0;
|
||||
int32_t sum_diff = 0;
|
||||
int32_t shift_inc1 = 3;
|
||||
int32_t delta = 0;
|
||||
int32_t sum_block = 0;
|
||||
int32_t sum_diff_thresh;
|
||||
int64_t dst0, dst1, src0, src1, src2, src3;
|
||||
v16u8 mc_running_avg_y0, running_avg_y, sig0;
|
||||
v16u8 mc_running_avg_y1, running_avg_y1, sig1;
|
||||
v16u8 sig2, sig3, sig4, sig5, sig6, sig7;
|
||||
v16u8 coeff0;
|
||||
v8i16 diff0, abs_diff0, abs_diff_neg0;
|
||||
v8i16 adjust0, adjust2;
|
||||
v8i16 shift_inc1_vec = { 0 };
|
||||
v8i16 col_sum0 = { 0 };
|
||||
v8i16 temp0_h, temp2_h, cmp, delta_vec;
|
||||
v4i32 temp0_w;
|
||||
v2i64 temp0_d, temp1_d;
|
||||
v16i8 zero = { 0 };
|
||||
v8i16 one = __msa_ldi_h(1);
|
||||
v8i16 four = __msa_ldi_h(4);
|
||||
v8i16 adj_val = { 6, 4, 3, 0, -6, -4, -3, 0 };
|
||||
|
||||
sig0 = LD_UB(sig_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
temp0_h = (v8i16)__msa_ilvr_b(zero, (v16i8)sig0);
|
||||
sig1 = LD_UB(sig_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig1);
|
||||
sig2 = LD_UB(sig_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig2);
|
||||
sig3 = LD_UB(sig_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig3);
|
||||
sig4 = LD_UB(sig_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig4);
|
||||
sig5 = LD_UB(sig_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig5);
|
||||
sig6 = LD_UB(sig_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig6);
|
||||
sig7 = LD_UB(sig_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig7);
|
||||
temp0_w = __msa_hadd_s_w(temp0_h, temp0_h);
|
||||
temp0_d = __msa_hadd_s_d(temp0_w, temp0_w);
|
||||
temp1_d = __msa_splati_d(temp0_d, 1);
|
||||
temp0_d += temp1_d;
|
||||
sum_block = __msa_copy_s_w((v4i32)temp0_d, 0);
|
||||
sig_ptr -= sig_stride * 8;
|
||||
|
||||
if (abs(sum_block - (128 * 8 * 8)) < SUM_DIFF_FROM_AVG_THRESH_UV) {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
|
||||
if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) {
|
||||
adj_val = __msa_add_a_h(adj_val, one);
|
||||
|
||||
if (increase_denoising) {
|
||||
adj_val = __msa_add_a_h(adj_val, one);
|
||||
shift_inc1 = 4;
|
||||
}
|
||||
|
||||
temp0_h = (v8i16)zero - adj_val;
|
||||
adj_val = (v8i16)__msa_ilvev_d((v2i64)temp0_h, (v2i64)adj_val);
|
||||
}
|
||||
|
||||
adj_val = __msa_insert_h(adj_val, 3, cnt);
|
||||
adj_val = __msa_insert_h(adj_val, 7, cnt);
|
||||
shift_inc1_vec = __msa_fill_h(shift_inc1);
|
||||
for (cnt = 4; cnt--;) {
|
||||
v8i16 mask0 = { 0 };
|
||||
mc_running_avg_y0 = LD_UB(mc_running_avg_y_ptr);
|
||||
sig0 = LD_UB(sig_ptr);
|
||||
sig_ptr += sig_stride;
|
||||
mc_running_avg_y_ptr += mc_avg_y_stride;
|
||||
mc_running_avg_y1 = LD_UB(mc_running_avg_y_ptr);
|
||||
sig1 = LD_UB(sig_ptr);
|
||||
coeff0 = (v16u8)__msa_ilvr_b((v16i8)mc_running_avg_y0, (v16i8)sig0);
|
||||
diff0 = __msa_hsub_u_h(coeff0, coeff0);
|
||||
abs_diff0 = __msa_add_a_h(diff0, (v8i16)zero);
|
||||
cmp = __msa_clei_s_h(abs_diff0, 15);
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
cmp = __msa_clei_s_h(abs_diff0, 7);
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
cmp = abs_diff0 < shift_inc1_vec;
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
temp0_h = __msa_clei_s_h(diff0, 0);
|
||||
temp0_h = temp0_h & four;
|
||||
mask0 += temp0_h;
|
||||
adjust0 = __msa_vshf_h(mask0, adj_val, adj_val);
|
||||
temp2_h = __msa_ceqi_h(adjust0, 0);
|
||||
adjust0 = (v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)diff0, (v16u8)temp2_h);
|
||||
col_sum0 += adjust0;
|
||||
temp0_h = (v8i16)__msa_ilvr_b(zero, (v16i8)sig0);
|
||||
temp0_h += adjust0;
|
||||
temp0_h = __msa_maxi_s_h(temp0_h, 0);
|
||||
temp0_h = (v8i16)__msa_sat_u_h((v8u16)temp0_h, 7);
|
||||
temp2_h = (v8i16)__msa_pckev_b((v16i8)temp2_h, (v16i8)temp2_h);
|
||||
running_avg_y = (v16u8)__msa_pckev_b((v16i8)temp0_h, (v16i8)temp0_h);
|
||||
running_avg_y =
|
||||
__msa_bmnz_v(running_avg_y, mc_running_avg_y0, (v16u8)temp2_h);
|
||||
dst0 = __msa_copy_s_d((v2i64)running_avg_y, 0);
|
||||
SD(dst0, running_avg_y_ptr);
|
||||
running_avg_y_ptr += avg_y_stride;
|
||||
|
||||
mask0 = __msa_ldi_h(0);
|
||||
coeff0 = (v16u8)__msa_ilvr_b((v16i8)mc_running_avg_y1, (v16i8)sig1);
|
||||
diff0 = __msa_hsub_u_h(coeff0, coeff0);
|
||||
abs_diff0 = __msa_add_a_h(diff0, (v8i16)zero);
|
||||
cmp = __msa_clei_s_h(abs_diff0, 15);
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
cmp = __msa_clei_s_h(abs_diff0, 7);
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
cmp = abs_diff0 < shift_inc1_vec;
|
||||
cmp = cmp & one;
|
||||
mask0 += cmp;
|
||||
temp0_h = __msa_clei_s_h(diff0, 0);
|
||||
temp0_h = temp0_h & four;
|
||||
mask0 += temp0_h;
|
||||
adjust0 = __msa_vshf_h(mask0, adj_val, adj_val);
|
||||
temp2_h = __msa_ceqi_h(adjust0, 0);
|
||||
adjust0 = (v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)diff0, (v16u8)temp2_h);
|
||||
col_sum0 += adjust0;
|
||||
temp0_h = (v8i16)__msa_ilvr_b(zero, (v16i8)sig1);
|
||||
temp0_h += adjust0;
|
||||
temp0_h = __msa_maxi_s_h(temp0_h, 0);
|
||||
temp0_h = (v8i16)__msa_sat_u_h((v8u16)temp0_h, 7);
|
||||
|
||||
temp2_h = (v8i16)__msa_pckev_b((v16i8)temp2_h, (v16i8)temp2_h);
|
||||
running_avg_y = (v16u8)__msa_pckev_b((v16i8)temp0_h, (v16i8)temp0_h);
|
||||
running_avg_y =
|
||||
__msa_bmnz_v(running_avg_y, mc_running_avg_y1, (v16u8)temp2_h);
|
||||
dst1 = __msa_copy_s_d((v2i64)running_avg_y, 0);
|
||||
SD(dst1, running_avg_y_ptr);
|
||||
|
||||
sig_ptr += sig_stride;
|
||||
mc_running_avg_y_ptr += mc_avg_y_stride;
|
||||
running_avg_y_ptr += avg_y_stride;
|
||||
}
|
||||
|
||||
temp0_h = col_sum0;
|
||||
temp0_w = __msa_hadd_s_w(temp0_h, temp0_h);
|
||||
temp0_d = __msa_hadd_s_d(temp0_w, temp0_w);
|
||||
temp1_d = __msa_splati_d(temp0_d, 1);
|
||||
temp0_d += temp1_d;
|
||||
sum_diff = __msa_copy_s_w((v4i32)temp0_d, 0);
|
||||
sig_ptr -= sig_stride * 8;
|
||||
mc_running_avg_y_ptr -= mc_avg_y_stride * 8;
|
||||
running_avg_y_ptr -= avg_y_stride * 8;
|
||||
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) {
|
||||
delta = ((abs(sum_diff) - sum_diff_thresh) >> 8) + 1;
|
||||
delta_vec = __msa_fill_h(delta);
|
||||
if (delta < 4) {
|
||||
for (cnt = 4; cnt--;) {
|
||||
running_avg_y = LD_UB(running_avg_y_ptr);
|
||||
mc_running_avg_y0 = LD_UB(mc_running_avg_y_ptr);
|
||||
sig0 = LD_UB(sig_ptr);
|
||||
/* Update pointers for next iteration. */
|
||||
sig_ptr += sig_stride;
|
||||
mc_running_avg_y_ptr += mc_avg_y_stride;
|
||||
running_avg_y_ptr += avg_y_stride;
|
||||
|
||||
mc_running_avg_y1 = LD_UB(mc_running_avg_y_ptr);
|
||||
sig1 = LD_UB(sig_ptr);
|
||||
running_avg_y1 = LD_UB(running_avg_y_ptr);
|
||||
|
||||
coeff0 = (v16u8)__msa_ilvr_b((v16i8)mc_running_avg_y0, (v16i8)sig0);
|
||||
diff0 = __msa_hsub_u_h(coeff0, coeff0);
|
||||
abs_diff0 = __msa_add_a_h(diff0, (v8i16)zero);
|
||||
temp0_h = delta_vec < abs_diff0;
|
||||
abs_diff0 = (v8i16)__msa_bmnz_v((v16u8)abs_diff0, (v16u8)delta_vec,
|
||||
(v16u8)temp0_h);
|
||||
abs_diff_neg0 = (v8i16)zero - abs_diff0;
|
||||
temp0_h = __msa_clei_s_h(diff0, 0);
|
||||
adjust0 = (v8i16)__msa_bmz_v((v16u8)abs_diff0, (v16u8)abs_diff_neg0,
|
||||
(v16u8)temp0_h);
|
||||
temp2_h = (v8i16)__msa_ilvr_b(zero, (v16i8)running_avg_y);
|
||||
adjust2 = temp2_h + adjust0;
|
||||
adjust2 = __msa_maxi_s_h(adjust2, 0);
|
||||
adjust2 = (v8i16)__msa_sat_u_h((v8u16)adjust2, 7);
|
||||
temp0_h = __msa_ceqi_h(diff0, 0);
|
||||
adjust2 =
|
||||
(v8i16)__msa_bmnz_v((v16u8)adjust2, (v16u8)temp2_h, (v16u8)temp0_h);
|
||||
adjust0 =
|
||||
(v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)zero, (v16u8)temp0_h);
|
||||
col_sum0 += adjust0;
|
||||
running_avg_y = (v16u8)__msa_pckev_b((v16i8)adjust2, (v16i8)adjust2);
|
||||
dst0 = __msa_copy_s_d((v2i64)running_avg_y, 0);
|
||||
SD(dst0, running_avg_y_ptr - avg_y_stride);
|
||||
|
||||
coeff0 = (v16u8)__msa_ilvr_b((v16i8)mc_running_avg_y1, (v16i8)sig1);
|
||||
diff0 = __msa_hsub_u_h(coeff0, coeff0);
|
||||
abs_diff0 = __msa_add_a_h(diff0, (v8i16)zero);
|
||||
temp0_h = delta_vec < abs_diff0;
|
||||
abs_diff0 = (v8i16)__msa_bmnz_v((v16u8)abs_diff0, (v16u8)delta_vec,
|
||||
(v16u8)temp0_h);
|
||||
abs_diff_neg0 = (v8i16)zero - abs_diff0;
|
||||
temp0_h = __msa_clei_s_h(diff0, 0);
|
||||
adjust0 = (v8i16)__msa_bmz_v((v16u8)abs_diff0, (v16u8)abs_diff_neg0,
|
||||
(v16u8)temp0_h);
|
||||
temp2_h = (v8i16)__msa_ilvr_b(zero, (v16i8)running_avg_y1);
|
||||
adjust2 = temp2_h + adjust0;
|
||||
adjust2 = __msa_maxi_s_h(adjust2, 0);
|
||||
adjust2 = (v8i16)__msa_sat_u_h((v8u16)adjust2, 7);
|
||||
temp0_h = __msa_ceqi_h(diff0, 0);
|
||||
adjust2 =
|
||||
(v8i16)__msa_bmnz_v((v16u8)adjust2, (v16u8)temp2_h, (v16u8)temp0_h);
|
||||
adjust0 =
|
||||
(v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)zero, (v16u8)temp0_h);
|
||||
col_sum0 += adjust0;
|
||||
running_avg_y = (v16u8)__msa_pckev_b((v16i8)adjust2, (v16i8)adjust2);
|
||||
dst1 = __msa_copy_s_d((v2i64)running_avg_y, 0);
|
||||
SD(dst1, running_avg_y_ptr);
|
||||
running_avg_y_ptr += avg_y_stride;
|
||||
}
|
||||
|
||||
temp0_h = col_sum0;
|
||||
temp0_w = __msa_hadd_s_w(temp0_h, temp0_h);
|
||||
temp0_d = __msa_hadd_s_d(temp0_w, temp0_w);
|
||||
temp1_d = __msa_splati_d(temp0_d, 1);
|
||||
temp0_d += temp1_d;
|
||||
sum_diff = __msa_copy_s_w((v4i32)temp0_d, 0);
|
||||
|
||||
if (abs(sum_diff) > sum_diff_thresh) {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
} else {
|
||||
return COPY_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
LD4(sig_start, sig_stride, src0, src1, src2, src3);
|
||||
sig_start += (4 * sig_stride);
|
||||
SD4(src0, src1, src2, src3, running_avg_y_start, avg_y_stride);
|
||||
running_avg_y_start += (4 * avg_y_stride);
|
||||
|
||||
LD4(sig_start, sig_stride, src0, src1, src2, src3);
|
||||
SD4(src0, src1, src2, src3, running_avg_y_start, avg_y_stride);
|
||||
|
||||
return FILTER_BLOCK;
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "vp8/common/mips/msa/vp8_macros_msa.h"
|
||||
#include "vp8/encoder/block.h"
|
||||
|
||||
int32_t vp8_block_error_msa(int16_t *coeff_ptr, int16_t *dq_coeff_ptr) {
|
||||
int32_t err = 0;
|
||||
uint32_t loop_cnt;
|
||||
v8i16 coeff, dq_coeff, coeff0, coeff1;
|
||||
v4i32 diff0, diff1;
|
||||
v2i64 err0 = { 0 };
|
||||
v2i64 err1 = { 0 };
|
||||
|
||||
for (loop_cnt = 2; loop_cnt--;) {
|
||||
coeff = LD_SH(coeff_ptr);
|
||||
dq_coeff = LD_SH(dq_coeff_ptr);
|
||||
ILVRL_H2_SH(coeff, dq_coeff, coeff0, coeff1);
|
||||
HSUB_UH2_SW(coeff0, coeff1, diff0, diff1);
|
||||
DPADD_SD2_SD(diff0, diff1, err0, err1);
|
||||
coeff_ptr += 8;
|
||||
dq_coeff_ptr += 8;
|
||||
}
|
||||
|
||||
err0 += __msa_splati_d(err0, 1);
|
||||
err1 += __msa_splati_d(err1, 1);
|
||||
err = __msa_copy_s_d(err0, 0);
|
||||
err += __msa_copy_s_d(err1, 0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t vp8_mbblock_error_msa(MACROBLOCK *mb, int32_t dc) {
|
||||
BLOCK *be;
|
||||
BLOCKD *bd;
|
||||
int16_t *coeff_ptr, *dq_coeff_ptr;
|
||||
int32_t err = 0;
|
||||
uint32_t loop_cnt;
|
||||
v8i16 coeff, coeff0, coeff1, coeff2, coeff3, coeff4;
|
||||
v8i16 dq_coeff, dq_coeff2, dq_coeff3, dq_coeff4;
|
||||
v4i32 diff0, diff1;
|
||||
v2i64 err0, err1;
|
||||
v16u8 zero = { 0 };
|
||||
v16u8 mask0 = (v16u8)__msa_ldi_b(255);
|
||||
|
||||
if (1 == dc) {
|
||||
mask0 = (v16u8)__msa_insve_w((v4i32)mask0, 0, (v4i32)zero);
|
||||
}
|
||||
|
||||
for (loop_cnt = 0; loop_cnt < 8; ++loop_cnt) {
|
||||
be = &mb->block[2 * loop_cnt];
|
||||
bd = &mb->e_mbd.block[2 * loop_cnt];
|
||||
coeff_ptr = be->coeff;
|
||||
dq_coeff_ptr = bd->dqcoeff;
|
||||
coeff = LD_SH(coeff_ptr);
|
||||
dq_coeff = LD_SH(dq_coeff_ptr);
|
||||
coeff_ptr += 8;
|
||||
dq_coeff_ptr += 8;
|
||||
coeff2 = LD_SH(coeff_ptr);
|
||||
dq_coeff2 = LD_SH(dq_coeff_ptr);
|
||||
be = &mb->block[2 * loop_cnt + 1];
|
||||
bd = &mb->e_mbd.block[2 * loop_cnt + 1];
|
||||
coeff_ptr = be->coeff;
|
||||
dq_coeff_ptr = bd->dqcoeff;
|
||||
coeff3 = LD_SH(coeff_ptr);
|
||||
dq_coeff3 = LD_SH(dq_coeff_ptr);
|
||||
coeff_ptr += 8;
|
||||
dq_coeff_ptr += 8;
|
||||
coeff4 = LD_SH(coeff_ptr);
|
||||
dq_coeff4 = LD_SH(dq_coeff_ptr);
|
||||
ILVRL_H2_SH(coeff, dq_coeff, coeff0, coeff1);
|
||||
HSUB_UH2_SW(coeff0, coeff1, diff0, diff1);
|
||||
diff0 = (v4i32)__msa_bmnz_v(zero, (v16u8)diff0, mask0);
|
||||
DOTP_SW2_SD(diff0, diff1, diff0, diff1, err0, err1);
|
||||
ILVRL_H2_SH(coeff2, dq_coeff2, coeff0, coeff1);
|
||||
HSUB_UH2_SW(coeff0, coeff1, diff0, diff1);
|
||||
DPADD_SD2_SD(diff0, diff1, err0, err1);
|
||||
err0 += __msa_splati_d(err0, 1);
|
||||
err1 += __msa_splati_d(err1, 1);
|
||||
err += __msa_copy_s_d(err0, 0);
|
||||
err += __msa_copy_s_d(err1, 0);
|
||||
|
||||
ILVRL_H2_SH(coeff3, dq_coeff3, coeff0, coeff1);
|
||||
HSUB_UH2_SW(coeff0, coeff1, diff0, diff1);
|
||||
diff0 = (v4i32)__msa_bmnz_v(zero, (v16u8)diff0, mask0);
|
||||
DOTP_SW2_SD(diff0, diff1, diff0, diff1, err0, err1);
|
||||
ILVRL_H2_SH(coeff4, dq_coeff4, coeff0, coeff1);
|
||||
HSUB_UH2_SW(coeff0, coeff1, diff0, diff1);
|
||||
DPADD_SD2_SD(diff0, diff1, err0, err1);
|
||||
err0 += __msa_splati_d(err0, 1);
|
||||
err1 += __msa_splati_d(err1, 1);
|
||||
err += __msa_copy_s_d(err0, 0);
|
||||
err += __msa_copy_s_d(err1, 0);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t vp8_mbuverror_msa(MACROBLOCK *mb) {
|
||||
BLOCK *be;
|
||||
BLOCKD *bd;
|
||||
int16_t *coeff_ptr, *dq_coeff_ptr;
|
||||
int32_t err = 0;
|
||||
uint32_t loop_cnt;
|
||||
v8i16 coeff, coeff0, coeff1, coeff2, coeff3, coeff4;
|
||||
v8i16 dq_coeff, dq_coeff2, dq_coeff3, dq_coeff4;
|
||||
v4i32 diff0, diff1;
|
||||
v2i64 err0, err1, err_dup0, err_dup1;
|
||||
|
||||
for (loop_cnt = 16; loop_cnt < 24; loop_cnt += 2) {
|
||||
be = &mb->block[loop_cnt];
|
||||
bd = &mb->e_mbd.block[loop_cnt];
|
||||
coeff_ptr = be->coeff;
|
||||
dq_coeff_ptr = bd->dqcoeff;
|
||||
coeff = LD_SH(coeff_ptr);
|
||||
dq_coeff = LD_SH(dq_coeff_ptr);
|
||||
coeff_ptr += 8;
|
||||
dq_coeff_ptr += 8;
|
||||
coeff2 = LD_SH(coeff_ptr);
|
||||
dq_coeff2 = LD_SH(dq_coeff_ptr);
|
||||
be = &mb->block[loop_cnt + 1];
|
||||
bd = &mb->e_mbd.block[loop_cnt + 1];
|
||||
coeff_ptr = be->coeff;
|
||||
dq_coeff_ptr = bd->dqcoeff;
|
||||
coeff3 = LD_SH(coeff_ptr);
|
||||
dq_coeff3 = LD_SH(dq_coeff_ptr);
|
||||
coeff_ptr += 8;
|
||||
dq_coeff_ptr += 8;
|
||||
coeff4 = LD_SH(coeff_ptr);
|
||||
dq_coeff4 = LD_SH(dq_coeff_ptr);
|
||||
|
||||
ILVRL_H2_SH(coeff, dq_coeff, coeff0, coeff1);
|
||||
HSUB_UH2_SW(coeff0, coeff1, diff0, diff1);
|
||||
DOTP_SW2_SD(diff0, diff1, diff0, diff1, err0, err1);
|
||||
|
||||
ILVRL_H2_SH(coeff2, dq_coeff2, coeff0, coeff1);
|
||||
HSUB_UH2_SW(coeff0, coeff1, diff0, diff1);
|
||||
DPADD_SD2_SD(diff0, diff1, err0, err1);
|
||||
err_dup0 = __msa_splati_d(err0, 1);
|
||||
err_dup1 = __msa_splati_d(err1, 1);
|
||||
ADD2(err0, err_dup0, err1, err_dup1, err0, err1);
|
||||
err += __msa_copy_s_d(err0, 0);
|
||||
err += __msa_copy_s_d(err1, 0);
|
||||
|
||||
ILVRL_H2_SH(coeff3, dq_coeff3, coeff0, coeff1);
|
||||
HSUB_UH2_SW(coeff0, coeff1, diff0, diff1);
|
||||
DOTP_SW2_SD(diff0, diff1, diff0, diff1, err0, err1);
|
||||
ILVRL_H2_SH(coeff4, dq_coeff4, coeff0, coeff1);
|
||||
HSUB_UH2_SW(coeff0, coeff1, diff0, diff1);
|
||||
DPADD_SD2_SD(diff0, diff1, err0, err1);
|
||||
err_dup0 = __msa_splati_d(err0, 1);
|
||||
err_dup1 = __msa_splati_d(err1, 1);
|
||||
ADD2(err0, err_dup0, err1, err_dup1, err0, err1);
|
||||
err += __msa_copy_s_d(err0, 0);
|
||||
err += __msa_copy_s_d(err1, 0);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "vp8/common/mips/msa/vp8_macros_msa.h"
|
||||
#include "vp8/encoder/block.h"
|
||||
|
||||
static int8_t fast_quantize_b_msa(int16_t *coeff_ptr, int16_t *round,
|
||||
int16_t *quant, int16_t *de_quant,
|
||||
int16_t *q_coeff, int16_t *dq_coeff) {
|
||||
int32_t cnt, eob;
|
||||
v16i8 inv_zig_zag = { 0, 1, 5, 6, 2, 4, 7, 12, 3, 8, 11, 13, 9, 10, 14, 15 };
|
||||
v8i16 round0, round1;
|
||||
v8i16 sign_z0, sign_z1;
|
||||
v8i16 q_coeff0, q_coeff1;
|
||||
v8i16 x0, x1, de_quant0, de_quant1;
|
||||
v8i16 coeff0, coeff1, z0, z1;
|
||||
v8i16 quant0, quant1, quant2, quant3;
|
||||
v8i16 zero = { 0 };
|
||||
v8i16 inv_zig_zag0, inv_zig_zag1;
|
||||
v8i16 zigzag_mask0 = { 0, 1, 4, 8, 5, 2, 3, 6 };
|
||||
v8i16 zigzag_mask1 = { 9, 12, 13, 10, 7, 11, 14, 15 };
|
||||
v8i16 temp0_h, temp1_h, temp2_h, temp3_h;
|
||||
v4i32 temp0_w, temp1_w, temp2_w, temp3_w;
|
||||
|
||||
ILVRL_B2_SH(zero, inv_zig_zag, inv_zig_zag0, inv_zig_zag1);
|
||||
eob = -1;
|
||||
LD_SH2(coeff_ptr, 8, coeff0, coeff1);
|
||||
VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, z0,
|
||||
z1);
|
||||
LD_SH2(round, 8, coeff0, coeff1);
|
||||
VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, round0,
|
||||
round1);
|
||||
LD_SH2(quant, 8, coeff0, coeff1);
|
||||
VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, quant0,
|
||||
quant2);
|
||||
sign_z0 = z0 >> 15;
|
||||
sign_z1 = z1 >> 15;
|
||||
x0 = __msa_add_a_h(z0, zero);
|
||||
x1 = __msa_add_a_h(z1, zero);
|
||||
ILVL_H2_SH(quant0, quant0, quant2, quant2, quant1, quant3);
|
||||
ILVR_H2_SH(quant0, quant0, quant2, quant2, quant0, quant2);
|
||||
ILVL_H2_SH(round0, x0, round1, x1, temp1_h, temp3_h);
|
||||
ILVR_H2_SH(round0, x0, round1, x1, temp0_h, temp2_h);
|
||||
DOTP_SH4_SW(temp0_h, temp1_h, temp2_h, temp3_h, quant0, quant1, quant2,
|
||||
quant3, temp0_w, temp1_w, temp2_w, temp3_w);
|
||||
SRA_4V(temp0_w, temp1_w, temp2_w, temp3_w, 16);
|
||||
PCKEV_H2_SH(temp1_w, temp0_w, temp3_w, temp2_w, x0, x1);
|
||||
x0 = x0 ^ sign_z0;
|
||||
x1 = x1 ^ sign_z1;
|
||||
SUB2(x0, sign_z0, x1, sign_z1, x0, x1);
|
||||
VSHF_H2_SH(x0, x1, x0, x1, inv_zig_zag0, inv_zig_zag1, q_coeff0, q_coeff1);
|
||||
ST_SH2(q_coeff0, q_coeff1, q_coeff, 8);
|
||||
LD_SH2(de_quant, 8, de_quant0, de_quant1);
|
||||
q_coeff0 *= de_quant0;
|
||||
q_coeff1 *= de_quant1;
|
||||
ST_SH2(q_coeff0, q_coeff1, dq_coeff, 8);
|
||||
|
||||
for (cnt = 0; cnt < 16; ++cnt) {
|
||||
if ((cnt <= 7) && (x1[7 - cnt] != 0)) {
|
||||
eob = (15 - cnt);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((cnt > 7) && (x0[7 - (cnt - 8)] != 0)) {
|
||||
eob = (7 - (cnt - 8));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (int8_t)(eob + 1);
|
||||
}
|
||||
|
||||
static int8_t exact_regular_quantize_b_msa(
|
||||
int16_t *zbin_boost, int16_t *coeff_ptr, int16_t *zbin, int16_t *round,
|
||||
int16_t *quant, int16_t *quant_shift, int16_t *de_quant, int16_t zbin_oq_in,
|
||||
int16_t *q_coeff, int16_t *dq_coeff) {
|
||||
int32_t cnt, eob;
|
||||
int16_t *boost_temp = zbin_boost;
|
||||
v16i8 inv_zig_zag = { 0, 1, 5, 6, 2, 4, 7, 12, 3, 8, 11, 13, 9, 10, 14, 15 };
|
||||
v8i16 round0, round1;
|
||||
v8i16 sign_z0, sign_z1;
|
||||
v8i16 q_coeff0, q_coeff1;
|
||||
v8i16 z_bin0, z_bin1, zbin_o_q;
|
||||
v8i16 x0, x1, sign_x0, sign_x1, de_quant0, de_quant1;
|
||||
v8i16 coeff0, coeff1, z0, z1;
|
||||
v8i16 quant0, quant1, quant2, quant3;
|
||||
v8i16 zero = { 0 };
|
||||
v8i16 inv_zig_zag0, inv_zig_zag1;
|
||||
v8i16 zigzag_mask0 = { 0, 1, 4, 8, 5, 2, 3, 6 };
|
||||
v8i16 zigzag_mask1 = { 9, 12, 13, 10, 7, 11, 14, 15 };
|
||||
v8i16 temp0_h, temp1_h, temp2_h, temp3_h;
|
||||
v4i32 temp0_w, temp1_w, temp2_w, temp3_w;
|
||||
|
||||
ILVRL_B2_SH(zero, inv_zig_zag, inv_zig_zag0, inv_zig_zag1);
|
||||
zbin_o_q = __msa_fill_h(zbin_oq_in);
|
||||
eob = -1;
|
||||
LD_SH2(coeff_ptr, 8, coeff0, coeff1);
|
||||
VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, z0,
|
||||
z1);
|
||||
LD_SH2(round, 8, coeff0, coeff1);
|
||||
VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, round0,
|
||||
round1);
|
||||
LD_SH2(quant, 8, coeff0, coeff1);
|
||||
VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, quant0,
|
||||
quant2);
|
||||
LD_SH2(zbin, 8, coeff0, coeff1);
|
||||
VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, z_bin0,
|
||||
z_bin1);
|
||||
sign_z0 = z0 >> 15;
|
||||
sign_z1 = z1 >> 15;
|
||||
x0 = __msa_add_a_h(z0, zero);
|
||||
x1 = __msa_add_a_h(z1, zero);
|
||||
SUB2(x0, z_bin0, x1, z_bin1, z_bin0, z_bin1);
|
||||
SUB2(z_bin0, zbin_o_q, z_bin1, zbin_o_q, z_bin0, z_bin1);
|
||||
ILVL_H2_SH(quant0, quant0, quant2, quant2, quant1, quant3);
|
||||
ILVR_H2_SH(quant0, quant0, quant2, quant2, quant0, quant2);
|
||||
ILVL_H2_SH(round0, x0, round1, x1, temp1_h, temp3_h);
|
||||
ILVR_H2_SH(round0, x0, round1, x1, temp0_h, temp2_h);
|
||||
DOTP_SH4_SW(temp0_h, temp1_h, temp2_h, temp3_h, quant0, quant1, quant2,
|
||||
quant3, temp0_w, temp1_w, temp2_w, temp3_w);
|
||||
SRA_4V(temp0_w, temp1_w, temp2_w, temp3_w, 16);
|
||||
PCKEV_H2_SH(temp1_w, temp0_w, temp3_w, temp2_w, temp0_h, temp2_h);
|
||||
LD_SH2(quant_shift, 8, coeff0, coeff1);
|
||||
VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, quant0,
|
||||
quant2);
|
||||
ILVL_H2_SH(quant0, quant0, quant2, quant2, quant1, quant3);
|
||||
ILVR_H2_SH(quant0, quant0, quant2, quant2, quant0, quant2);
|
||||
ADD2(x0, round0, x1, round1, x0, x1);
|
||||
ILVL_H2_SH(temp0_h, x0, temp2_h, x1, temp1_h, temp3_h);
|
||||
ILVR_H2_SH(temp0_h, x0, temp2_h, x1, temp0_h, temp2_h);
|
||||
DOTP_SH4_SW(temp0_h, temp1_h, temp2_h, temp3_h, quant0, quant1, quant2,
|
||||
quant3, temp0_w, temp1_w, temp2_w, temp3_w);
|
||||
SRA_4V(temp0_w, temp1_w, temp2_w, temp3_w, 16);
|
||||
PCKEV_H2_SH(temp1_w, temp0_w, temp3_w, temp2_w, x0, x1);
|
||||
sign_x0 = x0 ^ sign_z0;
|
||||
sign_x1 = x1 ^ sign_z1;
|
||||
SUB2(sign_x0, sign_z0, sign_x1, sign_z1, sign_x0, sign_x1);
|
||||
for (cnt = 0; cnt < 16; ++cnt) {
|
||||
if (cnt <= 7) {
|
||||
if (boost_temp[0] <= z_bin0[cnt]) {
|
||||
if (x0[cnt]) {
|
||||
eob = cnt;
|
||||
boost_temp = zbin_boost;
|
||||
} else {
|
||||
boost_temp++;
|
||||
}
|
||||
} else {
|
||||
sign_x0[cnt] = 0;
|
||||
boost_temp++;
|
||||
}
|
||||
} else {
|
||||
if (boost_temp[0] <= z_bin1[cnt - 8]) {
|
||||
if (x1[cnt - 8]) {
|
||||
eob = cnt;
|
||||
boost_temp = zbin_boost;
|
||||
} else {
|
||||
boost_temp++;
|
||||
}
|
||||
} else {
|
||||
sign_x1[cnt - 8] = 0;
|
||||
boost_temp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VSHF_H2_SH(sign_x0, sign_x1, sign_x0, sign_x1, inv_zig_zag0, inv_zig_zag1,
|
||||
q_coeff0, q_coeff1);
|
||||
ST_SH2(q_coeff0, q_coeff1, q_coeff, 8);
|
||||
LD_SH2(de_quant, 8, de_quant0, de_quant1);
|
||||
MUL2(de_quant0, q_coeff0, de_quant1, q_coeff1, de_quant0, de_quant1);
|
||||
ST_SH2(de_quant0, de_quant1, dq_coeff, 8);
|
||||
|
||||
return (int8_t)(eob + 1);
|
||||
}
|
||||
|
||||
void vp8_fast_quantize_b_msa(BLOCK *b, BLOCKD *d) {
|
||||
int16_t *coeff_ptr = b->coeff;
|
||||
int16_t *round_ptr = b->round;
|
||||
int16_t *quant_ptr = b->quant_fast;
|
||||
int16_t *qcoeff_ptr = d->qcoeff;
|
||||
int16_t *dqcoeff_ptr = d->dqcoeff;
|
||||
int16_t *dequant_ptr = d->dequant;
|
||||
|
||||
*d->eob = fast_quantize_b_msa(coeff_ptr, round_ptr, quant_ptr, dequant_ptr,
|
||||
qcoeff_ptr, dqcoeff_ptr);
|
||||
}
|
||||
|
||||
void vp8_regular_quantize_b_msa(BLOCK *b, BLOCKD *d) {
|
||||
int16_t *zbin_boost_ptr = b->zrun_zbin_boost;
|
||||
int16_t *coeff_ptr = b->coeff;
|
||||
int16_t *zbin_ptr = b->zbin;
|
||||
int16_t *round_ptr = b->round;
|
||||
int16_t *quant_ptr = b->quant;
|
||||
int16_t *quant_shift_ptr = b->quant_shift;
|
||||
int16_t *qcoeff_ptr = d->qcoeff;
|
||||
int16_t *dqcoeff_ptr = d->dqcoeff;
|
||||
int16_t *dequant_ptr = d->dequant;
|
||||
int16_t zbin_oq_value = b->zbin_extra;
|
||||
|
||||
*d->eob = exact_regular_quantize_b_msa(
|
||||
zbin_boost_ptr, coeff_ptr, zbin_ptr, round_ptr, quant_ptr,
|
||||
quant_shift_ptr, dequant_ptr, zbin_oq_value, qcoeff_ptr, dqcoeff_ptr);
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "vp8/common/mips/msa/vp8_macros_msa.h"
|
||||
|
||||
static void temporal_filter_apply_16size_msa(
|
||||
uint8_t *frame1_ptr, uint32_t stride, uint8_t *frame2_ptr,
|
||||
int32_t strength_in, int32_t filter_wt_in, uint32_t *acc, uint16_t *cnt) {
|
||||
uint32_t row;
|
||||
v16i8 frame1_0_b, frame1_1_b, frame2_0_b, frame2_1_b;
|
||||
v16u8 frame_l, frame_h;
|
||||
v16i8 zero = { 0 };
|
||||
v8i16 frame2_0_h, frame2_1_h, mod0_h, mod1_h;
|
||||
v8i16 diff0, diff1, cnt0, cnt1;
|
||||
v4i32 const3, const16, filter_wt, strength;
|
||||
v4i32 mod0_w, mod1_w, mod2_w, mod3_w;
|
||||
v4i32 diff0_r, diff0_l, diff1_r, diff1_l;
|
||||
v4i32 frame2_0, frame2_1, frame2_2, frame2_3;
|
||||
v4i32 acc0, acc1, acc2, acc3;
|
||||
|
||||
filter_wt = __msa_fill_w(filter_wt_in);
|
||||
strength = __msa_fill_w(strength_in);
|
||||
const3 = __msa_ldi_w(3);
|
||||
const16 = __msa_ldi_w(16);
|
||||
|
||||
for (row = 8; row--;) {
|
||||
frame1_0_b = LD_SB(frame1_ptr);
|
||||
frame2_0_b = LD_SB(frame2_ptr);
|
||||
frame1_ptr += stride;
|
||||
frame2_ptr += 16;
|
||||
frame1_1_b = LD_SB(frame1_ptr);
|
||||
frame2_1_b = LD_SB(frame2_ptr);
|
||||
LD_SW2(acc, 4, acc0, acc1);
|
||||
LD_SW2(acc + 8, 4, acc2, acc3);
|
||||
LD_SH2(cnt, 8, cnt0, cnt1);
|
||||
ILVRL_B2_UB(frame1_0_b, frame2_0_b, frame_l, frame_h);
|
||||
HSUB_UB2_SH(frame_l, frame_h, diff0, diff1);
|
||||
UNPCK_SH_SW(diff0, diff0_r, diff0_l);
|
||||
UNPCK_SH_SW(diff1, diff1_r, diff1_l);
|
||||
MUL4(diff0_r, diff0_r, diff0_l, diff0_l, diff1_r, diff1_r, diff1_l, diff1_l,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
MUL4(mod0_w, const3, mod1_w, const3, mod2_w, const3, mod3_w, const3, mod0_w,
|
||||
mod1_w, mod2_w, mod3_w);
|
||||
SRAR_W4_SW(mod0_w, mod1_w, mod2_w, mod3_w, strength);
|
||||
diff0_r = (mod0_w < const16);
|
||||
diff0_l = (mod1_w < const16);
|
||||
diff1_r = (mod2_w < const16);
|
||||
diff1_l = (mod3_w < const16);
|
||||
SUB4(const16, mod0_w, const16, mod1_w, const16, mod2_w, const16, mod3_w,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
mod0_w = diff0_r & mod0_w;
|
||||
mod1_w = diff0_l & mod1_w;
|
||||
mod2_w = diff1_r & mod2_w;
|
||||
mod3_w = diff1_l & mod3_w;
|
||||
MUL4(mod0_w, filter_wt, mod1_w, filter_wt, mod2_w, filter_wt, mod3_w,
|
||||
filter_wt, mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
PCKEV_H2_SH(mod1_w, mod0_w, mod3_w, mod2_w, mod0_h, mod1_h)
|
||||
ADD2(mod0_h, cnt0, mod1_h, cnt1, mod0_h, mod1_h);
|
||||
ST_SH2(mod0_h, mod1_h, cnt, 8);
|
||||
cnt += 16;
|
||||
ILVRL_B2_SH(zero, frame2_0_b, frame2_0_h, frame2_1_h);
|
||||
UNPCK_SH_SW(frame2_0_h, frame2_0, frame2_1);
|
||||
UNPCK_SH_SW(frame2_1_h, frame2_2, frame2_3);
|
||||
MUL4(mod0_w, frame2_0, mod1_w, frame2_1, mod2_w, frame2_2, mod3_w, frame2_3,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
ADD4(mod0_w, acc0, mod1_w, acc1, mod2_w, acc2, mod3_w, acc3, mod0_w, mod1_w,
|
||||
mod2_w, mod3_w);
|
||||
ST_SW2(mod0_w, mod1_w, acc, 4);
|
||||
ST_SW2(mod2_w, mod3_w, acc + 8, 4);
|
||||
acc += 16;
|
||||
LD_SW2(acc, 4, acc0, acc1);
|
||||
LD_SW2(acc + 8, 4, acc2, acc3);
|
||||
LD_SH2(cnt, 8, cnt0, cnt1);
|
||||
ILVRL_B2_UB(frame1_1_b, frame2_1_b, frame_l, frame_h);
|
||||
HSUB_UB2_SH(frame_l, frame_h, diff0, diff1);
|
||||
UNPCK_SH_SW(diff0, diff0_r, diff0_l);
|
||||
UNPCK_SH_SW(diff1, diff1_r, diff1_l);
|
||||
MUL4(diff0_r, diff0_r, diff0_l, diff0_l, diff1_r, diff1_r, diff1_l, diff1_l,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
MUL4(mod0_w, const3, mod1_w, const3, mod2_w, const3, mod3_w, const3, mod0_w,
|
||||
mod1_w, mod2_w, mod3_w);
|
||||
SRAR_W4_SW(mod0_w, mod1_w, mod2_w, mod3_w, strength);
|
||||
diff0_r = (mod0_w < const16);
|
||||
diff0_l = (mod1_w < const16);
|
||||
diff1_r = (mod2_w < const16);
|
||||
diff1_l = (mod3_w < const16);
|
||||
SUB4(const16, mod0_w, const16, mod1_w, const16, mod2_w, const16, mod3_w,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
mod0_w = diff0_r & mod0_w;
|
||||
mod1_w = diff0_l & mod1_w;
|
||||
mod2_w = diff1_r & mod2_w;
|
||||
mod3_w = diff1_l & mod3_w;
|
||||
MUL4(mod0_w, filter_wt, mod1_w, filter_wt, mod2_w, filter_wt, mod3_w,
|
||||
filter_wt, mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
PCKEV_H2_SH(mod1_w, mod0_w, mod3_w, mod2_w, mod0_h, mod1_h);
|
||||
ADD2(mod0_h, cnt0, mod1_h, cnt1, mod0_h, mod1_h);
|
||||
ST_SH2(mod0_h, mod1_h, cnt, 8);
|
||||
cnt += 16;
|
||||
|
||||
UNPCK_UB_SH(frame2_1_b, frame2_0_h, frame2_1_h);
|
||||
UNPCK_SH_SW(frame2_0_h, frame2_0, frame2_1);
|
||||
UNPCK_SH_SW(frame2_1_h, frame2_2, frame2_3);
|
||||
MUL4(mod0_w, frame2_0, mod1_w, frame2_1, mod2_w, frame2_2, mod3_w, frame2_3,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
ADD4(mod0_w, acc0, mod1_w, acc1, mod2_w, acc2, mod3_w, acc3, mod0_w, mod1_w,
|
||||
mod2_w, mod3_w);
|
||||
ST_SW2(mod0_w, mod1_w, acc, 4);
|
||||
ST_SW2(mod2_w, mod3_w, acc + 8, 4);
|
||||
acc += 16;
|
||||
frame1_ptr += stride;
|
||||
frame2_ptr += 16;
|
||||
}
|
||||
}
|
||||
|
||||
static void temporal_filter_apply_8size_msa(
|
||||
uint8_t *frame1_ptr, uint32_t stride, uint8_t *frame2_ptr,
|
||||
int32_t strength_in, int32_t filter_wt_in, uint32_t *acc, uint16_t *cnt) {
|
||||
uint32_t row;
|
||||
uint64_t f0, f1, f2, f3, f4, f5, f6, f7;
|
||||
v16i8 frame1 = { 0 };
|
||||
v16i8 frame2 = { 0 };
|
||||
v16i8 frame3 = { 0 };
|
||||
v16i8 frame4 = { 0 };
|
||||
v16u8 frame_l, frame_h;
|
||||
v8i16 frame2_0_h, frame2_1_h, mod0_h, mod1_h;
|
||||
v8i16 diff0, diff1, cnt0, cnt1;
|
||||
v4i32 const3, const16;
|
||||
v4i32 filter_wt, strength;
|
||||
v4i32 mod0_w, mod1_w, mod2_w, mod3_w;
|
||||
v4i32 diff0_r, diff0_l, diff1_r, diff1_l;
|
||||
v4i32 frame2_0, frame2_1, frame2_2, frame2_3;
|
||||
v4i32 acc0, acc1, acc2, acc3;
|
||||
|
||||
filter_wt = __msa_fill_w(filter_wt_in);
|
||||
strength = __msa_fill_w(strength_in);
|
||||
const3 = __msa_ldi_w(3);
|
||||
const16 = __msa_ldi_w(16);
|
||||
|
||||
for (row = 2; row--;) {
|
||||
LD2(frame1_ptr, stride, f0, f1);
|
||||
frame1_ptr += (2 * stride);
|
||||
LD2(frame2_ptr, 8, f2, f3);
|
||||
frame2_ptr += 16;
|
||||
LD2(frame1_ptr, stride, f4, f5);
|
||||
frame1_ptr += (2 * stride);
|
||||
LD2(frame2_ptr, 8, f6, f7);
|
||||
frame2_ptr += 16;
|
||||
|
||||
LD_SW2(acc, 4, acc0, acc1);
|
||||
LD_SW2(acc + 8, 4, acc2, acc3);
|
||||
LD_SH2(cnt, 8, cnt0, cnt1);
|
||||
INSERT_D2_SB(f0, f1, frame1);
|
||||
INSERT_D2_SB(f2, f3, frame2);
|
||||
INSERT_D2_SB(f4, f5, frame3);
|
||||
INSERT_D2_SB(f6, f7, frame4);
|
||||
ILVRL_B2_UB(frame1, frame2, frame_l, frame_h);
|
||||
HSUB_UB2_SH(frame_l, frame_h, diff0, diff1);
|
||||
UNPCK_SH_SW(diff0, diff0_r, diff0_l);
|
||||
UNPCK_SH_SW(diff1, diff1_r, diff1_l);
|
||||
MUL4(diff0_r, diff0_r, diff0_l, diff0_l, diff1_r, diff1_r, diff1_l, diff1_l,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
MUL4(mod0_w, const3, mod1_w, const3, mod2_w, const3, mod3_w, const3, mod0_w,
|
||||
mod1_w, mod2_w, mod3_w);
|
||||
SRAR_W4_SW(mod0_w, mod1_w, mod2_w, mod3_w, strength);
|
||||
diff0_r = (mod0_w < const16);
|
||||
diff0_l = (mod1_w < const16);
|
||||
diff1_r = (mod2_w < const16);
|
||||
diff1_l = (mod3_w < const16);
|
||||
SUB4(const16, mod0_w, const16, mod1_w, const16, mod2_w, const16, mod3_w,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
mod0_w = diff0_r & mod0_w;
|
||||
mod1_w = diff0_l & mod1_w;
|
||||
mod2_w = diff1_r & mod2_w;
|
||||
mod3_w = diff1_l & mod3_w;
|
||||
MUL4(mod0_w, filter_wt, mod1_w, filter_wt, mod2_w, filter_wt, mod3_w,
|
||||
filter_wt, mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
PCKEV_H2_SH(mod1_w, mod0_w, mod3_w, mod2_w, mod0_h, mod1_h);
|
||||
ADD2(mod0_h, cnt0, mod1_h, cnt1, mod0_h, mod1_h);
|
||||
ST_SH2(mod0_h, mod1_h, cnt, 8);
|
||||
cnt += 16;
|
||||
|
||||
UNPCK_UB_SH(frame2, frame2_0_h, frame2_1_h);
|
||||
UNPCK_SH_SW(frame2_0_h, frame2_0, frame2_1);
|
||||
UNPCK_SH_SW(frame2_1_h, frame2_2, frame2_3);
|
||||
MUL4(mod0_w, frame2_0, mod1_w, frame2_1, mod2_w, frame2_2, mod3_w, frame2_3,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
ADD4(mod0_w, acc0, mod1_w, acc1, mod2_w, acc2, mod3_w, acc3, mod0_w, mod1_w,
|
||||
mod2_w, mod3_w);
|
||||
ST_SW2(mod0_w, mod1_w, acc, 4);
|
||||
ST_SW2(mod2_w, mod3_w, acc + 8, 4);
|
||||
acc += 16;
|
||||
|
||||
LD_SW2(acc, 4, acc0, acc1);
|
||||
LD_SW2(acc + 8, 4, acc2, acc3);
|
||||
LD_SH2(cnt, 8, cnt0, cnt1);
|
||||
ILVRL_B2_UB(frame3, frame4, frame_l, frame_h);
|
||||
HSUB_UB2_SH(frame_l, frame_h, diff0, diff1);
|
||||
UNPCK_SH_SW(diff0, diff0_r, diff0_l);
|
||||
UNPCK_SH_SW(diff1, diff1_r, diff1_l);
|
||||
MUL4(diff0_r, diff0_r, diff0_l, diff0_l, diff1_r, diff1_r, diff1_l, diff1_l,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
MUL4(mod0_w, const3, mod1_w, const3, mod2_w, const3, mod3_w, const3, mod0_w,
|
||||
mod1_w, mod2_w, mod3_w);
|
||||
SRAR_W4_SW(mod0_w, mod1_w, mod2_w, mod3_w, strength);
|
||||
diff0_r = (mod0_w < const16);
|
||||
diff0_l = (mod1_w < const16);
|
||||
diff1_r = (mod2_w < const16);
|
||||
diff1_l = (mod3_w < const16);
|
||||
SUB4(const16, mod0_w, const16, mod1_w, const16, mod2_w, const16, mod3_w,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
mod0_w = diff0_r & mod0_w;
|
||||
mod1_w = diff0_l & mod1_w;
|
||||
mod2_w = diff1_r & mod2_w;
|
||||
mod3_w = diff1_l & mod3_w;
|
||||
MUL4(mod0_w, filter_wt, mod1_w, filter_wt, mod2_w, filter_wt, mod3_w,
|
||||
filter_wt, mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
PCKEV_H2_SH(mod1_w, mod0_w, mod3_w, mod2_w, mod0_h, mod1_h);
|
||||
ADD2(mod0_h, cnt0, mod1_h, cnt1, mod0_h, mod1_h);
|
||||
ST_SH2(mod0_h, mod1_h, cnt, 8);
|
||||
cnt += 16;
|
||||
|
||||
UNPCK_UB_SH(frame4, frame2_0_h, frame2_1_h);
|
||||
UNPCK_SH_SW(frame2_0_h, frame2_0, frame2_1);
|
||||
UNPCK_SH_SW(frame2_1_h, frame2_2, frame2_3);
|
||||
MUL4(mod0_w, frame2_0, mod1_w, frame2_1, mod2_w, frame2_2, mod3_w, frame2_3,
|
||||
mod0_w, mod1_w, mod2_w, mod3_w);
|
||||
ADD4(mod0_w, acc0, mod1_w, acc1, mod2_w, acc2, mod3_w, acc3, mod0_w, mod1_w,
|
||||
mod2_w, mod3_w);
|
||||
ST_SW2(mod0_w, mod1_w, acc, 4);
|
||||
ST_SW2(mod2_w, mod3_w, acc + 8, 4);
|
||||
acc += 16;
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_temporal_filter_apply_msa(uint8_t *frame1, uint32_t stride,
|
||||
uint8_t *frame2, uint32_t block_size,
|
||||
int32_t strength, int32_t filter_weight,
|
||||
uint32_t *accumulator, uint16_t *count) {
|
||||
if (8 == block_size) {
|
||||
temporal_filter_apply_8size_msa(frame1, stride, frame2, strength,
|
||||
filter_weight, accumulator, count);
|
||||
} else if (16 == block_size) {
|
||||
temporal_filter_apply_16size_msa(frame1, stride, frame2, strength,
|
||||
filter_weight, accumulator, count);
|
||||
} else {
|
||||
uint32_t i, j, k;
|
||||
int32_t modifier;
|
||||
int32_t byte = 0;
|
||||
const int32_t rounding = strength > 0 ? 1 << (strength - 1) : 0;
|
||||
|
||||
for (i = 0, k = 0; i < block_size; ++i) {
|
||||
for (j = 0; j < block_size; ++j, ++k) {
|
||||
int src_byte = frame1[byte];
|
||||
int pixel_value = *frame2++;
|
||||
|
||||
modifier = src_byte - pixel_value;
|
||||
modifier *= modifier;
|
||||
modifier *= 3;
|
||||
modifier += rounding;
|
||||
modifier >>= strength;
|
||||
|
||||
if (modifier > 16) modifier = 16;
|
||||
|
||||
modifier = 16 - modifier;
|
||||
modifier *= filter_weight;
|
||||
|
||||
count[k] += modifier;
|
||||
accumulator[k] += modifier * pixel_value;
|
||||
|
||||
byte++;
|
||||
}
|
||||
|
||||
byte += stride - block_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include "vp8/common/blockd.h"
|
||||
#include "modecosts.h"
|
||||
#include "onyx_int.h"
|
||||
#include "treewriter.h"
|
||||
#include "vp8/common/entropymode.h"
|
||||
|
||||
void vp8_init_mode_costs(VP8_COMP *c) {
|
||||
VP8_COMMON *x = &c->common;
|
||||
struct rd_costs_struct *rd_costs = &c->rd_costs;
|
||||
|
||||
{
|
||||
const vp8_tree_p T = vp8_bmode_tree;
|
||||
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
int j = 0;
|
||||
|
||||
do {
|
||||
vp8_cost_tokens(rd_costs->bmode_costs[i][j], vp8_kf_bmode_prob[i][j],
|
||||
T);
|
||||
} while (++j < VP8_BINTRAMODES);
|
||||
} while (++i < VP8_BINTRAMODES);
|
||||
|
||||
vp8_cost_tokens(rd_costs->inter_bmode_costs, x->fc.bmode_prob, T);
|
||||
}
|
||||
vp8_cost_tokens(rd_costs->inter_bmode_costs, x->fc.sub_mv_ref_prob,
|
||||
vp8_sub_mv_ref_tree);
|
||||
|
||||
vp8_cost_tokens(rd_costs->mbmode_cost[1], x->fc.ymode_prob, vp8_ymode_tree);
|
||||
vp8_cost_tokens(rd_costs->mbmode_cost[0], vp8_kf_ymode_prob,
|
||||
vp8_kf_ymode_tree);
|
||||
|
||||
vp8_cost_tokens(rd_costs->intra_uv_mode_cost[1], x->fc.uv_mode_prob,
|
||||
vp8_uv_mode_tree);
|
||||
vp8_cost_tokens(rd_costs->intra_uv_mode_cost[0], vp8_kf_uv_mode_prob,
|
||||
vp8_uv_mode_tree);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_MODECOSTS_H_
|
||||
#define VPX_VP8_ENCODER_MODECOSTS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct VP8_COMP;
|
||||
|
||||
void vp8_init_mode_costs(struct VP8_COMP *c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_MODECOSTS_H_
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include "vpx_config.h"
|
||||
#include "onyx_int.h"
|
||||
#include "mr_dissim.h"
|
||||
#include "vpx_dsp/vpx_dsp_common.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "rdopt.h"
|
||||
#include "vp8/common/common.h"
|
||||
|
||||
void vp8_cal_low_res_mb_cols(VP8_COMP *cpi) {
|
||||
int low_res_w;
|
||||
|
||||
/* Support arbitrary down-sampling factor */
|
||||
unsigned int iw = cpi->oxcf.Width * cpi->oxcf.mr_down_sampling_factor.den +
|
||||
cpi->oxcf.mr_down_sampling_factor.num - 1;
|
||||
|
||||
low_res_w = iw / cpi->oxcf.mr_down_sampling_factor.num;
|
||||
cpi->mr_low_res_mb_cols = ((low_res_w + 15) >> 4);
|
||||
}
|
||||
|
||||
#define GET_MV(x) \
|
||||
if (x->mbmi.ref_frame != INTRA_FRAME) { \
|
||||
mvx[cnt] = x->mbmi.mv.as_mv.row; \
|
||||
mvy[cnt] = x->mbmi.mv.as_mv.col; \
|
||||
cnt++; \
|
||||
}
|
||||
|
||||
#define GET_MV_SIGN(x) \
|
||||
if (x->mbmi.ref_frame != INTRA_FRAME) { \
|
||||
mvx[cnt] = x->mbmi.mv.as_mv.row; \
|
||||
mvy[cnt] = x->mbmi.mv.as_mv.col; \
|
||||
if (cm->ref_frame_sign_bias[x->mbmi.ref_frame] != \
|
||||
cm->ref_frame_sign_bias[tmp->mbmi.ref_frame]) { \
|
||||
mvx[cnt] *= -1; \
|
||||
mvy[cnt] *= -1; \
|
||||
} \
|
||||
cnt++; \
|
||||
}
|
||||
|
||||
void vp8_cal_dissimilarity(VP8_COMP *cpi) {
|
||||
VP8_COMMON *cm = &cpi->common;
|
||||
int i;
|
||||
|
||||
/* Note: The first row & first column in mip are outside the frame, which
|
||||
* were initialized to all 0.(ref_frame, mode, mv...)
|
||||
* Their ref_frame = 0 means they won't be counted in the following
|
||||
* calculation.
|
||||
*/
|
||||
if (cpi->oxcf.mr_total_resolutions > 1 &&
|
||||
cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1)) {
|
||||
/* Store info for show/no-show frames for supporting alt_ref.
|
||||
* If parent frame is alt_ref, child has one too.
|
||||
*/
|
||||
LOWER_RES_FRAME_INFO *store_info =
|
||||
(LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info;
|
||||
|
||||
store_info->frame_type = cm->frame_type;
|
||||
|
||||
if (cm->frame_type != KEY_FRAME) {
|
||||
store_info->is_frame_dropped = 0;
|
||||
for (i = 1; i < MAX_REF_FRAMES; ++i)
|
||||
store_info->low_res_ref_frames[i] = cpi->current_ref_frames[i];
|
||||
}
|
||||
|
||||
if (cm->frame_type != KEY_FRAME) {
|
||||
int mb_row;
|
||||
int mb_col;
|
||||
/* Point to beginning of allocated MODE_INFO arrays. */
|
||||
MODE_INFO *tmp = cm->mip + cm->mode_info_stride;
|
||||
LOWER_RES_MB_INFO *store_mode_info = store_info->mb_info;
|
||||
|
||||
for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
|
||||
tmp++;
|
||||
for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
|
||||
int dissim = INT_MAX;
|
||||
|
||||
if (tmp->mbmi.ref_frame != INTRA_FRAME) {
|
||||
int mvx[8];
|
||||
int mvy[8];
|
||||
int mmvx;
|
||||
int mmvy;
|
||||
int cnt = 0;
|
||||
const MODE_INFO *here = tmp;
|
||||
const MODE_INFO *above = here - cm->mode_info_stride;
|
||||
const MODE_INFO *left = here - 1;
|
||||
const MODE_INFO *aboveleft = above - 1;
|
||||
const MODE_INFO *aboveright = NULL;
|
||||
const MODE_INFO *right = NULL;
|
||||
const MODE_INFO *belowleft = NULL;
|
||||
const MODE_INFO *below = NULL;
|
||||
const MODE_INFO *belowright = NULL;
|
||||
|
||||
/* If alternate reference frame is used, we have to
|
||||
* check sign of MV. */
|
||||
if (cpi->oxcf.play_alternate) {
|
||||
/* Gather mv of neighboring MBs */
|
||||
GET_MV_SIGN(above)
|
||||
GET_MV_SIGN(left)
|
||||
GET_MV_SIGN(aboveleft)
|
||||
|
||||
if (mb_col < (cm->mb_cols - 1)) {
|
||||
right = here + 1;
|
||||
aboveright = above + 1;
|
||||
GET_MV_SIGN(right)
|
||||
GET_MV_SIGN(aboveright)
|
||||
}
|
||||
|
||||
if (mb_row < (cm->mb_rows - 1)) {
|
||||
below = here + cm->mode_info_stride;
|
||||
belowleft = below - 1;
|
||||
GET_MV_SIGN(below)
|
||||
GET_MV_SIGN(belowleft)
|
||||
}
|
||||
|
||||
if (mb_col < (cm->mb_cols - 1) && mb_row < (cm->mb_rows - 1)) {
|
||||
belowright = below + 1;
|
||||
GET_MV_SIGN(belowright)
|
||||
}
|
||||
} else {
|
||||
/* No alt_ref and gather mv of neighboring MBs */
|
||||
GET_MV(above)
|
||||
GET_MV(left)
|
||||
GET_MV(aboveleft)
|
||||
|
||||
if (mb_col < (cm->mb_cols - 1)) {
|
||||
right = here + 1;
|
||||
aboveright = above + 1;
|
||||
GET_MV(right)
|
||||
GET_MV(aboveright)
|
||||
}
|
||||
|
||||
if (mb_row < (cm->mb_rows - 1)) {
|
||||
below = here + cm->mode_info_stride;
|
||||
belowleft = below - 1;
|
||||
GET_MV(below)
|
||||
GET_MV(belowleft)
|
||||
}
|
||||
|
||||
if (mb_col < (cm->mb_cols - 1) && mb_row < (cm->mb_rows - 1)) {
|
||||
belowright = below + 1;
|
||||
GET_MV(belowright)
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt > 0) {
|
||||
int max_mvx = mvx[0];
|
||||
int min_mvx = mvx[0];
|
||||
int max_mvy = mvy[0];
|
||||
int min_mvy = mvy[0];
|
||||
int i;
|
||||
|
||||
if (cnt > 1) {
|
||||
for (i = 1; i < cnt; ++i) {
|
||||
if (mvx[i] > max_mvx)
|
||||
max_mvx = mvx[i];
|
||||
else if (mvx[i] < min_mvx)
|
||||
min_mvx = mvx[i];
|
||||
if (mvy[i] > max_mvy)
|
||||
max_mvy = mvy[i];
|
||||
else if (mvy[i] < min_mvy)
|
||||
min_mvy = mvy[i];
|
||||
}
|
||||
}
|
||||
|
||||
mmvx = VPXMAX(abs(min_mvx - here->mbmi.mv.as_mv.row),
|
||||
abs(max_mvx - here->mbmi.mv.as_mv.row));
|
||||
mmvy = VPXMAX(abs(min_mvy - here->mbmi.mv.as_mv.col),
|
||||
abs(max_mvy - here->mbmi.mv.as_mv.col));
|
||||
dissim = VPXMAX(mmvx, mmvy);
|
||||
}
|
||||
}
|
||||
|
||||
/* Store mode info for next resolution encoding */
|
||||
store_mode_info->mode = tmp->mbmi.mode;
|
||||
store_mode_info->ref_frame = tmp->mbmi.ref_frame;
|
||||
store_mode_info->mv.as_int = tmp->mbmi.mv.as_int;
|
||||
store_mode_info->dissim = dissim;
|
||||
tmp++;
|
||||
store_mode_info++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is called only when this frame is dropped at current
|
||||
resolution level. */
|
||||
void vp8_store_drop_frame_info(VP8_COMP *cpi) {
|
||||
/* If the frame is dropped in lower-resolution encoding, this information
|
||||
is passed to higher resolution level so that the encoder knows there
|
||||
is no mode & motion info available.
|
||||
*/
|
||||
if (cpi->oxcf.mr_total_resolutions > 1 &&
|
||||
cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1)) {
|
||||
/* Store info for show/no-show frames for supporting alt_ref.
|
||||
* If parent frame is alt_ref, child has one too.
|
||||
*/
|
||||
LOWER_RES_FRAME_INFO *store_info =
|
||||
(LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info;
|
||||
|
||||
/* Set frame_type to be INTER_FRAME since we won't drop key frame. */
|
||||
store_info->frame_type = INTER_FRAME;
|
||||
store_info->is_frame_dropped = 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_MR_DISSIM_H_
|
||||
#define VPX_VP8_ENCODER_MR_DISSIM_H_
|
||||
#include "vpx_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void vp8_cal_low_res_mb_cols(VP8_COMP *cpi);
|
||||
extern void vp8_cal_dissimilarity(VP8_COMP *cpi);
|
||||
extern void vp8_store_drop_frame_info(VP8_COMP *cpi);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_MR_DISSIM_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,743 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_ONYX_INT_H_
|
||||
#define VPX_VP8_ENCODER_ONYX_INT_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include "vpx_config.h"
|
||||
#include "vp8/common/onyx.h"
|
||||
#include "treewriter.h"
|
||||
#include "tokenize.h"
|
||||
#include "vp8/common/onyxc_int.h"
|
||||
#include "vpx_dsp/variance.h"
|
||||
#include "encodemb.h"
|
||||
#include "vp8/encoder/quantize.h"
|
||||
#include "vp8/common/entropy.h"
|
||||
#include "vp8/common/threading.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx/internal/vpx_codec_internal.h"
|
||||
#include "vpx/vp8.h"
|
||||
#include "mcomp.h"
|
||||
#include "vp8/common/findnearmv.h"
|
||||
#include "lookahead.h"
|
||||
#if CONFIG_TEMPORAL_DENOISING
|
||||
#include "vp8/encoder/denoising.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MIN_GF_INTERVAL 4
|
||||
#define DEFAULT_GF_INTERVAL 7
|
||||
|
||||
#define KEY_FRAME_CONTEXT 5
|
||||
|
||||
#define MAX_LAG_BUFFERS (CONFIG_REALTIME_ONLY ? 1 : 25)
|
||||
|
||||
#define AF_THRESH 25
|
||||
#define AF_THRESH2 100
|
||||
#define ARF_DECAY_THRESH 12
|
||||
|
||||
#define MIN_THRESHMULT 32
|
||||
#define MAX_THRESHMULT 512
|
||||
|
||||
#define GF_ZEROMV_ZBIN_BOOST 12
|
||||
#define LF_ZEROMV_ZBIN_BOOST 6
|
||||
#define MV_ZBIN_BOOST 4
|
||||
#define ZBIN_OQ_MAX 192
|
||||
|
||||
#define VP8_TEMPORAL_ALT_REF !CONFIG_REALTIME_ONLY
|
||||
|
||||
/* vp8 uses 10,000,000 ticks/second as time stamp */
|
||||
#define TICKS_PER_SEC 10000000
|
||||
|
||||
typedef struct {
|
||||
int kf_indicated;
|
||||
unsigned int frames_since_key;
|
||||
unsigned int frames_since_golden;
|
||||
int filter_level;
|
||||
int frames_till_gf_update_due;
|
||||
int recent_ref_frame_usage[MAX_REF_FRAMES];
|
||||
|
||||
MV_CONTEXT mvc[2];
|
||||
int mvcosts[2][MVvals + 1];
|
||||
|
||||
#ifdef MODE_STATS
|
||||
int y_modes[5];
|
||||
int uv_modes[4];
|
||||
int b_modes[10];
|
||||
int inter_y_modes[10];
|
||||
int inter_uv_modes[4];
|
||||
int inter_b_modes[10];
|
||||
#endif
|
||||
|
||||
vp8_prob ymode_prob[4], uv_mode_prob[3]; /* interframe intra mode probs */
|
||||
vp8_prob kf_ymode_prob[4], kf_uv_mode_prob[3]; /* keyframe "" */
|
||||
|
||||
int ymode_count[5], uv_mode_count[4]; /* intra MB type cts this frame */
|
||||
|
||||
int count_mb_ref_frame_usage[MAX_REF_FRAMES];
|
||||
|
||||
int this_frame_percent_intra;
|
||||
int last_frame_percent_intra;
|
||||
|
||||
} CODING_CONTEXT;
|
||||
|
||||
typedef struct {
|
||||
double frame;
|
||||
double intra_error;
|
||||
double coded_error;
|
||||
double ssim_weighted_pred_err;
|
||||
double pcnt_inter;
|
||||
double pcnt_motion;
|
||||
double pcnt_second_ref;
|
||||
double pcnt_neutral;
|
||||
double MVr;
|
||||
double mvr_abs;
|
||||
double MVc;
|
||||
double mvc_abs;
|
||||
double MVrv;
|
||||
double MVcv;
|
||||
double mv_in_out_count;
|
||||
double new_mv_count;
|
||||
double duration;
|
||||
double count;
|
||||
} FIRSTPASS_STATS;
|
||||
|
||||
typedef struct {
|
||||
int frames_so_far;
|
||||
double frame_intra_error;
|
||||
double frame_coded_error;
|
||||
double frame_pcnt_inter;
|
||||
double frame_pcnt_motion;
|
||||
double frame_mvr;
|
||||
double frame_mvr_abs;
|
||||
double frame_mvc;
|
||||
double frame_mvc_abs;
|
||||
|
||||
} ONEPASS_FRAMESTATS;
|
||||
|
||||
typedef enum {
|
||||
THR_ZERO1 = 0,
|
||||
THR_DC = 1,
|
||||
|
||||
THR_NEAREST1 = 2,
|
||||
THR_NEAR1 = 3,
|
||||
|
||||
THR_ZERO2 = 4,
|
||||
THR_NEAREST2 = 5,
|
||||
|
||||
THR_ZERO3 = 6,
|
||||
THR_NEAREST3 = 7,
|
||||
|
||||
THR_NEAR2 = 8,
|
||||
THR_NEAR3 = 9,
|
||||
|
||||
THR_V_PRED = 10,
|
||||
THR_H_PRED = 11,
|
||||
THR_TM = 12,
|
||||
|
||||
THR_NEW1 = 13,
|
||||
THR_NEW2 = 14,
|
||||
THR_NEW3 = 15,
|
||||
|
||||
THR_SPLIT1 = 16,
|
||||
THR_SPLIT2 = 17,
|
||||
THR_SPLIT3 = 18,
|
||||
|
||||
THR_B_PRED = 19
|
||||
} THR_MODES;
|
||||
|
||||
typedef enum { DIAMOND = 0, NSTEP = 1, HEX = 2 } SEARCH_METHODS;
|
||||
|
||||
typedef struct {
|
||||
int RD;
|
||||
SEARCH_METHODS search_method;
|
||||
int improved_quant;
|
||||
int improved_dct;
|
||||
int auto_filter;
|
||||
int recode_loop;
|
||||
int iterative_sub_pixel;
|
||||
int half_pixel_search;
|
||||
int quarter_pixel_search;
|
||||
int thresh_mult[MAX_MODES];
|
||||
int max_step_search_steps;
|
||||
int first_step;
|
||||
int optimize_coefficients;
|
||||
|
||||
int use_fastquant_for_pick;
|
||||
int no_skip_block4x4_search;
|
||||
int improved_mv_pred;
|
||||
|
||||
} SPEED_FEATURES;
|
||||
|
||||
typedef struct {
|
||||
MACROBLOCK mb;
|
||||
int segment_counts[MAX_MB_SEGMENTS];
|
||||
int totalrate;
|
||||
} MB_ROW_COMP;
|
||||
|
||||
typedef struct {
|
||||
TOKENEXTRA *start;
|
||||
TOKENEXTRA *stop;
|
||||
} TOKENLIST;
|
||||
|
||||
typedef struct {
|
||||
int ithread;
|
||||
void *ptr1;
|
||||
void *ptr2;
|
||||
} ENCODETHREAD_DATA;
|
||||
typedef struct {
|
||||
int ithread;
|
||||
void *ptr1;
|
||||
} LPFTHREAD_DATA;
|
||||
|
||||
enum {
|
||||
BLOCK_16X8,
|
||||
BLOCK_8X16,
|
||||
BLOCK_8X8,
|
||||
BLOCK_4X4,
|
||||
BLOCK_16X16,
|
||||
BLOCK_MAX_SEGMENTS
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/* Layer configuration */
|
||||
double framerate;
|
||||
int target_bandwidth;
|
||||
|
||||
/* Layer specific coding parameters */
|
||||
int64_t starting_buffer_level;
|
||||
int64_t optimal_buffer_level;
|
||||
int64_t maximum_buffer_size;
|
||||
int64_t starting_buffer_level_in_ms;
|
||||
int64_t optimal_buffer_level_in_ms;
|
||||
int64_t maximum_buffer_size_in_ms;
|
||||
|
||||
int avg_frame_size_for_layer;
|
||||
|
||||
int64_t buffer_level;
|
||||
int64_t bits_off_target;
|
||||
|
||||
int64_t total_actual_bits;
|
||||
int total_target_vs_actual;
|
||||
|
||||
int worst_quality;
|
||||
int active_worst_quality;
|
||||
int best_quality;
|
||||
int active_best_quality;
|
||||
|
||||
int ni_av_qi;
|
||||
int ni_tot_qi;
|
||||
int ni_frames;
|
||||
int avg_frame_qindex;
|
||||
|
||||
double rate_correction_factor;
|
||||
double key_frame_rate_correction_factor;
|
||||
double gf_rate_correction_factor;
|
||||
|
||||
int zbin_over_quant;
|
||||
|
||||
int inter_frame_target;
|
||||
int64_t total_byte_count;
|
||||
|
||||
int filter_level;
|
||||
|
||||
int frames_since_last_drop_overshoot;
|
||||
|
||||
int force_maxqp;
|
||||
|
||||
int last_frame_percent_intra;
|
||||
|
||||
int count_mb_ref_frame_usage[MAX_REF_FRAMES];
|
||||
|
||||
int last_q[2];
|
||||
} LAYER_CONTEXT;
|
||||
|
||||
typedef struct VP8_COMP {
|
||||
DECLARE_ALIGNED(16, short, Y1quant[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, Y1quant_shift[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, Y1zbin[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, Y1round[QINDEX_RANGE][16]);
|
||||
|
||||
DECLARE_ALIGNED(16, short, Y2quant[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, Y2quant_shift[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, Y2zbin[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, Y2round[QINDEX_RANGE][16]);
|
||||
|
||||
DECLARE_ALIGNED(16, short, UVquant[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, UVquant_shift[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, UVzbin[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, UVround[QINDEX_RANGE][16]);
|
||||
|
||||
DECLARE_ALIGNED(16, short, zrun_zbin_boost_y1[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, zrun_zbin_boost_y2[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, zrun_zbin_boost_uv[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, Y1quant_fast[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, Y2quant_fast[QINDEX_RANGE][16]);
|
||||
DECLARE_ALIGNED(16, short, UVquant_fast[QINDEX_RANGE][16]);
|
||||
|
||||
MACROBLOCK mb;
|
||||
VP8_COMMON common;
|
||||
vp8_writer bc[9]; /* one boolcoder for each partition */
|
||||
|
||||
VP8_CONFIG oxcf;
|
||||
|
||||
struct lookahead_ctx *lookahead;
|
||||
struct lookahead_entry *source;
|
||||
struct lookahead_entry *alt_ref_source;
|
||||
struct lookahead_entry *last_source;
|
||||
|
||||
YV12_BUFFER_CONFIG *Source;
|
||||
YV12_BUFFER_CONFIG *un_scaled_source;
|
||||
YV12_BUFFER_CONFIG scaled_source;
|
||||
YV12_BUFFER_CONFIG *last_frame_unscaled_source;
|
||||
|
||||
unsigned int frames_till_alt_ref_frame;
|
||||
/* frame in src_buffers has been identified to be encoded as an alt ref */
|
||||
int source_alt_ref_pending;
|
||||
/* an alt ref frame has been encoded and is usable */
|
||||
int source_alt_ref_active;
|
||||
/* source of frame to encode is an exact copy of an alt ref frame */
|
||||
int is_src_frame_alt_ref;
|
||||
|
||||
/* golden frame same as last frame ( short circuit gold searches) */
|
||||
int gold_is_last;
|
||||
/* Alt reference frame same as last ( short circuit altref search) */
|
||||
int alt_is_last;
|
||||
/* don't do both alt and gold search ( just do gold). */
|
||||
int gold_is_alt;
|
||||
|
||||
YV12_BUFFER_CONFIG pick_lf_lvl_frame;
|
||||
|
||||
TOKENEXTRA *tok;
|
||||
unsigned int tok_count;
|
||||
|
||||
unsigned int frames_since_key;
|
||||
unsigned int key_frame_frequency;
|
||||
unsigned int this_key_frame_forced;
|
||||
unsigned int next_key_frame_forced;
|
||||
|
||||
/* Ambient reconstruction err target for force key frames */
|
||||
int ambient_err;
|
||||
|
||||
unsigned int mode_check_freq[MAX_MODES];
|
||||
|
||||
int rd_baseline_thresh[MAX_MODES];
|
||||
|
||||
int RDMULT;
|
||||
int RDDIV;
|
||||
|
||||
CODING_CONTEXT coding_context;
|
||||
|
||||
/* Rate targetting variables */
|
||||
int64_t last_prediction_error;
|
||||
int64_t last_intra_error;
|
||||
|
||||
int this_frame_target;
|
||||
int projected_frame_size;
|
||||
int last_q[2]; /* Separate values for Intra/Inter */
|
||||
|
||||
double rate_correction_factor;
|
||||
double key_frame_rate_correction_factor;
|
||||
double gf_rate_correction_factor;
|
||||
|
||||
int frames_since_golden;
|
||||
/* Count down till next GF */
|
||||
int frames_till_gf_update_due;
|
||||
|
||||
/* GF interval chosen when we coded the last GF */
|
||||
int current_gf_interval;
|
||||
|
||||
/* Total bits overspent becasue of GF boost (cumulative) */
|
||||
int gf_overspend_bits;
|
||||
|
||||
/* Used in the few frames following a GF to recover the extra bits
|
||||
* spent in that GF
|
||||
*/
|
||||
int non_gf_bitrate_adjustment;
|
||||
|
||||
/* Extra bits spent on key frames that need to be recovered */
|
||||
int kf_overspend_bits;
|
||||
|
||||
/* Current number of bit s to try and recover on each inter frame. */
|
||||
int kf_bitrate_adjustment;
|
||||
int max_gf_interval;
|
||||
int baseline_gf_interval;
|
||||
int active_arnr_frames;
|
||||
|
||||
int64_t key_frame_count;
|
||||
int prior_key_frame_distance[KEY_FRAME_CONTEXT];
|
||||
/* Current section per frame bandwidth target */
|
||||
int per_frame_bandwidth;
|
||||
/* Average frame size target for clip */
|
||||
int av_per_frame_bandwidth;
|
||||
/* Minimum allocation that should be used for any frame */
|
||||
int min_frame_bandwidth;
|
||||
int inter_frame_target;
|
||||
double output_framerate;
|
||||
int64_t last_time_stamp_seen;
|
||||
int64_t last_end_time_stamp_seen;
|
||||
int64_t first_time_stamp_ever;
|
||||
|
||||
int ni_av_qi;
|
||||
int ni_tot_qi;
|
||||
int ni_frames;
|
||||
int avg_frame_qindex;
|
||||
|
||||
int64_t total_byte_count;
|
||||
|
||||
int buffered_mode;
|
||||
|
||||
double framerate;
|
||||
double ref_framerate;
|
||||
int64_t buffer_level;
|
||||
int64_t bits_off_target;
|
||||
|
||||
int rolling_target_bits;
|
||||
int rolling_actual_bits;
|
||||
|
||||
int long_rolling_target_bits;
|
||||
int long_rolling_actual_bits;
|
||||
|
||||
int64_t total_actual_bits;
|
||||
int total_target_vs_actual; /* debug stats */
|
||||
|
||||
int worst_quality;
|
||||
int active_worst_quality;
|
||||
int best_quality;
|
||||
int active_best_quality;
|
||||
|
||||
int cq_target_quality;
|
||||
|
||||
int drop_frames_allowed; /* Are we permitted to drop frames? */
|
||||
int drop_frame; /* Drop this frame? */
|
||||
#if defined(DROP_UNCODED_FRAMES)
|
||||
int drop_frame_count;
|
||||
#endif
|
||||
|
||||
vp8_prob frame_coef_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS]
|
||||
[ENTROPY_NODES];
|
||||
char update_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
|
||||
|
||||
unsigned int frame_branch_ct[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS]
|
||||
[ENTROPY_NODES][2];
|
||||
|
||||
int gfu_boost;
|
||||
int kf_boost;
|
||||
int last_boost;
|
||||
|
||||
int target_bandwidth;
|
||||
struct vpx_codec_pkt_list *output_pkt_list;
|
||||
|
||||
#if 0
|
||||
/* Experimental code for lagged and one pass */
|
||||
ONEPASS_FRAMESTATS one_pass_frame_stats[MAX_LAG_BUFFERS];
|
||||
int one_pass_frame_index;
|
||||
#endif
|
||||
|
||||
int decimation_factor;
|
||||
int decimation_count;
|
||||
|
||||
/* for real time encoding */
|
||||
int avg_encode_time; /* microsecond */
|
||||
int avg_pick_mode_time; /* microsecond */
|
||||
int Speed;
|
||||
int compressor_speed;
|
||||
|
||||
int auto_gold;
|
||||
int auto_adjust_gold_quantizer;
|
||||
int auto_worst_q;
|
||||
int cpu_used;
|
||||
int pass;
|
||||
|
||||
int prob_intra_coded;
|
||||
int prob_last_coded;
|
||||
int prob_gf_coded;
|
||||
int prob_skip_false;
|
||||
int last_skip_false_probs[3];
|
||||
int last_skip_probs_q[3];
|
||||
int recent_ref_frame_usage[MAX_REF_FRAMES];
|
||||
|
||||
int this_frame_percent_intra;
|
||||
int last_frame_percent_intra;
|
||||
|
||||
int ref_frame_flags;
|
||||
|
||||
SPEED_FEATURES sf;
|
||||
|
||||
/* Count ZEROMV on all reference frames. */
|
||||
int zeromv_count;
|
||||
int lf_zeromv_pct;
|
||||
|
||||
unsigned char *skin_map;
|
||||
|
||||
unsigned char *segmentation_map;
|
||||
signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS];
|
||||
int segment_encode_breakout[MAX_MB_SEGMENTS];
|
||||
|
||||
unsigned char *active_map;
|
||||
unsigned int active_map_enabled;
|
||||
|
||||
/* Video conferencing cyclic refresh mode flags. This is a mode
|
||||
* designed to clean up the background over time in live encoding
|
||||
* scenarious. It uses segmentation.
|
||||
*/
|
||||
int cyclic_refresh_mode_enabled;
|
||||
int cyclic_refresh_mode_max_mbs_perframe;
|
||||
int cyclic_refresh_mode_index;
|
||||
int cyclic_refresh_q;
|
||||
signed char *cyclic_refresh_map;
|
||||
// Count on how many (consecutive) times a macroblock uses ZER0MV_LAST.
|
||||
unsigned char *consec_zero_last;
|
||||
// Counter that is reset when a block is checked for a mode-bias against
|
||||
// ZEROMV_LASTREF.
|
||||
unsigned char *consec_zero_last_mvbias;
|
||||
|
||||
// Frame counter for the temporal pattern. Counter is rest when the temporal
|
||||
// layers are changed dynamically (run-time change).
|
||||
unsigned int temporal_pattern_counter;
|
||||
// Temporal layer id.
|
||||
int temporal_layer_id;
|
||||
|
||||
// Measure of average squared difference between source and denoised signal.
|
||||
int mse_source_denoised;
|
||||
|
||||
int force_maxqp;
|
||||
int frames_since_last_drop_overshoot;
|
||||
int last_pred_err_mb;
|
||||
|
||||
// GF update for 1 pass cbr.
|
||||
int gf_update_onepass_cbr;
|
||||
int gf_interval_onepass_cbr;
|
||||
int gf_noboost_onepass_cbr;
|
||||
|
||||
#if CONFIG_MULTITHREAD
|
||||
/* multithread data */
|
||||
vpx_atomic_int *mt_current_mb_col;
|
||||
int mt_sync_range;
|
||||
vpx_atomic_int b_multi_threaded;
|
||||
int encoding_thread_count;
|
||||
int b_lpf_running;
|
||||
|
||||
pthread_t *h_encoding_thread;
|
||||
pthread_t h_filter_thread;
|
||||
|
||||
MB_ROW_COMP *mb_row_ei;
|
||||
ENCODETHREAD_DATA *en_thread_data;
|
||||
LPFTHREAD_DATA lpf_thread_data;
|
||||
|
||||
/* events */
|
||||
sem_t *h_event_start_encoding;
|
||||
sem_t *h_event_end_encoding;
|
||||
sem_t h_event_start_lpf;
|
||||
sem_t h_event_end_lpf;
|
||||
#endif
|
||||
|
||||
TOKENLIST *tplist;
|
||||
unsigned int partition_sz[MAX_PARTITIONS];
|
||||
unsigned char *partition_d[MAX_PARTITIONS];
|
||||
unsigned char *partition_d_end[MAX_PARTITIONS];
|
||||
|
||||
fractional_mv_step_fp *find_fractional_mv_step;
|
||||
vp8_full_search_fn_t full_search_sad;
|
||||
vp8_refining_search_fn_t refining_search_sad;
|
||||
vp8_diamond_search_fn_t diamond_search_sad;
|
||||
vp8_variance_fn_ptr_t fn_ptr[BLOCK_MAX_SEGMENTS];
|
||||
uint64_t time_receive_data;
|
||||
uint64_t time_compress_data;
|
||||
uint64_t time_pick_lpf;
|
||||
uint64_t time_encode_mb_row;
|
||||
|
||||
int base_skip_false_prob[128];
|
||||
|
||||
FRAME_CONTEXT lfc_n; /* last frame entropy */
|
||||
FRAME_CONTEXT lfc_a; /* last alt ref entropy */
|
||||
FRAME_CONTEXT lfc_g; /* last gold ref entropy */
|
||||
|
||||
struct twopass_rc {
|
||||
unsigned int section_intra_rating;
|
||||
double section_max_qfactor;
|
||||
unsigned int next_iiratio;
|
||||
unsigned int this_iiratio;
|
||||
FIRSTPASS_STATS total_stats;
|
||||
FIRSTPASS_STATS this_frame_stats;
|
||||
FIRSTPASS_STATS *stats_in, *stats_in_end, *stats_in_start;
|
||||
FIRSTPASS_STATS total_left_stats;
|
||||
int first_pass_done;
|
||||
int64_t bits_left;
|
||||
int64_t clip_bits_total;
|
||||
double avg_iiratio;
|
||||
double modified_error_total;
|
||||
double modified_error_used;
|
||||
double modified_error_left;
|
||||
double kf_intra_err_min;
|
||||
double gf_intra_err_min;
|
||||
int frames_to_key;
|
||||
int maxq_max_limit;
|
||||
int maxq_min_limit;
|
||||
int gf_decay_rate;
|
||||
int static_scene_max_gf_interval;
|
||||
int kf_bits;
|
||||
/* Remaining error from uncoded frames in a gf group. */
|
||||
int gf_group_error_left;
|
||||
/* Projected total bits available for a key frame group of frames */
|
||||
int64_t kf_group_bits;
|
||||
/* Error score of frames still to be coded in kf group */
|
||||
int64_t kf_group_error_left;
|
||||
/* Projected Bits available for a group including 1 GF or ARF */
|
||||
int64_t gf_group_bits;
|
||||
/* Bits for the golden frame or ARF */
|
||||
int gf_bits;
|
||||
int alt_extra_bits;
|
||||
double est_max_qcorrection_factor;
|
||||
} twopass;
|
||||
|
||||
#if VP8_TEMPORAL_ALT_REF
|
||||
YV12_BUFFER_CONFIG alt_ref_buffer;
|
||||
YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS];
|
||||
int fixed_divide[512];
|
||||
#endif
|
||||
|
||||
#if CONFIG_INTERNAL_STATS
|
||||
int count;
|
||||
double total_y;
|
||||
double total_u;
|
||||
double total_v;
|
||||
double total;
|
||||
double total_sq_error;
|
||||
double totalp_y;
|
||||
double totalp_u;
|
||||
double totalp_v;
|
||||
double totalp;
|
||||
double total_sq_error2;
|
||||
int bytes;
|
||||
double summed_quality;
|
||||
double summed_weights;
|
||||
unsigned int tot_recode_hits;
|
||||
|
||||
int b_calculate_ssimg;
|
||||
#endif
|
||||
int b_calculate_psnr;
|
||||
|
||||
/* Per MB activity measurement */
|
||||
unsigned int activity_avg;
|
||||
unsigned int *mb_activity_map;
|
||||
|
||||
/* Record of which MBs still refer to last golden frame either
|
||||
* directly or through 0,0
|
||||
*/
|
||||
unsigned char *gf_active_flags;
|
||||
int gf_active_count;
|
||||
|
||||
int output_partition;
|
||||
|
||||
/* Store last frame's MV info for next frame MV prediction */
|
||||
int_mv *lfmv;
|
||||
int *lf_ref_frame_sign_bias;
|
||||
int *lf_ref_frame;
|
||||
|
||||
/* force next frame to intra when kf_auto says so */
|
||||
int force_next_frame_intra;
|
||||
|
||||
int droppable;
|
||||
|
||||
int initial_width;
|
||||
int initial_height;
|
||||
|
||||
#if CONFIG_TEMPORAL_DENOISING
|
||||
VP8_DENOISER denoiser;
|
||||
#endif
|
||||
|
||||
/* Coding layer state variables */
|
||||
unsigned int current_layer;
|
||||
LAYER_CONTEXT layer_context[VPX_TS_MAX_LAYERS];
|
||||
|
||||
int64_t frames_in_layer[VPX_TS_MAX_LAYERS];
|
||||
int64_t bytes_in_layer[VPX_TS_MAX_LAYERS];
|
||||
double sum_psnr[VPX_TS_MAX_LAYERS];
|
||||
double sum_psnr_p[VPX_TS_MAX_LAYERS];
|
||||
double total_error2[VPX_TS_MAX_LAYERS];
|
||||
double total_error2_p[VPX_TS_MAX_LAYERS];
|
||||
double sum_ssim[VPX_TS_MAX_LAYERS];
|
||||
double sum_weights[VPX_TS_MAX_LAYERS];
|
||||
|
||||
double total_ssimg_y_in_layer[VPX_TS_MAX_LAYERS];
|
||||
double total_ssimg_u_in_layer[VPX_TS_MAX_LAYERS];
|
||||
double total_ssimg_v_in_layer[VPX_TS_MAX_LAYERS];
|
||||
double total_ssimg_all_in_layer[VPX_TS_MAX_LAYERS];
|
||||
|
||||
#if CONFIG_MULTI_RES_ENCODING
|
||||
/* Number of MBs per row at lower-resolution level */
|
||||
int mr_low_res_mb_cols;
|
||||
/* Indicate if lower-res mv info is available */
|
||||
unsigned char mr_low_res_mv_avail;
|
||||
#endif
|
||||
/* The frame number of each reference frames */
|
||||
unsigned int current_ref_frames[MAX_REF_FRAMES];
|
||||
// Closest reference frame to current frame.
|
||||
MV_REFERENCE_FRAME closest_reference_frame;
|
||||
|
||||
struct rd_costs_struct {
|
||||
int mvcosts[2][MVvals + 1];
|
||||
int mvsadcosts[2][MVfpvals + 1];
|
||||
int mbmode_cost[2][MB_MODE_COUNT];
|
||||
int intra_uv_mode_cost[2][MB_MODE_COUNT];
|
||||
int bmode_costs[10][10][10];
|
||||
int inter_bmode_costs[B_MODE_COUNT];
|
||||
int token_costs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS]
|
||||
[MAX_ENTROPY_TOKENS];
|
||||
} rd_costs;
|
||||
|
||||
// Use the static threshold from ROI settings.
|
||||
int use_roi_static_threshold;
|
||||
|
||||
int ext_refresh_frame_flags_pending;
|
||||
} VP8_COMP;
|
||||
|
||||
void vp8_initialize_enc(void);
|
||||
|
||||
void vp8_alloc_compressor_data(VP8_COMP *cpi);
|
||||
int vp8_reverse_trans(int x);
|
||||
void vp8_new_framerate(VP8_COMP *cpi, double framerate);
|
||||
void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm);
|
||||
|
||||
void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest,
|
||||
unsigned char *dest_end, size_t *size);
|
||||
|
||||
void vp8_tokenize_mb(VP8_COMP *, MACROBLOCK *, TOKENEXTRA **);
|
||||
|
||||
void vp8_set_speed_features(VP8_COMP *cpi);
|
||||
|
||||
#if CONFIG_DEBUG
|
||||
#define CHECK_MEM_ERROR(lval, expr) \
|
||||
do { \
|
||||
(lval) = (expr); \
|
||||
if (!(lval)) \
|
||||
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, \
|
||||
"Failed to allocate " #lval " at %s:%d", __FILE__, \
|
||||
__LINE__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define CHECK_MEM_ERROR(lval, expr) \
|
||||
do { \
|
||||
(lval) = (expr); \
|
||||
if (!(lval)) \
|
||||
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, \
|
||||
"Failed to allocate " #lval); \
|
||||
} while (0)
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_ONYX_INT_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_PICKINTER_H_
|
||||
#define VPX_VP8_ENCODER_PICKINTER_H_
|
||||
#include "vpx_config.h"
|
||||
#include "vp8/common/onyxc_int.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
|
||||
int recon_uvoffset, int *returnrate,
|
||||
int *returndistortion, int *returnintra,
|
||||
int mb_row, int mb_col);
|
||||
extern void vp8_pick_intra_mode(MACROBLOCK *x, int *rate);
|
||||
|
||||
extern int vp8_get_inter_mbpred_error(MACROBLOCK *mb,
|
||||
const vp8_variance_fn_ptr_t *vfp,
|
||||
unsigned int *sse, int_mv this_mv);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_PICKINTER_H_
|
||||
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "./vpx_scale_rtcd.h"
|
||||
#include "vp8/common/onyxc_int.h"
|
||||
#include "onyx_int.h"
|
||||
#include "vp8/encoder/picklpf.h"
|
||||
#include "vp8/encoder/quantize.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_scale/vpx_scale.h"
|
||||
#include "vp8/common/alloccommon.h"
|
||||
#include "vp8/common/loopfilter.h"
|
||||
#if VPX_ARCH_ARM
|
||||
#include "vpx_ports/arm.h"
|
||||
#endif
|
||||
|
||||
extern int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source,
|
||||
YV12_BUFFER_CONFIG *dest);
|
||||
|
||||
static void yv12_copy_partial_frame(YV12_BUFFER_CONFIG *src_ybc,
|
||||
YV12_BUFFER_CONFIG *dst_ybc) {
|
||||
unsigned char *src_y, *dst_y;
|
||||
int yheight;
|
||||
int ystride;
|
||||
int yoffset;
|
||||
int linestocopy;
|
||||
|
||||
yheight = src_ybc->y_height;
|
||||
ystride = src_ybc->y_stride;
|
||||
|
||||
/* number of MB rows to use in partial filtering */
|
||||
linestocopy = (yheight >> 4) / PARTIAL_FRAME_FRACTION;
|
||||
linestocopy = linestocopy ? linestocopy << 4 : 16; /* 16 lines per MB */
|
||||
|
||||
/* Copy extra 4 so that full filter context is available if filtering done
|
||||
* on the copied partial frame and not original. Partial filter does mb
|
||||
* filtering for top row also, which can modify3 pixels above.
|
||||
*/
|
||||
linestocopy += 4;
|
||||
/* partial image starts at ~middle of frame (macroblock border)*/
|
||||
yoffset = ystride * (((yheight >> 5) * 16) - 4);
|
||||
src_y = src_ybc->y_buffer + yoffset;
|
||||
dst_y = dst_ybc->y_buffer + yoffset;
|
||||
|
||||
memcpy(dst_y, src_y, ystride * linestocopy);
|
||||
}
|
||||
|
||||
static int calc_partial_ssl_err(YV12_BUFFER_CONFIG *source,
|
||||
YV12_BUFFER_CONFIG *dest) {
|
||||
int i, j;
|
||||
int Total = 0;
|
||||
int srcoffset, dstoffset;
|
||||
unsigned char *src = source->y_buffer;
|
||||
unsigned char *dst = dest->y_buffer;
|
||||
|
||||
int linestocopy;
|
||||
|
||||
/* number of MB rows to use in partial filtering */
|
||||
linestocopy = (source->y_height >> 4) / PARTIAL_FRAME_FRACTION;
|
||||
linestocopy = linestocopy ? linestocopy << 4 : 16; /* 16 lines per MB */
|
||||
|
||||
/* partial image starts at ~middle of frame (macroblock border)*/
|
||||
srcoffset = source->y_stride * ((dest->y_height >> 5) * 16);
|
||||
dstoffset = dest->y_stride * ((dest->y_height >> 5) * 16);
|
||||
|
||||
src += srcoffset;
|
||||
dst += dstoffset;
|
||||
|
||||
/* Loop through the Y plane raw and reconstruction data summing
|
||||
* (square differences)
|
||||
*/
|
||||
for (i = 0; i < linestocopy; i += 16) {
|
||||
for (j = 0; j < source->y_width; j += 16) {
|
||||
unsigned int sse;
|
||||
Total += vpx_mse16x16(src + j, source->y_stride, dst + j, dest->y_stride,
|
||||
&sse);
|
||||
}
|
||||
|
||||
src += 16 * source->y_stride;
|
||||
dst += 16 * dest->y_stride;
|
||||
}
|
||||
|
||||
return Total;
|
||||
}
|
||||
|
||||
/* Enforce a minimum filter level based upon baseline Q */
|
||||
static int get_min_filter_level(VP8_COMP *cpi, int base_qindex) {
|
||||
int min_filter_level;
|
||||
|
||||
if (cpi->source_alt_ref_active && cpi->common.refresh_golden_frame &&
|
||||
!cpi->common.refresh_alt_ref_frame) {
|
||||
min_filter_level = 0;
|
||||
} else {
|
||||
if (base_qindex <= 6) {
|
||||
min_filter_level = 0;
|
||||
} else if (base_qindex <= 16) {
|
||||
min_filter_level = 1;
|
||||
} else {
|
||||
min_filter_level = (base_qindex / 8);
|
||||
}
|
||||
}
|
||||
|
||||
return min_filter_level;
|
||||
}
|
||||
|
||||
/* Enforce a maximum filter level based upon baseline Q */
|
||||
static int get_max_filter_level(VP8_COMP *cpi, int base_qindex) {
|
||||
/* PGW August 2006: Highest filter values almost always a bad idea */
|
||||
|
||||
/* jbb chg: 20100118 - not so any more with this overquant stuff allow
|
||||
* high values with lots of intra coming in.
|
||||
*/
|
||||
int max_filter_level = MAX_LOOP_FILTER;
|
||||
(void)base_qindex;
|
||||
|
||||
if (cpi->twopass.section_intra_rating > 8) {
|
||||
max_filter_level = MAX_LOOP_FILTER * 3 / 4;
|
||||
}
|
||||
|
||||
return max_filter_level;
|
||||
}
|
||||
|
||||
void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) {
|
||||
VP8_COMMON *cm = &cpi->common;
|
||||
|
||||
int best_err = 0;
|
||||
int filt_err = 0;
|
||||
int min_filter_level = get_min_filter_level(cpi, cm->base_qindex);
|
||||
int max_filter_level = get_max_filter_level(cpi, cm->base_qindex);
|
||||
int filt_val;
|
||||
int best_filt_val;
|
||||
YV12_BUFFER_CONFIG *saved_frame = cm->frame_to_show;
|
||||
|
||||
/* Replace unfiltered frame buffer with a new one */
|
||||
cm->frame_to_show = &cpi->pick_lf_lvl_frame;
|
||||
|
||||
if (cm->frame_type == KEY_FRAME) {
|
||||
cm->sharpness_level = 0;
|
||||
} else {
|
||||
cm->sharpness_level = cpi->oxcf.Sharpness;
|
||||
}
|
||||
|
||||
if (cm->sharpness_level != cm->last_sharpness_level) {
|
||||
vp8_loop_filter_update_sharpness(&cm->lf_info, cm->sharpness_level);
|
||||
cm->last_sharpness_level = cm->sharpness_level;
|
||||
}
|
||||
|
||||
/* Start the search at the previous frame filter level unless it is
|
||||
* now out of range.
|
||||
*/
|
||||
if (cm->filter_level < min_filter_level) {
|
||||
cm->filter_level = min_filter_level;
|
||||
} else if (cm->filter_level > max_filter_level) {
|
||||
cm->filter_level = max_filter_level;
|
||||
}
|
||||
|
||||
filt_val = cm->filter_level;
|
||||
best_filt_val = filt_val;
|
||||
|
||||
/* Get the err using the previous frame's filter value. */
|
||||
|
||||
/* Copy the unfiltered / processed recon buffer to the new buffer */
|
||||
yv12_copy_partial_frame(saved_frame, cm->frame_to_show);
|
||||
vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val);
|
||||
|
||||
best_err = calc_partial_ssl_err(sd, cm->frame_to_show);
|
||||
|
||||
filt_val -= 1 + (filt_val > 10);
|
||||
|
||||
/* Search lower filter levels */
|
||||
while (filt_val >= min_filter_level) {
|
||||
/* Apply the loop filter */
|
||||
yv12_copy_partial_frame(saved_frame, cm->frame_to_show);
|
||||
vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val);
|
||||
|
||||
/* Get the err for filtered frame */
|
||||
filt_err = calc_partial_ssl_err(sd, cm->frame_to_show);
|
||||
|
||||
/* Update the best case record or exit loop. */
|
||||
if (filt_err < best_err) {
|
||||
best_err = filt_err;
|
||||
best_filt_val = filt_val;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Adjust filter level */
|
||||
filt_val -= 1 + (filt_val > 10);
|
||||
}
|
||||
|
||||
/* Search up (note that we have already done filt_val = cm->filter_level) */
|
||||
filt_val = cm->filter_level + 1 + (filt_val > 10);
|
||||
|
||||
if (best_filt_val == cm->filter_level) {
|
||||
/* Resist raising filter level for very small gains */
|
||||
best_err -= (best_err >> 10);
|
||||
|
||||
while (filt_val < max_filter_level) {
|
||||
/* Apply the loop filter */
|
||||
yv12_copy_partial_frame(saved_frame, cm->frame_to_show);
|
||||
|
||||
vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val);
|
||||
|
||||
/* Get the err for filtered frame */
|
||||
filt_err = calc_partial_ssl_err(sd, cm->frame_to_show);
|
||||
|
||||
/* Update the best case record or exit loop. */
|
||||
if (filt_err < best_err) {
|
||||
/* Do not raise filter level if improvement is < 1 part
|
||||
* in 4096
|
||||
*/
|
||||
best_err = filt_err - (filt_err >> 10);
|
||||
|
||||
best_filt_val = filt_val;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Adjust filter level */
|
||||
filt_val += 1 + (filt_val > 10);
|
||||
}
|
||||
}
|
||||
|
||||
cm->filter_level = best_filt_val;
|
||||
|
||||
if (cm->filter_level < min_filter_level) cm->filter_level = min_filter_level;
|
||||
|
||||
if (cm->filter_level > max_filter_level) cm->filter_level = max_filter_level;
|
||||
|
||||
/* restore unfiltered frame pointer */
|
||||
cm->frame_to_show = saved_frame;
|
||||
}
|
||||
|
||||
/* Stub function for now Alt LF not used */
|
||||
void vp8cx_set_alt_lf_level(VP8_COMP *cpi, int filt_val) {
|
||||
MACROBLOCKD *mbd = &cpi->mb.e_mbd;
|
||||
(void)filt_val;
|
||||
|
||||
mbd->segment_feature_data[MB_LVL_ALT_LF][0] =
|
||||
cpi->segment_feature_data[MB_LVL_ALT_LF][0];
|
||||
mbd->segment_feature_data[MB_LVL_ALT_LF][1] =
|
||||
cpi->segment_feature_data[MB_LVL_ALT_LF][1];
|
||||
mbd->segment_feature_data[MB_LVL_ALT_LF][2] =
|
||||
cpi->segment_feature_data[MB_LVL_ALT_LF][2];
|
||||
mbd->segment_feature_data[MB_LVL_ALT_LF][3] =
|
||||
cpi->segment_feature_data[MB_LVL_ALT_LF][3];
|
||||
}
|
||||
|
||||
void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) {
|
||||
VP8_COMMON *cm = &cpi->common;
|
||||
|
||||
int best_err = 0;
|
||||
int filt_err = 0;
|
||||
int min_filter_level = get_min_filter_level(cpi, cm->base_qindex);
|
||||
int max_filter_level = get_max_filter_level(cpi, cm->base_qindex);
|
||||
|
||||
int filter_step;
|
||||
int filt_high = 0;
|
||||
int filt_mid;
|
||||
int filt_low = 0;
|
||||
int filt_best;
|
||||
int filt_direction = 0;
|
||||
|
||||
/* Bias against raising loop filter and in favor of lowering it */
|
||||
int Bias = 0;
|
||||
|
||||
int ss_err[MAX_LOOP_FILTER + 1];
|
||||
|
||||
YV12_BUFFER_CONFIG *saved_frame = cm->frame_to_show;
|
||||
|
||||
memset(ss_err, 0, sizeof(ss_err));
|
||||
|
||||
/* Replace unfiltered frame buffer with a new one */
|
||||
cm->frame_to_show = &cpi->pick_lf_lvl_frame;
|
||||
|
||||
if (cm->frame_type == KEY_FRAME) {
|
||||
cm->sharpness_level = 0;
|
||||
} else {
|
||||
cm->sharpness_level = cpi->oxcf.Sharpness;
|
||||
}
|
||||
|
||||
/* Start the search at the previous frame filter level unless it is
|
||||
* now out of range.
|
||||
*/
|
||||
filt_mid = cm->filter_level;
|
||||
|
||||
if (filt_mid < min_filter_level) {
|
||||
filt_mid = min_filter_level;
|
||||
} else if (filt_mid > max_filter_level) {
|
||||
filt_mid = max_filter_level;
|
||||
}
|
||||
|
||||
/* Define the initial step size */
|
||||
filter_step = (filt_mid < 16) ? 4 : filt_mid / 4;
|
||||
|
||||
/* Get baseline error score */
|
||||
|
||||
/* Copy the unfiltered / processed recon buffer to the new buffer */
|
||||
vpx_yv12_copy_y(saved_frame, cm->frame_to_show);
|
||||
|
||||
vp8cx_set_alt_lf_level(cpi, filt_mid);
|
||||
vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_mid);
|
||||
|
||||
best_err = vp8_calc_ss_err(sd, cm->frame_to_show);
|
||||
|
||||
ss_err[filt_mid] = best_err;
|
||||
|
||||
filt_best = filt_mid;
|
||||
|
||||
while (filter_step > 0) {
|
||||
Bias = (best_err >> (15 - (filt_mid / 8))) * filter_step;
|
||||
|
||||
if (cpi->twopass.section_intra_rating < 20) {
|
||||
Bias = Bias * cpi->twopass.section_intra_rating / 20;
|
||||
}
|
||||
|
||||
filt_high = ((filt_mid + filter_step) > max_filter_level)
|
||||
? max_filter_level
|
||||
: (filt_mid + filter_step);
|
||||
filt_low = ((filt_mid - filter_step) < min_filter_level)
|
||||
? min_filter_level
|
||||
: (filt_mid - filter_step);
|
||||
|
||||
if ((filt_direction <= 0) && (filt_low != filt_mid)) {
|
||||
if (ss_err[filt_low] == 0) {
|
||||
/* Get Low filter error score */
|
||||
vpx_yv12_copy_y(saved_frame, cm->frame_to_show);
|
||||
vp8cx_set_alt_lf_level(cpi, filt_low);
|
||||
vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_low);
|
||||
|
||||
filt_err = vp8_calc_ss_err(sd, cm->frame_to_show);
|
||||
ss_err[filt_low] = filt_err;
|
||||
} else {
|
||||
filt_err = ss_err[filt_low];
|
||||
}
|
||||
|
||||
/* If value is close to the best so far then bias towards a
|
||||
* lower loop filter value.
|
||||
*/
|
||||
if ((filt_err - Bias) < best_err) {
|
||||
/* Was it actually better than the previous best? */
|
||||
if (filt_err < best_err) best_err = filt_err;
|
||||
|
||||
filt_best = filt_low;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now look at filt_high */
|
||||
if ((filt_direction >= 0) && (filt_high != filt_mid)) {
|
||||
if (ss_err[filt_high] == 0) {
|
||||
vpx_yv12_copy_y(saved_frame, cm->frame_to_show);
|
||||
vp8cx_set_alt_lf_level(cpi, filt_high);
|
||||
vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_high);
|
||||
|
||||
filt_err = vp8_calc_ss_err(sd, cm->frame_to_show);
|
||||
ss_err[filt_high] = filt_err;
|
||||
} else {
|
||||
filt_err = ss_err[filt_high];
|
||||
}
|
||||
|
||||
/* Was it better than the previous best? */
|
||||
if (filt_err < (best_err - Bias)) {
|
||||
best_err = filt_err;
|
||||
filt_best = filt_high;
|
||||
}
|
||||
}
|
||||
|
||||
/* Half the step distance if the best filter value was the same
|
||||
* as last time
|
||||
*/
|
||||
if (filt_best == filt_mid) {
|
||||
filter_step = filter_step / 2;
|
||||
filt_direction = 0;
|
||||
} else {
|
||||
filt_direction = (filt_best < filt_mid) ? -1 : 1;
|
||||
filt_mid = filt_best;
|
||||
}
|
||||
}
|
||||
|
||||
cm->filter_level = filt_best;
|
||||
|
||||
/* restore unfiltered frame pointer */
|
||||
cm->frame_to_show = saved_frame;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_PICKLPF_H_
|
||||
#define VPX_VP8_ENCODER_PICKLPF_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct VP8_COMP;
|
||||
struct yv12_buffer_config;
|
||||
|
||||
void vp8cx_pick_filter_level_fast(struct yv12_buffer_config *sd,
|
||||
struct VP8_COMP *cpi);
|
||||
void vp8cx_set_alt_lf_level(struct VP8_COMP *cpi, int filt_val);
|
||||
void vp8cx_pick_filter_level(struct yv12_buffer_config *sd, VP8_COMP *cpi);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_PICKLPF_H_
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_QUANTIZE_H_
|
||||
#define VPX_VP8_ENCODER_QUANTIZE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct VP8_COMP;
|
||||
struct macroblock;
|
||||
extern void vp8_quantize_mb(struct macroblock *x);
|
||||
extern void vp8_quantize_mby(struct macroblock *x);
|
||||
extern void vp8_quantize_mbuv(struct macroblock *x);
|
||||
extern void vp8_set_quantizer(struct VP8_COMP *cpi, int Q);
|
||||
extern void vp8cx_frame_init_quantizer(struct VP8_COMP *cpi);
|
||||
extern void vp8_update_zbin_extra(struct VP8_COMP *cpi, struct macroblock *x);
|
||||
extern void vp8cx_mb_init_quantizer(struct VP8_COMP *cpi, struct macroblock *x,
|
||||
int ok_to_skip);
|
||||
extern void vp8cx_init_quantizer(struct VP8_COMP *cpi);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_QUANTIZE_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_RATECTRL_H_
|
||||
#define VPX_VP8_ENCODER_RATECTRL_H_
|
||||
|
||||
#include "onyx_int.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void vp8_save_coding_context(VP8_COMP *cpi);
|
||||
extern void vp8_restore_coding_context(VP8_COMP *cpi);
|
||||
|
||||
extern void vp8_setup_key_frame(VP8_COMP *cpi);
|
||||
extern void vp8_update_rate_correction_factors(VP8_COMP *cpi, int damp_var);
|
||||
extern int vp8_regulate_q(VP8_COMP *cpi, int target_bits_per_frame);
|
||||
extern void vp8_adjust_key_frame_context(VP8_COMP *cpi);
|
||||
extern void vp8_compute_frame_size_bounds(VP8_COMP *cpi,
|
||||
int *frame_under_shoot_limit,
|
||||
int *frame_over_shoot_limit);
|
||||
|
||||
/* return of 0 means drop frame */
|
||||
extern int vp8_pick_frame_size(VP8_COMP *cpi);
|
||||
|
||||
extern int vp8_drop_encodedframe_overshoot(VP8_COMP *cpi, int Q);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_RATECTRL_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_RDOPT_H_
|
||||
#define VPX_VP8_ENCODER_RDOPT_H_
|
||||
|
||||
#include "./vpx_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RDCOST(RM, DM, R, D) (((128 + (R) * (RM)) >> 8) + (DM) * (D))
|
||||
|
||||
void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex);
|
||||
void vp8_auto_select_speed(VP8_COMP *cpi);
|
||||
|
||||
static INLINE void insertsortmv(int arr[], int len) {
|
||||
int i, j, k;
|
||||
|
||||
for (i = 1; i <= len - 1; ++i) {
|
||||
for (j = 0; j < i; ++j) {
|
||||
if (arr[j] > arr[i]) {
|
||||
int temp;
|
||||
|
||||
temp = arr[i];
|
||||
|
||||
for (k = i; k > j; k--) arr[k] = arr[k - 1];
|
||||
|
||||
arr[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void insertsortsad(int arr[], int idx[], int len) {
|
||||
int i, j, k;
|
||||
|
||||
for (i = 1; i <= len - 1; ++i) {
|
||||
for (j = 0; j < i; ++j) {
|
||||
if (arr[j] > arr[i]) {
|
||||
int temp, tempi;
|
||||
|
||||
temp = arr[i];
|
||||
tempi = idx[i];
|
||||
|
||||
for (k = i; k > j; k--) {
|
||||
arr[k] = arr[k - 1];
|
||||
idx[k] = idx[k - 1];
|
||||
}
|
||||
|
||||
arr[j] = temp;
|
||||
idx[j] = tempi;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_initialize_rd_consts(VP8_COMP *cpi, MACROBLOCK *x, int Qvalue);
|
||||
void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
|
||||
int recon_uvoffset, int *returnrate,
|
||||
int *returndistortion, int *returnintra, int mb_row,
|
||||
int mb_col);
|
||||
void vp8_rd_pick_intra_mode(MACROBLOCK *x, int *rate);
|
||||
|
||||
static INLINE void get_plane_pointers(const YV12_BUFFER_CONFIG *fb,
|
||||
unsigned char *plane[3],
|
||||
unsigned int recon_yoffset,
|
||||
unsigned int recon_uvoffset) {
|
||||
plane[0] = fb->y_buffer + recon_yoffset;
|
||||
plane[1] = fb->u_buffer + recon_uvoffset;
|
||||
plane[2] = fb->v_buffer + recon_uvoffset;
|
||||
}
|
||||
|
||||
static INLINE void get_predictor_pointers(const VP8_COMP *cpi,
|
||||
unsigned char *plane[4][3],
|
||||
unsigned int recon_yoffset,
|
||||
unsigned int recon_uvoffset) {
|
||||
if (cpi->ref_frame_flags & VP8_LAST_FRAME) {
|
||||
get_plane_pointers(&cpi->common.yv12_fb[cpi->common.lst_fb_idx],
|
||||
plane[LAST_FRAME], recon_yoffset, recon_uvoffset);
|
||||
}
|
||||
|
||||
if (cpi->ref_frame_flags & VP8_GOLD_FRAME) {
|
||||
get_plane_pointers(&cpi->common.yv12_fb[cpi->common.gld_fb_idx],
|
||||
plane[GOLDEN_FRAME], recon_yoffset, recon_uvoffset);
|
||||
}
|
||||
|
||||
if (cpi->ref_frame_flags & VP8_ALTR_FRAME) {
|
||||
get_plane_pointers(&cpi->common.yv12_fb[cpi->common.alt_fb_idx],
|
||||
plane[ALTREF_FRAME], recon_yoffset, recon_uvoffset);
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void get_reference_search_order(const VP8_COMP *cpi,
|
||||
int ref_frame_map[4]) {
|
||||
int i = 0;
|
||||
|
||||
ref_frame_map[i++] = INTRA_FRAME;
|
||||
if (cpi->ref_frame_flags & VP8_LAST_FRAME) ref_frame_map[i++] = LAST_FRAME;
|
||||
if (cpi->ref_frame_flags & VP8_GOLD_FRAME) ref_frame_map[i++] = GOLDEN_FRAME;
|
||||
if (cpi->ref_frame_flags & VP8_ALTR_FRAME) ref_frame_map[i++] = ALTREF_FRAME;
|
||||
for (; i < 4; ++i) ref_frame_map[i] = -1;
|
||||
}
|
||||
|
||||
void vp8_mv_pred(VP8_COMP *cpi, MACROBLOCKD *xd, const MODE_INFO *here,
|
||||
int_mv *mvp, int refframe, int *ref_frame_sign_bias, int *sr,
|
||||
int near_sadidx[]);
|
||||
void vp8_cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x,
|
||||
int recon_yoffset, int near_sadidx[]);
|
||||
int VP8_UVSSE(MACROBLOCK *x);
|
||||
int vp8_cost_mv_ref(MB_PREDICTION_MODE m, const int near_mv_ref_ct[4]);
|
||||
void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_RDOPT_H_
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include "segmentation.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
void vp8_update_gf_useage_maps(VP8_COMP *cpi, VP8_COMMON *cm, MACROBLOCK *x) {
|
||||
int mb_row, mb_col;
|
||||
|
||||
MODE_INFO *this_mb_mode_info = cm->mi;
|
||||
|
||||
x->gf_active_ptr = (signed char *)cpi->gf_active_flags;
|
||||
|
||||
if ((cm->frame_type == KEY_FRAME) || (cm->refresh_golden_frame)) {
|
||||
/* Reset Gf useage monitors */
|
||||
memset(cpi->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols));
|
||||
cpi->gf_active_count = cm->mb_rows * cm->mb_cols;
|
||||
} else {
|
||||
/* for each macroblock row in image */
|
||||
for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
|
||||
/* for each macroblock col in image */
|
||||
for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
|
||||
/* If using golden then set GF active flag if not already set.
|
||||
* If using last frame 0,0 mode then leave flag as it is
|
||||
* else if using non 0,0 motion or intra modes then clear
|
||||
* flag if it is currently set
|
||||
*/
|
||||
if ((this_mb_mode_info->mbmi.ref_frame == GOLDEN_FRAME) ||
|
||||
(this_mb_mode_info->mbmi.ref_frame == ALTREF_FRAME)) {
|
||||
if (*(x->gf_active_ptr) == 0) {
|
||||
*(x->gf_active_ptr) = 1;
|
||||
cpi->gf_active_count++;
|
||||
}
|
||||
} else if ((this_mb_mode_info->mbmi.mode != ZEROMV) &&
|
||||
*(x->gf_active_ptr)) {
|
||||
*(x->gf_active_ptr) = 0;
|
||||
cpi->gf_active_count--;
|
||||
}
|
||||
|
||||
x->gf_active_ptr++; /* Step onto next entry */
|
||||
this_mb_mode_info++; /* skip to next mb */
|
||||
}
|
||||
|
||||
/* this is to account for the border */
|
||||
this_mb_mode_info++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_SEGMENTATION_H_
|
||||
#define VPX_VP8_ENCODER_SEGMENTATION_H_
|
||||
|
||||
#include "string.h"
|
||||
#include "vp8/common/blockd.h"
|
||||
#include "onyx_int.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void vp8_update_gf_useage_maps(VP8_COMP *cpi, VP8_COMMON *cm,
|
||||
MACROBLOCK *x);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_SEGMENTATION_H_
|
||||
@@ -0,0 +1,434 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include "vp8/common/onyxc_int.h"
|
||||
#include "onyx_int.h"
|
||||
#include "vp8/common/systemdependent.h"
|
||||
#include "vp8/encoder/quantize.h"
|
||||
#include "vp8/common/alloccommon.h"
|
||||
#include "mcomp.h"
|
||||
#include "firstpass.h"
|
||||
#include "vpx_scale/vpx_scale.h"
|
||||
#include "vp8/common/extend.h"
|
||||
#include "ratectrl.h"
|
||||
#include "vp8/common/quant_common.h"
|
||||
#include "segmentation.h"
|
||||
#include "temporal_filter.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vp8/common/swapyv12buffer.h"
|
||||
#include "vp8/common/threading.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define ALT_REF_MC_ENABLED 1 /* toggle MC in AltRef filtering */
|
||||
#define ALT_REF_SUBPEL_ENABLED 1 /* toggle subpel in MC AltRef filtering */
|
||||
|
||||
#if VP8_TEMPORAL_ALT_REF
|
||||
|
||||
static void vp8_temporal_filter_predictors_mb_c(
|
||||
MACROBLOCKD *x, unsigned char *y_mb_ptr, unsigned char *u_mb_ptr,
|
||||
unsigned char *v_mb_ptr, int stride, int mv_row, int mv_col,
|
||||
unsigned char *pred) {
|
||||
int offset;
|
||||
unsigned char *yptr, *uptr, *vptr;
|
||||
|
||||
/* Y */
|
||||
yptr = y_mb_ptr + (mv_row >> 3) * stride + (mv_col >> 3);
|
||||
|
||||
if ((mv_row | mv_col) & 7) {
|
||||
x->subpixel_predict16x16(yptr, stride, mv_col & 7, mv_row & 7, &pred[0],
|
||||
16);
|
||||
} else {
|
||||
vp8_copy_mem16x16(yptr, stride, &pred[0], 16);
|
||||
}
|
||||
|
||||
/* U & V */
|
||||
mv_row >>= 1;
|
||||
mv_col >>= 1;
|
||||
stride = (stride + 1) >> 1;
|
||||
offset = (mv_row >> 3) * stride + (mv_col >> 3);
|
||||
uptr = u_mb_ptr + offset;
|
||||
vptr = v_mb_ptr + offset;
|
||||
|
||||
if ((mv_row | mv_col) & 7) {
|
||||
x->subpixel_predict8x8(uptr, stride, mv_col & 7, mv_row & 7, &pred[256], 8);
|
||||
x->subpixel_predict8x8(vptr, stride, mv_col & 7, mv_row & 7, &pred[320], 8);
|
||||
} else {
|
||||
vp8_copy_mem8x8(uptr, stride, &pred[256], 8);
|
||||
vp8_copy_mem8x8(vptr, stride, &pred[320], 8);
|
||||
}
|
||||
}
|
||||
void vp8_temporal_filter_apply_c(unsigned char *frame1, unsigned int stride,
|
||||
unsigned char *frame2, unsigned int block_size,
|
||||
int strength, int filter_weight,
|
||||
unsigned int *accumulator,
|
||||
unsigned short *count) {
|
||||
unsigned int i, j, k;
|
||||
int modifier;
|
||||
int byte = 0;
|
||||
const int rounding = strength > 0 ? 1 << (strength - 1) : 0;
|
||||
|
||||
for (i = 0, k = 0; i < block_size; ++i) {
|
||||
for (j = 0; j < block_size; j++, k++) {
|
||||
int src_byte = frame1[byte];
|
||||
int pixel_value = *frame2++;
|
||||
|
||||
modifier = src_byte - pixel_value;
|
||||
/* This is an integer approximation of:
|
||||
* float coeff = (3.0 * modifer * modifier) / pow(2, strength);
|
||||
* modifier = (int)roundf(coeff > 16 ? 0 : 16-coeff);
|
||||
*/
|
||||
modifier *= modifier;
|
||||
modifier *= 3;
|
||||
modifier += rounding;
|
||||
modifier >>= strength;
|
||||
|
||||
if (modifier > 16) modifier = 16;
|
||||
|
||||
modifier = 16 - modifier;
|
||||
modifier *= filter_weight;
|
||||
|
||||
count[k] += modifier;
|
||||
accumulator[k] += modifier * pixel_value;
|
||||
|
||||
byte++;
|
||||
}
|
||||
|
||||
byte += stride - block_size;
|
||||
}
|
||||
}
|
||||
|
||||
#if ALT_REF_MC_ENABLED
|
||||
|
||||
static int vp8_temporal_filter_find_matching_mb_c(VP8_COMP *cpi,
|
||||
YV12_BUFFER_CONFIG *arf_frame,
|
||||
YV12_BUFFER_CONFIG *frame_ptr,
|
||||
int mb_offset,
|
||||
int error_thresh) {
|
||||
MACROBLOCK *x = &cpi->mb;
|
||||
int step_param;
|
||||
int sadpb = x->sadperbit16;
|
||||
int bestsme = INT_MAX;
|
||||
|
||||
BLOCK *b = &x->block[0];
|
||||
BLOCKD *d = &x->e_mbd.block[0];
|
||||
int_mv best_ref_mv1;
|
||||
int_mv best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */
|
||||
|
||||
/* Save input state */
|
||||
unsigned char **base_src = b->base_src;
|
||||
int src = b->src;
|
||||
int src_stride = b->src_stride;
|
||||
unsigned char *base_pre = x->e_mbd.pre.y_buffer;
|
||||
int pre = d->offset;
|
||||
int pre_stride = x->e_mbd.pre.y_stride;
|
||||
|
||||
(void)error_thresh;
|
||||
|
||||
best_ref_mv1.as_int = 0;
|
||||
best_ref_mv1_full.as_mv.col = best_ref_mv1.as_mv.col >> 3;
|
||||
best_ref_mv1_full.as_mv.row = best_ref_mv1.as_mv.row >> 3;
|
||||
|
||||
/* Setup frame pointers */
|
||||
b->base_src = &arf_frame->y_buffer;
|
||||
b->src_stride = arf_frame->y_stride;
|
||||
b->src = mb_offset;
|
||||
|
||||
x->e_mbd.pre.y_buffer = frame_ptr->y_buffer;
|
||||
x->e_mbd.pre.y_stride = frame_ptr->y_stride;
|
||||
d->offset = mb_offset;
|
||||
|
||||
/* Further step/diamond searches as necessary */
|
||||
if (cpi->Speed < 8) {
|
||||
step_param = cpi->sf.first_step + (cpi->Speed > 5);
|
||||
} else {
|
||||
step_param = cpi->sf.first_step + 2;
|
||||
}
|
||||
|
||||
/* TODO Check that the 16x16 vf & sdf are selected here */
|
||||
/* Ignore mv costing by sending NULL cost arrays */
|
||||
bestsme =
|
||||
vp8_hex_search(x, b, d, &best_ref_mv1_full, &d->bmi.mv, step_param, sadpb,
|
||||
&cpi->fn_ptr[BLOCK_16X16], NULL, &best_ref_mv1);
|
||||
(void)bestsme; // Ignore unused return value.
|
||||
|
||||
#if ALT_REF_SUBPEL_ENABLED
|
||||
/* Try sub-pixel MC? */
|
||||
{
|
||||
int distortion;
|
||||
unsigned int sse;
|
||||
/* Ignore mv costing by sending NULL cost array */
|
||||
bestsme = cpi->find_fractional_mv_step(
|
||||
x, b, d, &d->bmi.mv, &best_ref_mv1, x->errorperbit,
|
||||
&cpi->fn_ptr[BLOCK_16X16], NULL, &distortion, &sse);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Save input state */
|
||||
b->base_src = base_src;
|
||||
b->src = src;
|
||||
b->src_stride = src_stride;
|
||||
x->e_mbd.pre.y_buffer = base_pre;
|
||||
d->offset = pre;
|
||||
x->e_mbd.pre.y_stride = pre_stride;
|
||||
|
||||
return bestsme;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void vp8_temporal_filter_iterate_c(VP8_COMP *cpi, int frame_count,
|
||||
int alt_ref_index, int strength) {
|
||||
int byte;
|
||||
int frame;
|
||||
int mb_col, mb_row;
|
||||
unsigned int filter_weight;
|
||||
int mb_cols = cpi->common.mb_cols;
|
||||
int mb_rows = cpi->common.mb_rows;
|
||||
int mb_y_offset = 0;
|
||||
int mb_uv_offset = 0;
|
||||
DECLARE_ALIGNED(16, unsigned int, accumulator[16 * 16 + 8 * 8 + 8 * 8]);
|
||||
DECLARE_ALIGNED(16, unsigned short, count[16 * 16 + 8 * 8 + 8 * 8]);
|
||||
MACROBLOCKD *mbd = &cpi->mb.e_mbd;
|
||||
YV12_BUFFER_CONFIG *f = cpi->frames[alt_ref_index];
|
||||
unsigned char *dst1, *dst2;
|
||||
DECLARE_ALIGNED(16, unsigned char, predictor[16 * 16 + 8 * 8 + 8 * 8]);
|
||||
|
||||
/* Save input state */
|
||||
unsigned char *y_buffer = mbd->pre.y_buffer;
|
||||
unsigned char *u_buffer = mbd->pre.u_buffer;
|
||||
unsigned char *v_buffer = mbd->pre.v_buffer;
|
||||
|
||||
for (mb_row = 0; mb_row < mb_rows; ++mb_row) {
|
||||
#if ALT_REF_MC_ENABLED
|
||||
/* Source frames are extended to 16 pixels. This is different than
|
||||
* L/A/G reference frames that have a border of 32 (VP8BORDERINPIXELS)
|
||||
* A 6 tap filter is used for motion search. This requires 2 pixels
|
||||
* before and 3 pixels after. So the largest Y mv on a border would
|
||||
* then be 16 - 3. The UV blocks are half the size of the Y and
|
||||
* therefore only extended by 8. The largest mv that a UV block
|
||||
* can support is 8 - 3. A UV mv is half of a Y mv.
|
||||
* (16 - 3) >> 1 == 6 which is greater than 8 - 3.
|
||||
* To keep the mv in play for both Y and UV planes the max that it
|
||||
* can be on a border is therefore 16 - 5.
|
||||
*/
|
||||
cpi->mb.mv_row_min = -((mb_row * 16) + (16 - 5));
|
||||
cpi->mb.mv_row_max = ((cpi->common.mb_rows - 1 - mb_row) * 16) + (16 - 5);
|
||||
#endif
|
||||
|
||||
for (mb_col = 0; mb_col < mb_cols; ++mb_col) {
|
||||
int i, j, k;
|
||||
int stride;
|
||||
|
||||
memset(accumulator, 0, 384 * sizeof(unsigned int));
|
||||
memset(count, 0, 384 * sizeof(unsigned short));
|
||||
|
||||
#if ALT_REF_MC_ENABLED
|
||||
cpi->mb.mv_col_min = -((mb_col * 16) + (16 - 5));
|
||||
cpi->mb.mv_col_max = ((cpi->common.mb_cols - 1 - mb_col) * 16) + (16 - 5);
|
||||
#endif
|
||||
|
||||
for (frame = 0; frame < frame_count; ++frame) {
|
||||
if (cpi->frames[frame] == NULL) continue;
|
||||
|
||||
mbd->block[0].bmi.mv.as_mv.row = 0;
|
||||
mbd->block[0].bmi.mv.as_mv.col = 0;
|
||||
|
||||
if (frame == alt_ref_index) {
|
||||
filter_weight = 2;
|
||||
} else {
|
||||
int err = 0;
|
||||
#if ALT_REF_MC_ENABLED
|
||||
#define THRESH_LOW 10000
|
||||
#define THRESH_HIGH 20000
|
||||
/* Find best match in this frame by MC */
|
||||
err = vp8_temporal_filter_find_matching_mb_c(
|
||||
cpi, cpi->frames[alt_ref_index], cpi->frames[frame], mb_y_offset,
|
||||
THRESH_LOW);
|
||||
#endif
|
||||
/* Assign higher weight to matching MB if it's error
|
||||
* score is lower. If not applying MC default behavior
|
||||
* is to weight all MBs equal.
|
||||
*/
|
||||
filter_weight = err < THRESH_LOW ? 2 : err < THRESH_HIGH ? 1 : 0;
|
||||
}
|
||||
|
||||
if (filter_weight != 0) {
|
||||
/* Construct the predictors */
|
||||
vp8_temporal_filter_predictors_mb_c(
|
||||
mbd, cpi->frames[frame]->y_buffer + mb_y_offset,
|
||||
cpi->frames[frame]->u_buffer + mb_uv_offset,
|
||||
cpi->frames[frame]->v_buffer + mb_uv_offset,
|
||||
cpi->frames[frame]->y_stride, mbd->block[0].bmi.mv.as_mv.row,
|
||||
mbd->block[0].bmi.mv.as_mv.col, predictor);
|
||||
|
||||
/* Apply the filter (YUV) */
|
||||
vp8_temporal_filter_apply(f->y_buffer + mb_y_offset, f->y_stride,
|
||||
predictor, 16, strength, filter_weight,
|
||||
accumulator, count);
|
||||
|
||||
vp8_temporal_filter_apply(f->u_buffer + mb_uv_offset, f->uv_stride,
|
||||
predictor + 256, 8, strength, filter_weight,
|
||||
accumulator + 256, count + 256);
|
||||
|
||||
vp8_temporal_filter_apply(f->v_buffer + mb_uv_offset, f->uv_stride,
|
||||
predictor + 320, 8, strength, filter_weight,
|
||||
accumulator + 320, count + 320);
|
||||
}
|
||||
}
|
||||
|
||||
/* Normalize filter output to produce AltRef frame */
|
||||
dst1 = cpi->alt_ref_buffer.y_buffer;
|
||||
stride = cpi->alt_ref_buffer.y_stride;
|
||||
byte = mb_y_offset;
|
||||
for (i = 0, k = 0; i < 16; ++i) {
|
||||
for (j = 0; j < 16; j++, k++) {
|
||||
unsigned int pval = accumulator[k] + (count[k] >> 1);
|
||||
pval *= cpi->fixed_divide[count[k]];
|
||||
pval >>= 19;
|
||||
|
||||
dst1[byte] = (unsigned char)pval;
|
||||
|
||||
/* move to next pixel */
|
||||
byte++;
|
||||
}
|
||||
|
||||
byte += stride - 16;
|
||||
}
|
||||
|
||||
dst1 = cpi->alt_ref_buffer.u_buffer;
|
||||
dst2 = cpi->alt_ref_buffer.v_buffer;
|
||||
stride = cpi->alt_ref_buffer.uv_stride;
|
||||
byte = mb_uv_offset;
|
||||
for (i = 0, k = 256; i < 8; ++i) {
|
||||
for (j = 0; j < 8; j++, k++) {
|
||||
int m = k + 64;
|
||||
|
||||
/* U */
|
||||
unsigned int pval = accumulator[k] + (count[k] >> 1);
|
||||
pval *= cpi->fixed_divide[count[k]];
|
||||
pval >>= 19;
|
||||
dst1[byte] = (unsigned char)pval;
|
||||
|
||||
/* V */
|
||||
pval = accumulator[m] + (count[m] >> 1);
|
||||
pval *= cpi->fixed_divide[count[m]];
|
||||
pval >>= 19;
|
||||
dst2[byte] = (unsigned char)pval;
|
||||
|
||||
/* move to next pixel */
|
||||
byte++;
|
||||
}
|
||||
|
||||
byte += stride - 8;
|
||||
}
|
||||
|
||||
mb_y_offset += 16;
|
||||
mb_uv_offset += 8;
|
||||
}
|
||||
|
||||
mb_y_offset += 16 * (f->y_stride - mb_cols);
|
||||
mb_uv_offset += 8 * (f->uv_stride - mb_cols);
|
||||
}
|
||||
|
||||
/* Restore input state */
|
||||
mbd->pre.y_buffer = y_buffer;
|
||||
mbd->pre.u_buffer = u_buffer;
|
||||
mbd->pre.v_buffer = v_buffer;
|
||||
}
|
||||
|
||||
void vp8_temporal_filter_prepare_c(VP8_COMP *cpi, int distance) {
|
||||
int frame = 0;
|
||||
|
||||
int num_frames_backward = 0;
|
||||
int num_frames_forward = 0;
|
||||
int frames_to_blur_backward = 0;
|
||||
int frames_to_blur_forward = 0;
|
||||
int frames_to_blur = 0;
|
||||
int start_frame = 0;
|
||||
|
||||
int strength = cpi->oxcf.arnr_strength;
|
||||
|
||||
int blur_type = cpi->oxcf.arnr_type;
|
||||
|
||||
int max_frames = cpi->active_arnr_frames;
|
||||
|
||||
num_frames_backward = distance;
|
||||
num_frames_forward =
|
||||
vp8_lookahead_depth(cpi->lookahead) - (num_frames_backward + 1);
|
||||
|
||||
switch (blur_type) {
|
||||
case 1:
|
||||
/* Backward Blur */
|
||||
|
||||
frames_to_blur_backward = num_frames_backward;
|
||||
|
||||
if (frames_to_blur_backward >= max_frames) {
|
||||
frames_to_blur_backward = max_frames - 1;
|
||||
}
|
||||
|
||||
frames_to_blur = frames_to_blur_backward + 1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Forward Blur */
|
||||
|
||||
frames_to_blur_forward = num_frames_forward;
|
||||
|
||||
if (frames_to_blur_forward >= max_frames) {
|
||||
frames_to_blur_forward = max_frames - 1;
|
||||
}
|
||||
|
||||
frames_to_blur = frames_to_blur_forward + 1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
default:
|
||||
/* Center Blur */
|
||||
frames_to_blur_forward = num_frames_forward;
|
||||
frames_to_blur_backward = num_frames_backward;
|
||||
|
||||
if (frames_to_blur_forward > frames_to_blur_backward) {
|
||||
frames_to_blur_forward = frames_to_blur_backward;
|
||||
}
|
||||
|
||||
if (frames_to_blur_backward > frames_to_blur_forward) {
|
||||
frames_to_blur_backward = frames_to_blur_forward;
|
||||
}
|
||||
|
||||
/* When max_frames is even we have 1 more frame backward than forward */
|
||||
if (frames_to_blur_forward > (max_frames - 1) / 2) {
|
||||
frames_to_blur_forward = ((max_frames - 1) / 2);
|
||||
}
|
||||
|
||||
if (frames_to_blur_backward > (max_frames / 2)) {
|
||||
frames_to_blur_backward = (max_frames / 2);
|
||||
}
|
||||
|
||||
frames_to_blur = frames_to_blur_backward + frames_to_blur_forward + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
start_frame = distance + frames_to_blur_forward;
|
||||
|
||||
/* Setup frame pointers, NULL indicates frame not included in filter */
|
||||
memset(cpi->frames, 0, max_frames * sizeof(YV12_BUFFER_CONFIG *));
|
||||
for (frame = 0; frame < frames_to_blur; ++frame) {
|
||||
int which_buffer = start_frame - frame;
|
||||
struct lookahead_entry *buf =
|
||||
vp8_lookahead_peek(cpi->lookahead, which_buffer, PEEK_FORWARD);
|
||||
cpi->frames[frames_to_blur - 1 - frame] = &buf->img;
|
||||
}
|
||||
|
||||
vp8_temporal_filter_iterate_c(cpi, frames_to_blur, frames_to_blur_backward,
|
||||
strength);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_TEMPORAL_FILTER_H_
|
||||
#define VPX_VP8_ENCODER_TEMPORAL_FILTER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct VP8_COMP;
|
||||
|
||||
void vp8_temporal_filter_prepare_c(struct VP8_COMP *cpi, int distance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_TEMPORAL_FILTER_H_
|
||||
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "onyx_int.h"
|
||||
#include "tokenize.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
/* Global event counters used for accumulating statistics across several
|
||||
compressions, then generating context.c = initial stats. */
|
||||
|
||||
void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t);
|
||||
void vp8_fix_contexts(MACROBLOCKD *x);
|
||||
|
||||
#include "dct_value_tokens.h"
|
||||
#include "dct_value_cost.h"
|
||||
|
||||
const TOKENVALUE *const vp8_dct_value_tokens_ptr =
|
||||
dct_value_tokens + DCT_MAX_VALUE;
|
||||
const short *const vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
|
||||
|
||||
#if 0
|
||||
int skip_true_count = 0;
|
||||
int skip_false_count = 0;
|
||||
#endif
|
||||
|
||||
/* function used to generate dct_value_tokens and dct_value_cost tables */
|
||||
/*
|
||||
static void fill_value_tokens()
|
||||
{
|
||||
|
||||
TOKENVALUE *t = dct_value_tokens + DCT_MAX_VALUE;
|
||||
const vp8_extra_bit_struct *e = vp8_extra_bits;
|
||||
|
||||
int i = -DCT_MAX_VALUE;
|
||||
int sign = 1;
|
||||
|
||||
do
|
||||
{
|
||||
if (!i)
|
||||
sign = 0;
|
||||
|
||||
{
|
||||
const int a = sign ? -i : i;
|
||||
int eb = sign;
|
||||
|
||||
if (a > 4)
|
||||
{
|
||||
int j = 4;
|
||||
|
||||
while (++j < 11 && e[j].base_val <= a) {}
|
||||
|
||||
t[i].Token = --j;
|
||||
eb |= (a - e[j].base_val) << 1;
|
||||
}
|
||||
else
|
||||
t[i].Token = a;
|
||||
|
||||
t[i].Extra = eb;
|
||||
}
|
||||
|
||||
// initialize the cost for extra bits for all possible coefficient
|
||||
value.
|
||||
{
|
||||
int cost = 0;
|
||||
const vp8_extra_bit_struct *p = vp8_extra_bits + t[i].Token;
|
||||
|
||||
if (p->base_val)
|
||||
{
|
||||
const int extra = t[i].Extra;
|
||||
const int Length = p->Len;
|
||||
|
||||
if (Length)
|
||||
cost += vp8_treed_cost(p->tree, p->prob, extra >> 1,
|
||||
Length);
|
||||
|
||||
cost += vp8_cost_bit(vp8_prob_half, extra & 1); // sign
|
||||
dct_value_cost[i + DCT_MAX_VALUE] = cost;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
while (++i < DCT_MAX_VALUE);
|
||||
|
||||
vp8_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE;
|
||||
vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
|
||||
}
|
||||
*/
|
||||
|
||||
static void tokenize2nd_order_b(MACROBLOCK *x, TOKENEXTRA **tp, VP8_COMP *cpi) {
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
int pt; /* near block/prev token context index */
|
||||
int c; /* start at DC */
|
||||
TOKENEXTRA *t = *tp; /* store tokens starting here */
|
||||
const BLOCKD *b;
|
||||
const short *qcoeff_ptr;
|
||||
ENTROPY_CONTEXT *a;
|
||||
ENTROPY_CONTEXT *l;
|
||||
int band, rc, v, token;
|
||||
int eob;
|
||||
|
||||
b = xd->block + 24;
|
||||
qcoeff_ptr = b->qcoeff;
|
||||
a = (ENTROPY_CONTEXT *)xd->above_context + 8;
|
||||
l = (ENTROPY_CONTEXT *)xd->left_context + 8;
|
||||
eob = xd->eobs[24];
|
||||
VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
|
||||
|
||||
if (!eob) {
|
||||
/* c = band for this case */
|
||||
t->Token = DCT_EOB_TOKEN;
|
||||
t->context_tree = cpi->common.fc.coef_probs[1][0][pt];
|
||||
t->skip_eob_node = 0;
|
||||
|
||||
++x->coef_counts[1][0][pt][DCT_EOB_TOKEN];
|
||||
t++;
|
||||
*tp = t;
|
||||
*a = *l = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
v = qcoeff_ptr[0];
|
||||
t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
|
||||
token = vp8_dct_value_tokens_ptr[v].Token;
|
||||
t->Token = token;
|
||||
|
||||
t->context_tree = cpi->common.fc.coef_probs[1][0][pt];
|
||||
t->skip_eob_node = 0;
|
||||
++x->coef_counts[1][0][pt][token];
|
||||
pt = vp8_prev_token_class[token];
|
||||
t++;
|
||||
c = 1;
|
||||
|
||||
for (; c < eob; ++c) {
|
||||
rc = vp8_default_zig_zag1d[c];
|
||||
band = vp8_coef_bands[c];
|
||||
v = qcoeff_ptr[rc];
|
||||
|
||||
t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
|
||||
token = vp8_dct_value_tokens_ptr[v].Token;
|
||||
|
||||
t->Token = token;
|
||||
t->context_tree = cpi->common.fc.coef_probs[1][band][pt];
|
||||
|
||||
t->skip_eob_node = ((pt == 0));
|
||||
|
||||
++x->coef_counts[1][band][pt][token];
|
||||
|
||||
pt = vp8_prev_token_class[token];
|
||||
t++;
|
||||
}
|
||||
if (c < 16) {
|
||||
band = vp8_coef_bands[c];
|
||||
t->Token = DCT_EOB_TOKEN;
|
||||
t->context_tree = cpi->common.fc.coef_probs[1][band][pt];
|
||||
|
||||
t->skip_eob_node = 0;
|
||||
|
||||
++x->coef_counts[1][band][pt][DCT_EOB_TOKEN];
|
||||
|
||||
t++;
|
||||
}
|
||||
|
||||
*tp = t;
|
||||
*a = *l = 1;
|
||||
}
|
||||
|
||||
static void tokenize1st_order_b(
|
||||
MACROBLOCK *x, TOKENEXTRA **tp,
|
||||
int type, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
|
||||
VP8_COMP *cpi) {
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
unsigned int block;
|
||||
const BLOCKD *b;
|
||||
int pt; /* near block/prev token context index */
|
||||
int c;
|
||||
int token;
|
||||
TOKENEXTRA *t = *tp; /* store tokens starting here */
|
||||
const short *qcoeff_ptr;
|
||||
ENTROPY_CONTEXT *a;
|
||||
ENTROPY_CONTEXT *l;
|
||||
int band, rc, v;
|
||||
int tmp1, tmp2;
|
||||
|
||||
b = xd->block;
|
||||
/* Luma */
|
||||
for (block = 0; block < 16; block++, b++) {
|
||||
const int eob = *b->eob;
|
||||
tmp1 = vp8_block2above[block];
|
||||
tmp2 = vp8_block2left[block];
|
||||
qcoeff_ptr = b->qcoeff;
|
||||
a = (ENTROPY_CONTEXT *)xd->above_context + tmp1;
|
||||
l = (ENTROPY_CONTEXT *)xd->left_context + tmp2;
|
||||
|
||||
VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
|
||||
|
||||
c = type ? 0 : 1;
|
||||
|
||||
if (c >= eob) {
|
||||
/* c = band for this case */
|
||||
t->Token = DCT_EOB_TOKEN;
|
||||
t->context_tree = cpi->common.fc.coef_probs[type][c][pt];
|
||||
t->skip_eob_node = 0;
|
||||
|
||||
++x->coef_counts[type][c][pt][DCT_EOB_TOKEN];
|
||||
t++;
|
||||
*tp = t;
|
||||
*a = *l = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
v = qcoeff_ptr[c];
|
||||
|
||||
t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
|
||||
token = vp8_dct_value_tokens_ptr[v].Token;
|
||||
t->Token = token;
|
||||
|
||||
t->context_tree = cpi->common.fc.coef_probs[type][c][pt];
|
||||
t->skip_eob_node = 0;
|
||||
++x->coef_counts[type][c][pt][token];
|
||||
pt = vp8_prev_token_class[token];
|
||||
t++;
|
||||
c++;
|
||||
|
||||
assert(eob <= 16);
|
||||
for (; c < eob; ++c) {
|
||||
rc = vp8_default_zig_zag1d[c];
|
||||
band = vp8_coef_bands[c];
|
||||
v = qcoeff_ptr[rc];
|
||||
|
||||
t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
|
||||
token = vp8_dct_value_tokens_ptr[v].Token;
|
||||
|
||||
t->Token = token;
|
||||
t->context_tree = cpi->common.fc.coef_probs[type][band][pt];
|
||||
|
||||
t->skip_eob_node = (pt == 0);
|
||||
++x->coef_counts[type][band][pt][token];
|
||||
|
||||
pt = vp8_prev_token_class[token];
|
||||
t++;
|
||||
}
|
||||
if (c < 16) {
|
||||
band = vp8_coef_bands[c];
|
||||
t->Token = DCT_EOB_TOKEN;
|
||||
t->context_tree = cpi->common.fc.coef_probs[type][band][pt];
|
||||
|
||||
t->skip_eob_node = 0;
|
||||
++x->coef_counts[type][band][pt][DCT_EOB_TOKEN];
|
||||
|
||||
t++;
|
||||
}
|
||||
*tp = t;
|
||||
*a = *l = 1;
|
||||
}
|
||||
|
||||
/* Chroma */
|
||||
for (block = 16; block < 24; block++, b++) {
|
||||
const int eob = *b->eob;
|
||||
tmp1 = vp8_block2above[block];
|
||||
tmp2 = vp8_block2left[block];
|
||||
qcoeff_ptr = b->qcoeff;
|
||||
a = (ENTROPY_CONTEXT *)xd->above_context + tmp1;
|
||||
l = (ENTROPY_CONTEXT *)xd->left_context + tmp2;
|
||||
|
||||
VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
|
||||
|
||||
if (!eob) {
|
||||
/* c = band for this case */
|
||||
t->Token = DCT_EOB_TOKEN;
|
||||
t->context_tree = cpi->common.fc.coef_probs[2][0][pt];
|
||||
t->skip_eob_node = 0;
|
||||
|
||||
++x->coef_counts[2][0][pt][DCT_EOB_TOKEN];
|
||||
t++;
|
||||
*tp = t;
|
||||
*a = *l = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
v = qcoeff_ptr[0];
|
||||
|
||||
t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
|
||||
token = vp8_dct_value_tokens_ptr[v].Token;
|
||||
t->Token = token;
|
||||
|
||||
t->context_tree = cpi->common.fc.coef_probs[2][0][pt];
|
||||
t->skip_eob_node = 0;
|
||||
++x->coef_counts[2][0][pt][token];
|
||||
pt = vp8_prev_token_class[token];
|
||||
t++;
|
||||
c = 1;
|
||||
|
||||
assert(eob <= 16);
|
||||
for (; c < eob; ++c) {
|
||||
rc = vp8_default_zig_zag1d[c];
|
||||
band = vp8_coef_bands[c];
|
||||
v = qcoeff_ptr[rc];
|
||||
|
||||
t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
|
||||
token = vp8_dct_value_tokens_ptr[v].Token;
|
||||
|
||||
t->Token = token;
|
||||
t->context_tree = cpi->common.fc.coef_probs[2][band][pt];
|
||||
|
||||
t->skip_eob_node = (pt == 0);
|
||||
|
||||
++x->coef_counts[2][band][pt][token];
|
||||
|
||||
pt = vp8_prev_token_class[token];
|
||||
t++;
|
||||
}
|
||||
if (c < 16) {
|
||||
band = vp8_coef_bands[c];
|
||||
t->Token = DCT_EOB_TOKEN;
|
||||
t->context_tree = cpi->common.fc.coef_probs[2][band][pt];
|
||||
|
||||
t->skip_eob_node = 0;
|
||||
|
||||
++x->coef_counts[2][band][pt][DCT_EOB_TOKEN];
|
||||
|
||||
t++;
|
||||
}
|
||||
*tp = t;
|
||||
*a = *l = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int mb_is_skippable(MACROBLOCKD *x, int has_y2_block) {
|
||||
int skip = 1;
|
||||
int i = 0;
|
||||
|
||||
if (has_y2_block) {
|
||||
for (i = 0; i < 16; ++i) skip &= (x->eobs[i] < 2);
|
||||
}
|
||||
|
||||
for (; i < 24 + has_y2_block; ++i) skip &= (!x->eobs[i]);
|
||||
|
||||
return skip;
|
||||
}
|
||||
|
||||
void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) {
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
int plane_type;
|
||||
int has_y2_block;
|
||||
|
||||
has_y2_block = (xd->mode_info_context->mbmi.mode != B_PRED &&
|
||||
xd->mode_info_context->mbmi.mode != SPLITMV);
|
||||
|
||||
xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable(xd, has_y2_block);
|
||||
if (xd->mode_info_context->mbmi.mb_skip_coeff) {
|
||||
if (!cpi->common.mb_no_coeff_skip) {
|
||||
vp8_stuff_mb(cpi, x, t);
|
||||
} else {
|
||||
vp8_fix_contexts(xd);
|
||||
x->skip_true_count++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
plane_type = 3;
|
||||
if (has_y2_block) {
|
||||
tokenize2nd_order_b(x, t, cpi);
|
||||
plane_type = 0;
|
||||
}
|
||||
|
||||
tokenize1st_order_b(x, t, plane_type, cpi);
|
||||
}
|
||||
|
||||
static void stuff2nd_order_b(TOKENEXTRA **tp, ENTROPY_CONTEXT *a,
|
||||
ENTROPY_CONTEXT *l, VP8_COMP *cpi, MACROBLOCK *x) {
|
||||
int pt; /* near block/prev token context index */
|
||||
TOKENEXTRA *t = *tp; /* store tokens starting here */
|
||||
VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
|
||||
|
||||
t->Token = DCT_EOB_TOKEN;
|
||||
t->context_tree = cpi->common.fc.coef_probs[1][0][pt];
|
||||
t->skip_eob_node = 0;
|
||||
++x->coef_counts[1][0][pt][DCT_EOB_TOKEN];
|
||||
++t;
|
||||
|
||||
*tp = t;
|
||||
pt = 0;
|
||||
*a = *l = pt;
|
||||
}
|
||||
|
||||
static void stuff1st_order_b(TOKENEXTRA **tp, ENTROPY_CONTEXT *a,
|
||||
ENTROPY_CONTEXT *l, int type, VP8_COMP *cpi,
|
||||
MACROBLOCK *x) {
|
||||
int pt; /* near block/prev token context index */
|
||||
int band;
|
||||
TOKENEXTRA *t = *tp; /* store tokens starting here */
|
||||
VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
|
||||
band = type ? 0 : 1;
|
||||
t->Token = DCT_EOB_TOKEN;
|
||||
t->context_tree = cpi->common.fc.coef_probs[type][band][pt];
|
||||
t->skip_eob_node = 0;
|
||||
++x->coef_counts[type][band][pt][DCT_EOB_TOKEN];
|
||||
++t;
|
||||
*tp = t;
|
||||
pt = 0; /* 0 <-> all coeff data is zero */
|
||||
*a = *l = pt;
|
||||
}
|
||||
|
||||
static void stuff1st_order_buv(TOKENEXTRA **tp, ENTROPY_CONTEXT *a,
|
||||
ENTROPY_CONTEXT *l, VP8_COMP *cpi,
|
||||
MACROBLOCK *x) {
|
||||
int pt; /* near block/prev token context index */
|
||||
TOKENEXTRA *t = *tp; /* store tokens starting here */
|
||||
VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
|
||||
|
||||
t->Token = DCT_EOB_TOKEN;
|
||||
t->context_tree = cpi->common.fc.coef_probs[2][0][pt];
|
||||
t->skip_eob_node = 0;
|
||||
++x->coef_counts[2][0][pt][DCT_EOB_TOKEN];
|
||||
++t;
|
||||
*tp = t;
|
||||
pt = 0; /* 0 <-> all coeff data is zero */
|
||||
*a = *l = pt;
|
||||
}
|
||||
|
||||
void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) {
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context;
|
||||
ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context;
|
||||
int plane_type;
|
||||
int b;
|
||||
plane_type = 3;
|
||||
if ((xd->mode_info_context->mbmi.mode != B_PRED &&
|
||||
xd->mode_info_context->mbmi.mode != SPLITMV)) {
|
||||
stuff2nd_order_b(t, A + vp8_block2above[24], L + vp8_block2left[24], cpi,
|
||||
x);
|
||||
plane_type = 0;
|
||||
}
|
||||
|
||||
for (b = 0; b < 16; ++b) {
|
||||
stuff1st_order_b(t, A + vp8_block2above[b], L + vp8_block2left[b],
|
||||
plane_type, cpi, x);
|
||||
}
|
||||
|
||||
for (b = 16; b < 24; ++b) {
|
||||
stuff1st_order_buv(t, A + vp8_block2above[b], L + vp8_block2left[b], cpi,
|
||||
x);
|
||||
}
|
||||
}
|
||||
void vp8_fix_contexts(MACROBLOCKD *x) {
|
||||
/* Clear entropy contexts for Y2 blocks */
|
||||
if (x->mode_info_context->mbmi.mode != B_PRED &&
|
||||
x->mode_info_context->mbmi.mode != SPLITMV) {
|
||||
memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
} else {
|
||||
memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
|
||||
memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_TOKENIZE_H_
|
||||
#define VPX_VP8_ENCODER_TOKENIZE_H_
|
||||
|
||||
#include "vp8/common/entropy.h"
|
||||
#include "block.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void vp8_tokenize_initialize();
|
||||
|
||||
typedef struct {
|
||||
short Token;
|
||||
short Extra;
|
||||
} TOKENVALUE;
|
||||
|
||||
typedef struct {
|
||||
const vp8_prob *context_tree;
|
||||
short Extra;
|
||||
unsigned char Token;
|
||||
unsigned char skip_eob_node;
|
||||
} TOKENEXTRA;
|
||||
|
||||
int rd_cost_mby(MACROBLOCKD *);
|
||||
|
||||
extern const short *const vp8_dct_value_cost_ptr;
|
||||
/* TODO: The Token field should be broken out into a separate char array to
|
||||
* improve cache locality, since it's needed for costing when the rest of the
|
||||
* fields are not.
|
||||
*/
|
||||
extern const TOKENVALUE *const vp8_dct_value_tokens_ptr;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_TOKENIZE_H_
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include "treewriter.h"
|
||||
|
||||
static void cost(int *const C, vp8_tree T, const vp8_prob *const P, int i,
|
||||
int c) {
|
||||
const vp8_prob p = P[i >> 1];
|
||||
|
||||
do {
|
||||
const vp8_tree_index j = T[i];
|
||||
const int d = c + vp8_cost_bit(p, i & 1);
|
||||
|
||||
if (j <= 0) {
|
||||
C[-j] = d;
|
||||
} else {
|
||||
cost(C, T, P, j, d);
|
||||
}
|
||||
} while (++i & 1);
|
||||
}
|
||||
void vp8_cost_tokens(int *c, const vp8_prob *p, vp8_tree t) {
|
||||
cost(c, t, p, 0, 0);
|
||||
}
|
||||
void vp8_cost_tokens2(int *c, const vp8_prob *p, vp8_tree t, int start) {
|
||||
cost(c, t, p, start, 0);
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef VPX_VP8_ENCODER_TREEWRITER_H_
|
||||
#define VPX_VP8_ENCODER_TREEWRITER_H_
|
||||
|
||||
/* Trees map alphabets into huffman-like codes suitable for an arithmetic
|
||||
bit coder. Timothy S Murphy 11 October 2004 */
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "vp8/common/treecoder.h"
|
||||
|
||||
#include "boolhuff.h" /* for now */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef BOOL_CODER vp8_writer;
|
||||
|
||||
#define vp8_write vp8_encode_bool
|
||||
#define vp8_write_literal vp8_encode_value
|
||||
#define vp8_write_bit(W, V) vp8_write(W, V, vp8_prob_half)
|
||||
|
||||
#define vp8bc_write vp8bc_write_bool
|
||||
#define vp8bc_write_literal vp8bc_write_bits
|
||||
#define vp8bc_write_bit(W, V) vp8bc_write_bits(W, V, 1)
|
||||
|
||||
/* Approximate length of an encoded bool in 256ths of a bit at given prob */
|
||||
|
||||
#define vp8_cost_zero(x) (vp8_prob_cost[x])
|
||||
#define vp8_cost_one(x) vp8_cost_zero(vp8_complement(x))
|
||||
|
||||
#define vp8_cost_bit(x, b) vp8_cost_zero((b) ? vp8_complement(x) : (x))
|
||||
|
||||
/* VP8BC version is scaled by 2^20 rather than 2^8; see bool_coder.h */
|
||||
|
||||
/* Both of these return bits, not scaled bits. */
|
||||
|
||||
static INLINE unsigned int vp8_cost_branch(const unsigned int ct[2],
|
||||
vp8_prob p) {
|
||||
/* Imitate existing calculation */
|
||||
|
||||
return ((ct[0] * vp8_cost_zero(p)) + (ct[1] * vp8_cost_one(p))) >> 8;
|
||||
}
|
||||
|
||||
/* Small functions to write explicit values and tokens, as well as
|
||||
estimate their lengths. */
|
||||
|
||||
static void vp8_treed_write(vp8_writer *const w, vp8_tree t,
|
||||
const vp8_prob *const p, int v,
|
||||
int n) { /* number of bits in v, assumed nonzero */
|
||||
vp8_tree_index i = 0;
|
||||
|
||||
do {
|
||||
const int b = (v >> --n) & 1;
|
||||
vp8_write(w, b, p[i >> 1]);
|
||||
i = t[i + b];
|
||||
} while (n);
|
||||
}
|
||||
static INLINE void vp8_write_token(vp8_writer *const w, vp8_tree t,
|
||||
const vp8_prob *const p,
|
||||
vp8_token *const x) {
|
||||
vp8_treed_write(w, t, p, x->value, x->Len);
|
||||
}
|
||||
|
||||
static int vp8_treed_cost(vp8_tree t, const vp8_prob *const p, int v,
|
||||
int n) { /* number of bits in v, assumed nonzero */
|
||||
int c = 0;
|
||||
vp8_tree_index i = 0;
|
||||
|
||||
do {
|
||||
const int b = (v >> --n) & 1;
|
||||
c += vp8_cost_bit(p[i >> 1], b);
|
||||
i = t[i + b];
|
||||
} while (n);
|
||||
|
||||
return c;
|
||||
}
|
||||
static INLINE int vp8_cost_token(vp8_tree t, const vp8_prob *const p,
|
||||
vp8_token *const x) {
|
||||
return vp8_treed_cost(t, p, x->value, x->Len);
|
||||
}
|
||||
|
||||
/* Fill array of costs for all possible token values. */
|
||||
|
||||
void vp8_cost_tokens(int *c, const vp8_prob *, vp8_tree);
|
||||
|
||||
void vp8_cost_tokens2(int *c, const vp8_prob *, vp8_tree, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_VP8_ENCODER_TREEWRITER_H_
|
||||
@@ -0,0 +1,489 @@
|
||||
/*
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
#include "onyx_int.h"
|
||||
#include "vp8/encoder/quantize.h"
|
||||
#include "vp8/common/quant_common.h"
|
||||
|
||||
void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) {
|
||||
int i, rc, eob;
|
||||
int x, y, z, sz;
|
||||
short *coeff_ptr = b->coeff;
|
||||
short *round_ptr = b->round;
|
||||
short *quant_ptr = b->quant_fast;
|
||||
short *qcoeff_ptr = d->qcoeff;
|
||||
short *dqcoeff_ptr = d->dqcoeff;
|
||||
short *dequant_ptr = d->dequant;
|
||||
|
||||
eob = -1;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
rc = vp8_default_zig_zag1d[i];
|
||||
z = coeff_ptr[rc];
|
||||
|
||||
sz = (z >> 31); /* sign of z */
|
||||
x = (z ^ sz) - sz; /* x = abs(z) */
|
||||
|
||||
y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; /* quantize (x) */
|
||||
x = (y ^ sz) - sz; /* get the sign back */
|
||||
qcoeff_ptr[rc] = x; /* write to destination */
|
||||
dqcoeff_ptr[rc] = x * dequant_ptr[rc]; /* dequantized value */
|
||||
|
||||
if (y) {
|
||||
eob = i; /* last nonzero coeffs */
|
||||
}
|
||||
}
|
||||
*d->eob = (char)(eob + 1);
|
||||
}
|
||||
|
||||
void vp8_regular_quantize_b_c(BLOCK *b, BLOCKD *d) {
|
||||
int i, rc, eob;
|
||||
int zbin;
|
||||
int x, y, z, sz;
|
||||
short *zbin_boost_ptr = b->zrun_zbin_boost;
|
||||
short *coeff_ptr = b->coeff;
|
||||
short *zbin_ptr = b->zbin;
|
||||
short *round_ptr = b->round;
|
||||
short *quant_ptr = b->quant;
|
||||
short *quant_shift_ptr = b->quant_shift;
|
||||
short *qcoeff_ptr = d->qcoeff;
|
||||
short *dqcoeff_ptr = d->dqcoeff;
|
||||
short *dequant_ptr = d->dequant;
|
||||
short zbin_oq_value = b->zbin_extra;
|
||||
|
||||
memset(qcoeff_ptr, 0, 32);
|
||||
memset(dqcoeff_ptr, 0, 32);
|
||||
|
||||
eob = -1;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
rc = vp8_default_zig_zag1d[i];
|
||||
z = coeff_ptr[rc];
|
||||
|
||||
zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
|
||||
|
||||
zbin_boost_ptr++;
|
||||
sz = (z >> 31); /* sign of z */
|
||||
x = (z ^ sz) - sz; /* x = abs(z) */
|
||||
|
||||
if (x >= zbin) {
|
||||
x += round_ptr[rc];
|
||||
y = ((((x * quant_ptr[rc]) >> 16) + x) * quant_shift_ptr[rc]) >>
|
||||
16; /* quantize (x) */
|
||||
x = (y ^ sz) - sz; /* get the sign back */
|
||||
qcoeff_ptr[rc] = x; /* write to destination */
|
||||
dqcoeff_ptr[rc] = x * dequant_ptr[rc]; /* dequantized value */
|
||||
|
||||
if (y) {
|
||||
eob = i; /* last nonzero coeffs */
|
||||
zbin_boost_ptr = b->zrun_zbin_boost; /* reset zero runlength */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*d->eob = (char)(eob + 1);
|
||||
}
|
||||
|
||||
void vp8_quantize_mby(MACROBLOCK *x) {
|
||||
int i;
|
||||
int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&
|
||||
x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
|
||||
|
||||
for (i = 0; i < 16; ++i) x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
|
||||
|
||||
if (has_2nd_order) x->quantize_b(&x->block[24], &x->e_mbd.block[24]);
|
||||
}
|
||||
|
||||
void vp8_quantize_mb(MACROBLOCK *x) {
|
||||
int i;
|
||||
int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&
|
||||
x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
|
||||
|
||||
for (i = 0; i < 24 + has_2nd_order; ++i) {
|
||||
x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_quantize_mbuv(MACROBLOCK *x) {
|
||||
int i;
|
||||
|
||||
for (i = 16; i < 24; ++i) x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
|
||||
}
|
||||
|
||||
static const int qrounding_factors[129] = {
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48
|
||||
};
|
||||
|
||||
static const int qzbin_factors[129] = {
|
||||
84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
|
||||
84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
|
||||
84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 80, 80, 80, 80, 80, 80, 80, 80, 80,
|
||||
80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
|
||||
80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
|
||||
80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
|
||||
80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80
|
||||
};
|
||||
|
||||
static const int qrounding_factors_y2[129] = {
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48
|
||||
};
|
||||
|
||||
static const int qzbin_factors_y2[129] = {
|
||||
84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
|
||||
84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
|
||||
84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 80, 80, 80, 80, 80, 80, 80, 80, 80,
|
||||
80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
|
||||
80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
|
||||
80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
|
||||
80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80
|
||||
};
|
||||
|
||||
static void invert_quant(int improved_quant, short *quant, short *shift,
|
||||
short d) {
|
||||
if (improved_quant) {
|
||||
unsigned t;
|
||||
int l, m;
|
||||
t = d;
|
||||
for (l = 0; t > 1; ++l) t >>= 1;
|
||||
m = 1 + (1 << (16 + l)) / d;
|
||||
*quant = (short)(m - (1 << 16));
|
||||
*shift = l;
|
||||
/* use multiplication and constant shift by 16 */
|
||||
*shift = 1 << (16 - *shift);
|
||||
} else {
|
||||
*quant = (1 << 16) / d;
|
||||
*shift = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void vp8cx_init_quantizer(VP8_COMP *cpi) {
|
||||
int i;
|
||||
int quant_val;
|
||||
int Q;
|
||||
|
||||
int zbin_boost[16] = { 0, 0, 8, 10, 12, 14, 16, 20,
|
||||
24, 28, 32, 36, 40, 44, 44, 44 };
|
||||
|
||||
for (Q = 0; Q < QINDEX_RANGE; ++Q) {
|
||||
/* dc values */
|
||||
quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
|
||||
cpi->Y1quant_fast[Q][0] = (1 << 16) / quant_val;
|
||||
invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0,
|
||||
cpi->Y1quant_shift[Q] + 0, quant_val);
|
||||
cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
|
||||
cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
|
||||
cpi->common.Y1dequant[Q][0] = quant_val;
|
||||
cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
|
||||
|
||||
quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
|
||||
cpi->Y2quant_fast[Q][0] = (1 << 16) / quant_val;
|
||||
invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0,
|
||||
cpi->Y2quant_shift[Q] + 0, quant_val);
|
||||
cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
|
||||
cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7;
|
||||
cpi->common.Y2dequant[Q][0] = quant_val;
|
||||
cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
|
||||
|
||||
quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
|
||||
cpi->UVquant_fast[Q][0] = (1 << 16) / quant_val;
|
||||
invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0,
|
||||
cpi->UVquant_shift[Q] + 0, quant_val);
|
||||
cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
|
||||
cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
|
||||
cpi->common.UVdequant[Q][0] = quant_val;
|
||||
cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7;
|
||||
|
||||
/* all the ac values = ; */
|
||||
quant_val = vp8_ac_yquant(Q);
|
||||
cpi->Y1quant_fast[Q][1] = (1 << 16) / quant_val;
|
||||
invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 1,
|
||||
cpi->Y1quant_shift[Q] + 1, quant_val);
|
||||
cpi->Y1zbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
|
||||
cpi->Y1round[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;
|
||||
cpi->common.Y1dequant[Q][1] = quant_val;
|
||||
cpi->zrun_zbin_boost_y1[Q][1] = (quant_val * zbin_boost[1]) >> 7;
|
||||
|
||||
quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
|
||||
cpi->Y2quant_fast[Q][1] = (1 << 16) / quant_val;
|
||||
invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 1,
|
||||
cpi->Y2quant_shift[Q] + 1, quant_val);
|
||||
cpi->Y2zbin[Q][1] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
|
||||
cpi->Y2round[Q][1] = (qrounding_factors_y2[Q] * quant_val) >> 7;
|
||||
cpi->common.Y2dequant[Q][1] = quant_val;
|
||||
cpi->zrun_zbin_boost_y2[Q][1] = (quant_val * zbin_boost[1]) >> 7;
|
||||
|
||||
quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
|
||||
cpi->UVquant_fast[Q][1] = (1 << 16) / quant_val;
|
||||
invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 1,
|
||||
cpi->UVquant_shift[Q] + 1, quant_val);
|
||||
cpi->UVzbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
|
||||
cpi->UVround[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;
|
||||
cpi->common.UVdequant[Q][1] = quant_val;
|
||||
cpi->zrun_zbin_boost_uv[Q][1] = (quant_val * zbin_boost[1]) >> 7;
|
||||
|
||||
for (i = 2; i < 16; ++i) {
|
||||
cpi->Y1quant_fast[Q][i] = cpi->Y1quant_fast[Q][1];
|
||||
cpi->Y1quant[Q][i] = cpi->Y1quant[Q][1];
|
||||
cpi->Y1quant_shift[Q][i] = cpi->Y1quant_shift[Q][1];
|
||||
cpi->Y1zbin[Q][i] = cpi->Y1zbin[Q][1];
|
||||
cpi->Y1round[Q][i] = cpi->Y1round[Q][1];
|
||||
cpi->zrun_zbin_boost_y1[Q][i] =
|
||||
(cpi->common.Y1dequant[Q][1] * zbin_boost[i]) >> 7;
|
||||
|
||||
cpi->Y2quant_fast[Q][i] = cpi->Y2quant_fast[Q][1];
|
||||
cpi->Y2quant[Q][i] = cpi->Y2quant[Q][1];
|
||||
cpi->Y2quant_shift[Q][i] = cpi->Y2quant_shift[Q][1];
|
||||
cpi->Y2zbin[Q][i] = cpi->Y2zbin[Q][1];
|
||||
cpi->Y2round[Q][i] = cpi->Y2round[Q][1];
|
||||
cpi->zrun_zbin_boost_y2[Q][i] =
|
||||
(cpi->common.Y2dequant[Q][1] * zbin_boost[i]) >> 7;
|
||||
|
||||
cpi->UVquant_fast[Q][i] = cpi->UVquant_fast[Q][1];
|
||||
cpi->UVquant[Q][i] = cpi->UVquant[Q][1];
|
||||
cpi->UVquant_shift[Q][i] = cpi->UVquant_shift[Q][1];
|
||||
cpi->UVzbin[Q][i] = cpi->UVzbin[Q][1];
|
||||
cpi->UVround[Q][i] = cpi->UVround[Q][1];
|
||||
cpi->zrun_zbin_boost_uv[Q][i] =
|
||||
(cpi->common.UVdequant[Q][1] * zbin_boost[i]) >> 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define ZBIN_EXTRA_Y \
|
||||
((cpi->common.Y1dequant[QIndex][1] * \
|
||||
(x->zbin_over_quant + x->zbin_mode_boost + x->act_zbin_adj)) >> \
|
||||
7)
|
||||
|
||||
#define ZBIN_EXTRA_UV \
|
||||
((cpi->common.UVdequant[QIndex][1] * \
|
||||
(x->zbin_over_quant + x->zbin_mode_boost + x->act_zbin_adj)) >> \
|
||||
7)
|
||||
|
||||
#define ZBIN_EXTRA_Y2 \
|
||||
((cpi->common.Y2dequant[QIndex][1] * \
|
||||
((x->zbin_over_quant / 2) + x->zbin_mode_boost + x->act_zbin_adj)) >> \
|
||||
7)
|
||||
|
||||
void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip) {
|
||||
int i;
|
||||
int QIndex;
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
int zbin_extra;
|
||||
|
||||
/* Select the baseline MB Q index. */
|
||||
if (xd->segmentation_enabled) {
|
||||
/* Abs Value */
|
||||
if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA) {
|
||||
QIndex = xd->segment_feature_data[MB_LVL_ALT_Q]
|
||||
[xd->mode_info_context->mbmi.segment_id];
|
||||
/* Delta Value */
|
||||
} else {
|
||||
QIndex = cpi->common.base_qindex +
|
||||
xd->segment_feature_data[MB_LVL_ALT_Q]
|
||||
[xd->mode_info_context->mbmi.segment_id];
|
||||
/* Clamp to valid range */
|
||||
QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;
|
||||
}
|
||||
} else {
|
||||
QIndex = cpi->common.base_qindex;
|
||||
}
|
||||
|
||||
/* This initialization should be called at least once. Use ok_to_skip to
|
||||
* decide if it is ok to skip.
|
||||
* Before encoding a frame, this function is always called with ok_to_skip
|
||||
* =0, which means no skiping of calculations. The "last" values are
|
||||
* initialized at that time.
|
||||
*/
|
||||
if (!ok_to_skip || QIndex != x->q_index) {
|
||||
xd->dequant_y1_dc[0] = 1;
|
||||
xd->dequant_y1[0] = cpi->common.Y1dequant[QIndex][0];
|
||||
xd->dequant_y2[0] = cpi->common.Y2dequant[QIndex][0];
|
||||
xd->dequant_uv[0] = cpi->common.UVdequant[QIndex][0];
|
||||
|
||||
for (i = 1; i < 16; ++i) {
|
||||
xd->dequant_y1_dc[i] = xd->dequant_y1[i] =
|
||||
cpi->common.Y1dequant[QIndex][1];
|
||||
xd->dequant_y2[i] = cpi->common.Y2dequant[QIndex][1];
|
||||
xd->dequant_uv[i] = cpi->common.UVdequant[QIndex][1];
|
||||
}
|
||||
#if 1
|
||||
/*TODO: Remove dequant from BLOCKD. This is a temporary solution until
|
||||
* the quantizer code uses a passed in pointer to the dequant constants.
|
||||
* This will also require modifications to the x86 and neon assembly.
|
||||
* */
|
||||
for (i = 0; i < 16; ++i) x->e_mbd.block[i].dequant = xd->dequant_y1;
|
||||
for (i = 16; i < 24; ++i) x->e_mbd.block[i].dequant = xd->dequant_uv;
|
||||
x->e_mbd.block[24].dequant = xd->dequant_y2;
|
||||
#endif
|
||||
|
||||
/* Y */
|
||||
zbin_extra = ZBIN_EXTRA_Y;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
x->block[i].quant = cpi->Y1quant[QIndex];
|
||||
x->block[i].quant_fast = cpi->Y1quant_fast[QIndex];
|
||||
x->block[i].quant_shift = cpi->Y1quant_shift[QIndex];
|
||||
x->block[i].zbin = cpi->Y1zbin[QIndex];
|
||||
x->block[i].round = cpi->Y1round[QIndex];
|
||||
x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex];
|
||||
x->block[i].zbin_extra = (short)zbin_extra;
|
||||
}
|
||||
|
||||
/* UV */
|
||||
zbin_extra = ZBIN_EXTRA_UV;
|
||||
|
||||
for (i = 16; i < 24; ++i) {
|
||||
x->block[i].quant = cpi->UVquant[QIndex];
|
||||
x->block[i].quant_fast = cpi->UVquant_fast[QIndex];
|
||||
x->block[i].quant_shift = cpi->UVquant_shift[QIndex];
|
||||
x->block[i].zbin = cpi->UVzbin[QIndex];
|
||||
x->block[i].round = cpi->UVround[QIndex];
|
||||
x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex];
|
||||
x->block[i].zbin_extra = (short)zbin_extra;
|
||||
}
|
||||
|
||||
/* Y2 */
|
||||
zbin_extra = ZBIN_EXTRA_Y2;
|
||||
|
||||
x->block[24].quant_fast = cpi->Y2quant_fast[QIndex];
|
||||
x->block[24].quant = cpi->Y2quant[QIndex];
|
||||
x->block[24].quant_shift = cpi->Y2quant_shift[QIndex];
|
||||
x->block[24].zbin = cpi->Y2zbin[QIndex];
|
||||
x->block[24].round = cpi->Y2round[QIndex];
|
||||
x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex];
|
||||
x->block[24].zbin_extra = (short)zbin_extra;
|
||||
|
||||
/* save this macroblock QIndex for vp8_update_zbin_extra() */
|
||||
x->q_index = QIndex;
|
||||
|
||||
x->last_zbin_over_quant = x->zbin_over_quant;
|
||||
x->last_zbin_mode_boost = x->zbin_mode_boost;
|
||||
x->last_act_zbin_adj = x->act_zbin_adj;
|
||||
|
||||
} else if (x->last_zbin_over_quant != x->zbin_over_quant ||
|
||||
x->last_zbin_mode_boost != x->zbin_mode_boost ||
|
||||
x->last_act_zbin_adj != x->act_zbin_adj) {
|
||||
/* Y */
|
||||
zbin_extra = ZBIN_EXTRA_Y;
|
||||
|
||||
for (i = 0; i < 16; ++i) x->block[i].zbin_extra = (short)zbin_extra;
|
||||
|
||||
/* UV */
|
||||
zbin_extra = ZBIN_EXTRA_UV;
|
||||
|
||||
for (i = 16; i < 24; ++i) x->block[i].zbin_extra = (short)zbin_extra;
|
||||
|
||||
/* Y2 */
|
||||
zbin_extra = ZBIN_EXTRA_Y2;
|
||||
x->block[24].zbin_extra = (short)zbin_extra;
|
||||
|
||||
x->last_zbin_over_quant = x->zbin_over_quant;
|
||||
x->last_zbin_mode_boost = x->zbin_mode_boost;
|
||||
x->last_act_zbin_adj = x->act_zbin_adj;
|
||||
}
|
||||
}
|
||||
|
||||
void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x) {
|
||||
int i;
|
||||
int QIndex = x->q_index;
|
||||
int zbin_extra;
|
||||
|
||||
/* Y */
|
||||
zbin_extra = ZBIN_EXTRA_Y;
|
||||
|
||||
for (i = 0; i < 16; ++i) x->block[i].zbin_extra = (short)zbin_extra;
|
||||
|
||||
/* UV */
|
||||
zbin_extra = ZBIN_EXTRA_UV;
|
||||
|
||||
for (i = 16; i < 24; ++i) x->block[i].zbin_extra = (short)zbin_extra;
|
||||
|
||||
/* Y2 */
|
||||
zbin_extra = ZBIN_EXTRA_Y2;
|
||||
x->block[24].zbin_extra = (short)zbin_extra;
|
||||
}
|
||||
#undef ZBIN_EXTRA_Y
|
||||
#undef ZBIN_EXTRA_UV
|
||||
#undef ZBIN_EXTRA_Y2
|
||||
|
||||
void vp8cx_frame_init_quantizer(VP8_COMP *cpi) {
|
||||
/* Clear Zbin mode boost for default case */
|
||||
cpi->mb.zbin_mode_boost = 0;
|
||||
|
||||
/* MB level quantizer setup */
|
||||
vp8cx_mb_init_quantizer(cpi, &cpi->mb, 0);
|
||||
}
|
||||
|
||||
void vp8_set_quantizer(struct VP8_COMP *cpi, int Q) {
|
||||
VP8_COMMON *cm = &cpi->common;
|
||||
MACROBLOCKD *mbd = &cpi->mb.e_mbd;
|
||||
int update = 0;
|
||||
int new_delta_q;
|
||||
int new_uv_delta_q;
|
||||
cm->base_qindex = Q;
|
||||
|
||||
/* if any of the delta_q values are changing update flag has to be set */
|
||||
/* currently only y2dc_delta_q may change */
|
||||
|
||||
cm->y1dc_delta_q = 0;
|
||||
cm->y2ac_delta_q = 0;
|
||||
|
||||
if (Q < 4) {
|
||||
new_delta_q = 4 - Q;
|
||||
} else {
|
||||
new_delta_q = 0;
|
||||
}
|
||||
|
||||
update |= cm->y2dc_delta_q != new_delta_q;
|
||||
cm->y2dc_delta_q = new_delta_q;
|
||||
|
||||
new_uv_delta_q = 0;
|
||||
// For screen content, lower the q value for UV channel. For now, select
|
||||
// conservative delta; same delta for dc and ac, and decrease it with lower
|
||||
// Q, and set to 0 below some threshold. May want to condition this in
|
||||
// future on the variance/energy in UV channel.
|
||||
if (cpi->oxcf.screen_content_mode && Q > 40) {
|
||||
new_uv_delta_q = -(int)(0.15 * Q);
|
||||
// Check range: magnitude of delta is 4 bits.
|
||||
if (new_uv_delta_q < -15) {
|
||||
new_uv_delta_q = -15;
|
||||
}
|
||||
}
|
||||
update |= cm->uvdc_delta_q != new_uv_delta_q;
|
||||
cm->uvdc_delta_q = new_uv_delta_q;
|
||||
cm->uvac_delta_q = new_uv_delta_q;
|
||||
|
||||
/* Set Segment specific quatizers */
|
||||
mbd->segment_feature_data[MB_LVL_ALT_Q][0] =
|
||||
cpi->segment_feature_data[MB_LVL_ALT_Q][0];
|
||||
mbd->segment_feature_data[MB_LVL_ALT_Q][1] =
|
||||
cpi->segment_feature_data[MB_LVL_ALT_Q][1];
|
||||
mbd->segment_feature_data[MB_LVL_ALT_Q][2] =
|
||||
cpi->segment_feature_data[MB_LVL_ALT_Q][2];
|
||||
mbd->segment_feature_data[MB_LVL_ALT_Q][3] =
|
||||
cpi->segment_feature_data[MB_LVL_ALT_Q][3];
|
||||
|
||||
/* quantizer has to be reinitialized for any delta_q changes */
|
||||
if (update) vp8cx_init_quantizer(cpi);
|
||||
}
|
||||
Reference in New Issue
Block a user