ref: 2c04e85d06ea03d49e6b3c8823f33b08ff6396da
parent: 82dc1332af4b16d3e4ad3c4358498820637b7add
parent: aaabbd67b240e0dd581902b857fc040c94275190
author: Pengchong Jin <[email protected]>
date: Wed Jul 2 04:36:22 EDT 2014
Merge "Store/read 16x16 block statistics obtained from the first pass"
--- a/configure
+++ b/configure
@@ -274,6 +274,7 @@
multiple_arf
spatial_svc
denoising
+ fp_mb_stats
"
CONFIG_LIST="
external_build
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -199,6 +199,13 @@
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) {
@@ -765,6 +772,17 @@
vpx_calloc(cm->MBs *
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;
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -348,6 +348,10 @@
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;
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -106,6 +106,34 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
// 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) {
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -18,7 +18,19 @@
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;
double coded_error;
@@ -75,6 +87,10 @@
double modified_error_left;
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;