Merge "vp8: Add an aggressive denoising mode."
This commit is contained in:
@@ -579,7 +579,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (strncmp(encoder->name, "vp8", 3) == 0) {
|
if (strncmp(encoder->name, "vp8", 3) == 0) {
|
||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
||||||
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOnYOnly);
|
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOnYOnly);
|
||||||
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
|
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
|
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
|
||||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
||||||
|
@@ -108,8 +108,8 @@ extern "C"
|
|||||||
* For temporal denoiser: noise_sensitivity = 0 means off,
|
* For temporal denoiser: noise_sensitivity = 0 means off,
|
||||||
* noise_sensitivity = 1 means temporal denoiser on for Y channel only,
|
* noise_sensitivity = 1 means temporal denoiser on for Y channel only,
|
||||||
* noise_sensitivity = 2 means temporal denoiser on for all channels.
|
* noise_sensitivity = 2 means temporal denoiser on for all channels.
|
||||||
* noise_sensitivity = 3 will be used for aggressive mode in future.
|
* noise_sensitivity = 3 means aggressive denoising mode.
|
||||||
* Temporal denoiser is enabled via the build option
|
* Temporal denoiser is enabled via the configuration option:
|
||||||
* CONFIG_TEMPORAL_DENOISING.
|
* CONFIG_TEMPORAL_DENOISING.
|
||||||
* For spatial denoiser: noise_sensitivity controls the amount of
|
* For spatial denoiser: noise_sensitivity controls the amount of
|
||||||
* pre-processing blur: noise_sensitivity = 0 means off.
|
* pre-processing blur: noise_sensitivity = 0 means off.
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "denoising.h"
|
#include "denoising.h"
|
||||||
|
|
||||||
#include "vp8/common/reconinter.h"
|
#include "vp8/common/reconinter.h"
|
||||||
@@ -333,12 +335,33 @@ int vp8_denoiser_filter_uv_c(unsigned char *mc_running_avg_uv,
|
|||||||
return FILTER_BLOCK;
|
return FILTER_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vp8_denoiser_set_parameters(VP8_DENOISER *denoiser) {
|
||||||
|
if (!denoiser->aggressive_mode) {
|
||||||
|
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;
|
||||||
|
} 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 = 60;
|
||||||
|
denoiser->denoise_pars.qp_thresh = 100;
|
||||||
|
denoiser->denoise_pars.consec_zerolast = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height,
|
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height,
|
||||||
int num_mb_rows, int num_mb_cols)
|
int num_mb_rows, int num_mb_cols, int mode)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
assert(denoiser);
|
assert(denoiser);
|
||||||
denoiser->num_mb_cols = num_mb_cols;
|
denoiser->num_mb_cols = num_mb_cols;
|
||||||
|
denoiser->aggressive_mode = mode;
|
||||||
|
|
||||||
for (i = 0; i < MAX_REF_FRAMES; i++)
|
for (i = 0; i < MAX_REF_FRAMES; i++)
|
||||||
{
|
{
|
||||||
@@ -369,10 +392,11 @@ int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height,
|
|||||||
|
|
||||||
denoiser->denoise_state = vpx_calloc((num_mb_rows * num_mb_cols), 1);
|
denoiser->denoise_state = vpx_calloc((num_mb_rows * num_mb_cols), 1);
|
||||||
vpx_memset(denoiser->denoise_state, 0, (num_mb_rows * num_mb_cols));
|
vpx_memset(denoiser->denoise_state, 0, (num_mb_rows * num_mb_cols));
|
||||||
|
vp8_denoiser_set_parameters(denoiser);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void vp8_denoiser_free(VP8_DENOISER *denoiser)
|
void vp8_denoiser_free(VP8_DENOISER *denoiser)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -401,6 +425,7 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
|
|||||||
{
|
{
|
||||||
int mv_row;
|
int mv_row;
|
||||||
int mv_col;
|
int mv_col;
|
||||||
|
unsigned int motion_threshold;
|
||||||
unsigned int motion_magnitude2;
|
unsigned int motion_magnitude2;
|
||||||
unsigned int sse_thresh;
|
unsigned int sse_thresh;
|
||||||
int sse_diff_thresh = 0;
|
int sse_diff_thresh = 0;
|
||||||
@@ -424,7 +449,7 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
|
|||||||
MB_MODE_INFO *mbmi = &filter_xd->mode_info_context->mbmi;
|
MB_MODE_INFO *mbmi = &filter_xd->mode_info_context->mbmi;
|
||||||
int sse_diff = 0;
|
int sse_diff = 0;
|
||||||
// Bias on zero motion vector sse.
|
// Bias on zero motion vector sse.
|
||||||
int zero_bias = 95;
|
const int zero_bias = denoiser->denoise_pars.denoise_mv_bias;
|
||||||
zero_mv_sse = (unsigned int)((int64_t)zero_mv_sse * zero_bias / 100);
|
zero_mv_sse = (unsigned int)((int64_t)zero_mv_sse * zero_bias / 100);
|
||||||
sse_diff = zero_mv_sse - best_sse;
|
sse_diff = zero_mv_sse - best_sse;
|
||||||
|
|
||||||
@@ -502,14 +527,19 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
|
|||||||
mv_row = x->best_sse_mv.as_mv.row;
|
mv_row = x->best_sse_mv.as_mv.row;
|
||||||
mv_col = x->best_sse_mv.as_mv.col;
|
mv_col = x->best_sse_mv.as_mv.col;
|
||||||
motion_magnitude2 = mv_row * mv_row + mv_col * mv_col;
|
motion_magnitude2 = mv_row * mv_row + mv_col * mv_col;
|
||||||
sse_thresh = SSE_THRESHOLD;
|
motion_threshold = denoiser->denoise_pars.scale_motion_thresh *
|
||||||
if (x->increase_denoising) sse_thresh = SSE_THRESHOLD_HIGH;
|
NOISE_MOTION_THRESHOLD;
|
||||||
|
|
||||||
if (best_sse > sse_thresh || motion_magnitude2
|
if (motion_magnitude2 <
|
||||||
> 8 * NOISE_MOTION_THRESHOLD)
|
denoiser->denoise_pars.scale_increase_filter * NOISE_MOTION_THRESHOLD)
|
||||||
{
|
x->increase_denoising = 1;
|
||||||
decision = COPY_BLOCK;
|
|
||||||
}
|
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 (decision == FILTER_BLOCK)
|
if (decision == FILTER_BLOCK)
|
||||||
{
|
{
|
||||||
|
@@ -39,16 +39,40 @@ enum vp8_denoiser_filter_state {
|
|||||||
kFilterNonZeroMV
|
kFilterNonZeroMV
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
} denoise_params;
|
||||||
|
|
||||||
typedef struct vp8_denoiser
|
typedef struct vp8_denoiser
|
||||||
{
|
{
|
||||||
YV12_BUFFER_CONFIG yv12_running_avg[MAX_REF_FRAMES];
|
YV12_BUFFER_CONFIG yv12_running_avg[MAX_REF_FRAMES];
|
||||||
YV12_BUFFER_CONFIG yv12_mc_running_avg;
|
YV12_BUFFER_CONFIG yv12_mc_running_avg;
|
||||||
unsigned char* denoise_state;
|
unsigned char* denoise_state;
|
||||||
int num_mb_cols;
|
int num_mb_cols;
|
||||||
|
int aggressive_mode;
|
||||||
|
denoise_params denoise_pars;
|
||||||
} VP8_DENOISER;
|
} VP8_DENOISER;
|
||||||
|
|
||||||
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height,
|
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height,
|
||||||
int num_mb_rows, int num_mb_cols);
|
int num_mb_rows, int num_mb_cols, int mode);
|
||||||
|
|
||||||
void vp8_denoiser_free(VP8_DENOISER *denoiser);
|
void vp8_denoiser_free(VP8_DENOISER *denoiser);
|
||||||
|
|
||||||
|
@@ -522,6 +522,19 @@ void encode_mb_row(VP8_COMP *cpi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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;
|
||||||
|
} else {
|
||||||
|
cpi->consec_zero_last[map_index+mb_col] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Special case code for cyclic refresh
|
/* Special case code for cyclic refresh
|
||||||
* If cyclic update enabled then copy xd->mbmi.segment_id; (which
|
* If cyclic update enabled then copy xd->mbmi.segment_id; (which
|
||||||
|
@@ -206,6 +206,21 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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;
|
||||||
|
} else {
|
||||||
|
cpi->consec_zero_last[map_index+mb_col] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Special case code for cyclic refresh
|
/* Special case code for cyclic refresh
|
||||||
* If cyclic update enabled then copy
|
* If cyclic update enabled then copy
|
||||||
|
@@ -613,6 +613,24 @@ static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment)
|
|||||||
while(block_count && i != cpi->cyclic_refresh_mode_index);
|
while(block_count && i != cpi->cyclic_refresh_mode_index);
|
||||||
|
|
||||||
cpi->cyclic_refresh_mode_index = i;
|
cpi->cyclic_refresh_mode_index = i;
|
||||||
|
|
||||||
|
#if CONFIG_TEMPORAL_DENOISING
|
||||||
|
if (cpi->denoiser.aggressive_mode != 0 &&
|
||||||
|
Q < cpi->denoiser.denoise_pars.qp_thresh) {
|
||||||
|
// Under aggressive denoising mode, use segmentation to turn off loop
|
||||||
|
// filter below some qp thresh. The loop filter is turned off for all
|
||||||
|
// blocks that have been encoded as ZEROMV LAST x frames in a row,
|
||||||
|
// where x is set by cpi->denoiser.denoise_pars.consec_zerolast.
|
||||||
|
// This is to avoid "dot" artifacts that can occur from repeated
|
||||||
|
// loop filtering on noisy input source.
|
||||||
|
cpi->cyclic_refresh_q = Q;
|
||||||
|
lf_adjustment = -MAX_LOOP_FILTER;
|
||||||
|
for (i = 0; i < mbs_in_frame; ++i) {
|
||||||
|
seg_map[i] = (cpi->consec_zero_last[i] >
|
||||||
|
cpi->denoiser.denoise_pars.consec_zerolast) ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Activate segmentation. */
|
/* Activate segmentation. */
|
||||||
@@ -1752,7 +1770,8 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf)
|
|||||||
int width = (cpi->oxcf.Width + 15) & ~15;
|
int width = (cpi->oxcf.Width + 15) & ~15;
|
||||||
int height = (cpi->oxcf.Height + 15) & ~15;
|
int height = (cpi->oxcf.Height + 15) & ~15;
|
||||||
vp8_denoiser_allocate(&cpi->denoiser, width, height,
|
vp8_denoiser_allocate(&cpi->denoiser, width, height,
|
||||||
cpi->common.mb_rows, cpi->common.mb_cols);
|
cm->mb_rows, cm->mb_cols,
|
||||||
|
((cpi->oxcf.noise_sensitivity == 3) ? 1 : 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1896,6 +1915,9 @@ struct VP8_COMP* vp8_create_compressor(VP8_CONFIG *oxcf)
|
|||||||
else
|
else
|
||||||
cpi->cyclic_refresh_map = (signed char *) NULL;
|
cpi->cyclic_refresh_map = (signed char *) NULL;
|
||||||
|
|
||||||
|
CHECK_MEM_ERROR(cpi->consec_zero_last,
|
||||||
|
vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
|
||||||
|
|
||||||
#ifdef VP8_ENTROPY_STATS
|
#ifdef VP8_ENTROPY_STATS
|
||||||
init_context_counters();
|
init_context_counters();
|
||||||
#endif
|
#endif
|
||||||
@@ -2416,6 +2438,7 @@ void vp8_remove_compressor(VP8_COMP **ptr)
|
|||||||
vpx_free(cpi->mb.ss);
|
vpx_free(cpi->mb.ss);
|
||||||
vpx_free(cpi->tok);
|
vpx_free(cpi->tok);
|
||||||
vpx_free(cpi->cyclic_refresh_map);
|
vpx_free(cpi->cyclic_refresh_map);
|
||||||
|
vpx_free(cpi->consec_zero_last);
|
||||||
|
|
||||||
vp8_remove_common(&cpi->common);
|
vp8_remove_common(&cpi->common);
|
||||||
vpx_free(cpi);
|
vpx_free(cpi);
|
||||||
@@ -3478,6 +3501,9 @@ static void encode_frame_to_data_rate
|
|||||||
{
|
{
|
||||||
cpi->mb.rd_thresh_mult[i] = 128;
|
cpi->mb.rd_thresh_mult[i] = 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset the zero_last counter to 0 on key frame.
|
||||||
|
vpx_memset(cpi->consec_zero_last, 0, cm->mb_rows * cm->mb_cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -3899,6 +3925,7 @@ static void encode_frame_to_data_rate
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef OUTPUT_YUV_SRC
|
#ifdef OUTPUT_YUV_SRC
|
||||||
vp8_write_yuv_frame(yuv_file, cpi->Source);
|
vp8_write_yuv_frame(yuv_file, cpi->Source);
|
||||||
#endif
|
#endif
|
||||||
@@ -3994,6 +4021,8 @@ static void encode_frame_to_data_rate
|
|||||||
else
|
else
|
||||||
disable_segmentation(cpi);
|
disable_segmentation(cpi);
|
||||||
}
|
}
|
||||||
|
// Reset the consec_zero_last counter on key frame.
|
||||||
|
vpx_memset(cpi->consec_zero_last, 0, cm->mb_rows * cm->mb_cols);
|
||||||
vp8_set_quantizer(cpi, Q);
|
vp8_set_quantizer(cpi, Q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -511,6 +511,8 @@ typedef struct VP8_COMP
|
|||||||
int cyclic_refresh_mode_index;
|
int cyclic_refresh_mode_index;
|
||||||
int cyclic_refresh_q;
|
int cyclic_refresh_q;
|
||||||
signed char *cyclic_refresh_map;
|
signed char *cyclic_refresh_map;
|
||||||
|
// Count on how many (consecutive) times a macroblock uses ZER0MV_LAST.
|
||||||
|
unsigned char *consec_zero_last;
|
||||||
|
|
||||||
// Frame counter for the temporal pattern. Counter is rest when the temporal
|
// Frame counter for the temporal pattern. Counter is rest when the temporal
|
||||||
// layers are changed dynamically (run-time change).
|
// layers are changed dynamically (run-time change).
|
||||||
|
@@ -40,7 +40,6 @@ extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];
|
|||||||
|
|
||||||
extern int vp8_cost_mv_ref(MB_PREDICTION_MODE m, const int near_mv_ref_ct[4]);
|
extern int vp8_cost_mv_ref(MB_PREDICTION_MODE m, const int near_mv_ref_ct[4]);
|
||||||
|
|
||||||
|
|
||||||
int vp8_skip_fractional_mv_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d,
|
int vp8_skip_fractional_mv_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d,
|
||||||
int_mv *bestmv, int_mv *ref_mv,
|
int_mv *bestmv, int_mv *ref_mv,
|
||||||
int error_per_bit,
|
int error_per_bit,
|
||||||
@@ -694,6 +693,13 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
|
|||||||
*/
|
*/
|
||||||
calculate_zeromv_rd_adjustment(cpi, x, &rd_adjustment);
|
calculate_zeromv_rd_adjustment(cpi, x, &rd_adjustment);
|
||||||
|
|
||||||
|
#if CONFIG_TEMPORAL_DENOISING
|
||||||
|
if (cpi->oxcf.noise_sensitivity) {
|
||||||
|
rd_adjustment = (int)(rd_adjustment *
|
||||||
|
cpi->denoiser.denoise_pars.pickmode_mv_bias / 100);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* if we encode a new mv this is important
|
/* if we encode a new mv this is important
|
||||||
* find the best new motion vector
|
* find the best new motion vector
|
||||||
*/
|
*/
|
||||||
@@ -1168,7 +1174,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
|
|||||||
#if CONFIG_TEMPORAL_DENOISING
|
#if CONFIG_TEMPORAL_DENOISING
|
||||||
if (cpi->oxcf.noise_sensitivity)
|
if (cpi->oxcf.noise_sensitivity)
|
||||||
{
|
{
|
||||||
int uv_denoise = (cpi->oxcf.noise_sensitivity == 2) ? 1 : 0;
|
int uv_denoise = (cpi->oxcf.noise_sensitivity >= 2) ? 1 : 0;
|
||||||
int block_index = mb_row * cpi->common.mb_cols + mb_col;
|
int block_index = mb_row * cpi->common.mb_cols + mb_col;
|
||||||
if (x->best_sse_inter_mode == DC_PRED)
|
if (x->best_sse_inter_mode == DC_PRED)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user