Index: source/libvpx/vp9/encoder/vp9_encoder.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_encoder.c (revision 278778) |
+++ source/libvpx/vp9/encoder/vp9_encoder.c (working copy) |
@@ -64,6 +64,9 @@ |
// #define OUTPUT_YUV_REC |
+#ifdef OUTPUT_YUV_DENOISED |
+FILE *yuv_denoised_file; |
+#endif |
#ifdef OUTPUT_YUV_SRC |
FILE *yuv_file; |
#endif |
@@ -187,7 +190,7 @@ |
vpx_free(cpi->tok); |
cpi->tok = 0; |
- vp9_free_pc_tree(&cpi->mb); |
+ vp9_free_pc_tree(cpi); |
for (i = 0; i < cpi->svc.number_spatial_layers; ++i) { |
LAYER_CONTEXT *const lc = &cpi->svc.layer_context[i]; |
@@ -393,11 +396,6 @@ |
// Set rd thresholds based on mode and speed setting |
vp9_set_rd_speed_thresholds(cpi); |
vp9_set_rd_speed_thresholds_sub8x8(cpi); |
- |
- cpi->mb.fwd_txm4x4 = vp9_fdct4x4; |
- if (cpi->oxcf.lossless || cpi->mb.e_mbd.lossless) { |
- cpi->mb.fwd_txm4x4 = vp9_fwht4x4; |
- } |
} |
static void alloc_raw_frame_buffers(VP9_COMP *cpi) { |
@@ -455,7 +453,7 @@ |
CHECK_MEM_ERROR(cm, cpi->tok, vpx_calloc(tokens, sizeof(*cpi->tok))); |
} |
- vp9_setup_pc_tree(&cpi->common, &cpi->mb); |
+ vp9_setup_pc_tree(&cpi->common, cpi); |
} |
static void update_frame_size(VP9_COMP *cpi) { |
@@ -489,9 +487,9 @@ |
{ |
int y_stride = cpi->scaled_source.y_stride; |
- if (cpi->sf.search_method == NSTEP) { |
+ if (cpi->sf.mv.search_method == NSTEP) { |
vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride); |
- } else if (cpi->sf.search_method == DIAMOND) { |
+ } else if (cpi->sf.mv.search_method == DIAMOND) { |
vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride); |
} |
} |
@@ -543,7 +541,7 @@ |
cpi->svc.number_temporal_layers = oxcf->ts_number_layers; |
if ((cpi->svc.number_temporal_layers > 1 && |
- cpi->oxcf.rc_mode == RC_MODE_CBR) || |
+ cpi->oxcf.rc_mode == VPX_CBR) || |
(cpi->svc.number_spatial_layers > 1 && |
cpi->oxcf.mode == TWO_PASS_SECOND_BEST)) { |
vp9_init_layer_context(cpi); |
@@ -593,19 +591,7 @@ |
cpi->oxcf = *oxcf; |
cpi->pass = get_pass(cpi->oxcf.mode); |
- if (cpi->oxcf.mode == REALTIME) |
- cpi->oxcf.play_alternate = 0; |
- cpi->oxcf.lossless = oxcf->lossless; |
- if (cpi->oxcf.lossless) { |
- // In lossless mode, make sure right quantizer range and correct transform |
- // is set. |
- cpi->oxcf.worst_allowed_q = 0; |
- cpi->oxcf.best_allowed_q = 0; |
- cpi->mb.e_mbd.itxm_add = vp9_iwht4x4_add; |
- } else { |
- cpi->mb.e_mbd.itxm_add = vp9_idct4x4_add; |
- } |
rc->baseline_gf_interval = DEFAULT_GF_INTERVAL; |
cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; |
@@ -626,37 +612,31 @@ |
cpi->encode_breakout = cpi->oxcf.encode_breakout; |
// local file playback mode == really big buffer |
- if (cpi->oxcf.rc_mode == RC_MODE_VBR) { |
- cpi->oxcf.starting_buffer_level = 60000; |
- cpi->oxcf.optimal_buffer_level = 60000; |
- cpi->oxcf.maximum_buffer_size = 240000; |
+ if (cpi->oxcf.rc_mode == VPX_VBR) { |
+ cpi->oxcf.starting_buffer_level_ms = 60000; |
+ cpi->oxcf.optimal_buffer_level_ms = 60000; |
+ cpi->oxcf.maximum_buffer_size_ms = 240000; |
} |
- // Convert target bandwidth from Kbit/s to Bit/s |
- cpi->oxcf.target_bandwidth *= 1000; |
+ rc->starting_buffer_level = vp9_rescale(cpi->oxcf.starting_buffer_level_ms, |
+ cpi->oxcf.target_bandwidth, 1000); |
- cpi->oxcf.starting_buffer_level = |
- vp9_rescale(cpi->oxcf.starting_buffer_level, |
- cpi->oxcf.target_bandwidth, 1000); |
- |
// Set or reset optimal and maximum buffer levels. |
- if (cpi->oxcf.optimal_buffer_level == 0) |
- cpi->oxcf.optimal_buffer_level = cpi->oxcf.target_bandwidth / 8; |
+ if (cpi->oxcf.optimal_buffer_level_ms == 0) |
+ rc->optimal_buffer_level = cpi->oxcf.target_bandwidth / 8; |
else |
- cpi->oxcf.optimal_buffer_level = |
- vp9_rescale(cpi->oxcf.optimal_buffer_level, |
- cpi->oxcf.target_bandwidth, 1000); |
+ rc->optimal_buffer_level = vp9_rescale(cpi->oxcf.optimal_buffer_level_ms, |
+ cpi->oxcf.target_bandwidth, 1000); |
- if (cpi->oxcf.maximum_buffer_size == 0) |
- cpi->oxcf.maximum_buffer_size = cpi->oxcf.target_bandwidth / 8; |
+ if (cpi->oxcf.maximum_buffer_size_ms == 0) |
+ rc->maximum_buffer_size = cpi->oxcf.target_bandwidth / 8; |
else |
- cpi->oxcf.maximum_buffer_size = |
- vp9_rescale(cpi->oxcf.maximum_buffer_size, |
- cpi->oxcf.target_bandwidth, 1000); |
+ rc->maximum_buffer_size = vp9_rescale(cpi->oxcf.maximum_buffer_size_ms, |
+ cpi->oxcf.target_bandwidth, 1000); |
// Under a configuration change, where maximum_buffer_size may change, |
// keep buffer level clipped to the maximum allowed buffer size. |
- rc->bits_off_target = MIN(rc->bits_off_target, cpi->oxcf.maximum_buffer_size); |
- rc->buffer_level = MIN(rc->buffer_level, cpi->oxcf.maximum_buffer_size); |
+ rc->bits_off_target = MIN(rc->bits_off_target, rc->maximum_buffer_size); |
+ rc->buffer_level = MIN(rc->buffer_level, rc->maximum_buffer_size); |
// Set up frame rate and related parameters rate control values. |
vp9_new_framerate(cpi, cpi->oxcf.framerate); |
@@ -680,7 +660,7 @@ |
update_frame_size(cpi); |
if ((cpi->svc.number_temporal_layers > 1 && |
- cpi->oxcf.rc_mode == RC_MODE_CBR) || |
+ cpi->oxcf.rc_mode == VPX_CBR) || |
(cpi->svc.number_spatial_layers > 1 && cpi->pass == 2)) { |
vp9_update_layer_context_change_config(cpi, |
(int)cpi->oxcf.target_bandwidth); |
@@ -703,6 +683,17 @@ |
cpi->ext_refresh_frame_flags_pending = 0; |
cpi->ext_refresh_frame_context_pending = 0; |
+ |
+#if CONFIG_DENOISING |
+ vp9_denoiser_alloc(&(cpi->denoiser), cm->width, cm->height, |
+ // TODO(tkopp) An unrelated bug causes |
+ // cm->subsampling_{x,y} to be uninitialized at this point |
+ // in execution. For now we assume YUV-420, which is x/y |
+ // subsampling of 1. |
+ 1, 1, |
+ // cm->subsampling_x, cm->subsampling_y, |
+ VP9_ENC_BORDER_IN_PIXELS); |
+#endif |
} |
#ifndef M_LOG2_E |
@@ -878,6 +869,9 @@ |
cpi->mb.nmvsadcost_hp[1] = &cpi->mb.nmvsadcosts_hp[1][MV_MAX]; |
cal_nmvsadcosts_hp(cpi->mb.nmvsadcost_hp); |
+#ifdef OUTPUT_YUV_DENOISED |
+ yuv_denoised_file = fopen("denoised.yuv", "ab"); |
+#endif |
#ifdef OUTPUT_YUV_SRC |
yuv_file = fopen("bd.yuv", "ab"); |
#endif |
@@ -1108,6 +1102,10 @@ |
#endif |
} |
+#if CONFIG_DENOISING |
+ vp9_denoiser_free(&(cpi->denoiser)); |
+#endif |
+ |
dealloc_compressor_data(cpi); |
vpx_free(cpi->tok); |
@@ -1119,6 +1117,9 @@ |
vp9_remove_common(&cpi->common); |
vpx_free(cpi); |
+#ifdef OUTPUT_YUV_DENOISED |
+ fclose(yuv_denoised_file); |
+#endif |
#ifdef OUTPUT_YUV_SRC |
fclose(yuv_file); |
#endif |
@@ -1300,13 +1301,13 @@ |
} |
-#ifdef OUTPUT_YUV_SRC |
-void vp9_write_yuv_frame(YV12_BUFFER_CONFIG *s) { |
+#if defined(OUTPUT_YUV_SRC) || defined(OUTPUT_YUV_DENOISED) |
+void vp9_write_yuv_frame(YV12_BUFFER_CONFIG *s, FILE *f) { |
uint8_t *src = s->y_buffer; |
int h = s->y_height; |
do { |
- fwrite(src, s->y_width, 1, yuv_file); |
+ fwrite(src, s->y_width, 1, f); |
src += s->y_stride; |
} while (--h); |
@@ -1314,7 +1315,7 @@ |
h = s->uv_height; |
do { |
- fwrite(src, s->uv_width, 1, yuv_file); |
+ fwrite(src, s->uv_width, 1, f); |
src += s->uv_stride; |
} while (--h); |
@@ -1322,7 +1323,7 @@ |
h = s->uv_height; |
do { |
- fwrite(src, s->uv_width, 1, yuv_file); |
+ fwrite(src, s->uv_width, 1, f); |
src += s->uv_stride; |
} while (--h); |
} |
@@ -1414,6 +1415,7 @@ |
dst->alpha_buffer}; |
const int dst_strides[4] = {dst->y_stride, dst->uv_stride, dst->uv_stride, |
dst->alpha_stride}; |
+ const InterpKernel *const kernel = vp9_get_interp_kernel(EIGHTTAP); |
int x, y, i; |
for (y = 0; y < dst_h; y += 16) { |
@@ -1429,8 +1431,8 @@ |
uint8_t *dst_ptr = dsts[i] + (y / factor) * dst_stride + (x / factor); |
vp9_convolve8(src_ptr, src_stride, dst_ptr, dst_stride, |
- vp9_sub_pel_filters_8[x_q4 & 0xf], 16 * src_w / dst_w, |
- vp9_sub_pel_filters_8[y_q4 & 0xf], 16 * src_h / dst_h, |
+ kernel[x_q4 & 0xf], 16 * src_w / dst_w, |
+ kernel[y_q4 & 0xf], 16 * src_h / dst_h, |
16 / factor, 16 / factor); |
} |
} |
@@ -1441,21 +1443,6 @@ |
vp8_yv12_extend_frame_borders_c(dst); |
} |
-static int find_fp_qindex() { |
- int i; |
- |
- for (i = 0; i < QINDEX_RANGE; i++) { |
- if (vp9_convert_qindex_to_q(i) >= 30.0) { |
- break; |
- } |
- } |
- |
- if (i == QINDEX_RANGE) |
- i--; |
- |
- return i; |
-} |
- |
#define WRITE_RECON_BUFFER 0 |
#if WRITE_RECON_BUFFER |
void write_cx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame) { |
@@ -1515,7 +1502,7 @@ |
if ((rc->projected_frame_size > high_limit && q < maxq) || |
(rc->projected_frame_size < low_limit && q > minq)) { |
force_recode = 1; |
- } else if (cpi->oxcf.rc_mode == RC_MODE_CONSTRAINED_QUALITY) { |
+ } else if (cpi->oxcf.rc_mode == VPX_CQ) { |
// Deal with frame undershoot and whether or not we are |
// below the automatically set cq level. |
if (q > oxcf->cq_level && |
@@ -1584,6 +1571,14 @@ |
ref_cnt_fb(cm->frame_bufs, |
&cm->ref_frame_map[cpi->lst_fb_idx], cm->new_fb_idx); |
} |
+#if CONFIG_DENOISING |
+ vp9_denoiser_update_frame_info(&cpi->denoiser, |
+ *cpi->Source, |
+ cpi->common.frame_type, |
+ cpi->refresh_alt_ref_frame, |
+ cpi->refresh_golden_frame, |
+ cpi->refresh_last_frame); |
+#endif |
} |
static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) { |
@@ -1688,7 +1683,7 @@ |
(cpi->rc.projected_frame_size - cpi->rc.this_frame_target), |
cpi->rc.vbr_bits_off_target, |
cpi->rc.total_target_vs_actual, |
- (cpi->oxcf.starting_buffer_level - cpi->rc.bits_off_target), |
+ (cpi->rc.starting_buffer_level - cpi->rc.bits_off_target), |
cpi->rc.total_actual_bits, cm->base_qindex, |
vp9_convert_qindex_to_q(cm->base_qindex), |
(double)vp9_dc_quant(cm->base_qindex, 0) / 4.0, |
@@ -1810,7 +1805,7 @@ |
frame_over_shoot_limit = 1; |
} |
- if (cpi->oxcf.rc_mode == RC_MODE_CONSTANT_QUALITY) { |
+ if (cpi->oxcf.rc_mode == VPX_Q) { |
loop = 0; |
} else { |
if ((cm->frame_type == KEY_FRAME) && |
@@ -1908,7 +1903,7 @@ |
// This should only trigger where there is very substantial |
// undershoot on a frame and the auto cq level is above |
// the user passsed in value. |
- if (cpi->oxcf.rc_mode == RC_MODE_CONSTRAINED_QUALITY && |
+ if (cpi->oxcf.rc_mode == VPX_CQ && |
q < q_low) { |
q_low = q; |
} |
@@ -2049,7 +2044,7 @@ |
// Initialize cpi->mv_step_param to default based on max resolution. |
cpi->mv_step_param = vp9_init_search_range(sf, max_mv_def); |
// Initialize cpi->max_mv_magnitude and cpi->mv_step_param if appropriate. |
- if (sf->auto_mv_step_size) { |
+ if (sf->mv.auto_mv_step_size) { |
if (frame_is_intra_only(cm)) { |
// Initialize max_mv_magnitude for use in the first INTER frame |
// after a key/intra-only frame. |
@@ -2106,7 +2101,7 @@ |
// For 1 pass CBR, check if we are dropping this frame. |
// Never drop on key frame. |
if (cpi->pass == 0 && |
- cpi->oxcf.rc_mode == RC_MODE_CBR && |
+ cpi->oxcf.rc_mode == VPX_CBR && |
cm->frame_type != KEY_FRAME) { |
if (vp9_rc_drop_frame(cpi)) { |
vp9_rc_postencode_update_drop_frame(cpi); |
@@ -2117,8 +2112,6 @@ |
vp9_clear_system_state(); |
- vp9_zero(cpi->rd.tx_select_threshes); |
- |
#if CONFIG_VP9_POSTPROC |
if (cpi->oxcf.noise_sensitivity > 0) { |
int l = 0; |
@@ -2144,8 +2137,12 @@ |
} |
#endif |
+#ifdef OUTPUT_YUV_DENOISED |
+ vp9_write_yuv_frame(&cpi->denoiser.running_avg_y[INTRA_FRAME], |
+ yuv_denoised_file); |
+#endif |
#ifdef OUTPUT_YUV_SRC |
- vp9_write_yuv_frame(cpi->Source); |
+ vp9_write_yuv_frame(cpi->Source, yuv_file); |
#endif |
set_speed_features(cpi); |
@@ -2304,7 +2301,7 @@ |
static void Pass0Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, |
unsigned int *frame_flags) { |
- if (cpi->oxcf.rc_mode == RC_MODE_CBR) { |
+ if (cpi->oxcf.rc_mode == VPX_CBR) { |
vp9_rc_get_one_pass_cbr_params(cpi); |
} else { |
vp9_rc_get_one_pass_vbr_params(cpi); |
@@ -2312,17 +2309,6 @@ |
encode_frame_to_data_rate(cpi, size, dest, frame_flags); |
} |
-static void Pass1Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, |
- unsigned int *frame_flags) { |
- (void) size; |
- (void) dest; |
- (void) frame_flags; |
- |
- vp9_rc_get_first_pass_params(cpi); |
- vp9_set_quantizer(&cpi->common, find_fp_qindex()); |
- vp9_first_pass(cpi); |
-} |
- |
static void Pass2Encode(VP9_COMP *cpi, size_t *size, |
uint8_t *dest, unsigned int *frame_flags) { |
cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED; |
@@ -2464,7 +2450,7 @@ |
cpi->refresh_alt_ref_frame = 0; |
// Should we code an alternate reference frame. |
- if (cpi->oxcf.play_alternate && rc->source_alt_ref_pending) { |
+ if (is_altref_enabled(&cpi->oxcf) && rc->source_alt_ref_pending) { |
int frames_to_arf; |
#if CONFIG_MULTIPLE_ARF |
@@ -2595,7 +2581,7 @@ |
} |
if (cpi->svc.number_temporal_layers > 1 && |
- cpi->oxcf.rc_mode == RC_MODE_CBR) { |
+ cpi->oxcf.rc_mode == VPX_CBR) { |
vp9_update_temporal_layer_framerate(cpi); |
vp9_restore_layer_context(cpi); |
} |
@@ -2628,7 +2614,7 @@ |
if (cpi->pass == 2 && |
cm->current_video_frame == 0 && |
cpi->oxcf.allow_spatial_resampling && |
- cpi->oxcf.rc_mode == RC_MODE_VBR) { |
+ cpi->oxcf.rc_mode == VPX_VBR) { |
// Internal scaling is triggered on the first frame. |
vp9_set_size_literal(cpi, cpi->oxcf.scaled_frame_width, |
cpi->oxcf.scaled_frame_height); |
@@ -2662,7 +2648,10 @@ |
if (cpi->pass == 1 && |
(!cpi->use_svc || cpi->svc.number_temporal_layers == 1)) { |
- Pass1Encode(cpi, size, dest, frame_flags); |
+ const int lossless = is_lossless_requested(&cpi->oxcf); |
+ cpi->mb.fwd_txm4x4 = lossless ? vp9_fwht4x4 : vp9_fdct4x4; |
+ cpi->mb.itxm_add = lossless ? vp9_iwht4x4_add : vp9_idct4x4_add; |
+ vp9_first_pass(cpi); |
} else if (cpi->pass == 2 && |
(!cpi->use_svc || cpi->svc.number_temporal_layers == 1)) { |
Pass2Encode(cpi, size, dest, frame_flags); |
@@ -2687,7 +2676,7 @@ |
// Save layer specific state. |
if ((cpi->svc.number_temporal_layers > 1 && |
- cpi->oxcf.rc_mode == RC_MODE_CBR) || |
+ cpi->oxcf.rc_mode == VPX_CBR) || |
(cpi->svc.number_spatial_layers > 1 && cpi->pass == 2)) { |
vp9_save_layer_context(cpi); |
} |