* [FFmpeg-devel] [PATCH 01/11] avcodec/vvcdec: refact out deblock_bs to reduce duplicate code
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
@ 2024-02-22 7:13 ` Nuo Mi
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 02/11] avcodec/vvcdec: set CuPredMode table for chroma Nuo Mi
` (9 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-22 7:13 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Nuo Mi
---
libavcodec/vvc/vvc_filter.c | 176 +++++++++++-------------------------
1 file changed, 55 insertions(+), 121 deletions(-)
diff --git a/libavcodec/vvc/vvc_filter.c b/libavcodec/vvc/vvc_filter.c
index 5fa711c9e0..ca541fd997 100644
--- a/libavcodec/vvc/vvc_filter.c
+++ b/libavcodec/vvc/vvc_filter.c
@@ -474,8 +474,9 @@ static void vvc_deblock_subblock_bs_horizontal(const VVCLocalContext *lc,
}
}
-static void vvc_deblock_bs_luma_vertical(const VVCLocalContext *lc,
- const int x0, const int y0, const int width, const int height)
+static av_always_inline int deblock_bs(const VVCLocalContext *lc,
+ const int x_p, const int y_p, const int x_q, const int y_q,
+ const RefPicList *rpl_p, const int c_idx, const int off_to_cb, const uint8_t has_sub_block)
{
const VVCFrameContext *fc = lc->fc;
const MvField *tab_mvf = fc->tab.mvf;
@@ -483,6 +484,44 @@ static void vvc_deblock_bs_luma_vertical(const VVCLocalContext *lc,
const int log2_min_tu_size = MIN_TU_LOG2;
const int min_pu_width = fc->ps.pps->min_pu_width;
const int min_tu_width = fc->ps.pps->min_tu_width;
+ const int pu_p = (y_p >> log2_min_pu_size) * min_pu_width + (x_p >> log2_min_pu_size);
+ const int pu_q = (y_q >> log2_min_pu_size) * min_pu_width + (x_q >> log2_min_pu_size);
+ const MvField *mvf_p = &tab_mvf[pu_p];
+ const MvField *mvf_q = &tab_mvf[pu_q];
+ const uint8_t chroma = !!c_idx;
+ const int tu_p = (y_p >> log2_min_tu_size) * min_tu_width + (x_p >> log2_min_tu_size);
+ const int tu_q = (y_q >> log2_min_tu_size) * min_tu_width + (x_q >> log2_min_tu_size);
+ const uint8_t pcmf = fc->tab.pcmf[chroma][tu_p] && fc->tab.pcmf[chroma][tu_q];
+
+ if (pcmf)
+ return 0;
+
+ if (mvf_p->pred_flag == PF_INTRA || mvf_q->pred_flag == PF_INTRA || mvf_p->ciip_flag || mvf_q->ciip_flag)
+ return 2;
+
+ if (chroma) {
+ return fc->tab.tu_coded_flag[c_idx][tu_p] ||
+ fc->tab.tu_coded_flag[c_idx][tu_q] ||
+ fc->tab.tu_joint_cbcr_residual_flag[tu_p] ||
+ fc->tab.tu_joint_cbcr_residual_flag[tu_q];
+ }
+
+ if (fc->tab.tu_coded_flag[LUMA][tu_p] || fc->tab.tu_coded_flag[LUMA][tu_q])
+ return 1;
+
+ if ((off_to_cb && ((off_to_cb % 8) || !has_sub_block)))
+ return 0; // inside a cu, not aligned to 8 or with no subblocks
+
+ return boundary_strength(lc, mvf_q, mvf_p, rpl_p);
+}
+
+static void vvc_deblock_bs_luma_vertical(const VVCLocalContext *lc,
+ const int x0, const int y0, const int width, const int height)
+{
+ const VVCFrameContext *fc = lc->fc;
+ const MvField *tab_mvf = fc->tab.mvf;
+ const int log2_min_pu_size = MIN_PU_LOG2;
+ const int min_pu_width = fc->ps.pps->min_pu_width;
const int min_cb_log2 = fc->ps.sps->min_cb_log2_size_y;
const int min_cb_width = fc->ps.pps->min_cb_width;
const int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
@@ -494,6 +533,7 @@ static void vvc_deblock_bs_luma_vertical(const VVCLocalContext *lc,
const int cb_x = fc->tab.cb_pos_x[LUMA][off_q];
const int cb_y = fc->tab.cb_pos_y[LUMA][off_q];
const int cb_width = fc->tab.cb_width[LUMA][off_q];
+ const int off_x = cb_x - x0;
if (!is_intra) {
if (fc->tab.msf[off_q] || fc->tab.iaf[off_q])
@@ -514,34 +554,9 @@ static void vvc_deblock_bs_luma_vertical(const VVCLocalContext *lc,
if (boundary_left) {
const RefPicList *rpl_left =
(lc->boundary_flags & BOUNDARY_LEFT_SLICE) ? ff_vvc_get_ref_list(fc, fc->ref, x0 - 1, y0) : lc->sc->rpl;
- const int xp_pu = (x0 - 1) >> log2_min_pu_size;
- const int xq_pu = x0 >> log2_min_pu_size;
- const int xp_tu = (x0 - 1) >> log2_min_tu_size;
- const int xq_tu = x0 >> log2_min_tu_size;
-
for (int i = 0; i < height; i += 4) {
- const int off_x = cb_x - x0;
- const int y_pu = (y0 + i) >> log2_min_pu_size;
- const int y_tu = (y0 + i) >> log2_min_tu_size;
- const MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
- const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
- const uint8_t left_cbf_luma = fc->tab.tu_coded_flag[LUMA][y_tu * min_tu_width + xp_tu];
- const uint8_t curr_cbf_luma = fc->tab.tu_coded_flag[LUMA][y_tu * min_tu_width + xq_tu];
- const uint8_t pcmf = fc->tab.pcmf[LUMA][y_tu * min_tu_width + xp_tu] &&
- fc->tab.pcmf[LUMA][y_tu * min_tu_width + xq_tu];
uint8_t max_len_p, max_len_q;
- int bs;
-
- if (pcmf)
- bs = 0;
- else if (curr->pred_flag == PF_INTRA || left->pred_flag == PF_INTRA || curr->ciip_flag || left->ciip_flag)
- bs = 2;
- else if (curr_cbf_luma || left_cbf_luma)
- bs = 1;
- else if (off_x && ((off_x % 8) || !has_vertical_sb))
- bs = 0; ////inside a cu, not aligned to 8 or with no subblocks
- else
- bs = boundary_strength(lc, curr, left, rpl_left);
+ const int bs = deblock_bs(lc, x0 - 1, y0 + i, x0, y0 + i, rpl_left, 0, off_x, has_vertical_sb);
TAB_BS(fc->tab.vertical_bs[LUMA], x0, (y0 + i)) = bs;
@@ -561,11 +576,9 @@ static void vvc_deblock_bs_luma_horizontal(const VVCLocalContext *lc,
const int x0, const int y0, const int width, const int height)
{
const VVCFrameContext *fc = lc->fc;
- const MvField *tab_mvf = fc->tab.mvf;
+ const MvField *tab_mvf = fc->tab.mvf;
const int log2_min_pu_size = MIN_PU_LOG2;
- const int log2_min_tu_size = MIN_TU_LOG2;
const int min_pu_width = fc->ps.pps->min_pu_width;
- const int min_tu_width = fc->ps.pps->min_tu_width;
const int min_cb_log2 = fc->ps.sps->min_cb_log2_size_y;
const int min_cb_width = fc->ps.pps->min_cb_width;
const int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
@@ -577,6 +590,7 @@ static void vvc_deblock_bs_luma_horizontal(const VVCLocalContext *lc,
const int cb_x = fc->tab.cb_pos_x[LUMA][off_q];
const int cb_y = fc->tab.cb_pos_y[LUMA][off_q];
const int cb_height = fc->tab.cb_height[LUMA][off_q];
+ const int off_y = y0 - cb_y;
if (!is_intra) {
if (fc->tab.msf[off_q] || fc->tab.iaf[off_q])
@@ -596,34 +610,10 @@ static void vvc_deblock_bs_luma_horizontal(const VVCLocalContext *lc,
if (boundary_upper) {
const RefPicList *rpl_top =
(lc->boundary_flags & BOUNDARY_UPPER_SLICE) ? ff_vvc_get_ref_list(fc, fc->ref, x0, y0 - 1) : lc->sc->rpl;
- int yp_pu = (y0 - 1) >> log2_min_pu_size;
- int yq_pu = y0 >> log2_min_pu_size;
- int yp_tu = (y0 - 1) >> log2_min_tu_size;
- int yq_tu = y0 >> log2_min_tu_size;
for (int i = 0; i < width; i += 4) {
- const int off_y = y0 - cb_y;
- const int x_pu = (x0 + i) >> log2_min_pu_size;
- const int x_tu = (x0 + i) >> log2_min_tu_size;
- const MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
- const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
- const uint8_t top_cbf_luma = fc->tab.tu_coded_flag[LUMA][yp_tu * min_tu_width + x_tu];
- const uint8_t curr_cbf_luma = fc->tab.tu_coded_flag[LUMA][yq_tu * min_tu_width + x_tu];
- const uint8_t pcmf = fc->tab.pcmf[LUMA][yp_tu * min_tu_width + x_tu] &&
- fc->tab.pcmf[LUMA][yq_tu * min_tu_width + x_tu];
uint8_t max_len_p, max_len_q;
- int bs;
-
- if (pcmf)
- bs = 0;
- else if (curr->pred_flag == PF_INTRA || top->pred_flag == PF_INTRA || curr->ciip_flag || top->ciip_flag)
- bs = 2;
- else if (curr_cbf_luma || top_cbf_luma)
- bs = 1;
- else if (off_y && ((off_y % 8) || !has_horizontal_sb))
- bs = 0; //inside a cu, not aligned to 8 or with no subblocks
- else
- bs = boundary_strength(lc, curr, top, rpl_top);
+ const int bs = deblock_bs(lc, x0 + i, y0 - 1, x0 + i, y0, rpl_top, 0, off_y, has_horizontal_sb);
TAB_BS(fc->tab.horizontal_bs[LUMA], x0 + i, y0) = bs;
@@ -642,12 +632,7 @@ static void vvc_deblock_bs_luma_horizontal(const VVCLocalContext *lc,
static void vvc_deblock_bs_chroma_vertical(const VVCLocalContext *lc,
const int x0, const int y0, const int width, const int height)
{
- const VVCFrameContext *fc = lc->fc;
- const MvField *tab_mvf = fc->tab.mvf;
- const int log2_min_pu_size = MIN_PU_LOG2;
- const int log2_min_tu_size = MIN_PU_LOG2;
- const int min_pu_width = fc->ps.pps->min_pu_width;
- const int min_tu_width = fc->ps.pps->min_tu_width;
+ const VVCFrameContext *fc = lc->fc;
int boundary_left;
// bs for vertical TU boundaries
@@ -662,34 +647,11 @@ static void vvc_deblock_bs_chroma_vertical(const VVCLocalContext *lc,
boundary_left = 0;
if (boundary_left) {
- const int xp_pu = (x0 - 1) >> log2_min_pu_size;
- const int xq_pu = x0 >> log2_min_pu_size;
- const int xp_tu = (x0 - 1) >> log2_min_tu_size;
- const int xq_tu = x0 >> log2_min_tu_size;
-
for (int i = 0; i < height; i += 2) {
- const int y_pu = (y0 + i) >> log2_min_pu_size;
- const int y_tu = (y0 + i) >> log2_min_tu_size;
- const MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
- const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
- const int left_tu = y_tu * min_tu_width + xp_tu;
- const int curr_tu = y_tu * min_tu_width + xq_tu;
- const uint8_t pcmf = fc->tab.pcmf[CHROMA][left_tu] && fc->tab.pcmf[CHROMA][curr_tu];
-
- for (int c = CB; c <= CR; c++) {
- uint8_t cbf = fc->tab.tu_coded_flag[c][left_tu] |
- fc->tab.tu_coded_flag[c][curr_tu] |
- fc->tab.tu_joint_cbcr_residual_flag[left_tu] |
- fc->tab.tu_joint_cbcr_residual_flag[curr_tu];
- int bs = 0;
-
- if (pcmf)
- bs = 0;
- else if (curr->pred_flag == PF_INTRA || left->pred_flag == PF_INTRA || curr->ciip_flag || left->ciip_flag)
- bs = 2;
- else if (cbf)
- bs = 1;
- TAB_BS(fc->tab.vertical_bs[c], x0, (y0 + i)) = bs;
+ for (int c_idx = CB; c_idx <= CR; c_idx++) {
+ const int bs = deblock_bs(lc, x0 - 1, y0 + i, x0, y0 + i, NULL, c_idx, 0, 0);
+
+ TAB_BS(fc->tab.vertical_bs[c_idx], x0, (y0 + i)) = bs;
}
}
}
@@ -699,11 +661,6 @@ static void vvc_deblock_bs_chroma_horizontal(const VVCLocalContext *lc,
const int x0, const int y0, const int width, const int height)
{
const VVCFrameContext *fc = lc->fc;
- MvField *tab_mvf = fc->tab.mvf;
- const int log2_min_pu_size = MIN_PU_LOG2;
- const int log2_min_tu_size = MIN_PU_LOG2;
- const int min_pu_width = fc->ps.pps->min_pu_width;
- const int min_tu_width = fc->ps.pps->min_tu_width;
int boundary_upper;
boundary_upper = y0 > 0 && !(y0 & ((CHROMA_GRID << fc->ps.sps->vshift[1]) - 1));
@@ -717,34 +674,11 @@ static void vvc_deblock_bs_chroma_horizontal(const VVCLocalContext *lc,
boundary_upper = 0;
if (boundary_upper) {
- int yp_pu = (y0 - 1) >> log2_min_pu_size;
- int yq_pu = y0 >> log2_min_pu_size;
- int yp_tu = (y0 - 1) >> log2_min_tu_size;
- int yq_tu = y0 >> log2_min_tu_size;
-
for (int i = 0; i < width; i += 2) {
- const int x_pu = (x0 + i) >> log2_min_pu_size;
- const int x_tu = (x0 + i) >> log2_min_tu_size;
- const MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
- const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
- const int top_tu = yp_tu * min_tu_width + x_tu;
- const int curr_tu = yq_tu * min_tu_width + x_tu;
- const uint8_t pcmf = fc->tab.pcmf[CHROMA][top_tu] && fc->tab.pcmf[CHROMA][curr_tu];
-
- for (int c = CB; c <= CR; c++) {
- uint8_t cbf = fc->tab.tu_coded_flag[c][top_tu] |
- fc->tab.tu_coded_flag[c][curr_tu] |
- fc->tab.tu_joint_cbcr_residual_flag[top_tu] |
- fc->tab.tu_joint_cbcr_residual_flag[curr_tu];
- int bs = 0;
-
- if (pcmf)
- bs = 0;
- else if (curr->pred_flag == PF_INTRA || top->pred_flag == PF_INTRA || curr->ciip_flag || top->ciip_flag)
- bs = 2;
- else if (cbf)
- bs = 1;
- TAB_BS(fc->tab.horizontal_bs[c], x0 + i, y0) = bs;
+ for (int c_idx = CB; c_idx <= CR; c_idx++) {
+ const int bs = deblock_bs(lc, x0 + i, y0 - 1, x0 + i, y0, NULL, c_idx, 0, 0);
+
+ TAB_BS(fc->tab.horizontal_bs[c_idx], x0 + i, y0) = bs;
}
}
}
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* [FFmpeg-devel] [PATCH 02/11] avcodec/vvcdec: set CuPredMode table for chroma
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 01/11] avcodec/vvcdec: refact out deblock_bs to reduce duplicate code Nuo Mi
@ 2024-02-22 7:13 ` Nuo Mi
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 03/11] avcodec/vvcdec: deblock_bs, fix intra check for IBC Nuo Mi
` (8 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-22 7:13 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Nuo Mi
follow the spec
---
libavcodec/vvc/vvc_ctu.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/libavcodec/vvc/vvc_ctu.c b/libavcodec/vvc/vvc_ctu.c
index 36f98f5f2b..2e48f7bed8 100644
--- a/libavcodec/vvc/vvc_ctu.c
+++ b/libavcodec/vvc/vvc_ctu.c
@@ -1227,9 +1227,12 @@ static void set_cu_tabs(const VVCLocalContext *lc, const CodingUnit *cu)
const VVCFrameContext *fc = lc->fc;
const TransformUnit *tu = cu->tus.head;
- set_cb_tab(lc, fc->tab.cpm[cu->ch_type], cu->pred_mode);
- if (cu->tree_type != DUAL_TREE_CHROMA)
+ if (cu->tree_type != DUAL_TREE_CHROMA) {
+ set_cb_tab(lc, fc->tab.cpm[LUMA], cu->pred_mode);
set_cb_tab(lc, fc->tab.skip, cu->skip_flag);
+ }
+ if (fc->ps.sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA)
+ set_cb_tab(lc, fc->tab.cpm[CHROMA], cu->pred_mode);
while (tu) {
for (int j = 0; j < tu->nb_tbs; j++) {
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* [FFmpeg-devel] [PATCH 03/11] avcodec/vvcdec: deblock_bs, fix intra check for IBC
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 01/11] avcodec/vvcdec: refact out deblock_bs to reduce duplicate code Nuo Mi
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 02/11] avcodec/vvcdec: set CuPredMode table for chroma Nuo Mi
@ 2024-02-22 7:13 ` Nuo Mi
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 04/11] avcodec/vvcdec: cabac, fix non_inter_flag, pred_mode_flag, amvr_shift " Nuo Mi
` (7 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-22 7:13 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Nuo Mi
An Intra Block Copy clip may use different modes for luma and chroma.
For example, MODE_IBC for luma and MODE_INTRA for chroma.
We have to check luma and chroma CuPredMode (cpm) separately.
---
libavcodec/vvc/vvc_filter.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/libavcodec/vvc/vvc_filter.c b/libavcodec/vvc/vvc_filter.c
index ca541fd997..379d90d02b 100644
--- a/libavcodec/vvc/vvc_filter.c
+++ b/libavcodec/vvc/vvc_filter.c
@@ -482,8 +482,10 @@ static av_always_inline int deblock_bs(const VVCLocalContext *lc,
const MvField *tab_mvf = fc->tab.mvf;
const int log2_min_pu_size = MIN_PU_LOG2;
const int log2_min_tu_size = MIN_TU_LOG2;
+ const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y;
const int min_pu_width = fc->ps.pps->min_pu_width;
const int min_tu_width = fc->ps.pps->min_tu_width;
+ const int min_cb_width = fc->ps.pps->min_cb_width;
const int pu_p = (y_p >> log2_min_pu_size) * min_pu_width + (x_p >> log2_min_pu_size);
const int pu_q = (y_q >> log2_min_pu_size) * min_pu_width + (x_q >> log2_min_pu_size);
const MvField *mvf_p = &tab_mvf[pu_p];
@@ -492,11 +494,14 @@ static av_always_inline int deblock_bs(const VVCLocalContext *lc,
const int tu_p = (y_p >> log2_min_tu_size) * min_tu_width + (x_p >> log2_min_tu_size);
const int tu_q = (y_q >> log2_min_tu_size) * min_tu_width + (x_q >> log2_min_tu_size);
const uint8_t pcmf = fc->tab.pcmf[chroma][tu_p] && fc->tab.pcmf[chroma][tu_q];
+ const int cb_p = (y_p >> log2_min_cb_size) * min_cb_width + (x_p >> log2_min_cb_size);
+ const int cb_q = (y_q >> log2_min_cb_size) * min_cb_width + (x_q >> log2_min_cb_size);
+ const uint8_t intra = fc->tab.cpm[chroma][cb_p] == MODE_INTRA || fc->tab.cpm[chroma][cb_q] == MODE_INTRA;
if (pcmf)
return 0;
- if (mvf_p->pred_flag == PF_INTRA || mvf_q->pred_flag == PF_INTRA || mvf_p->ciip_flag || mvf_q->ciip_flag)
+ if (intra || mvf_p->ciip_flag || mvf_q->ciip_flag)
return 2;
if (chroma) {
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* [FFmpeg-devel] [PATCH 04/11] avcodec/vvcdec: cabac, fix non_inter_flag, pred_mode_flag, amvr_shift for IBC
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
` (2 preceding siblings ...)
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 03/11] avcodec/vvcdec: deblock_bs, fix intra check for IBC Nuo Mi
@ 2024-02-22 7:13 ` Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 05/11] avcodec/vvcdec: implement update_hmvp " Nuo Mi
` (6 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-22 7:13 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Nuo Mi
---
libavcodec/vvc/vvc_cabac.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libavcodec/vvc/vvc_cabac.c b/libavcodec/vvc/vvc_cabac.c
index 4342dfc342..5e24a1b677 100644
--- a/libavcodec/vvc/vvc_cabac.c
+++ b/libavcodec/vvc/vvc_cabac.c
@@ -1196,10 +1196,10 @@ VVCSplitMode ff_vvc_split_mode(VVCLocalContext *lc, const int x0, const int y0,
int ff_vvc_non_inter_flag(VVCLocalContext *lc, const int x0, const int y0, const int ch_type)
{
const VVCFrameContext *fc = lc->fc;
- uint8_t inc, left = 0, top = 0;
+ uint8_t inc, left = MODE_INTER, top = MODE_INTER;
get_left_top(lc, &left, &top, x0, y0, fc->tab.cpm[ch_type], fc->tab.cpm[ch_type]);
- inc = left || top;
+ inc = left == MODE_INTRA || top == MODE_INTRA;
return GET_CABAC(NON_INTER_FLAG + inc);
}
@@ -1207,10 +1207,10 @@ int ff_vvc_pred_mode_flag(VVCLocalContext *lc, const int is_chroma)
{
const VVCFrameContext *fc = lc->fc;
const CodingUnit *cu = lc->cu;
- uint8_t inc, left = 0, top = 0;
+ uint8_t inc, left = MODE_INTER, top = MODE_INTER;
get_left_top(lc, &left, &top, cu->x0, cu->y0, fc->tab.cpm[is_chroma], fc->tab.cpm[is_chroma]);
- inc = left || top;
+ inc = left == MODE_INTRA || top == MODE_INTRA;
return GET_CABAC(PRED_MODE_FLAG + inc);
}
@@ -1569,7 +1569,7 @@ int ff_vvc_amvr_shift(VVCLocalContext *lc, const int inter_affine_flag,
{
int amvr_shift = 2;
if (has_amvr_flag) {
- if (amvr_flag(lc, inter_affine_flag)) {
+ if (pred_mode == MODE_IBC || amvr_flag(lc, inter_affine_flag)) {
int idx;
if (inter_affine_flag) {
idx = amvr_precision_idx(lc, 2, 1);
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* [FFmpeg-devel] [PATCH 05/11] avcodec/vvcdec: implement update_hmvp for IBC
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
` (3 preceding siblings ...)
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 04/11] avcodec/vvcdec: cabac, fix non_inter_flag, pred_mode_flag, amvr_shift " Nuo Mi
@ 2024-02-22 7:14 ` Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 06/11] avcodec/vvcdec: skip inter prediction for IBC blocks Nuo Mi
` (5 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-22 7:14 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Nuo Mi, Wu Jianhua
From: Wu Jianhua <toqsxw@outlook.com>
Signed-off-by: Wu Jianhua <toqsxw@outlook.com>
Signed-off-by: Nuo Mi <nuomi2021@gmail.com>
---
libavcodec/vvc/vvc_ctu.c | 9 +++++--
libavcodec/vvc/vvc_ctu.h | 3 +++
libavcodec/vvc/vvc_mvs.c | 53 ++++++++++++++++++++++++++--------------
3 files changed, 44 insertions(+), 21 deletions(-)
diff --git a/libavcodec/vvc/vvc_ctu.c b/libavcodec/vvc/vvc_ctu.c
index 2e48f7bed8..b78a1417c7 100644
--- a/libavcodec/vvc/vvc_ctu.c
+++ b/libavcodec/vvc/vvc_ctu.c
@@ -1717,10 +1717,15 @@ static int inter_data(VVCLocalContext *lc)
} else {
ret = mvp_data(lc);
}
- if (!pu->merge_gpm_flag && !pu->inter_affine_flag && !pu->merge_subblock_flag) {
+
+ if (cu->pred_mode == MODE_IBC)
+ {
+ ff_vvc_update_hmvp(lc, mi);
+ } else if (!pu->merge_gpm_flag && !pu->inter_affine_flag && !pu->merge_subblock_flag) {
refine_regular_subblock(lc);
ff_vvc_update_hmvp(lc, mi);
}
+
if (!pu->dmvr_flag)
fill_dmvr_info(lc->fc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
return ret;
@@ -2394,8 +2399,8 @@ int ff_vvc_coding_tree_unit(VVCLocalContext *lc,
int ret;
if (rx == pps->ctb_to_col_bd[rx]) {
- //fix me for ibc
ep->num_hmvp = 0;
+ ep->num_hmvp_ibc = 0;
ep->is_first_qg = ry == pps->ctb_to_row_bd[ry] || !ctu_idx;
}
diff --git a/libavcodec/vvc/vvc_ctu.h b/libavcodec/vvc/vvc_ctu.h
index ab3fac626d..5ed331a831 100644
--- a/libavcodec/vvc/vvc_ctu.h
+++ b/libavcodec/vvc/vvc_ctu.h
@@ -357,8 +357,11 @@ typedef struct EntryPoint {
int ctu_end;
uint8_t is_first_qg; // first quantization group
+
MvField hmvp[MAX_NUM_HMVP_CANDS]; ///< HmvpCandList
int num_hmvp; ///< NumHmvpCand
+ MvField hmvp_ibc[MAX_NUM_HMVP_CANDS]; ///< HmvpIbcCandList
+ int num_hmvp_ibc; ///< NumHmvpIbcCand
} EntryPoint;
typedef struct VVCLocalContext {
diff --git a/libavcodec/vvc/vvc_mvs.c b/libavcodec/vvc/vvc_mvs.c
index 2ed05ad2a4..8af57e8ed3 100644
--- a/libavcodec/vvc/vvc_mvs.c
+++ b/libavcodec/vvc/vvc_mvs.c
@@ -1758,34 +1758,49 @@ static av_always_inline int is_greater_mer(const VVCFrameContext *fc, const int
y0_br >> plevel > y0 >> plevel;
}
-//8.5.2.16 Updating process for the history-based motion vector predictor candidate list
-void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi)
+static void update_hmvp(MvField *hmvp, int *num_hmvp, const MvField *mvf,
+ int (*compare)(const MvField *n, const MvField *o))
{
- const VVCFrameContext *fc = lc->fc;
- const CodingUnit *cu = lc->cu;
- const int min_pu_width = fc->ps.pps->min_pu_width;
- const MvField* tab_mvf = fc->tab.mvf;
- EntryPoint* ep = lc->ep;
- const MvField *mvf;
int i;
-
- if (!is_greater_mer(fc, cu->x0, cu->y0, cu->x0 + cu->cb_width, cu->y0 + cu->cb_height))
- return;
- mvf = &TAB_MVF(cu->x0, cu->y0);
-
- for (i = 0; i < ep->num_hmvp; i++) {
- if (compare_mv_ref_idx(mvf, ep->hmvp + i)) {
- ep->num_hmvp--;
+ for (i = 0; i < *num_hmvp; i++) {
+ if (compare(mvf, hmvp + i)) {
+ (*num_hmvp)--;
break;
}
}
if (i == MAX_NUM_HMVP_CANDS) {
- ep->num_hmvp--;
+ (*num_hmvp)--;
i = 0;
}
- memmove(ep->hmvp + i, ep->hmvp + i + 1, (ep->num_hmvp - i) * sizeof(MvField));
- ep->hmvp[ep->num_hmvp++] = *mvf;
+ memmove(hmvp + i, hmvp + i + 1, (*num_hmvp - i) * sizeof(MvField));
+ hmvp[(*num_hmvp)++] = *mvf;
+}
+
+static int compare_l0_mv(const MvField *n, const MvField *o)
+{
+ return IS_SAME_MV(&n->mv[L0], &o->mv[L0]);
+}
+
+//8.6.2.4 Derivation process for IBC history-based block vector candidates
+//8.5.2.16 Updating process for the history-based motion vector predictor candidate list
+void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi)
+{
+ const VVCFrameContext *fc = lc->fc;
+ const CodingUnit *cu = lc->cu;
+ const int min_pu_width = fc->ps.pps->min_pu_width;
+ const MvField *tab_mvf = fc->tab.mvf;
+ EntryPoint *ep = lc->ep;
+
+ if (cu->pred_mode == MODE_IBC) {
+ if (cu->cb_width * cu->cb_height <= 16)
+ return;
+ update_hmvp(ep->hmvp_ibc, &ep->num_hmvp_ibc, &TAB_MVF(cu->x0, cu->y0), compare_l0_mv);
+ } else {
+ if (!is_greater_mer(fc, cu->x0, cu->y0, cu->x0 + cu->cb_width, cu->y0 + cu->cb_height))
+ return;
+ update_hmvp(ep->hmvp, &ep->num_hmvp, &TAB_MVF(cu->x0, cu->y0), compare_mv_ref_idx);
+ }
}
MvField* ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0)
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* [FFmpeg-devel] [PATCH 06/11] avcodec/vvcdec: skip inter prediction for IBC blocks
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
` (4 preceding siblings ...)
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 05/11] avcodec/vvcdec: implement update_hmvp " Nuo Mi
@ 2024-02-22 7:14 ` Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 07/11] avcodec/vvcdec: ff_vvc_set_intra_mvf, refact to support dmvr tab Nuo Mi
` (4 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-22 7:14 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Nuo Mi
Intra Block Copy relies on reconstructed pixels from the current frame.
We skip IBC during the inter prediction stage and handle it during the reconstruction stage.
---
libavcodec/vvc/vvc_inter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavcodec/vvc/vvc_inter.c b/libavcodec/vvc/vvc_inter.c
index 6c9c8a7165..d5be32aa14 100644
--- a/libavcodec/vvc/vvc_inter.c
+++ b/libavcodec/vvc/vvc_inter.c
@@ -893,7 +893,7 @@ static void predict_inter(VVCLocalContext *lc)
static int has_inter_luma(const CodingUnit *cu)
{
- return cu->pred_mode != MODE_INTRA && cu->pred_mode != MODE_PLT && cu->tree_type != DUAL_TREE_CHROMA;
+ return (cu->pred_mode == MODE_INTER || cu->pred_mode == MODE_SKIP) && cu->tree_type != DUAL_TREE_CHROMA;
}
int ff_vvc_predict_inter(VVCLocalContext *lc, const int rs)
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* [FFmpeg-devel] [PATCH 07/11] avcodec/vvcdec: ff_vvc_set_intra_mvf, refact to support dmvr tab
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
` (5 preceding siblings ...)
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 06/11] avcodec/vvcdec: skip inter prediction for IBC blocks Nuo Mi
@ 2024-02-22 7:14 ` Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 08/11] avcodec/vvcdec: fix dual tree for skipped transform tree/unit Nuo Mi
` (3 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-22 7:14 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Nuo Mi
---
libavcodec/vvc/vvc_ctu.c | 2 +-
libavcodec/vvc/vvc_mvs.c | 4 ++--
libavcodec/vvc/vvc_mvs.h | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libavcodec/vvc/vvc_ctu.c b/libavcodec/vvc/vvc_ctu.c
index b78a1417c7..00476c81e4 100644
--- a/libavcodec/vvc/vvc_ctu.c
+++ b/libavcodec/vvc/vvc_ctu.c
@@ -1776,7 +1776,7 @@ static int hls_coding_unit(VVCLocalContext *lc, int x0, int y0, int cb_width, in
} else {
intra_luma_pred_modes(lc);
}
- ff_vvc_set_intra_mvf(lc);
+ ff_vvc_set_intra_mvf(lc, 0);
}
if ((tree_type == SINGLE_TREE || tree_type == DUAL_TREE_CHROMA) && sps->r->sps_chroma_format_idc) {
if (pred_mode_plt_flag && tree_type == DUAL_TREE_CHROMA) {
diff --git a/libavcodec/vvc/vvc_mvs.c b/libavcodec/vvc/vvc_mvs.c
index 8af57e8ed3..8fdbb00a41 100644
--- a/libavcodec/vvc/vvc_mvs.c
+++ b/libavcodec/vvc/vvc_mvs.c
@@ -262,11 +262,11 @@ void ff_vvc_set_mvf(const VVCLocalContext *lc, const int x0, const int y0, const
}
}
-void ff_vvc_set_intra_mvf(const VVCLocalContext *lc)
+void ff_vvc_set_intra_mvf(const VVCLocalContext *lc, const int dmvr)
{
const VVCFrameContext *fc = lc->fc;
const CodingUnit *cu = lc->cu;
- MvField *tab_mvf = fc->tab.mvf;
+ MvField *tab_mvf = dmvr ? fc->ref->tab_dmvr_mvf : fc->tab.mvf;
const int min_pu_width = fc->ps.pps->min_pu_width;
const int min_pu_size = 1 << MIN_PU_LOG2;
for (int dy = 0; dy < cu->cb_height; dy += min_pu_size) {
diff --git a/libavcodec/vvc/vvc_mvs.h b/libavcodec/vvc/vvc_mvs.h
index 6c46f9fdb2..358de5ec45 100644
--- a/libavcodec/vvc/vvc_mvs.h
+++ b/libavcodec/vvc/vvc_mvs.h
@@ -41,6 +41,6 @@ void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi);
int ff_vvc_no_backward_pred_flag(const VVCLocalContext *lc);
MvField* ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0);
void ff_vvc_set_mvf(const VVCLocalContext *lc, const int x0, const int y0, const int w, const int h, const MvField *mvf);
-void ff_vvc_set_intra_mvf(const VVCLocalContext *lc);
+void ff_vvc_set_intra_mvf(const VVCLocalContext *lc, int dmvr);
#endif //AVCODEC_VVC_VVC_MVS_H
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* [FFmpeg-devel] [PATCH 08/11] avcodec/vvcdec: fix dual tree for skipped transform tree/unit
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
` (6 preceding siblings ...)
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 07/11] avcodec/vvcdec: ff_vvc_set_intra_mvf, refact to support dmvr tab Nuo Mi
@ 2024-02-22 7:14 ` Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 09/11] avcodec/vvcdec: refact, rename !is_mvp to check_mer Nuo Mi
` (2 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-22 7:14 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Nuo Mi
fix IBC_E_Tencent_1.bit
---
libavcodec/vvc/vvc_ctu.c | 24 +++++++++++++++---------
libavcodec/vvc/vvc_intra.c | 6 ++++--
2 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/libavcodec/vvc/vvc_ctu.c b/libavcodec/vvc/vvc_ctu.c
index 00476c81e4..2cf6e82f26 100644
--- a/libavcodec/vvc/vvc_ctu.c
+++ b/libavcodec/vvc/vvc_ctu.c
@@ -481,8 +481,9 @@ static int hls_transform_tree(VVCLocalContext *lc, int x0, int y0,int tu_width,
static int skipped_transform_tree(VVCLocalContext *lc, int x0, int y0,int tu_width, int tu_height)
{
- VVCFrameContext *fc = lc->fc;
- const VVCSPS *sps = fc->ps.sps;
+ VVCFrameContext *fc = lc->fc;
+ const CodingUnit *cu = lc->cu;
+ const VVCSPS *sps = fc->ps.sps;
if (tu_width > sps->max_tb_size_y || tu_height > sps->max_tb_size_y) {
const int ver_split_first = tu_width > sps->max_tb_size_y && tu_width > tu_height;
@@ -501,11 +502,14 @@ static int skipped_transform_tree(VVCLocalContext *lc, int x0, int y0,int tu_wid
else
SKIPPED_TRANSFORM_TREE(x0, y0 + trafo_height);
} else {
- TransformUnit *tu = add_tu(fc, lc->cu, x0, y0, tu_width, tu_height);
- const int c_end = sps->r->sps_chroma_format_idc ? VVC_MAX_SAMPLE_ARRAYS : (LUMA + 1);
+ TransformUnit *tu = add_tu(fc, lc->cu, x0, y0, tu_width, tu_height);
+ const int has_chroma = sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA;
+ const int c_start = cu->tree_type == DUAL_TREE_CHROMA ? CB : LUMA;
+ const int c_end = has_chroma ? VVC_MAX_SAMPLE_ARRAYS : CB;
+
if (!tu)
return AVERROR_INVALIDDATA;
- for (int i = LUMA; i < c_end; i++) {
+ for (int i = c_start; i < c_end; i++) {
TransformBlock *tb = add_tb(tu, lc, x0, y0, tu_width >> sps->hshift[i], tu_height >> sps->vshift[i], i);
if (i != CR)
set_tb_pos(fc, tb);
@@ -1125,11 +1129,14 @@ static void sbt_info(VVCLocalContext *lc, const VVCSPS *sps)
static int skipped_transform_tree_unit(VVCLocalContext *lc)
{
- const CodingUnit *cu = lc->cu;
+ const H266RawSPS *rsps = lc->fc->ps.sps->r;
+ const CodingUnit *cu = lc->cu;
int ret;
- set_qp_y(lc, cu->x0, cu->y0, 0);
- set_qp_c(lc);
+ if (cu->tree_type != DUAL_TREE_CHROMA)
+ set_qp_y(lc, cu->x0, cu->y0, 0);
+ if (rsps->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA)
+ set_qp_c(lc);
ret = skipped_transform_tree(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
if (ret < 0)
return ret;
@@ -1815,7 +1822,6 @@ static int hls_coding_unit(VVCLocalContext *lc, int x0, int y0, int cb_width, in
if (ret < 0)
return ret;
} else {
- av_assert0(tree_type == SINGLE_TREE);
ret = skipped_transform_tree_unit(lc);
if (ret < 0)
return ret;
diff --git a/libavcodec/vvc/vvc_intra.c b/libavcodec/vvc/vvc_intra.c
index 214ad38c8c..fb001d6713 100644
--- a/libavcodec/vvc/vvc_intra.c
+++ b/libavcodec/vvc/vvc_intra.c
@@ -602,8 +602,10 @@ int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const in
if (cu->coded_flag) {
ret = reconstruct(lc);
} else {
- add_reconstructed_area(lc, LUMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
- add_reconstructed_area(lc, CHROMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
+ if (cu->tree_type != DUAL_TREE_CHROMA)
+ add_reconstructed_area(lc, LUMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
+ if (sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA)
+ add_reconstructed_area(lc, CHROMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
}
cu = cu->next;
}
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* [FFmpeg-devel] [PATCH 09/11] avcodec/vvcdec: refact, rename !is_mvp to check_mer
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
` (7 preceding siblings ...)
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 08/11] avcodec/vvcdec: fix dual tree for skipped transform tree/unit Nuo Mi
@ 2024-02-22 7:14 ` Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 10/11] avcodec/vvcdec: add Intra Block Copy parser Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 11/11] avcodec/vvcdec: add Intra Block Copy decoder Nuo Mi
10 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-22 7:14 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Nuo Mi
For IBC, we'll utilize the check_available function.
However, neither MVP nor merge mode need to check the motion estimation region.
Let's rename it to avoid confusion.
---
libavcodec/vvc/vvc_mvs.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/libavcodec/vvc/vvc_mvs.c b/libavcodec/vvc/vvc_mvs.c
index 8fdbb00a41..56e4009741 100644
--- a/libavcodec/vvc/vvc_mvs.c
+++ b/libavcodec/vvc/vvc_mvs.c
@@ -589,7 +589,7 @@ static void init_neighbour_context(NeighbourContext *ctx, const VVCLocalContext
ctx->lc = lc;
}
-static int check_available(Neighbour *n, const VVCLocalContext *lc, const int is_mvp)
+static int check_available(Neighbour *n, const VVCLocalContext *lc, const int check_mer)
{
const VVCFrameContext *fc = lc->fc;
const VVCSPS *sps = fc->ps.sps;
@@ -601,7 +601,7 @@ static int check_available(Neighbour *n, const VVCLocalContext *lc, const int is
n->checked = 1;
n->available = !sps->r->sps_entropy_coding_sync_enabled_flag || ((n->x >> sps->ctb_log2_size_y) <= (cu->x0 >> sps->ctb_log2_size_y));
n->available &= TAB_MVF(n->x, n->y).pred_flag != PF_INTRA;
- if (!is_mvp)
+ if (check_mer)
n->available &= !is_same_mer(fc, n->x, n->y, cu->x0, cu->y0);
}
return n->available;
@@ -620,10 +620,9 @@ static const MvField *mv_merge_candidate(const VVCLocalContext *lc, const int x_
static const MvField* mv_merge_from_nb(NeighbourContext *ctx, const NeighbourIdx nb)
{
const VVCLocalContext *lc = ctx->lc;
- const int is_mvp = 0;
Neighbour *n = &ctx->neighbours[nb];
- if (check_available(n, lc, is_mvp))
+ if (check_available(n, lc, 1))
return mv_merge_candidate(lc, n->x, n->y);
return 0;
}
@@ -943,10 +942,9 @@ static int affine_merge_candidate(const VVCLocalContext *lc, const int x_cand, c
static int affine_merge_from_nbs(NeighbourContext *ctx, const NeighbourIdx *nbs, const int num_nbs, MotionInfo* cand)
{
const VVCLocalContext *lc = ctx->lc;
- const int is_mvp = 0;
for (int i = 0; i < num_nbs; i++) {
Neighbour *n = &ctx->neighbours[nbs[i]];
- if (check_available(n, lc, is_mvp) && affine_merge_candidate(lc, n->x, n->y, cand))
+ if (check_available(n, lc, 1) && affine_merge_candidate(lc, n->x, n->y, cand))
return 1;
}
return 0;
@@ -961,7 +959,7 @@ static const MvField* derive_corner_mvf(NeighbourContext *ctx, const NeighbourId
const int min_pu_width = fc->ps.pps->min_pu_width;
for (int i = 0; i < num_neighbour; i++) {
Neighbour *n = &ctx->neighbours[neighbour[i]];
- if (check_available(n, ctx->lc, 0)) {
+ if (check_available(n, ctx->lc, 1)) {
return &TAB_MVF(n->x, n->y);
}
}
@@ -1461,12 +1459,11 @@ static int mvp_from_nbs(NeighbourContext *ctx,
Mv *cps, const int num_cps)
{
const VVCLocalContext *lc = ctx->lc;
- const int is_mvp = 1;
int available = 0;
for (int i = 0; i < num_nbs; i++) {
Neighbour *n = &ctx->neighbours[nbs[i]];
- if (check_available(n, lc, is_mvp)) {
+ if (check_available(n, lc, 0)) {
if (num_cps > 1)
available = affine_mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps, num_cps);
else
@@ -1601,12 +1598,11 @@ static int affine_mvp_constructed_cp(NeighbourContext *ctx,
const MvField *tab_mvf = fc->tab.mvf;
const int min_pu_width = fc->ps.pps->min_pu_width;
const RefPicList* rpl = lc->sc->rpl;
- const int is_mvp = 1;
int available = 0;
for (int i = 0; i < num_neighbour; i++) {
Neighbour *n = &ctx->neighbours[neighbour[i]];
- if (check_available(n, ctx->lc, is_mvp)) {
+ if (check_available(n, ctx->lc, 0)) {
const PredFlag maskx = lx + 1;
const MvField* mvf = &TAB_MVF(n->x, n->y);
const int poc = rpl[lx].list[ref_idx];
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* [FFmpeg-devel] [PATCH 10/11] avcodec/vvcdec: add Intra Block Copy parser
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
` (8 preceding siblings ...)
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 09/11] avcodec/vvcdec: refact, rename !is_mvp to check_mer Nuo Mi
@ 2024-02-22 7:14 ` Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 11/11] avcodec/vvcdec: add Intra Block Copy decoder Nuo Mi
10 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-22 7:14 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Nuo Mi, Wu Jianhua
From: Wu Jianhua <toqsxw@outlook.com>
Co-authored-by: Nuo Mi <nuomi2021@gmail.com>
---
libavcodec/vvc/vvc_ctu.c | 76 +++++++++++++++++++++-----
libavcodec/vvc/vvc_ctu.h | 1 +
libavcodec/vvc/vvc_mvs.c | 113 ++++++++++++++++++++++++++++++++++++++-
libavcodec/vvc/vvc_mvs.h | 2 +
4 files changed, 177 insertions(+), 15 deletions(-)
diff --git a/libavcodec/vvc/vvc_ctu.c b/libavcodec/vvc/vvc_ctu.c
index 2cf6e82f26..75b9e73ae3 100644
--- a/libavcodec/vvc/vvc_ctu.c
+++ b/libavcodec/vvc/vvc_ctu.c
@@ -1444,6 +1444,22 @@ static void merge_data_block(VVCLocalContext *lc)
}
}
+static void merge_data_ibc(VVCLocalContext *lc)
+{
+ const VVCFrameContext* fc = lc->fc;
+ const VVCSPS* sps = fc->ps.sps;
+ MotionInfo *mi = &lc->cu->pu.mi;
+ int merge_idx = 0;
+
+ mi->pred_flag = PF_IBC;
+
+ if (sps->max_num_ibc_merge_cand > 1)
+ merge_idx = ff_vvc_merge_idx(lc);
+
+ ff_vvc_luma_mv_merge_ibc(lc, merge_idx, &mi->mv[L0][0]);
+ ff_vvc_store_mv(lc, mi);
+}
+
static int hls_merge_data(VVCLocalContext *lc)
{
const VVCFrameContext *fc = lc->fc;
@@ -1454,8 +1470,7 @@ static int hls_merge_data(VVCLocalContext *lc)
pu->merge_gpm_flag = 0;
pu->mi.num_sb_x = pu->mi.num_sb_y = 1;
if (cu->pred_mode == MODE_IBC) {
- avpriv_report_missing_feature(fc->log_ctx, "Intra Block Copy");
- return AVERROR_PATCHWELCOME;
+ merge_data_ibc(lc);
} else {
if (ph->max_num_subblock_merge_cand > 0 && cu->cb_width >= 8 && cu->cb_height >= 8)
pu->merge_subblock_flag = ff_vvc_merge_subblock_flag(lc);
@@ -1571,6 +1586,33 @@ static void mvp_add_difference(MotionInfo *mi, const int num_cp_mv,
}
}
+static int mvp_data_ibc(VVCLocalContext *lc)
+{
+ const VVCFrameContext *fc = lc->fc;
+ const CodingUnit *cu = lc->cu;
+ const PredictionUnit *pu = &lc->cu->pu;
+ const VVCSPS *sps = fc->ps.sps;
+ MotionInfo *mi = &lc->cu->pu.mi;
+ int mvp_l0_flag = 0;
+ int amvr_shift = 4;
+ Mv *mv = &mi->mv[L0][0];
+
+ mi->pred_flag = PF_IBC;
+ mi->num_sb_x = 1;
+ mi->num_sb_y = 1;
+
+ hls_mvd_coding(lc, mv);
+ if (sps->max_num_ibc_merge_cand > 1)
+ mvp_l0_flag = ff_vvc_mvp_lx_flag(lc);
+ if (sps->r->sps_amvr_enabled_flag && (mv->x || mv->y))
+ amvr_shift = ff_vvc_amvr_shift(lc, pu->inter_affine_flag, cu->pred_mode, 1);
+
+ ff_vvc_mvp_ibc(lc, mvp_l0_flag, amvr_shift, mv);
+ ff_vvc_store_mv(lc, mi);
+
+ return 0;
+}
+
static int mvp_data(VVCLocalContext *lc)
{
const VVCFrameContext *fc = lc->fc;
@@ -1691,17 +1733,24 @@ static void refine_regular_subblock(const VVCLocalContext *lc)
}
}
-static void fill_dmvr_info(const VVCFrameContext *fc, const int x0, const int y0,
- const int width, const int height)
+static void fill_dmvr_info(const VVCLocalContext *lc)
{
- const VVCPPS *pps = fc->ps.pps;
- const int w = width >> MIN_PU_LOG2;
+ const VVCFrameContext *fc = lc->fc;
+ const CodingUnit *cu = lc->cu;
+
+ if (cu->pred_mode == MODE_IBC) {
+ ff_vvc_set_intra_mvf(lc, 1);
+ } else {
+ const VVCPPS *pps = fc->ps.pps;
+ const int w = cu->cb_width >> MIN_PU_LOG2;
+
+ for (int y = cu->y0 >> MIN_PU_LOG2; y < (cu->y0 + cu->cb_height) >> MIN_PU_LOG2; y++) {
+ const int idx = pps->min_pu_width * y + (cu->x0 >> MIN_PU_LOG2);
+ const MvField *mvf = fc->tab.mvf + idx;
+ MvField *dmvr_mvf = fc->ref->tab_dmvr_mvf + idx;
- for (int y = y0 >> MIN_PU_LOG2; y < (y0 + height) >> MIN_PU_LOG2; y++) {
- const int idx = pps->min_pu_width * y + (x0 >> MIN_PU_LOG2);
- const MvField *mvf = fc->tab.mvf + idx;
- MvField *dmvr_mvf = fc->ref->tab_dmvr_mvf + idx;
- memcpy(dmvr_mvf, mvf, sizeof(MvField) * w);
+ memcpy(dmvr_mvf, mvf, sizeof(MvField) * w);
+ }
}
}
@@ -1719,8 +1768,7 @@ static int inter_data(VVCLocalContext *lc)
if (pu->general_merge_flag) {
hls_merge_data(lc);
} else if (cu->pred_mode == MODE_IBC){
- avpriv_report_missing_feature(lc->fc->log_ctx, "Intra Block Copy");
- return AVERROR_PATCHWELCOME;
+ ret = mvp_data_ibc(lc);
} else {
ret = mvp_data(lc);
}
@@ -1734,7 +1782,7 @@ static int inter_data(VVCLocalContext *lc)
}
if (!pu->dmvr_flag)
- fill_dmvr_info(lc->fc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
+ fill_dmvr_info(lc);
return ret;
}
diff --git a/libavcodec/vvc/vvc_ctu.h b/libavcodec/vvc/vvc_ctu.h
index 5ed331a831..8020e184c5 100644
--- a/libavcodec/vvc/vvc_ctu.h
+++ b/libavcodec/vvc/vvc_ctu.h
@@ -217,6 +217,7 @@ typedef enum PredFlag {
PF_L0 = 0x1,
PF_L1 = 0x2,
PF_BI = 0x3,
+ PF_IBC = PF_L0 | 0x4,
} PredFlag;
typedef enum IntraPredMode {
diff --git a/libavcodec/vvc/vvc_mvs.c b/libavcodec/vvc/vvc_mvs.c
index 56e4009741..6398fd3571 100644
--- a/libavcodec/vvc/vvc_mvs.c
+++ b/libavcodec/vvc/vvc_mvs.c
@@ -589,6 +589,11 @@ static void init_neighbour_context(NeighbourContext *ctx, const VVCLocalContext
ctx->lc = lc;
}
+static av_always_inline PredMode pred_flag_to_mode(PredFlag pred)
+{
+ return pred == PF_IBC ? MODE_IBC : (pred == PF_INTRA ? MODE_INTRA : MODE_INTER);
+}
+
static int check_available(Neighbour *n, const VVCLocalContext *lc, const int check_mer)
{
const VVCFrameContext *fc = lc->fc;
@@ -600,7 +605,7 @@ static int check_available(Neighbour *n, const VVCLocalContext *lc, const int ch
if (!n->checked) {
n->checked = 1;
n->available = !sps->r->sps_entropy_coding_sync_enabled_flag || ((n->x >> sps->ctb_log2_size_y) <= (cu->x0 >> sps->ctb_log2_size_y));
- n->available &= TAB_MVF(n->x, n->y).pred_flag != PF_INTRA;
+ n->available &= cu->pred_mode == pred_flag_to_mode(TAB_MVF(n->x, n->y).pred_flag);
if (check_mer)
n->available &= !is_same_mer(fc, n->x, n->y, cu->x0, cu->y0);
}
@@ -1589,6 +1594,112 @@ void ff_vvc_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shif
mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, &mi->mv[L1][0]);
}
+static int ibc_spatial_candidates(const VVCLocalContext *lc, const int merge_idx, Mv *const cand_list, int *nb_merge_cand)
+{
+ const CodingUnit *cu = lc->cu;
+ const VVCFrameContext *fc = lc->fc;
+ const int min_pu_width = fc->ps.pps->min_pu_width;
+ const MvField *tab_mvf = fc->tab.mvf;
+ const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16;
+ int num_cands = 0;
+
+ NeighbourContext nctx;
+ Neighbour *a1 = &nctx.neighbours[A1];
+ Neighbour *b1 = &nctx.neighbours[B1];
+
+ if (!is_gt4by4) {
+ *nb_merge_cand = 0;
+ return 0;
+ }
+
+ init_neighbour_context(&nctx, lc);
+
+ if (check_available(a1, lc, 1)) {
+ cand_list[num_cands++] = TAB_MVF(a1->x, a1->y).mv[L0];
+ if (num_cands > merge_idx)
+ return 1;
+ }
+ if (check_available(b1, lc, 1)) {
+ const MvField *mvf = &TAB_MVF(b1->x, b1->y);
+ if (!num_cands || !IS_SAME_MV(&cand_list[0], mvf->mv)) {
+ cand_list[num_cands++] = mvf->mv[L0];
+ if (num_cands > merge_idx)
+ return 1;
+ }
+ }
+
+ *nb_merge_cand = num_cands;
+ return 0;
+}
+
+static int ibc_history_candidates(const VVCLocalContext *lc,
+ const int merge_idx, Mv *cand_list, int *nb_merge_cand)
+{
+ const CodingUnit *cu = lc->cu;
+ const EntryPoint *ep = lc->ep;
+ const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16;
+ int num_cands = *nb_merge_cand;
+
+ for (int i = 1; i <= ep->num_hmvp_ibc; i++) {
+ int same_motion = 0;
+ const MvField *mvf = &ep->hmvp_ibc[ep->num_hmvp_ibc - i];
+ for (int j = 0; j < *nb_merge_cand; j++) {
+ same_motion = is_gt4by4 && i == 1 && IS_SAME_MV(&mvf->mv[L0], &cand_list[j]);
+ if (same_motion)
+ break;
+ }
+ if (!same_motion) {
+ cand_list[num_cands++] = mvf->mv[L0];
+ if (num_cands > merge_idx)
+ return 1;
+ }
+ }
+
+ *nb_merge_cand = num_cands;
+ return 0;
+}
+
+#define MV_BITS 18
+#define IBC_SHIFT(v) ((v) >= (1 << (MV_BITS - 1)) ? ((v) - (1 << MV_BITS)) : (v))
+
+static inline void ibc_add_mvp(Mv *mv, Mv *mvp, const int amvr_shift)
+{
+ ff_vvc_round_mv(mv, amvr_shift, 0);
+ ff_vvc_round_mv(mvp, amvr_shift, amvr_shift);
+ mv->x = IBC_SHIFT(mv->x + mvp->x);
+ mv->y = IBC_SHIFT(mv->y + mvp->y);
+}
+
+static void ibc_merge_candidates(VVCLocalContext *lc, const int merge_idx, Mv *mv)
+{
+ const CodingUnit *cu = lc->cu;
+ LOCAL_ALIGNED_8(Mv, cand_list, [MRG_MAX_NUM_CANDS]);
+ int nb_cands;
+
+ ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
+ if (ibc_spatial_candidates(lc, merge_idx, cand_list, &nb_cands) ||
+ ibc_history_candidates(lc, merge_idx, cand_list, &nb_cands)) {
+ *mv = cand_list[merge_idx];
+ return;
+ }
+
+ //zero mv
+ memset(mv, 0, sizeof(*mv));
+}
+
+void ff_vvc_mvp_ibc(VVCLocalContext *lc, const int mvp_l0_flag, const int amvr_shift, Mv *mv)
+{
+ LOCAL_ALIGNED_8(Mv, mvp, [1]);
+
+ ibc_merge_candidates(lc, mvp_l0_flag, mvp);
+ ibc_add_mvp(mv, mvp, amvr_shift);
+}
+
+void ff_vvc_luma_mv_merge_ibc(VVCLocalContext *lc, const int merge_idx, Mv *mv)
+{
+ ibc_merge_candidates(lc, merge_idx, mv);
+}
+
static int affine_mvp_constructed_cp(NeighbourContext *ctx,
const NeighbourIdx *neighbour, const int num_neighbour,
const int lx, const int8_t ref_idx, const int amvr_shift, Mv *cp)
diff --git a/libavcodec/vvc/vvc_mvs.h b/libavcodec/vvc/vvc_mvs.h
index 358de5ec45..a546a324c2 100644
--- a/libavcodec/vvc/vvc_mvs.h
+++ b/libavcodec/vvc/vvc_mvs.h
@@ -30,7 +30,9 @@ void ff_vvc_clip_mv(Mv *mv);
void ff_vvc_mv_scale(Mv *dst, const Mv *src, int td, int tb);
void ff_vvc_luma_mv_merge_mode(VVCLocalContext *lc, int merge_idx, int ciip_flag, MvField *mv);
void ff_vvc_luma_mv_merge_gpm(VVCLocalContext *lc, const int merge_gpm_idx[2], MvField *mv);
+void ff_vvc_luma_mv_merge_ibc(VVCLocalContext *lc, int merge_idx, Mv *mv);
void ff_vvc_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi);
+void ff_vvc_mvp_ibc(VVCLocalContext *lc, int mvp_l0_flag, int amvr_shift, Mv *mv);
void ff_vvc_sb_mv_merge_mode(VVCLocalContext *lc, int merge_subblock_idx, PredictionUnit *pu);
void ff_vvc_affine_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo* mi);
void ff_vvc_store_sb_mvs(const VVCLocalContext *lc, PredictionUnit *pu);
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* [FFmpeg-devel] [PATCH 11/11] avcodec/vvcdec: add Intra Block Copy decoder
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
` (9 preceding siblings ...)
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 10/11] avcodec/vvcdec: add Intra Block Copy parser Nuo Mi
@ 2024-02-22 7:14 ` Nuo Mi
2024-02-23 13:03 ` Nuo Mi
2024-02-24 13:20 ` Ronald S. Bultje
10 siblings, 2 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-22 7:14 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Nuo Mi, Wu Jianhua
From: Wu Jianhua <toqsxw@outlook.com>
Introduction at https://ieeexplore.ieee.org/document/9408666
passed files:
10b444_A_Kwai_3.bit
10b444_B_Kwai_3.bit
CodingToolsSets_D_Tencent_2.bit
IBC_A_Tencent_2.bit
IBC_B_Tencent_2.bit
IBC_C_Tencent_2.bit
IBC_D_Tencent_2.bit
IBC_E_Tencent_1.bit
LOSSLESS_B_HHI_3.bit
Signed-off-by: Wu Jianhua <toqsxw@outlook.com>
Signed-off-by: Nuo Mi <nuomi2021@gmail.com>
---
libavcodec/vvc/vvc_intra.c | 81 ++++++++++++++++++++++++++++++++++++++
libavcodec/vvc/vvcdec.c | 25 ++++++++++++
libavcodec/vvc/vvcdec.h | 3 ++
3 files changed, 109 insertions(+)
diff --git a/libavcodec/vvc/vvc_intra.c b/libavcodec/vvc/vvc_intra.c
index fb001d6713..58dd492478 100644
--- a/libavcodec/vvc/vvc_intra.c
+++ b/libavcodec/vvc/vvc_intra.c
@@ -20,11 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/frame.h"
+#include "libavutil/imgutils.h"
#include "vvc_data.h"
#include "vvc_inter.h"
#include "vvc_intra.h"
#include "vvc_itx_1d.h"
+#include "vvc_mvs.h"
static int is_cclm(enum IntraPredMode mode)
{
@@ -580,6 +582,81 @@ static int reconstruct(VVCLocalContext *lc)
return 0;
}
+#define POS(c_idx, x, y) \
+ &fc->frame->data[c_idx][((y) >> fc->ps.sps->vshift[c_idx]) * fc->frame->linesize[c_idx] + \
+ (((x) >> fc->ps.sps->hshift[c_idx]) << fc->ps.sps->pixel_shift)]
+
+#define IBC_POS(c_idx, x, y) \
+ (fc->tab.ibc_vir_buf[c_idx] + \
+ (x << ps) + (y + ((cu->y0 & ~(sps->ctb_size_y - 1)) >> vs)) * ibc_stride)
+#define IBC_X(x) ((x) & ((fc->tab.sz.ibc_buffer_width >> hs) - 1))
+#define IBC_Y(y) ((y) & ((1 << sps->ctb_log2_size_y >> vs) - 1))
+
+static void intra_block_copy(const VVCLocalContext *lc, const int c_idx)
+{
+ const CodingUnit *cu = lc->cu;
+ const PredictionUnit *pu = &cu->pu;
+ const VVCFrameContext *fc = lc->fc;
+ const VVCSPS *sps = fc->ps.sps;
+ const Mv *bv = &pu->mi.mv[L0][0];
+ const int hs = sps->hshift[c_idx];
+ const int vs = sps->vshift[c_idx];
+ const int ps = sps->pixel_shift;
+ const int ref_x = IBC_X((cu->x0 >> hs) + (bv->x >> (4 + hs)));
+ const int ref_y = IBC_Y((cu->y0 >> vs) + (bv->y >> (4 + vs)));
+ const int w = cu->cb_width >> hs;
+ const int h = cu->cb_height >> vs;
+ const int ibc_buf_width = fc->tab.sz.ibc_buffer_width >> hs; ///< IbcBufWidthY and IbcBufWidthC
+ const int rw = FFMIN(w, ibc_buf_width - ref_x);
+ const int ibc_stride = ibc_buf_width << ps;
+ const int dst_stride = fc->frame->linesize[c_idx];
+ const uint8_t *ibc_buf = IBC_POS(c_idx, ref_x, ref_y);
+ uint8_t *dst = POS(c_idx, cu->x0, cu->y0);
+
+ av_image_copy_plane(dst, dst_stride, ibc_buf, ibc_stride, rw << ps, h);
+
+ if (w > rw) {
+ //wrap around, left part
+ ibc_buf = IBC_POS(c_idx, 0, ref_y);
+ dst += rw << ps;
+ av_image_copy_plane(dst, dst_stride, ibc_buf, ibc_stride, (w - rw) << ps, h);
+ }
+}
+
+static void vvc_predict_ibc(const VVCLocalContext *lc)
+{
+ const H266RawSPS *rsps = lc->fc->ps.sps->r;
+
+ intra_block_copy(lc, LUMA);
+ if (lc->cu->tree_type == SINGLE_TREE && rsps->sps_chroma_format_idc) {
+ intra_block_copy(lc, CB);
+ intra_block_copy(lc, CR);
+ }
+}
+
+static void ibc_fill_vir_buf(const VVCLocalContext *lc, const CodingUnit *cu)
+{
+ const VVCFrameContext *fc = lc->fc;
+ const VVCSPS *sps = fc->ps.sps;
+ const int has_chroma = sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA;
+ const int start = cu->tree_type == DUAL_TREE_CHROMA;
+ const int end = has_chroma ? CR : LUMA;
+
+ for (int c_idx = start; c_idx <= end; c_idx++) {
+ const int hs = sps->hshift[c_idx];
+ const int vs = sps->vshift[c_idx];
+ const int ps = sps->pixel_shift;
+ const int x = IBC_X(cu->x0 >> hs);
+ const int y = IBC_Y(cu->y0 >> vs);
+ const int src_stride = fc->frame->linesize[c_idx];
+ const int ibc_stride = fc->tab.sz.ibc_buffer_width >> hs << ps;
+ const uint8_t *src = POS(c_idx, cu->x0, cu->y0);
+ uint8_t *ibc_buf = IBC_POS(c_idx, x, y);
+
+ av_image_copy_plane(ibc_buf, ibc_stride, src, src_stride, cu->cb_width >> hs << ps , cu->cb_height >> vs);
+ }
+}
+
int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const int ry)
{
const VVCFrameContext *fc = lc->fc;
@@ -599,6 +676,8 @@ int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const in
if (cu->ciip_flag)
ff_vvc_predict_ciip(lc);
+ else if (cu->pred_mode == MODE_IBC)
+ vvc_predict_ibc(lc);
if (cu->coded_flag) {
ret = reconstruct(lc);
} else {
@@ -607,6 +686,8 @@ int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const in
if (sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA)
add_reconstructed_area(lc, CHROMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
}
+ if (sps->r->sps_ibc_enabled_flag)
+ ibc_fill_vir_buf(lc, cu);
cu = cu->next;
}
ff_vvc_ctu_free_cus(ctu);
diff --git a/libavcodec/vvc/vvcdec.c b/libavcodec/vvc/vvcdec.c
index e88e746de4..caba1b28c6 100644
--- a/libavcodec/vvc/vvcdec.c
+++ b/libavcodec/vvc/vvcdec.c
@@ -262,6 +262,30 @@ static void ispmf_tl_init(TabList *l, VVCFrameContext *fc)
TL_ADD(ispmf, w64 * h64);
}
+static void ibc_tl_init(TabList *l, VVCFrameContext *fc)
+{
+ const VVCSPS *sps = fc->ps.sps;
+ const VVCPPS *pps = fc->ps.pps;
+ const int ctu_height = pps ? pps->ctb_height : 0;
+ const int ctu_size = sps ? sps->ctb_size_y : 0;
+ const int ps = sps ? sps->pixel_shift : 0;
+ const int chroma_idc = sps ? sps->r->sps_chroma_format_idc : 0;
+ const int changed = fc->tab.sz.chroma_format_idc != chroma_idc ||
+ fc->tab.sz.ctu_height != ctu_height ||
+ fc->tab.sz.ctu_size != ctu_size ||
+ fc->tab.sz.pixel_shift != ps;
+
+ fc->tab.sz.ibc_buffer_width = ctu_size ? 2 * MAX_CTU_SIZE * MAX_CTU_SIZE / ctu_size : 0;
+
+ tl_init(l, 0, changed);
+
+ for (int i = LUMA; i < VVC_MAX_SAMPLE_ARRAYS; i++) {
+ const int hs = sps ? sps->hshift[i] : 0;
+ const int vs = sps ? sps->vshift[i] : 0;
+ TL_ADD(ibc_vir_buf[i], fc->tab.sz.ibc_buffer_width * ctu_size * ctu_height << ps >> hs >> vs);
+ }
+}
+
typedef void (*tl_init_fn)(TabList *l, VVCFrameContext *fc);
static int frame_context_for_each_tl(VVCFrameContext *fc, int (*unary_fn)(TabList *l))
@@ -276,6 +300,7 @@ static int frame_context_for_each_tl(VVCFrameContext *fc, int (*unary_fn)(TabLis
pixel_buffer_nz_tl_init,
msm_tl_init,
ispmf_tl_init,
+ ibc_tl_init,
};
for (int i = 0; i < FF_ARRAY_ELEMS(init); i++) {
diff --git a/libavcodec/vvc/vvcdec.h b/libavcodec/vvc/vvcdec.h
index 4f7ef3a32f..aa3d715524 100644
--- a/libavcodec/vvc/vvcdec.h
+++ b/libavcodec/vvc/vvcdec.h
@@ -170,6 +170,8 @@ typedef struct VVCFrameContext {
int *coeffs;
struct CTU *ctus;
+ uint8_t *ibc_vir_buf[VVC_MAX_SAMPLE_ARRAYS]; ///< IbcVirBuf[]
+
//used in arrays_init only
struct {
int ctu_count;
@@ -185,6 +187,7 @@ typedef struct VVCFrameContext {
int pixel_shift;
int bs_width;
int bs_height;
+ int ibc_buffer_width; ///< IbcBufWidth
} sz;
} tab;
} VVCFrameContext;
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [FFmpeg-devel] [PATCH 11/11] avcodec/vvcdec: add Intra Block Copy decoder
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 11/11] avcodec/vvcdec: add Intra Block Copy decoder Nuo Mi
@ 2024-02-23 13:03 ` Nuo Mi
2024-02-24 12:33 ` Nuo Mi
2024-02-24 13:20 ` Ronald S. Bultje
1 sibling, 1 reply; 15+ messages in thread
From: Nuo Mi @ 2024-02-23 13:03 UTC (permalink / raw)
To: ffmpeg-devel
On Thu, Feb 22, 2024 at 3:15 PM Nuo Mi <nuomi2021@gmail.com> wrote:
> From: Wu Jianhua <toqsxw@outlook.com>
>
> Introduction at https://ieeexplore.ieee.org/document/9408666
>
> passed files:
> 10b444_A_Kwai_3.bit
> 10b444_B_Kwai_3.bit
> CodingToolsSets_D_Tencent_2.bit
> IBC_A_Tencent_2.bit
> IBC_B_Tencent_2.bit
> IBC_C_Tencent_2.bit
> IBC_D_Tencent_2.bit
> IBC_E_Tencent_1.bit
> LOSSLESS_B_HHI_3.bit
>
Will push tomorrow if there are no objections.
>
>
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [FFmpeg-devel] [PATCH 11/11] avcodec/vvcdec: add Intra Block Copy decoder
2024-02-23 13:03 ` Nuo Mi
@ 2024-02-24 12:33 ` Nuo Mi
0 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-24 12:33 UTC (permalink / raw)
To: ffmpeg-devel
On Fri, Feb 23, 2024 at 9:03 PM Nuo Mi <nuomi2021@gmail.com> wrote:
>
>
> On Thu, Feb 22, 2024 at 3:15 PM Nuo Mi <nuomi2021@gmail.com> wrote:
>
>> From: Wu Jianhua <toqsxw@outlook.com>
>>
>> Introduction at https://ieeexplore.ieee.org/document/9408666
>>
>> passed files:
>> 10b444_A_Kwai_3.bit
>> 10b444_B_Kwai_3.bit
>> CodingToolsSets_D_Tencent_2.bit
>> IBC_A_Tencent_2.bit
>> IBC_B_Tencent_2.bit
>> IBC_C_Tencent_2.bit
>> IBC_D_Tencent_2.bit
>> IBC_E_Tencent_1.bit
>> LOSSLESS_B_HHI_3.bit
>>
> Will push tomorrow if there are no objections.
>
pushed.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [FFmpeg-devel] [PATCH 11/11] avcodec/vvcdec: add Intra Block Copy decoder
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 11/11] avcodec/vvcdec: add Intra Block Copy decoder Nuo Mi
2024-02-23 13:03 ` Nuo Mi
@ 2024-02-24 13:20 ` Ronald S. Bultje
2024-02-25 3:07 ` Nuo Mi
1 sibling, 1 reply; 15+ messages in thread
From: Ronald S. Bultje @ 2024-02-24 13:20 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Nuo Mi, Wu Jianhua
Hi,
On Thu, Feb 22, 2024 at 2:15 AM Nuo Mi <nuomi2021@gmail.com> wrote:
> +static void ibc_fill_vir_buf(const VVCLocalContext *lc, const CodingUnit
> *cu)
> [..]
>
+ av_image_copy_plane(ibc_buf, ibc_stride, src, src_stride,
> cu->cb_width >> hs << ps , cu->cb_height >> vs);
>
I'm admittedly not super-familiar with VVC, but I wonder why we need the
double buffering here (from ref_pos in pic to ibc_buf, and then back from
ibc_buf back to cur block in pic)? In AV1, this is done with just a single
copy. Why is this done this way?
Ronald
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [FFmpeg-devel] [PATCH 11/11] avcodec/vvcdec: add Intra Block Copy decoder
2024-02-24 13:20 ` Ronald S. Bultje
@ 2024-02-25 3:07 ` Nuo Mi
0 siblings, 0 replies; 15+ messages in thread
From: Nuo Mi @ 2024-02-25 3:07 UTC (permalink / raw)
To: Ronald S. Bultje; +Cc: Wu Jianhua, FFmpeg development discussions and patches
On Sat, Feb 24, 2024 at 9:20 PM Ronald S. Bultje <rsbultje@gmail.com> wrote:
> Hi,
>
> On Thu, Feb 22, 2024 at 2:15 AM Nuo Mi <nuomi2021@gmail.com> wrote:
>
>> +static void ibc_fill_vir_buf(const VVCLocalContext *lc, const CodingUnit
>> *cu)
>> [..]
>>
> + av_image_copy_plane(ibc_buf, ibc_stride, src, src_stride,
>> cu->cb_width >> hs << ps , cu->cb_height >> vs);
>>
>
> I'm admittedly not super-familiar with VVC, but I wonder why we need the
> double buffering here (from ref_pos in pic to ibc_buf, and then back from
> ibc_buf back to cur block in pic)? In AV1, this is done with just a single
> copy. Why is this done this way?
>
Hi Ronald,
Two major differences between AV1 and VVC are:
1. AV1 disables all in-loop filters for IBC, while VVC does not.
2. AV1 can refer to any reconstructed super blocks, except the delayed
super block, whereas VVC can only refer to the left and current CTU.
Therefore, in VVC, we need to allocate memory for each line to save pixels
before applying filters. VVC refers to this memory as IbcVirBuf, which is a
2D cyclic buffer.
Every new reconstructed Coding Block will be copied to this buffer, and we
can only copy pixels from this buffer.
Best Regards.
>
> Ronald
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2024-02-25 3:07 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <20240222071406.5714-1-nuomi2021@gmail.com>
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 01/11] avcodec/vvcdec: refact out deblock_bs to reduce duplicate code Nuo Mi
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 02/11] avcodec/vvcdec: set CuPredMode table for chroma Nuo Mi
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 03/11] avcodec/vvcdec: deblock_bs, fix intra check for IBC Nuo Mi
2024-02-22 7:13 ` [FFmpeg-devel] [PATCH 04/11] avcodec/vvcdec: cabac, fix non_inter_flag, pred_mode_flag, amvr_shift " Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 05/11] avcodec/vvcdec: implement update_hmvp " Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 06/11] avcodec/vvcdec: skip inter prediction for IBC blocks Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 07/11] avcodec/vvcdec: ff_vvc_set_intra_mvf, refact to support dmvr tab Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 08/11] avcodec/vvcdec: fix dual tree for skipped transform tree/unit Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 09/11] avcodec/vvcdec: refact, rename !is_mvp to check_mer Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 10/11] avcodec/vvcdec: add Intra Block Copy parser Nuo Mi
2024-02-22 7:14 ` [FFmpeg-devel] [PATCH 11/11] avcodec/vvcdec: add Intra Block Copy decoder Nuo Mi
2024-02-23 13:03 ` Nuo Mi
2024-02-24 12:33 ` Nuo Mi
2024-02-24 13:20 ` Ronald S. Bultje
2024-02-25 3:07 ` Nuo Mi
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git