Commit aaabbd67 authored by Pengchong Jin's avatar Pengchong Jin

Store/read 16x16 block statistics obtained from the first pass

Add a conditional compile flag for this feature. Also add a
switch to enable the encoder to use these statistics in the
second pass. Currently, the switch is turned off.

Change-Id: Ia1c858c35ec90e36f19f5cffe156b97ddaa04922
parent 64742f82
......@@ -274,6 +274,7 @@ EXPERIMENT_LIST="
multiple_arf
spatial_svc
denoising
fp_mb_stats
"
CONFIG_LIST="
external_build
......
......@@ -199,6 +199,13 @@ static void dealloc_compressor_data(VP9_COMP *cpi) {
vpx_free(cpi->source_diff_var);
cpi->source_diff_var = NULL;
}
#if CONFIG_FP_MB_STATS
if (cpi->use_fp_mb_stats) {
vpx_free(cpi->twopass.this_frame_mb_stats.mb_stats);
cpi->twopass.this_frame_mb_stats.mb_stats = NULL;
}
#endif
}
static void save_coding_context(VP9_COMP *cpi) {
......@@ -766,6 +773,17 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) {
sizeof(*cpi->mbgraph_stats[i].mb_stats), 1));
}
#if CONFIG_FP_MB_STATS
cpi->use_fp_mb_stats = 0;
if (cpi->use_fp_mb_stats) {
// a place holder for the mb stats obtained from the first pass
CHECK_MEM_ERROR(cm, cpi->twopass.this_frame_mb_stats.mb_stats,
vpx_calloc(cm->MBs * sizeof(FIRSTPASS_MB_STATS), 1));
} else {
cpi->twopass.this_frame_mb_stats.mb_stats = NULL;
}
#endif
cpi->refresh_alt_ref_frame = 0;
// Note that at the moment multi_arf will not work with svc.
......
......@@ -348,6 +348,10 @@ typedef struct VP9_COMP {
uint64_t time_pick_lpf;
uint64_t time_encode_sb_row;
#if CONFIG_FP_MB_STATS
int use_fp_mb_stats;
#endif
TWO_PASS twopass;
YV12_BUFFER_CONFIG alt_ref_buffer;
......
......@@ -106,6 +106,34 @@ static int read_frame_stats(const TWO_PASS *p,
return 1;
}
#if CONFIG_FP_MB_STATS
static int input_mb_stats(FIRSTPASS_FRAME_MB_STATS *fp_frame_stats,
const VP9_COMMON *const cm) {
FILE *fpfile;
int ret;
fpfile = fopen("firstpass_mb.stt", "r");
fseek(fpfile, cm->current_video_frame * cm->MBs * sizeof(FIRSTPASS_MB_STATS),
SEEK_SET);
ret = fread(fp_frame_stats->mb_stats, sizeof(FIRSTPASS_MB_STATS), cm->MBs,
fpfile);
fclose(fpfile);
if (ret < cm->MBs) {
return EOF;
}
return 1;
}
static void output_mb_stats(FIRSTPASS_FRAME_MB_STATS *fp_frame_stats,
const VP9_COMMON *const cm) {
FILE *fpfile;
fpfile = fopen("firstpass_mb.stt", "a");
fwrite(fp_frame_stats->mb_stats, sizeof(FIRSTPASS_MB_STATS), cm->MBs, fpfile);
fclose(fpfile);
}
#endif
static int input_stats(TWO_PASS *p, FIRSTPASS_STATS *fps) {
if (p->stats_in >= p->stats_in_end)
return EOF;
......@@ -452,6 +480,10 @@ void vp9_first_pass(VP9_COMP *cpi) {
const MV zero_mv = {0, 0};
const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
#if CONFIG_FP_MB_STATS
FIRSTPASS_FRAME_MB_STATS *this_frame_mb_stats = &twopass->this_frame_mb_stats;
#endif
vp9_clear_system_state();
set_first_pass_params(cpi);
......@@ -579,6 +611,17 @@ void vp9_first_pass(VP9_COMP *cpi) {
// Accumulate the intra error.
intra_error += (int64_t)this_error;
#if CONFIG_FP_MB_STATS
if (cpi->use_fp_mb_stats) {
this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mode =
DC_PRED;
this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].err =
this_error;
this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mv.as_int
= 0;
}
#endif
// Set up limit values for motion vectors to prevent them extending
// outside the UMV borders.
x->mv_col_min = -((mb_col * 16) + BORDER_MV_PIXELS_B16);
......@@ -704,6 +747,17 @@ void vp9_first_pass(VP9_COMP *cpi) {
best_ref_mv.as_int = mv.as_int;
#if CONFIG_FP_MB_STATS
if (cpi->use_fp_mb_stats) {
this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mode =
NEWMV;
this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].err =
motion_error;
this_frame_mb_stats->mb_stats[mb_row * cm->mb_cols + mb_col].mv.
as_int = mv.as_int;
}
#endif
if (mv.as_int) {
++mvcount;
......@@ -808,6 +862,12 @@ void vp9_first_pass(VP9_COMP *cpi) {
twopass->this_frame_stats = fps;
output_stats(&twopass->this_frame_stats, cpi->output_pkt_list);
accumulate_stats(&twopass->total_stats, &fps);
#if CONFIG_FP_MB_STATS
if (cpi->use_fp_mb_stats) {
output_mb_stats(this_frame_mb_stats, cm);
}
#endif
}
// Copy the previous Last Frame back into gf and and arf buffers if
......@@ -2167,6 +2227,12 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
// Update the total stats remaining structure.
subtract_stats(&twopass->total_left_stats, &this_frame);
#if CONFIG_FP_MB_STATS
if (cpi->use_fp_mb_stats) {
input_mb_stats(&twopass->this_frame_mb_stats, cm);
}
#endif
}
void vp9_twopass_postencode_update(VP9_COMP *cpi) {
......
......@@ -18,6 +18,18 @@
extern "C" {
#endif
#if CONFIG_FP_MB_STATS
typedef struct {
PREDICTION_MODE mode;
int err;
int_mv mv;
} FIRSTPASS_MB_STATS;
typedef struct {
FIRSTPASS_MB_STATS *mb_stats;
} FIRSTPASS_FRAME_MB_STATS;
#endif
typedef struct {
double frame;
double intra_error;
......@@ -76,6 +88,10 @@ typedef struct {
double kf_intra_err_min;
double gf_intra_err_min;
#if CONFIG_FP_MB_STATS
FIRSTPASS_FRAME_MB_STATS this_frame_mb_stats;
#endif
// Projected total bits available for a key frame group of frames
int64_t kf_group_bits;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment