summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorPengchong Jin <pengchong@google.com>2014-06-30 09:52:27 -0700
committerPengchong Jin <pengchong@google.com>2014-07-01 16:47:17 -0700
commitaaabbd67b240e0dd581902b857fc040c94275190 (patch)
tree847215065929589e8715f462513cf7a6d11b6745 /vp9/encoder
parent64742f825d1e17a33ed412001414848789258e03 (diff)
downloadlibvpx-aaabbd67b240e0dd581902b857fc040c94275190.tar
libvpx-aaabbd67b240e0dd581902b857fc040c94275190.tar.gz
libvpx-aaabbd67b240e0dd581902b857fc040c94275190.tar.bz2
libvpx-aaabbd67b240e0dd581902b857fc040c94275190.zip
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
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_encoder.c18
-rw-r--r--vp9/encoder/vp9_encoder.h4
-rw-r--r--vp9/encoder/vp9_firstpass.c66
-rw-r--r--vp9/encoder/vp9_firstpass.h16
4 files changed, 104 insertions, 0 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 54fb68bb6..4f17a15a9 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -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.
diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h
index 5e8430a91..b38f9c246 100644
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -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;
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 971b15931..f90c9df5e 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -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) {
diff --git a/vp9/encoder/vp9_firstpass.h b/vp9/encoder/vp9_firstpass.h
index 1ee56a3a7..7e4c9ee20 100644
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -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;