Unified · Split
| @@ -44,112 +44,59 @@ static void subpic_width_height(int *pic_width, int *pic_height, · 43 unmodified lines | ||
| 44 | 44 | *pic_height = pps->subpic_height[subpic_idx] >> sps->vshift[is_chroma]; |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | −static int emulated_edge(const VVCLocalContext *lc, uint8_t *dst, const uint8_t **src, ptrdiff_t *src_stride, const VVCFrame *src_frame, | |
| 48 | − int x_off, int y_off, const int block_w, const int block_h, const int is_chroma) | |
| 47 | +static void emulated_edge(const VVCLocalContext *lc, uint8_t *dst, | |
| 48 | + const uint8_t **src, ptrdiff_t *src_stride, const VVCFrame *src_frame, | |
| 49 | + int x_sb, int y_sb, int x_off, int y_off, const int block_w, const int block_h, | |
| 50 | + const int is_chroma, const int extra_before, const int extra_after) | |
| 49 | 51 | { |
| 50 | 52 | const VVCFrameContext *fc = lc->fc; |
| 51 | 53 | const VVCSPS *sps = src_frame->sps; |
| 52 | 54 | const VVCPPS *pps = src_frame->pps; |
| 53 | 55 | const int subpic_idx = lc->sc->sh.r->curr_subpic_idx; |
| 54 | − const int extra_before = is_chroma ? CHROMA_EXTRA_BEFORE : LUMA_EXTRA_BEFORE; | |
| 55 | − const int extra_after = is_chroma ? CHROMA_EXTRA_AFTER : LUMA_EXTRA_AFTER; | |
| 56 | − const int extra = is_chroma ? CHROMA_EXTRA : LUMA_EXTRA; | |
| 57 | − int pic_width, pic_height; | |
| 58 | − | |
| 59 | − subpic_offset(&x_off, &y_off, sps, pps, subpic_idx, is_chroma); | |
| 60 | − subpic_width_height(&pic_width, &pic_height, sps, pps, subpic_idx, is_chroma); | |
| 61 | − | |
| 62 | − if (x_off < extra_before || y_off < extra_before || | |
| 63 | − x_off >= pic_width - block_w - extra_after || | |
| 64 | − y_off >= pic_height - block_h - extra_after) { | |
| 65 | − const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << fc->ps.sps->pixel_shift; | |
| 66 | − int offset = extra_before * *src_stride + (extra_before << fc->ps.sps->pixel_shift); | |
| 67 | − int buf_offset = extra_before * edge_emu_stride + (extra_before << fc->ps.sps->pixel_shift); | |
| 68 | − | |
| 69 | − fc->vdsp.emulated_edge_mc(dst, *src - offset, edge_emu_stride, *src_stride, | |
| 70 | − block_w + extra, block_h + extra, x_off - extra_before, y_off - extra_before, | |
| 71 | − pic_width, pic_height); | |
| 72 | − | |
| 73 | − *src = dst + buf_offset; | |
| 74 | − *src_stride = edge_emu_stride; | |
| 75 | − return 1; | |
| 76 | − } | |
| 77 | − return 0; | |
| 78 | −} | |
| 79 | − | |
| 80 | −static void emulated_edge_dmvr(const VVCLocalContext *lc, uint8_t *dst, const uint8_t **src, ptrdiff_t *src_stride, | |
| 81 | − int x_sb, int y_sb, int x_off, int y_off, const int block_w, const int block_h, const int is_chroma) | |
| 82 | −{ | |
| 83 | − const VVCFrameContext *fc = lc->fc; | |
| 84 | − const VVCSPS *sps = fc->ps.sps; | |
| 85 | − const VVCPPS *pps = fc->ps.pps; | |
| 86 | − const int subpic_idx = lc->sc->sh.r->curr_subpic_idx; | |
| 87 | − const int extra_before = is_chroma ? CHROMA_EXTRA_BEFORE : LUMA_EXTRA_BEFORE; | |
| 88 | − const int extra_after = is_chroma ? CHROMA_EXTRA_AFTER : LUMA_EXTRA_AFTER; | |
| 89 | − const int extra = is_chroma ? CHROMA_EXTRA : LUMA_EXTRA; | |
| 56 | + const int extra = extra_before + extra_after; | |
| 57 | + const int dmvr_clip = x_sb != x_off || y_sb != y_off; | |
| 90 | 58 | int pic_width, pic_height; |
| 91 | 59 | |
| 92 | 60 | subpic_offset(&x_off, &y_off, sps, pps, subpic_idx, is_chroma); |
| 93 | 61 | subpic_offset(&x_sb, &y_sb, sps, pps, subpic_idx, is_chroma); |
| 94 | 62 | subpic_width_height(&pic_width, &pic_height, sps, pps, subpic_idx, is_chroma); |
| 63 | + if (dmvr_clip) { | |
| 64 | + const int start_x = FFMIN(FFMAX(x_sb - extra_before, 0), pic_width - 1); | |
| 65 | + const int start_y = FFMIN(FFMAX(y_sb - extra_before, 0), pic_height - 1); | |
| 66 | + pic_width = FFMAX(FFMIN(pic_width, x_sb + block_w + extra_after) - start_x, 1); | |
| 67 | + pic_height = FFMAX(FFMIN(pic_height, y_sb + block_h + extra_after) - start_y, 1); | |
| 68 | + x_off -= start_x; | |
| 69 | + y_off -= start_y; | |
| 70 | + } | |
| 95 | 71 | |
| 96 | − if (x_off < extra_before || y_off < extra_before || | |
| 72 | + if (dmvr_clip || x_off < extra_before || y_off < extra_before || | |
| 97 | 73 | x_off >= pic_width - block_w - extra_after || |
| 98 | − y_off >= pic_height - block_h - extra_after|| | |
| 99 | − (x_off != x_sb || y_off != y_sb)) { | |
| 74 | + y_off >= pic_height - block_h - extra_after) { | |
| 100 | 75 | const int ps = fc->ps.sps->pixel_shift; |
| 101 | 76 | const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << ps; |
| 102 | − const int offset = extra_before * *src_stride + (extra_before << ps); | |
| 77 | + const int offset = extra_before * *src_stride + (extra_before << ps); | |
| 103 | 78 | const int buf_offset = extra_before * edge_emu_stride + (extra_before << ps); |
| 104 | 79 | |
| 105 | − const int start_x = FFMIN(FFMAX(x_sb - extra_before, 0), pic_width - 1); | |
| 106 | − const int start_y = FFMIN(FFMAX(y_sb - extra_before, 0), pic_height - 1); | |
| 107 | − const int width = FFMAX(FFMIN(pic_width, x_sb + block_w + extra_after) - start_x, 1); | |
| 108 | − const int height = FFMAX(FFMIN(pic_height, y_sb + block_h + extra_after) - start_y, 1); | |
| 109 | − | |
| 110 | − fc->vdsp.emulated_edge_mc(dst, *src - offset, edge_emu_stride, *src_stride, block_w + extra, block_h + extra, | |
| 111 | − x_off - start_x - extra_before, y_off - start_y - extra_before, width, height); | |
| 112 | − | |
| 113 | − *src = dst + buf_offset; | |
| 114 | − *src_stride = edge_emu_stride; | |
| 115 | − } | |
| 116 | −} | |
| 117 | − | |
| 118 | −static void emulated_edge_bilinear(const VVCLocalContext *lc, uint8_t *dst, const uint8_t **src, ptrdiff_t *src_stride, | |
| 119 | − int x_off, int y_off, const int block_w, const int block_h) | |
| 120 | −{ | |
| 121 | − const VVCFrameContext *fc = lc->fc; | |
| 122 | − const VVCSPS *sps = fc->ps.sps; | |
| 123 | − const VVCPPS *pps = fc->ps.pps; | |
| 124 | − const int subpic_idx = lc->sc->sh.r->curr_subpic_idx; | |
| 125 | − int pic_width, pic_height; | |
| 126 | − | |
| 127 | − subpic_offset(&x_off, &y_off, sps, pps, subpic_idx, 0); | |
| 128 | − subpic_width_height(&pic_width, &pic_height, sps, pps, subpic_idx, 0); | |
| 129 | − | |
| 130 | − if (x_off < BILINEAR_EXTRA_BEFORE || y_off < BILINEAR_EXTRA_BEFORE || | |
| 131 | − x_off >= pic_width - block_w - BILINEAR_EXTRA_AFTER || | |
| 132 | − y_off >= pic_height - block_h - BILINEAR_EXTRA_AFTER) { | |
| 133 | − const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << fc->ps.sps->pixel_shift; | |
| 134 | − const int offset = BILINEAR_EXTRA_BEFORE * *src_stride + (BILINEAR_EXTRA_BEFORE << fc->ps.sps->pixel_shift); | |
| 135 | − const int buf_offset = BILINEAR_EXTRA_BEFORE * edge_emu_stride + (BILINEAR_EXTRA_BEFORE << fc->ps.sps->pixel_shift); | |
| 136 | − | |
| 137 | − fc->vdsp.emulated_edge_mc(dst, *src - offset, edge_emu_stride, *src_stride, block_w + BILINEAR_EXTRA, block_h + BILINEAR_EXTRA, | |
| 138 | − x_off - BILINEAR_EXTRA_BEFORE, y_off - BILINEAR_EXTRA_BEFORE, pic_width, pic_height); | |
| 80 | + fc->vdsp.emulated_edge_mc(dst, *src - offset, edge_emu_stride, *src_stride, | |
| 81 | + block_w + extra, block_h + extra, x_off - extra_before, y_off - extra_before, | |
| 82 | + pic_width, pic_height); | |
| 139 | 83 | |
| 140 | 84 | *src = dst + buf_offset; |
| 141 | 85 | *src_stride = edge_emu_stride; |
| 142 | 86 | } |
| 143 | 87 | } |
| 144 | 88 | |
| 145 | −#define MC_EMULATED_EDGE(dst, src, src_stride, x_off, y_off) \ | |
| 146 | − emulated_edge(lc, dst, src, src_stride, ref, x_off, y_off, block_w, block_h, is_chroma) | |
| 89 | +#define MC_EMULATED_EDGE(dst, src, src_stride, x_off, y_off) \ | |
| 90 | + emulated_edge(lc, dst, src, src_stride, ref, x_off, y_off, x_off, y_off, block_w, block_h, is_chroma, \ | |
| 91 | + is_chroma ? CHROMA_EXTRA_BEFORE : LUMA_EXTRA_BEFORE, is_chroma ? CHROMA_EXTRA_AFTER : LUMA_EXTRA_AFTER) | |
| 147 | 92 | |
| 148 | −#define MC_EMULATED_EDGE_DMVR(dst, src, src_stride, x_sb, y_sb, x_off, y_off) \ | |
| 149 | − emulated_edge_dmvr(lc, dst, src, src_stride, x_sb, y_sb, x_off, y_off, block_w, block_h, is_chroma) | |
| 93 | +#define MC_EMULATED_EDGE_DMVR(dst, src, src_stride, x_sb, y_sb, x_off, y_off) \ | |
| 94 | + emulated_edge(lc, dst, src, src_stride, ref, x_sb, y_sb, x_off, y_off, block_w, block_h, is_chroma, \ | |
| 95 | + is_chroma ? CHROMA_EXTRA_BEFORE : LUMA_EXTRA_BEFORE, is_chroma ? CHROMA_EXTRA_AFTER : LUMA_EXTRA_AFTER) | |
| 150 | 96 | |
| 151 | −#define MC_EMULATED_EDGE_BILINEAR(dst, src, src_stride, x_off, y_off) \ | |
| 152 | − emulated_edge_bilinear(lc, dst, src, src_stride, x_off, y_off, pred_w, pred_h) | |
| 97 | +#define MC_EMULATED_EDGE_BILINEAR(dst, src, src_stride, x_off, y_off) \ | |
| 98 | + emulated_edge(lc, dst, src, src_stride, ref, x_off, y_off, x_off, y_off, pred_w, pred_h, 0, \ | |
| 99 | + BILINEAR_EXTRA_BEFORE, BILINEAR_EXTRA_AFTER) | |
| 153 | 100 | |
| 154 | 101 | // part of 8.5.6.6 Weighted sample prediction process |
| 155 | 102 | static int derive_weight_uni(int *denom, int *wx, int *ox, |
| @@ -357,23 +304,21 @@ static void scaled_ref_pos_and_step(const VVCLocalContext *lc, const VVCRefPic * · 201 unmodified lines | ||
| 357 | 304 | } |
| 358 | 305 | |
| 359 | 306 | static void emulated_edge_scaled(VVCLocalContext *lc, const uint8_t **src, ptrdiff_t *src_stride, int *src_height, |
| 360 | − const VVCFrame *ref, const int x, const int y, const int dx, const int dy, | |
| 361 | − const int block_w, const int block_h, const int is_chroma) | |
| 307 | + const VVCFrame *ref, const int x, const int y, const int dx, const int dy, const int w, const int h, const int is_chroma) | |
| 362 | 308 | { |
| 363 | 309 | const VVCFrameContext *fc = lc->fc; |
| 364 | − const int x0 = SCALED_INT(x); | |
| 365 | − const int y0 = SCALED_INT(y); | |
| 366 | − const int x_end = SCALED_INT(x + block_w * dx); | |
| 367 | − const int y_end = SCALED_INT(y + block_h * dy); | |
| 368 | − const int x_last = SCALED_INT(x + (block_w - 1) * dx); | |
| 369 | − const int y_last = SCALED_INT(y + (block_h - 1) * dy); | |
| 370 | − const int src_width = x_end - x0 + (x_end == x_last); | |
| 310 | + const int x_off = SCALED_INT(x); | |
| 311 | + const int y_off = SCALED_INT(y); | |
| 312 | + const int x_end = SCALED_INT(x + w * dx); | |
| 313 | + const int y_end = SCALED_INT(y + h * dy); | |
| 314 | + const int x_last = SCALED_INT(x + (w - 1) * dx); | |
| 315 | + const int y_last = SCALED_INT(y + (h - 1) * dy); | |
| 316 | + const int block_w = x_end - x_off + (x_end == x_last); | |
| 317 | + const int block_h = *src_height = y_end - y_off + (y_end == y_last); | |
| 371 | 318 | |
| 372 | − *src_height = y_end - y0 + (y_end == y_last); | |
| 319 | + *src += y_off * *src_stride + (x_off * (1 << fc->ps.sps->pixel_shift)); | |
| 373 | 320 | |
| 374 | − *src += y0 * *src_stride + (x0 * (1 << fc->ps.sps->pixel_shift)); | |
| 375 | − | |
| 376 | − emulated_edge(lc, lc->edge_emu_buffer, src, src_stride, ref, x0, y0, src_width, *src_height, is_chroma); | |
| 321 | + MC_EMULATED_EDGE(lc->edge_emu_buffer, src, src_stride, x_off, y_off); | |
| 377 | 322 | } |
| 378 | 323 | |
| 379 | 324 | static void mc_scaled(VVCLocalContext *lc, int16_t *dst, const VVCRefPic *refp, const Mv *mv, |
| @@ -737,11 +682,11 @@ static int parametric_mv_refine(const int *sad, const int stride) · 357 unmodified lines | ||
| 737 | 682 | #define SAD_ARRAY_SIZE 5 |
| 738 | 683 | //8.5.3 Decoder-side motion vector refinement process |
| 739 | 684 | static void dmvr_mv_refine(VVCLocalContext *lc, MvField *mvf, MvField *orig_mv, int *sb_bdof_flag, |
| 740 | − const AVFrame *ref0, const AVFrame *ref1, const int x_off, const int y_off, const int block_w, const int block_h) | |
| 685 | + const VVCFrame *ref0, const VVCFrame *ref1, const int x_off, const int y_off, const int block_w, const int block_h) | |
| 741 | 686 | { |
| 742 | 687 | const VVCFrameContext *fc = lc->fc; |
| 743 | 688 | const int sr_range = 2; |
| 744 | − const AVFrame *ref[] = { ref0, ref1 }; | |
| 689 | + const VVCFrame *refs[] = { ref0, ref1 }; | |
| 745 | 690 | int16_t *tmp[] = { lc->tmp, lc->tmp1 }; |
| 746 | 691 | int sad[SAD_ARRAY_SIZE][SAD_ARRAY_SIZE]; |
| 747 | 692 | int min_dx, min_dy, min_sad, dx, dy; |
| @@ -757,8 +702,9 @@ static void dmvr_mv_refine(VVCLocalContext *lc, MvField *mvf, MvField *orig_mv, · 9 unmodified lines | ||
| 757 | 702 | const int my = mv->y & 0xf; |
| 758 | 703 | const int ox = x_off + (mv->x >> 4) - sr_range; |
| 759 | 704 | const int oy = y_off + (mv->y >> 4) - sr_range; |
| 760 | − ptrdiff_t src_stride = ref[i]->linesize[LUMA]; | |
| 761 | − const uint8_t *src = ref[i]->data[LUMA] + oy * src_stride + (ox * (1 << fc->ps.sps->pixel_shift)); | |
| 705 | + const VVCFrame *ref = refs[i]; | |
| 706 | + ptrdiff_t src_stride = ref->frame->linesize[LUMA]; | |
| 707 | + const uint8_t *src = ref->frame->data[LUMA] + oy * src_stride + (ox * (1 << fc->ps.sps->pixel_shift)); | |
| 762 | 708 | MC_EMULATED_EDGE_BILINEAR(lc->edge_emu_buffer, &src, &src_stride, ox, oy); |
| 763 | 709 | fc->vvcdsp.inter.dmvr[!!my][!!mx](tmp[i], src, src_stride, pred_h, mx, my, pred_w); |
| 764 | 710 | } |
| @@ -828,7 +774,7 @@ static void derive_sb_mv(VVCLocalContext *lc, MvField *mv, MvField *orig_mv, int · 63 unmodified lines | ||
| 828 | 774 | VVCRefPic *refp[2]; |
| 829 | 775 | if (pred_get_refs(lc, refp, mv) < 0) |
| 830 | 776 | return; |
| 831 | − dmvr_mv_refine(lc, mv, orig_mv, sb_bdof_flag, refp[L0]->ref->frame, refp[L1]->ref->frame, x0, y0, sbw, sbh); | |
| 777 | + dmvr_mv_refine(lc, mv, orig_mv, sb_bdof_flag, refp[L0]->ref, refp[L1]->ref, x0, y0, sbw, sbh); | |
| 832 | 778 | set_dmvr_info(fc, x0, y0, sbw, sbh, mv); |
| 833 | 779 | } |
| 834 | 780 | } |