History

Compound prediction mode for nonrd pickmode.

Allow for compound prediction mode in nonrd_pickmode for ZEROMV. For real-time encoding, 1 pass with non-zero lag-in-frames. Added speed feature to control the feature. Enabled for speed >=6 for now, under VBR mode. avgPSNR/SSIM metrics positive on ytlive set, for speed 6: some clips up by ~3-5%, some clips neutral gain, average gain across clips is ~1%. Small/negligible decrease in speed.

Marco committed 9 years ago

Commit eb7d4311 parent 3ba9a2c4 files · +85 −16Browse files

Unified · Split

4 files
  1. vp9/encoder/vp9_encodeframe.c +23 −0
  2. vp9/encoder/vp9_pickmode.c +55 −15
  3. vp9/encoder/vp9_speed_features.c +4 −1
  4. vp9/encoder/vp9_speed_features.h +3 −0
vp9/encoder/vp9_encodeframe.c+23−0
@@ -4797,8 +4797,31 @@ void vp9_encode_frame(VP9_COMP *cpi) { · 4796 unmodified lines
47974797 }
47984798 }
47994799 } else {
4800+ FRAME_COUNTS *counts = cpi->td.counts;
48004801 cm->reference_mode = SINGLE_REFERENCE;
4802+ if (cpi->allow_comp_inter_inter && cpi->sf.use_compound_nonrd_pickmode &&
4803+ cpi->rc.alt_ref_gf_group && !cpi->rc.is_src_frame_alt_ref &&
4804+ cm->frame_type != KEY_FRAME)
4805+ cm->reference_mode = REFERENCE_MODE_SELECT;
4806+
48014807 encode_frame_internal(cpi);
4808+
4809+ if (cm->reference_mode == REFERENCE_MODE_SELECT) {
4810+ int single_count_zero = 0;
4811+ int comp_count_zero = 0;
4812+ int i;
4813+ for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
4814+ single_count_zero += counts->comp_inter[i][0];
4815+ comp_count_zero += counts->comp_inter[i][1];
4816+ }
4817+ if (comp_count_zero == 0) {
4818+ cm->reference_mode = SINGLE_REFERENCE;
4819+ vp9_zero(counts->comp_inter);
4820+ } else if (single_count_zero == 0) {
4821+ cm->reference_mode = COMPOUND_REFERENCE;
4822+ vp9_zero(counts->comp_inter);
4823+ }
4824+ }
48024825 }
48034826
48044827 // If segmented AQ is enabled compute the average AQ weighting.
vp9/encoder/vp9_pickmode.c+55−15
@@ -1190,7 +1190,7 @@ static INLINE void find_predictors( · 1189 unmodified lines
11901190 int const_motion[MAX_REF_FRAMES], int *ref_frame_skip_mask,
11911191 const int flag_list[4], TileDataEnc *tile_data, int mi_row, int mi_col,
11921192 struct buf_2d yv12_mb[4][MAX_MB_PLANE], BLOCK_SIZE bsize,
1193− int force_skip_low_temp_var) {
1193+ int force_skip_low_temp_var, int comp_pred_allowed) {
11941194 VP9_COMMON *const cm = &cpi->common;
11951195 MACROBLOCKD *const xd = &x->e_mbd;
11961196 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
@@ -1204,7 +1204,7 @@ static INLINE void find_predictors( · 7 unmodified lines
12041204 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
12051205 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
12061206 vp9_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
1207− if (cm->use_prev_frame_mvs) {
1207+ if (cm->use_prev_frame_mvs || comp_pred_allowed) {
12081208 vp9_find_mv_refs(cm, xd, xd->mi[0], ref_frame, candidates, mi_row, mi_col,
12091209 x->mbmi_ext->mode_context);
12101210 } else {
@@ -1426,7 +1426,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 215 unmodified lines
14261426 struct macroblockd_plane *const pd = &xd->plane[0];
14271427 PREDICTION_MODE best_mode = ZEROMV;
14281428 MV_REFERENCE_FRAME ref_frame, best_ref_frame = LAST_FRAME;
1429− MV_REFERENCE_FRAME usable_ref_frame;
1429+ MV_REFERENCE_FRAME usable_ref_frame, second_ref_frame;
14301430 TX_SIZE best_tx_size = TX_SIZES;
14311431 INTERP_FILTER best_pred_filter = EIGHTTAP;
14321432 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
@@ -1494,6 +1494,8 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 61 unmodified lines
14941494 int denoise_svc_pickmode = 1;
14951495 #endif
14961496 INTERP_FILTER filter_gf_svc = EIGHTTAP;
1497+ MV_REFERENCE_FRAME best_second_ref_frame = NONE;
1498+ int comp_modes = 0;
14971499
14981500 init_ref_frame_cost(cm, xd, ref_frame_cost);
14991501
@@ -1626,18 +1628,24 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 126 unmodified lines
16261628 x->last_sb_high_content > 40 || cpi->rc.frames_since_golden > 120))
16271629 usable_ref_frame = LAST_FRAME;
16281630
1631+ // Compound prediction modes: (0,0) on LAST/GOLDEN and ARF.
1632+ if (cm->reference_mode == REFERENCE_MODE_SELECT &&
1633+ cpi->sf.use_compound_nonrd_pickmode && usable_ref_frame == ALTREF_FRAME)
1634+ comp_modes = 2;
1635+
16291636 for (ref_frame = LAST_FRAME; ref_frame <= usable_ref_frame; ++ref_frame) {
16301637 if (!skip_ref_find_pred[ref_frame]) {
16311638 find_predictors(cpi, x, ref_frame, frame_mv, const_motion,
16321639 &ref_frame_skip_mask, flag_list, tile_data, mi_row,
1633− mi_col, yv12_mb, bsize, force_skip_low_temp_var);
1640+ mi_col, yv12_mb, bsize, force_skip_low_temp_var,
1641+ comp_modes > 0);
16341642 }
16351643 }
16361644
16371645 if (cpi->use_svc || cpi->oxcf.speed <= 7 || bsize < BLOCK_32X32)
16381646 x->sb_use_mv_part = 0;
16391647
1640− for (idx = 0; idx < RT_INTER_MODES; ++idx) {
1648+ for (idx = 0; idx < RT_INTER_MODES + comp_modes; ++idx) {
16411649 int rate_mv = 0;
16421650 int mode_rd_thresh;
16431651 int mode_index;
@@ -1648,15 +1656,37 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 4 unmodified lines
16481656 int rd_computed = 0;
16491657 int inter_mv_mode = 0;
16501658 int skip_this_mv = 0;
1659+ int comp_pred = 0;
1660+ PREDICTION_MODE this_mode;
1661+ second_ref_frame = NONE;
16511662
1652− PREDICTION_MODE this_mode = ref_mode_set[idx].pred_mode;
1663+ if (idx < RT_INTER_MODES) {
1664+ this_mode = ref_mode_set[idx].pred_mode;
1665+ ref_frame = ref_mode_set[idx].ref_frame;
16531666
1654− ref_frame = ref_mode_set[idx].ref_frame;
1667+ if (cpi->use_svc) {
1668+ this_mode = ref_mode_set_svc[idx].pred_mode;
1669+ ref_frame = ref_mode_set_svc[idx].ref_frame;
1670+ }
1671+ } else {
1672+ // Add (0,0) compound modes.
1673+ this_mode = ZEROMV;
1674+ ref_frame = LAST_FRAME;
1675+ if (idx == RT_INTER_MODES + comp_modes - 1) ref_frame = GOLDEN_FRAME;
1676+ second_ref_frame = ALTREF_FRAME;
1677+ comp_pred = 1;
1678+ }
16551679
1656− if (cpi->use_svc) {
1657− this_mode = ref_mode_set_svc[idx].pred_mode;
1658− ref_frame = ref_mode_set_svc[idx].ref_frame;
1680+ if (comp_pred) {
1681+ const struct segmentation *const seg = &cm->seg;
1682+ if (!cpi->allow_comp_inter_inter) continue;
1683+ // Skip compound inter modes if ARF is not available.
1684+ if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
1685+ // Do not allow compound prediction if the segment level reference frame
1686+ // feature is in use as in this case there can only be one reference.
1687+ if (segfeature_active(seg, mi->segment_id, SEG_LVL_REF_FRAME)) continue;
16591688 }
1689+
16601690 if (ref_frame > usable_ref_frame) continue;
16611691 if (skip_ref_find_pred[ref_frame]) continue;
16621692
@@ -1748,11 +1778,14 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 85 unmodified lines
17481778 if (ref_frame_skip_mask & (1 << ref_frame)) continue;
17491779
17501780 // Select prediction reference frames.
1751− for (i = 0; i < MAX_MB_PLANE; i++)
1781+ for (i = 0; i < MAX_MB_PLANE; i++) {
17521782 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
1783+ if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
1784+ }
17531785
17541786 mi->ref_frame[0] = ref_frame;
1755− set_ref_ptrs(cm, xd, ref_frame, NONE);
1787+ mi->ref_frame[1] = second_ref_frame;
1788+ set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
17561789
17571790 mode_index = mode_idx[ref_frame][INTER_OFFSET(this_mode)];
17581791 mode_rd_thresh = best_mode_skip_txfm ? rd_threshes[mode_index] << 1
@@ -1862,7 +1895,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 103 unmodified lines
18621895 // causes some regression, leave it for duplicate zero-mv for now, until
18631896 // regression issue is resolved.
18641897 for (inter_mv_mode = NEARESTMV; inter_mv_mode <= NEWMV; inter_mv_mode++) {
1865− if (inter_mv_mode == this_mode) continue;
1898+ if (inter_mv_mode == this_mode || comp_pred) continue;
18661899 if (mode_checked[inter_mv_mode][ref_frame] &&
18671900 frame_mv[this_mode][ref_frame].as_int ==
18681901 frame_mv[inter_mv_mode][ref_frame].as_int &&
@@ -1888,13 +1921,14 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 19 unmodified lines
18881921 x->pred_mv_sad[LAST_FRAME] = best_pred_sad;
18891922 }
18901923
1891− if (this_mode != NEARESTMV &&
1924+ if (this_mode != NEARESTMV && !comp_pred &&
18921925 frame_mv[this_mode][ref_frame].as_int ==
18931926 frame_mv[NEARESTMV][ref_frame].as_int)
18941927 continue;
18951928
18961929 mi->mode = this_mode;
18971930 mi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
1931+ mi->mv[1].as_int = 0;
18981932
18991933 // Search for the best prediction filter type, when the resulting
19001934 // motion vector is at sub-pixel accuracy level for luma component, i.e.,
@@ -2050,6 +2084,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 149 unmodified lines
20502084 this_rdc.rate += rate_mv;
20512085 this_rdc.rate += cpi->inter_mode_cost[x->mbmi_ext->mode_context[ref_frame]]
20522086 [INTER_OFFSET(this_mode)];
2087+ // TODO(marpan): Add costing for compound mode.
20532088 this_rdc.rate += ref_frame_cost[ref_frame];
20542089 this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
20552090
@@ -2099,6 +2134,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 43 unmodified lines
20992134 best_ref_frame = ref_frame;
21002135 best_mode_skip_txfm = x->skip_txfm[0];
21012136 best_early_term = this_early_term;
2137+ best_second_ref_frame = second_ref_frame;
21022138
21032139 if (reuse_inter_pred) {
21042140 free_pred_buffer(best_pred);
@@ -2125,6 +2161,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 20 unmodified lines
21252161 mi->mv[0].as_int = frame_mv[best_mode][best_ref_frame].as_int;
21262162 xd->mi[0]->bmi[0].as_mv[0].as_int = mi->mv[0].as_int;
21272163 x->skip_txfm[0] = best_mode_skip_txfm;
2164+ mi->ref_frame[1] = best_second_ref_frame;
21282165
21292166 // For spatial enhancemanent layer: perform intra prediction only if base
21302167 // layer is chosen as the reference. Always perform intra prediction if
@@ -2238,8 +2275,10 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 107 unmodified lines
22382275 best_mode = this_mode;
22392276 best_intra_tx_size = mi->tx_size;
22402277 best_ref_frame = INTRA_FRAME;
2278+ best_second_ref_frame = NONE;
22412279 mi->uv_mode = this_mode;
22422280 mi->mv[0].as_int = INVALID_MV;
2281+ mi->mv[1].as_int = INVALID_MV;
22432282 best_mode_skip_txfm = x->skip_txfm[0];
22442283 }
22452284 }
@@ -2255,6 +2294,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 9 unmodified lines
22552294 pd->dst = orig_dst;
22562295 mi->mode = best_mode;
22572296 mi->ref_frame[0] = best_ref_frame;
2297+ mi->ref_frame[1] = best_second_ref_frame;
22582298 x->skip_txfm[0] = best_mode_skip_txfm;
22592299
22602300 if (!is_inter_block(mi)) {
@@ -2300,7 +2340,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 39 unmodified lines
23002340 }
23012341 #endif
23022342
2303− if (best_ref_frame == ALTREF_FRAME)
2343+ if (best_ref_frame == ALTREF_FRAME || best_second_ref_frame == ALTREF_FRAME)
23042344 x->arf_frame_usage++;
23052345 else if (best_ref_frame != INTRA_FRAME)
23062346 x->lastgolden_frame_usage++;
vp9/encoder/vp9_speed_features.c+4−1
@@ -370,6 +370,7 @@ static void set_rt_speed_feature_framesize_independent( · 369 unmodified lines
370370 sf->use_simple_block_yrd = 0;
371371 sf->adapt_partition_source_sad = 0;
372372 sf->use_altref_onepass = 0;
373+ sf->use_compound_nonrd_pickmode = 0;
373374 sf->nonrd_keyframe = 0;
374375
375376 if (speed >= 1) {
@@ -531,8 +532,10 @@ static void set_rt_speed_feature_framesize_independent( · 155 unmodified lines
531532 }
532533
533534 if (speed >= 6) {
534− if (cpi->oxcf.rc_mode == VPX_VBR && cpi->oxcf.lag_in_frames > 0)
535+ if (cpi->oxcf.rc_mode == VPX_VBR && cpi->oxcf.lag_in_frames > 0) {
535536 sf->use_altref_onepass = 1;
537+ sf->use_compound_nonrd_pickmode = 1;
538+ }
536539 sf->partition_search_type = VAR_BASED_PARTITION;
537540 // Turn on this to use non-RD key frame coding mode.
538541 sf->use_nonrd_pick_mode = 1;
vp9/encoder/vp9_speed_features.h+3−0
@@ -500,6 +500,9 @@ typedef struct SPEED_FEATURES { · 499 unmodified lines
500500 // Enable use of alt-refs in 1 pass VBR.
501501 int use_altref_onepass;
502502
503+ // Enable use of compound prediction, for nonrd_pickmode with nonzero lag.
504+ int use_compound_nonrd_pickmode;
505+
503506 // Always use nonrd_pick_intra for all block sizes on keyframes.
504507 int nonrd_keyframe;
505508 } SPEED_FEATURES;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t