| @@ -1190,7 +1190,7 @@ static INLINE void find_predictors( · 1189 unmodified lines |
| 1190 | 1190 | int const_motion[MAX_REF_FRAMES], int *ref_frame_skip_mask, |
| 1191 | 1191 | const int flag_list[4], TileDataEnc *tile_data, int mi_row, int mi_col, |
| 1192 | 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 | 1194 | VP9_COMMON *const cm = &cpi->common; |
| 1195 | 1195 | MACROBLOCKD *const xd = &x->e_mbd; |
| 1196 | 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 | 1204 | int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame]; |
| 1205 | 1205 | const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf; |
| 1206 | 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 | 1208 | vp9_find_mv_refs(cm, xd, xd->mi[0], ref_frame, candidates, mi_row, mi_col, |
| 1209 | 1209 | x->mbmi_ext->mode_context); |
| 1210 | 1210 | } else { |
| @@ -1426,7 +1426,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, · 215 unmodified lines |
| 1426 | 1426 | struct macroblockd_plane *const pd = &xd->plane[0]; |
| 1427 | 1427 | PREDICTION_MODE best_mode = ZEROMV; |
| 1428 | 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 | 1430 | TX_SIZE best_tx_size = TX_SIZES; |
| 1431 | 1431 | INTERP_FILTER best_pred_filter = EIGHTTAP; |
| 1432 | 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 | 1494 | int denoise_svc_pickmode = 1; |
| 1495 | 1495 | #endif |
| 1496 | 1496 | INTERP_FILTER filter_gf_svc = EIGHTTAP; |
| 1497 | + MV_REFERENCE_FRAME best_second_ref_frame = NONE; |
| 1498 | + int comp_modes = 0; |
| 1497 | 1499 | |
| 1498 | 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 | 1628 | x->last_sb_high_content > 40 || cpi->rc.frames_since_golden > 120)) |
| 1627 | 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 | 1636 | for (ref_frame = LAST_FRAME; ref_frame <= usable_ref_frame; ++ref_frame) { |
| 1630 | 1637 | if (!skip_ref_find_pred[ref_frame]) { |
| 1631 | 1638 | find_predictors(cpi, x, ref_frame, frame_mv, const_motion, |
| 1632 | 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 | 1645 | if (cpi->use_svc || cpi->oxcf.speed <= 7 || bsize < BLOCK_32X32) |
| 1638 | 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 | 1649 | int rate_mv = 0; |
| 1642 | 1650 | int mode_rd_thresh; |
| 1643 | 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 | 1656 | int rd_computed = 0; |
| 1649 | 1657 | int inter_mv_mode = 0; |
| 1650 | 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) { |
| 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; |
| 1659 | 1688 | } |
| 1689 | + |
| 1660 | 1690 | if (ref_frame > usable_ref_frame) continue; |
| 1661 | 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 | 1778 | if (ref_frame_skip_mask & (1 << ref_frame)) continue; |
| 1749 | 1779 | |
| 1750 | 1780 | // Select prediction reference frames. |
| 1751 | | − for (i = 0; i < MAX_MB_PLANE; i++) |
| 1781 | + for (i = 0; i < MAX_MB_PLANE; i++) { |
| 1752 | 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 | 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 | 1790 | mode_index = mode_idx[ref_frame][INTER_OFFSET(this_mode)]; |
| 1758 | 1791 | 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 | 1895 | // causes some regression, leave it for duplicate zero-mv for now, until |
| 1863 | 1896 | // regression issue is resolved. |
| 1864 | 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 | 1899 | if (mode_checked[inter_mv_mode][ref_frame] && |
| 1867 | 1900 | frame_mv[this_mode][ref_frame].as_int == |
| 1868 | 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 | 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 | 1925 | frame_mv[this_mode][ref_frame].as_int == |
| 1893 | 1926 | frame_mv[NEARESTMV][ref_frame].as_int) |
| 1894 | 1927 | continue; |
| 1895 | 1928 | |
| 1896 | 1929 | mi->mode = this_mode; |
| 1897 | 1930 | mi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int; |
| 1931 | + mi->mv[1].as_int = 0; |
| 1898 | 1932 | |
| 1899 | 1933 | // Search for the best prediction filter type, when the resulting |
| 1900 | 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 | 2084 | this_rdc.rate += rate_mv; |
| 2051 | 2085 | this_rdc.rate += cpi->inter_mode_cost[x->mbmi_ext->mode_context[ref_frame]] |
| 2052 | 2086 | [INTER_OFFSET(this_mode)]; |
| 2087 | + // TODO(marpan): Add costing for compound mode. |
| 2053 | 2088 | this_rdc.rate += ref_frame_cost[ref_frame]; |
| 2054 | 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 | 2134 | best_ref_frame = ref_frame; |
| 2100 | 2135 | best_mode_skip_txfm = x->skip_txfm[0]; |
| 2101 | 2136 | best_early_term = this_early_term; |
| 2137 | + best_second_ref_frame = second_ref_frame; |
| 2102 | 2138 | |
| 2103 | 2139 | if (reuse_inter_pred) { |
| 2104 | 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 | 2161 | mi->mv[0].as_int = frame_mv[best_mode][best_ref_frame].as_int; |
| 2126 | 2162 | xd->mi[0]->bmi[0].as_mv[0].as_int = mi->mv[0].as_int; |
| 2127 | 2163 | x->skip_txfm[0] = best_mode_skip_txfm; |
| 2164 | + mi->ref_frame[1] = best_second_ref_frame; |
| 2128 | 2165 | |
| 2129 | 2166 | // For spatial enhancemanent layer: perform intra prediction only if base |
| 2130 | 2167 | // 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 | 2275 | best_mode = this_mode; |
| 2239 | 2276 | best_intra_tx_size = mi->tx_size; |
| 2240 | 2277 | best_ref_frame = INTRA_FRAME; |
| 2278 | + best_second_ref_frame = NONE; |
| 2241 | 2279 | mi->uv_mode = this_mode; |
| 2242 | 2280 | mi->mv[0].as_int = INVALID_MV; |
| 2281 | + mi->mv[1].as_int = INVALID_MV; |
| 2243 | 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 | 2294 | pd->dst = orig_dst; |
| 2256 | 2295 | mi->mode = best_mode; |
| 2257 | 2296 | mi->ref_frame[0] = best_ref_frame; |
| 2297 | + mi->ref_frame[1] = best_second_ref_frame; |
| 2258 | 2298 | x->skip_txfm[0] = best_mode_skip_txfm; |
| 2259 | 2299 | |
| 2260 | 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 | 2341 | #endif |
| 2302 | 2342 | |
| 2303 | | − if (best_ref_frame == ALTREF_FRAME) |
| 2343 | + if (best_ref_frame == ALTREF_FRAME || best_second_ref_frame == ALTREF_FRAME) |
| 2304 | 2344 | x->arf_frame_usage++; |
| 2305 | 2345 | else if (best_ref_frame != INTRA_FRAME) |
| 2306 | 2346 | x->lastgolden_frame_usage++; |