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
4797 }4797 }
4798 }4798 }
4799 } else {4799 } else {
4800 FRAME_COUNTS *counts = cpi->td.counts;
4800 cm->reference_mode = SINGLE_REFERENCE;4801 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
4801 encode_frame_internal(cpi);4807 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 }
4802 }4825 }
4803 4826
4804 // If segmented AQ is enabled compute the average AQ weighting.4827 // 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
1190 int const_motion[MAX_REF_FRAMES], int *ref_frame_skip_mask,1190 int const_motion[MAX_REF_FRAMES], int *ref_frame_skip_mask,
1191 const int flag_list[4], TileDataEnc *tile_data, int mi_row, int mi_col,1191 const int flag_list[4], TileDataEnc *tile_data, int mi_row, int mi_col,
1192 struct buf_2d yv12_mb[4][MAX_MB_PLANE], BLOCK_SIZE bsize,1192 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) {
1194 VP9_COMMON *const cm = &cpi->common;1194 VP9_COMMON *const cm = &cpi->common;
1195 MACROBLOCKD *const xd = &x->e_mbd;1195 MACROBLOCKD *const xd = &x->e_mbd;
1196 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);1196 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
@@ -1204,7 +1204,7 @@ static INLINE void find_predictors( · 7 unmodified lines
1204 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];1204 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
1205 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;1205 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
1206 vp9_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);1206 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) {
1208 vp9_find_mv_refs(cm, xd, xd->mi[0], ref_frame, candidates, mi_row, mi_col,1208 vp9_find_mv_refs(cm, xd, xd->mi[0], ref_frame, candidates, mi_row, mi_col,
1209 x->mbmi_ext->mode_context);1209 x->mbmi_ext->mode_context);
1210 } else {1210 } else {
@@ -1426,7 +1426,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 215 unmodified lines
1426 struct macroblockd_plane *const pd = &xd->plane[0];1426 struct macroblockd_plane *const pd = &xd->plane[0];
1427 PREDICTION_MODE best_mode = ZEROMV;1427 PREDICTION_MODE best_mode = ZEROMV;
1428 MV_REFERENCE_FRAME ref_frame, best_ref_frame = LAST_FRAME;1428 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;
1430 TX_SIZE best_tx_size = TX_SIZES;1430 TX_SIZE best_tx_size = TX_SIZES;
1431 INTERP_FILTER best_pred_filter = EIGHTTAP;1431 INTERP_FILTER best_pred_filter = EIGHTTAP;
1432 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];1432 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
1494 int denoise_svc_pickmode = 1;1494 int denoise_svc_pickmode = 1;
1495#endif1495#endif
1496 INTERP_FILTER filter_gf_svc = EIGHTTAP;1496 INTERP_FILTER filter_gf_svc = EIGHTTAP;
1497 MV_REFERENCE_FRAME best_second_ref_frame = NONE;
1498 int comp_modes = 0;
1497 1499
1498 init_ref_frame_cost(cm, xd, ref_frame_cost);1500 init_ref_frame_cost(cm, xd, ref_frame_cost);
1499 1501
@@ -1626,18 +1628,24 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 126 unmodified lines
1626 x->last_sb_high_content > 40 || cpi->rc.frames_since_golden > 120))1628 x->last_sb_high_content > 40 || cpi->rc.frames_since_golden > 120))
1627 usable_ref_frame = LAST_FRAME;1629 usable_ref_frame = LAST_FRAME;
1628 1630
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
1629 for (ref_frame = LAST_FRAME; ref_frame <= usable_ref_frame; ++ref_frame) {1636 for (ref_frame = LAST_FRAME; ref_frame <= usable_ref_frame; ++ref_frame) {
1630 if (!skip_ref_find_pred[ref_frame]) {1637 if (!skip_ref_find_pred[ref_frame]) {
1631 find_predictors(cpi, x, ref_frame, frame_mv, const_motion,1638 find_predictors(cpi, x, ref_frame, frame_mv, const_motion,
1632 &ref_frame_skip_mask, flag_list, tile_data, mi_row,1639 &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);
1634 }1642 }
1635 }1643 }
1636 1644
1637 if (cpi->use_svc || cpi->oxcf.speed <= 7 || bsize < BLOCK_32X32)1645 if (cpi->use_svc || cpi->oxcf.speed <= 7 || bsize < BLOCK_32X32)
1638 x->sb_use_mv_part = 0;1646 x->sb_use_mv_part = 0;
1639 1647
1640 for (idx = 0; idx < RT_INTER_MODES; ++idx) {1648 for (idx = 0; idx < RT_INTER_MODES + comp_modes; ++idx) {
1641 int rate_mv = 0;1649 int rate_mv = 0;
1642 int mode_rd_thresh;1650 int mode_rd_thresh;
1643 int mode_index;1651 int mode_index;
@@ -1648,15 +1656,37 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 4 unmodified lines
1648 int rd_computed = 0;1656 int rd_computed = 0;
1649 int inter_mv_mode = 0;1657 int inter_mv_mode = 0;
1650 int skip_this_mv = 0;1658 int skip_this_mv = 0;
1659 int comp_pred = 0;
1660 PREDICTION_MODE this_mode;
1661 second_ref_frame = NONE;
1651 1662
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;
1653 1666
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 }
1655 1679
1656 if (cpi->use_svc) {1680 if (comp_pred) {
1657 this_mode = ref_mode_set_svc[idx].pred_mode;1681 const struct segmentation *const seg = &cm->seg;
1658 ref_frame = ref_mode_set_svc[idx].ref_frame;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;
1659 }1688 }
1689
1660 if (ref_frame > usable_ref_frame) continue;1690 if (ref_frame > usable_ref_frame) continue;
1661 if (skip_ref_find_pred[ref_frame]) continue;1691 if (skip_ref_find_pred[ref_frame]) continue;
1662 1692
@@ -1748,11 +1778,14 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 85 unmodified lines
1748 if (ref_frame_skip_mask & (1 << ref_frame)) continue;1778 if (ref_frame_skip_mask & (1 << ref_frame)) continue;
1749 1779
1750 // Select prediction reference frames.1780 // Select prediction reference frames.
1751 for (i = 0; i < MAX_MB_PLANE; i++)1781 for (i = 0; i < MAX_MB_PLANE; i++) {
1752 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];1782 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 }
1753 1785
1754 mi->ref_frame[0] = ref_frame;1786 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);
1756 1789
1757 mode_index = mode_idx[ref_frame][INTER_OFFSET(this_mode)];1790 mode_index = mode_idx[ref_frame][INTER_OFFSET(this_mode)];
1758 mode_rd_thresh = best_mode_skip_txfm ? rd_threshes[mode_index] << 11791 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
1862 // causes some regression, leave it for duplicate zero-mv for now, until1895 // causes some regression, leave it for duplicate zero-mv for now, until
1863 // regression issue is resolved.1896 // regression issue is resolved.
1864 for (inter_mv_mode = NEARESTMV; inter_mv_mode <= NEWMV; inter_mv_mode++) {1897 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;
1866 if (mode_checked[inter_mv_mode][ref_frame] &&1899 if (mode_checked[inter_mv_mode][ref_frame] &&
1867 frame_mv[this_mode][ref_frame].as_int ==1900 frame_mv[this_mode][ref_frame].as_int ==
1868 frame_mv[inter_mv_mode][ref_frame].as_int &&1901 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
1888 x->pred_mv_sad[LAST_FRAME] = best_pred_sad;1921 x->pred_mv_sad[LAST_FRAME] = best_pred_sad;
1889 }1922 }
1890 1923
1891 if (this_mode != NEARESTMV &&1924 if (this_mode != NEARESTMV && !comp_pred &&
1892 frame_mv[this_mode][ref_frame].as_int ==1925 frame_mv[this_mode][ref_frame].as_int ==
1893 frame_mv[NEARESTMV][ref_frame].as_int)1926 frame_mv[NEARESTMV][ref_frame].as_int)
1894 continue;1927 continue;
1895 1928
1896 mi->mode = this_mode;1929 mi->mode = this_mode;
1897 mi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;1930 mi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
1931 mi->mv[1].as_int = 0;
1898 1932
1899 // Search for the best prediction filter type, when the resulting1933 // Search for the best prediction filter type, when the resulting
1900 // motion vector is at sub-pixel accuracy level for luma component, i.e.,1934 // 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
2050 this_rdc.rate += rate_mv;2084 this_rdc.rate += rate_mv;
2051 this_rdc.rate += cpi->inter_mode_cost[x->mbmi_ext->mode_context[ref_frame]]2085 this_rdc.rate += cpi->inter_mode_cost[x->mbmi_ext->mode_context[ref_frame]]
2052 [INTER_OFFSET(this_mode)];2086 [INTER_OFFSET(this_mode)];
2087 // TODO(marpan): Add costing for compound mode.
2053 this_rdc.rate += ref_frame_cost[ref_frame];2088 this_rdc.rate += ref_frame_cost[ref_frame];
2054 this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);2089 this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
2055 2090
@@ -2099,6 +2134,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 43 unmodified lines
2099 best_ref_frame = ref_frame;2134 best_ref_frame = ref_frame;
2100 best_mode_skip_txfm = x->skip_txfm[0];2135 best_mode_skip_txfm = x->skip_txfm[0];
2101 best_early_term = this_early_term;2136 best_early_term = this_early_term;
2137 best_second_ref_frame = second_ref_frame;
2102 2138
2103 if (reuse_inter_pred) {2139 if (reuse_inter_pred) {
2104 free_pred_buffer(best_pred);2140 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
2125 mi->mv[0].as_int = frame_mv[best_mode][best_ref_frame].as_int;2161 mi->mv[0].as_int = frame_mv[best_mode][best_ref_frame].as_int;
2126 xd->mi[0]->bmi[0].as_mv[0].as_int = mi->mv[0].as_int;2162 xd->mi[0]->bmi[0].as_mv[0].as_int = mi->mv[0].as_int;
2127 x->skip_txfm[0] = best_mode_skip_txfm;2163 x->skip_txfm[0] = best_mode_skip_txfm;
2164 mi->ref_frame[1] = best_second_ref_frame;
2128 2165
2129 // For spatial enhancemanent layer: perform intra prediction only if base2166 // For spatial enhancemanent layer: perform intra prediction only if base
2130 // layer is chosen as the reference. Always perform intra prediction if2167 // 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
2238 best_mode = this_mode;2275 best_mode = this_mode;
2239 best_intra_tx_size = mi->tx_size;2276 best_intra_tx_size = mi->tx_size;
2240 best_ref_frame = INTRA_FRAME;2277 best_ref_frame = INTRA_FRAME;
2278 best_second_ref_frame = NONE;
2241 mi->uv_mode = this_mode;2279 mi->uv_mode = this_mode;
2242 mi->mv[0].as_int = INVALID_MV;2280 mi->mv[0].as_int = INVALID_MV;
2281 mi->mv[1].as_int = INVALID_MV;
2243 best_mode_skip_txfm = x->skip_txfm[0];2282 best_mode_skip_txfm = x->skip_txfm[0];
2244 }2283 }
2245 }2284 }
@@ -2255,6 +2294,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 9 unmodified lines
2255 pd->dst = orig_dst;2294 pd->dst = orig_dst;
2256 mi->mode = best_mode;2295 mi->mode = best_mode;
2257 mi->ref_frame[0] = best_ref_frame;2296 mi->ref_frame[0] = best_ref_frame;
2297 mi->ref_frame[1] = best_second_ref_frame;
2258 x->skip_txfm[0] = best_mode_skip_txfm;2298 x->skip_txfm[0] = best_mode_skip_txfm;
2259 2299
2260 if (!is_inter_block(mi)) {2300 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
2300 }2340 }
2301#endif2341#endif
2302 2342
2303 if (best_ref_frame == ALTREF_FRAME)2343 if (best_ref_frame == ALTREF_FRAME || best_second_ref_frame == ALTREF_FRAME)
2304 x->arf_frame_usage++;2344 x->arf_frame_usage++;
2305 else if (best_ref_frame != INTRA_FRAME)2345 else if (best_ref_frame != INTRA_FRAME)
2306 x->lastgolden_frame_usage++;2346 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
370 sf->use_simple_block_yrd = 0;370 sf->use_simple_block_yrd = 0;
371 sf->adapt_partition_source_sad = 0;371 sf->adapt_partition_source_sad = 0;
372 sf->use_altref_onepass = 0;372 sf->use_altref_onepass = 0;
373 sf->use_compound_nonrd_pickmode = 0;
373 sf->nonrd_keyframe = 0;374 sf->nonrd_keyframe = 0;
374 375
375 if (speed >= 1) {376 if (speed >= 1) {
@@ -531,8 +532,10 @@ static void set_rt_speed_feature_framesize_independent( · 155 unmodified lines
531 }532 }
532 533
533 if (speed >= 6) {534 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) {
535 sf->use_altref_onepass = 1;536 sf->use_altref_onepass = 1;
537 sf->use_compound_nonrd_pickmode = 1;
538 }
536 sf->partition_search_type = VAR_BASED_PARTITION;539 sf->partition_search_type = VAR_BASED_PARTITION;
537 // Turn on this to use non-RD key frame coding mode.540 // Turn on this to use non-RD key frame coding mode.
538 sf->use_nonrd_pick_mode = 1;541 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
500 // Enable use of alt-refs in 1 pass VBR.500 // Enable use of alt-refs in 1 pass VBR.
501 int use_altref_onepass;501 int use_altref_onepass;
502 502
503 // Enable use of compound prediction, for nonrd_pickmode with nonzero lag.
504 int use_compound_nonrd_pickmode;
505
503 // Always use nonrd_pick_intra for all block sizes on keyframes.506 // Always use nonrd_pick_intra for all block sizes on keyframes.
504 int nonrd_keyframe;507 int nonrd_keyframe;
505} SPEED_FEATURES;508} 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