History

Move joint_motion_search & delete function prototype

Adrian Grange committed 11 years ago

Commit 53c9ebe1 parent 067fc491 file · +184 −189Browse files

Unified · Split

vp9/encoder/vp9_rdopt.c+184−189
@@ -1261,13 +1261,6 @@ static int cost_mv_ref(const VP9_COMP *cpi, PREDICTION_MODE mode, · 1260 unmodified lines
12611261 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
12621262 }
12631263
1264−static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
1265− BLOCK_SIZE bsize,
1266− int_mv *frame_mv,
1267− int mi_row, int mi_col,
1268− int_mv single_newmv[MAX_REF_FRAMES],
1269− int *rate_mv);
1270−
12711264 static int set_and_cost_bmi_mvs(VP9_COMP *cpi, MACROBLOCKD *xd, int i,
12721265 PREDICTION_MODE mode, int_mv this_mv[2],
12731266 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
@@ -1541,6 +1534,190 @@ static int check_best_zero_mv( · 267 unmodified lines
15411534 return 1;
15421535 }
15431536
1537+static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
1538+ BLOCK_SIZE bsize,
1539+ int_mv *frame_mv,
1540+ int mi_row, int mi_col,
1541+ int_mv single_newmv[MAX_REF_FRAMES],
1542+ int *rate_mv) {
1543+ const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
1544+ const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
1545+ MACROBLOCKD *xd = &x->e_mbd;
1546+ MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
1547+ const int refs[2] = { mbmi->ref_frame[0],
1548+ mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
1549+ int_mv ref_mv[2];
1550+ int ite, ref;
1551+ // Prediction buffer from second frame.
1552+#if CONFIG_VP9_HIGHBITDEPTH
1553+ uint8_t *second_pred;
1554+ uint8_t *second_pred_alloc;
1555+#else
1556+ uint8_t *second_pred = vpx_memalign(16, pw * ph * sizeof(uint8_t));
1557+#endif // CONFIG_VP9_HIGHBITDEPTH
1558+ const InterpKernel *kernel = vp9_get_interp_kernel(mbmi->interp_filter);
1559+
1560+ // Do joint motion search in compound mode to get more accurate mv.
1561+ struct buf_2d backup_yv12[2][MAX_MB_PLANE];
1562+ struct buf_2d scaled_first_yv12 = xd->plane[0].pre[0];
1563+ int last_besterr[2] = {INT_MAX, INT_MAX};
1564+ const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
1565+ vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
1566+ vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
1567+ };
1568+#if CONFIG_VP9_HIGHBITDEPTH
1569+ if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1570+ second_pred_alloc = vpx_memalign(16, pw * ph * sizeof(uint16_t));
1571+ second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc);
1572+ } else {
1573+ second_pred_alloc = vpx_memalign(16, pw * ph * sizeof(uint8_t));
1574+ second_pred = second_pred_alloc;
1575+ }
1576+#endif // CONFIG_VP9_HIGHBITDEPTH
1577+
1578+ for (ref = 0; ref < 2; ++ref) {
1579+ ref_mv[ref] = mbmi->ref_mvs[refs[ref]][0];
1580+
1581+ if (scaled_ref_frame[ref]) {
1582+ int i;
1583+ // Swap out the reference frame for a version that's been scaled to
1584+ // match the resolution of the current frame, allowing the existing
1585+ // motion search code to be used without additional modifications.
1586+ for (i = 0; i < MAX_MB_PLANE; i++)
1587+ backup_yv12[ref][i] = xd->plane[i].pre[ref];
1588+ vp9_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
1589+ NULL);
1590+ }
1591+
1592+ frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
1593+ }
1594+
1595+ // Allow joint search multiple times iteratively for each ref frame
1596+ // and break out the search loop if it couldn't find better mv.
1597+ for (ite = 0; ite < 4; ite++) {
1598+ struct buf_2d ref_yv12[2];
1599+ int bestsme = INT_MAX;
1600+ int sadpb = x->sadperbit16;
1601+ MV tmp_mv;
1602+ int search_range = 3;
1603+
1604+ int tmp_col_min = x->mv_col_min;
1605+ int tmp_col_max = x->mv_col_max;
1606+ int tmp_row_min = x->mv_row_min;
1607+ int tmp_row_max = x->mv_row_max;
1608+ int id = ite % 2;
1609+
1610+ // Initialized here because of compiler problem in Visual Studio.
1611+ ref_yv12[0] = xd->plane[0].pre[0];
1612+ ref_yv12[1] = xd->plane[0].pre[1];
1613+
1614+ // Get pred block from second frame.
1615+#if CONFIG_VP9_HIGHBITDEPTH
1616+ if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1617+ vp9_highbd_build_inter_predictor(ref_yv12[!id].buf,
1618+ ref_yv12[!id].stride,
1619+ second_pred, pw,
1620+ &frame_mv[refs[!id]].as_mv,
1621+ &xd->block_refs[!id]->sf,
1622+ pw, ph, 0,
1623+ kernel, MV_PRECISION_Q3,
1624+ mi_col * MI_SIZE, mi_row * MI_SIZE,
1625+ xd->bd);
1626+ } else {
1627+ vp9_build_inter_predictor(ref_yv12[!id].buf,
1628+ ref_yv12[!id].stride,
1629+ second_pred, pw,
1630+ &frame_mv[refs[!id]].as_mv,
1631+ &xd->block_refs[!id]->sf,
1632+ pw, ph, 0,
1633+ kernel, MV_PRECISION_Q3,
1634+ mi_col * MI_SIZE, mi_row * MI_SIZE);
1635+ }
1636+#else
1637+ vp9_build_inter_predictor(ref_yv12[!id].buf,
1638+ ref_yv12[!id].stride,
1639+ second_pred, pw,
1640+ &frame_mv[refs[!id]].as_mv,
1641+ &xd->block_refs[!id]->sf,
1642+ pw, ph, 0,
1643+ kernel, MV_PRECISION_Q3,
1644+ mi_col * MI_SIZE, mi_row * MI_SIZE);
1645+#endif // CONFIG_VP9_HIGHBITDEPTH
1646+
1647+ // Compound motion search on first ref frame.
1648+ if (id)
1649+ xd->plane[0].pre[0] = ref_yv12[id];
1650+ vp9_set_mv_search_range(x, &ref_mv[id].as_mv);
1651+
1652+ // Use mv result from single mode as mvp.
1653+ tmp_mv = frame_mv[refs[id]].as_mv;
1654+
1655+ tmp_mv.col >>= 3;
1656+ tmp_mv.row >>= 3;
1657+
1658+ // Small-range full-pixel motion search
1659+ bestsme = vp9_refining_search_8p_c(x, &tmp_mv, sadpb,
1660+ search_range,
1661+ &cpi->fn_ptr[bsize],
1662+ &ref_mv[id].as_mv, second_pred);
1663+ if (bestsme < INT_MAX)
1664+ bestsme = vp9_get_mvpred_av_var(x, &tmp_mv, &ref_mv[id].as_mv,
1665+ second_pred, &cpi->fn_ptr[bsize], 1);
1666+
1667+ x->mv_col_min = tmp_col_min;
1668+ x->mv_col_max = tmp_col_max;
1669+ x->mv_row_min = tmp_row_min;
1670+ x->mv_row_max = tmp_row_max;
1671+
1672+ if (bestsme < INT_MAX) {
1673+ int dis; /* TODO: use dis in distortion calculation later. */
1674+ unsigned int sse;
1675+ bestsme = cpi->find_fractional_mv_step(
1676+ x, &tmp_mv,
1677+ &ref_mv[id].as_mv,
1678+ cpi->common.allow_high_precision_mv,
1679+ x->errorperbit,
1680+ &cpi->fn_ptr[bsize],
1681+ 0, cpi->sf.mv.subpel_iters_per_step,
1682+ NULL,
1683+ x->nmvjointcost, x->mvcost,
1684+ &dis, &sse, second_pred,
1685+ pw, ph);
1686+ }
1687+
1688+ if (id)
1689+ xd->plane[0].pre[0] = scaled_first_yv12;
1690+
1691+ if (bestsme < last_besterr[id]) {
1692+ frame_mv[refs[id]].as_mv = tmp_mv;
1693+ last_besterr[id] = bestsme;
1694+ } else {
1695+ break;
1696+ }
1697+ }
1698+
1699+ *rate_mv = 0;
1700+
1701+ for (ref = 0; ref < 2; ++ref) {
1702+ if (scaled_ref_frame[ref]) {
1703+ // restore the predictor
1704+ int i;
1705+ for (i = 0; i < MAX_MB_PLANE; i++)
1706+ xd->plane[i].pre[ref] = backup_yv12[ref][i];
1707+ }
1708+
1709+ *rate_mv += vp9_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
1710+ &mbmi->ref_mvs[refs[ref]][0].as_mv,
1711+ x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
1712+ }
1713+
1714+#if CONFIG_VP9_HIGHBITDEPTH
1715+ vpx_free(second_pred_alloc);
1716+#else
1717+ vpx_free(second_pred);
1718+#endif // CONFIG_VP9_HIGHBITDEPTH
1719+}
1720+
15441721 static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
15451722 const TileInfo * const tile,
15461723 int_mv *best_ref_mv,
@@ -2172,189 +2349,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, · 625 unmodified lines
21722349 }
21732350 }
21742351
2175−static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
2176− BLOCK_SIZE bsize,
2177− int_mv *frame_mv,
2178− int mi_row, int mi_col,
2179− int_mv single_newmv[MAX_REF_FRAMES],
2180− int *rate_mv) {
2181− const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
2182− const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
2183− MACROBLOCKD *xd = &x->e_mbd;
2184− MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
2185− const int refs[2] = { mbmi->ref_frame[0],
2186− mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
2187− int_mv ref_mv[2];
2188− int ite, ref;
2189− // Prediction buffer from second frame.
2190−#if CONFIG_VP9_HIGHBITDEPTH
2191− uint8_t *second_pred;
2192− uint8_t *second_pred_alloc;
2193−#else
2194− uint8_t *second_pred = vpx_memalign(16, pw * ph * sizeof(uint8_t));
2195−#endif // CONFIG_VP9_HIGHBITDEPTH
2196− const InterpKernel *kernel = vp9_get_interp_kernel(mbmi->interp_filter);
2197−
2198− // Do joint motion search in compound mode to get more accurate mv.
2199− struct buf_2d backup_yv12[2][MAX_MB_PLANE];
2200− struct buf_2d scaled_first_yv12 = xd->plane[0].pre[0];
2201− int last_besterr[2] = {INT_MAX, INT_MAX};
2202− const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
2203− vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
2204− vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
2205− };
2206−#if CONFIG_VP9_HIGHBITDEPTH
2207− if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2208− second_pred_alloc = vpx_memalign(16, pw * ph * sizeof(uint16_t));
2209− second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc);
2210− } else {
2211− second_pred_alloc = vpx_memalign(16, pw * ph * sizeof(uint8_t));
2212− second_pred = second_pred_alloc;
2213− }
2214−#endif // CONFIG_VP9_HIGHBITDEPTH
2215−
2216− for (ref = 0; ref < 2; ++ref) {
2217− ref_mv[ref] = mbmi->ref_mvs[refs[ref]][0];
2218−
2219− if (scaled_ref_frame[ref]) {
2220− int i;
2221− // Swap out the reference frame for a version that's been scaled to
2222− // match the resolution of the current frame, allowing the existing
2223− // motion search code to be used without additional modifications.
2224− for (i = 0; i < MAX_MB_PLANE; i++)
2225− backup_yv12[ref][i] = xd->plane[i].pre[ref];
2226− vp9_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
2227− NULL);
2228− }
2229−
2230− frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
2231− }
2232−
2233− // Allow joint search multiple times iteratively for each ref frame
2234− // and break out the search loop if it couldn't find better mv.
2235− for (ite = 0; ite < 4; ite++) {
2236− struct buf_2d ref_yv12[2];
2237− int bestsme = INT_MAX;
2238− int sadpb = x->sadperbit16;
2239− MV tmp_mv;
2240− int search_range = 3;
2241−
2242− int tmp_col_min = x->mv_col_min;
2243− int tmp_col_max = x->mv_col_max;
2244− int tmp_row_min = x->mv_row_min;
2245− int tmp_row_max = x->mv_row_max;
2246− int id = ite % 2;
2247−
2248− // Initialized here because of compiler problem in Visual Studio.
2249− ref_yv12[0] = xd->plane[0].pre[0];
2250− ref_yv12[1] = xd->plane[0].pre[1];
2251−
2252− // Get pred block from second frame.
2253−#if CONFIG_VP9_HIGHBITDEPTH
2254− if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2255− vp9_highbd_build_inter_predictor(ref_yv12[!id].buf,
2256− ref_yv12[!id].stride,
2257− second_pred, pw,
2258− &frame_mv[refs[!id]].as_mv,
2259− &xd->block_refs[!id]->sf,
2260− pw, ph, 0,
2261− kernel, MV_PRECISION_Q3,
2262− mi_col * MI_SIZE, mi_row * MI_SIZE,
2263− xd->bd);
2264− } else {
2265− vp9_build_inter_predictor(ref_yv12[!id].buf,
2266− ref_yv12[!id].stride,
2267− second_pred, pw,
2268− &frame_mv[refs[!id]].as_mv,
2269− &xd->block_refs[!id]->sf,
2270− pw, ph, 0,
2271− kernel, MV_PRECISION_Q3,
2272− mi_col * MI_SIZE, mi_row * MI_SIZE);
2273− }
2274−#else
2275− vp9_build_inter_predictor(ref_yv12[!id].buf,
2276− ref_yv12[!id].stride,
2277− second_pred, pw,
2278− &frame_mv[refs[!id]].as_mv,
2279− &xd->block_refs[!id]->sf,
2280− pw, ph, 0,
2281− kernel, MV_PRECISION_Q3,
2282− mi_col * MI_SIZE, mi_row * MI_SIZE);
2283−#endif // CONFIG_VP9_HIGHBITDEPTH
2284−
2285− // Compound motion search on first ref frame.
2286− if (id)
2287− xd->plane[0].pre[0] = ref_yv12[id];
2288− vp9_set_mv_search_range(x, &ref_mv[id].as_mv);
2289−
2290− // Use mv result from single mode as mvp.
2291− tmp_mv = frame_mv[refs[id]].as_mv;
2292−
2293− tmp_mv.col >>= 3;
2294− tmp_mv.row >>= 3;
22952352
2296− // Small-range full-pixel motion search
2297− bestsme = vp9_refining_search_8p_c(x, &tmp_mv, sadpb,
2298− search_range,
2299− &cpi->fn_ptr[bsize],
2300− &ref_mv[id].as_mv, second_pred);
2301− if (bestsme < INT_MAX)
2302− bestsme = vp9_get_mvpred_av_var(x, &tmp_mv, &ref_mv[id].as_mv,
2303− second_pred, &cpi->fn_ptr[bsize], 1);
2304−
2305− x->mv_col_min = tmp_col_min;
2306− x->mv_col_max = tmp_col_max;
2307− x->mv_row_min = tmp_row_min;
2308− x->mv_row_max = tmp_row_max;
2309−
2310− if (bestsme < INT_MAX) {
2311− int dis; /* TODO: use dis in distortion calculation later. */
2312− unsigned int sse;
2313− bestsme = cpi->find_fractional_mv_step(
2314− x, &tmp_mv,
2315− &ref_mv[id].as_mv,
2316− cpi->common.allow_high_precision_mv,
2317− x->errorperbit,
2318− &cpi->fn_ptr[bsize],
2319− 0, cpi->sf.mv.subpel_iters_per_step,
2320− NULL,
2321− x->nmvjointcost, x->mvcost,
2322− &dis, &sse, second_pred,
2323− pw, ph);
2324− }
2325−
2326− if (id)
2327− xd->plane[0].pre[0] = scaled_first_yv12;
2328−
2329− if (bestsme < last_besterr[id]) {
2330− frame_mv[refs[id]].as_mv = tmp_mv;
2331− last_besterr[id] = bestsme;
2332− } else {
2333− break;
2334− }
2335− }
2336−
2337− *rate_mv = 0;
2338−
2339− for (ref = 0; ref < 2; ++ref) {
2340− if (scaled_ref_frame[ref]) {
2341− // restore the predictor
2342− int i;
2343− for (i = 0; i < MAX_MB_PLANE; i++)
2344− xd->plane[i].pre[ref] = backup_yv12[ref][i];
2345− }
2346−
2347− *rate_mv += vp9_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
2348− &mbmi->ref_mvs[refs[ref]][0].as_mv,
2349− x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
2350− }
2351−
2352−#if CONFIG_VP9_HIGHBITDEPTH
2353− vpx_free(second_pred_alloc);
2354−#else
2355− vpx_free(second_pred);
2356−#endif // CONFIG_VP9_HIGHBITDEPTH
2357−}
23582353
23592354 static INLINE void restore_dst_buf(MACROBLOCKD *xd,
23602355 uint8_t *orig_dst[MAX_MB_PLANE],

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