1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-04 22:03:09 +02:00

avcodec/vvc/ctu: add palette support

Signed-off-by: Wu Jianhua <toqsxw@outlook.com>
This commit is contained in:
Wu Jianhua
2025-05-14 21:40:17 +08:00
committed by Nuo Mi
parent fd85f83608
commit 26215b8c83
5 changed files with 327 additions and 30 deletions

View File

@ -25,6 +25,7 @@
#include "cabac.h" #include "cabac.h"
#include "ctu.h" #include "ctu.h"
#include "inter.h" #include "inter.h"
#include "intra.h"
#include "mvs.h" #include "mvs.h"
#define PROF_TEMP_SIZE (PROF_BLOCK_SIZE) * sizeof(int16_t) #define PROF_TEMP_SIZE (PROF_BLOCK_SIZE) * sizeof(int16_t)
@ -1046,13 +1047,15 @@ static PredMode pred_mode_decode(VVCLocalContext *lc,
const H266RawSliceHeader *rsh = lc->sc->sh.r; const H266RawSliceHeader *rsh = lc->sc->sh.r;
const int ch_type = tree_type == DUAL_TREE_CHROMA ? 1 : 0; const int ch_type = tree_type == DUAL_TREE_CHROMA ? 1 : 0;
const int is_4x4 = cu->cb_width == 4 && cu->cb_height == 4; const int is_4x4 = cu->cb_width == 4 && cu->cb_height == 4;
const int is_128 = cu->cb_width == 128 || cu->cb_height == 128;
const int hs = sps->hshift[CHROMA];
const int vs = sps->vshift[CHROMA];
int pred_mode_flag; int pred_mode_flag;
int pred_mode_ibc_flag; int pred_mode_ibc_flag;
PredMode pred_mode; PredMode pred_mode;
cu->skip_flag = 0; cu->skip_flag = 0;
if (!IS_I(rsh) || sps->r->sps_ibc_enabled_flag) { if (!IS_I(rsh) || sps->r->sps_ibc_enabled_flag) {
const int is_128 = cu->cb_width == 128 || cu->cb_height == 128;
if (tree_type != DUAL_TREE_CHROMA && if (tree_type != DUAL_TREE_CHROMA &&
((!is_4x4 && mode_type != MODE_TYPE_INTRA) || ((!is_4x4 && mode_type != MODE_TYPE_INTRA) ||
(sps->r->sps_ibc_enabled_flag && !is_128))) { (sps->r->sps_ibc_enabled_flag && !is_128))) {
@ -1087,6 +1090,14 @@ static PredMode pred_mode_decode(VVCLocalContext *lc,
pred_mode = MODE_INTRA; pred_mode = MODE_INTRA;
} }
if (pred_mode == MODE_INTRA && sps->r->sps_palette_enabled_flag && !is_128 && !cu->skip_flag &&
mode_type != MODE_TYPE_INTER && ((cu->cb_width * cu->cb_height) >
(tree_type != DUAL_TREE_CHROMA ? 16 : (16 << hs << vs))) &&
(mode_type != MODE_TYPE_INTRA || tree_type != DUAL_TREE_CHROMA)) {
if (ff_vvc_pred_mode_plt_flag(lc))
pred_mode = MODE_PLT;
}
set_cb_tab(lc, fc->tab.cpm[cu->ch_type], pred_mode); set_cb_tab(lc, fc->tab.cpm[cu->ch_type], pred_mode);
if (tree_type == SINGLE_TREE) if (tree_type == SINGLE_TREE)
set_cb_tab(lc, fc->tab.cpm[CHROMA], pred_mode); set_cb_tab(lc, fc->tab.cpm[CHROMA], pred_mode);
@ -1755,8 +1766,8 @@ static void fill_dmvr_info(const VVCLocalContext *lc)
const VVCFrameContext *fc = lc->fc; const VVCFrameContext *fc = lc->fc;
const CodingUnit *cu = lc->cu; const CodingUnit *cu = lc->cu;
if (cu->pred_mode == MODE_IBC) { if (cu->pred_mode == MODE_IBC || cu->pred_mode == MODE_PLT) {
ff_vvc_set_intra_mvf(lc, true, PF_IBC, false); ff_vvc_set_intra_mvf(lc, true, cu->pred_mode == MODE_IBC ? PF_IBC : PF_PLT, false);
} else { } else {
const VVCPPS *pps = fc->ps.pps; const VVCPPS *pps = fc->ps.pps;
const int w = cu->cb_width >> MIN_PU_LOG2; const int w = cu->cb_width >> MIN_PU_LOG2;
@ -1805,9 +1816,291 @@ static int inter_data(VVCLocalContext *lc)
return ret; return ret;
} }
static TransformUnit* palette_add_tu(VVCLocalContext *lc, const int start, const int end, const VVCTreeType tree_type)
{
CodingUnit *cu = lc->cu;
const VVCSPS *sps = lc->fc->ps.sps;
TransformUnit *tu = add_tu(lc->fc, cu, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
if (!tu)
return NULL;
for (int c = start; c < end; c++) {
const int w = tu->width >> sps->hshift[c];
const int h = tu->height >> sps->vshift[c];
TransformBlock *tb = add_tb(tu, lc, tu->x0, tu->y0, w, h, c);
if (c != CR)
set_tb_size(lc->fc, tb);
}
for (int i = 0; i < FF_ARRAY_ELEMS(cu->plt); i++)
cu->plt[i].size = 0;
return tu;
}
static void palette_predicted(VVCLocalContext *lc, const bool local_dual_tree, int start, int end,
bool *predictor_reused, const int predictor_size, const int max_entries)
{
CodingUnit *cu = lc->cu;
int nb_predicted = 0;
if (local_dual_tree) {
start = LUMA;
end = VVC_MAX_SAMPLE_ARRAYS;
}
for (int i = 0; i < predictor_size && nb_predicted < max_entries; i++) {
const int run = ff_vvc_palette_predictor_run(lc);
if (run == 1)
break;
if (run > 1)
i += run - 1;
predictor_reused[i] = true;
for (int c = start; c < end; c++)
cu->plt[c].entries[nb_predicted] = lc->ep->pp[c].entries[i];
nb_predicted++;
}
for (int c = start; c < end; c++)
cu->plt[c].size = nb_predicted;
}
static void palette_signaled(VVCLocalContext *lc, const bool local_dual_tree,
const int start, const int end, const int max_entries)
{
const VVCSPS *sps = lc->fc->ps.sps;
CodingUnit *cu = lc->cu;
const int nb_predicted = cu->plt[start].size;
const int nb_signaled = nb_predicted < max_entries ? ff_vvc_num_signalled_palette_entries(lc) : 0;
const int size = nb_predicted + nb_signaled;
const bool dual_tree_luma = local_dual_tree && cu->tree_type == DUAL_TREE_LUMA;
for (int c = start; c < end; c++) {
Palette *plt = cu->plt + c;
for (int i = nb_predicted; i < size; i++) {
plt->entries[i] = ff_vvc_new_palette_entries(lc, sps->bit_depth);
if (dual_tree_luma) {
plt[CB].entries[i] = 1 << (sps->bit_depth - 1);
plt[CR].entries[i] = 1 << (sps->bit_depth - 1);
}
}
plt->size = size;
}
}
static void palette_update_predictor(VVCLocalContext *lc, const bool local_dual_tree, int start, int end,
bool *predictor_reused, const int predictor_size)
{
CodingUnit *cu = lc->cu;
const int max_predictor = VVC_MAX_NUM_PALETTE_PREDICTOR_SIZE >> (cu->tree_type != SINGLE_TREE && !local_dual_tree);
if (local_dual_tree) {
start = LUMA;
end = VVC_MAX_SAMPLE_ARRAYS;
}
for (int c = start; c < end; c++) {
Palette *pp = lc->ep->pp + c;
Palette *plt = cu->plt + c;
int i = cu->plt[start].size;;
// copy unused predictors to the end of plt
for (int j = 0; j < predictor_size && i < max_predictor; j++) {
if (!predictor_reused[j]) {
plt->entries[i] = pp->entries[j];
i++;
}
}
memcpy(pp->entries, plt->entries, i * sizeof(pp->entries[0]));
pp->size = i;
}
}
static void palette_qp(VVCLocalContext *lc, VVCTreeType tree_type, const bool escape_present)
{
const VVCFrameContext *fc = lc->fc;
const VVCPPS *pps = fc->ps.pps;
const H266RawSliceHeader *rsh = lc->sc->sh.r;
const CodingUnit *cu = lc->cu;
if (tree_type != DUAL_TREE_CHROMA) {
const bool has_qp_delta = escape_present &&
pps->r->pps_cu_qp_delta_enabled_flag && !lc->parse.is_cu_qp_delta_coded;
set_qp_y(lc, cu->x0, cu->y0, has_qp_delta);
}
if (tree_type != DUAL_TREE_LUMA) {
if (rsh->sh_cu_chroma_qp_offset_enabled_flag && !lc->parse.is_cu_chroma_qp_offset_coded)
chroma_qp_offset_decode(lc, 0, 1);
set_qp_c(lc);
}
}
#define PALETTE_SET_PIXEL(xc, yc, pix) \
do { \
const int off = ((xc) >> hs) + ((yc) >> vs) * tb->tb_width; \
if (sps->bit_depth == 8) \
u8[off] = pix; \
else \
u16[off] = pix; \
} while (0)
#define PALETTE_INDEX(x, y) index[(y) * cu->cb_width + (x)]
// 6.5.3 Horizontal and vertical traverse scan order array initialization process
// The hTravScan and vTravScan tables require approximately 576 KB of memory.
// To save space, we use a macro to achieve the same functionality.
#define TRAV_COL(p, wlog, mask) ((p & mask) ^ (-((p >> wlog) & 1) & mask))
#define TRAV_ROW(p, hlog) (p >> hlog)
#define TRAV(trans, p, wlog, hlog, mask) (trans ? TRAV_ROW((p), hlog) : TRAV_COL((p), wlog, mask))
#define TRAV_X(pos) TRAV(transpose, pos, wlog2, hlog2, wmask)
#define TRAV_Y(pos) TRAV(!transpose, pos, hlog2, wlog2, hmask)
static int palette_subblock_data(VVCLocalContext *lc,
const int max_index, const int subset_id, const bool transpose,
uint8_t *run_type, uint8_t *index, int *prev_run_pos, bool *adjust)
{
const CodingUnit *cu = lc->cu;
TransformUnit *tu = cu->tus.head;
const VVCSPS *sps = lc->fc->ps.sps;
const int min_pos = subset_id << 4;
const int max_pos = FFMIN(min_pos + 16, cu->cb_width * cu->cb_height);
const int wmask = cu->cb_width - 1;
const int hmask = cu->cb_height - 1;
const int wlog2 = av_log2(cu->cb_width);
const int hlog2 = av_log2(cu->cb_height);
const uint8_t esc = cu->plt[tu->tbs[0].c_idx].size;
uint8_t run_copy[16] = { 0 };
for (int i = min_pos; i < max_pos; i++) {
const int xc = TRAV_X(i);
const int yc = TRAV_Y(i);
if (i > 0 && max_index > 0)
run_copy[i - min_pos] = ff_vvc_run_copy_flag(lc, run_type[i - 1], *prev_run_pos, i);
run_type[i] = 0;
if (max_index > 0 && !run_copy[i - min_pos]) {
if (((!transpose && yc > 0) || (transpose && xc > 0))
&& i > 0 && !run_type[i - 1]) {
run_type[i] = ff_vvc_copy_above_palette_indices_flag(lc);
}
*prev_run_pos = i;
} else if (i > 0) {
run_type[i] = run_type[i - 1];
}
}
for (int i = min_pos; i < max_pos; i++) {
const int xc = TRAV_X(i);
const int yc = TRAV_Y(i);
const int prev_xc = i > 0 ? TRAV_X(i - 1) : 0;
const int prev_yc = i > 0 ? TRAV_Y(i - 1) : 0;
int idx = 0;
if (max_index > 0 && !run_copy[i - min_pos] && !run_type[i]) {
if (max_index - *adjust > 0)
idx = ff_vvc_palette_idx_idc(lc, max_index, *adjust);
if (i > 0) {
const int ref_idx = !run_type[i - 1] ?
PALETTE_INDEX(prev_xc, prev_yc) : PALETTE_INDEX(xc - transpose, yc - !transpose);
idx += (idx >= ref_idx);
}
*adjust = true;
} else {
idx = PALETTE_INDEX(prev_xc, prev_yc);
}
if (!run_type[i])
PALETTE_INDEX(xc, yc) = idx;
else
PALETTE_INDEX(xc, yc) = PALETTE_INDEX(xc - transpose, yc - !transpose);
}
for (int c = 0; c < tu->nb_tbs; c++) {
TransformBlock *tb = &tu->tbs[c];
const Palette *plt = cu->plt + tb->c_idx;
const int scale = ff_vvc_palette_derive_scale(lc, tu, tb);
const int hs = sps->hshift[c];
const int vs = sps->vshift[c];
uint8_t *u8 = (uint8_t *)tb->coeffs;
uint16_t *u16 = (uint16_t *)tb->coeffs;
for (int i = min_pos; i < max_pos; i++) {
const int xc = TRAV_X(i);
const int yc = TRAV_Y(i);
if (!(xc & hs) && !(yc & vs)) {
const int v = PALETTE_INDEX(xc, yc);
if (v == esc) {
const int coeff = ff_vvc_palette_escape_val(lc);
const int pixel = av_clip_intp2(RSHIFT(coeff * scale, 6), sps->bit_depth);
PALETTE_SET_PIXEL(xc, yc, pixel);
} else {
PALETTE_SET_PIXEL(xc, yc, plt->entries[v]);
}
}
}
}
return 0;
}
static int hls_palette_coding(VVCLocalContext *lc, const VVCTreeType tree_type)
{
const VVCFrameContext *fc = lc->fc;
const VVCSPS *sps = fc->ps.sps;
const H266RawSliceHeader *rsh = lc->sc->sh.r;
CodingUnit *cu = lc->cu;
Palette *pp = lc->ep->pp;
const int max_entries = tree_type == SINGLE_TREE ? 31 : 15;
const bool local_dual_tree = tree_type != SINGLE_TREE &&
(!IS_I(rsh) || (IS_I(rsh) && !sps->r->sps_qtbtt_dual_tree_intra_flag));
bool escape_present = false;
bool transpose = false;
bool adjust = false;
int max_index = 0;
int prev_run_pos = 0;
int predictor_size, start, end;
bool reused[VVC_MAX_NUM_PALETTE_PREDICTOR_SIZE];
uint8_t run_type[MAX_PALETTE_CU_SIZE * MAX_PALETTE_CU_SIZE];
uint8_t index[MAX_PALETTE_CU_SIZE * MAX_PALETTE_CU_SIZE];
ff_vvc_channel_range(&start, &end, tree_type, sps->r->sps_chroma_format_idc);
if (!palette_add_tu(lc, start, end, tree_type))
return AVERROR(ENOMEM);
predictor_size = pp[start].size;
memset(reused, 0, sizeof(reused[0]) * predictor_size);
palette_predicted(lc, local_dual_tree, start, end, reused, predictor_size, max_entries);
palette_signaled(lc, local_dual_tree, start, end, max_entries);
palette_update_predictor(lc, local_dual_tree, start, end, reused, predictor_size);
if (cu->plt[start].size > 0)
escape_present = ff_vvc_palette_escape_val_present_flag(lc);
max_index = cu->plt[start].size - 1 + escape_present;
if (max_index > 0) {
adjust = false;
transpose = ff_vvc_palette_transpose_flag(lc);
}
palette_qp(lc, tree_type, escape_present);
index[0] = 0;
for (int i = 0; i <= (cu->cb_width * cu->cb_height - 1) >> 4; i++)
palette_subblock_data(lc, max_index, i, transpose,
run_type, index, &prev_run_pos, &adjust);
return 0;
}
static int intra_data(VVCLocalContext *lc) static int intra_data(VVCLocalContext *lc)
{ {
const VVCFrameContext *fc = lc->fc;
const VVCSPS *sps = lc->fc->ps.sps; const VVCSPS *sps = lc->fc->ps.sps;
const CodingUnit *cu = lc->cu; const CodingUnit *cu = lc->cu;
const VVCTreeType tree_type = cu->tree_type; const VVCTreeType tree_type = cu->tree_type;
@ -1816,8 +2109,9 @@ static int intra_data(VVCLocalContext *lc)
if (tree_type == SINGLE_TREE || tree_type == DUAL_TREE_LUMA) { if (tree_type == SINGLE_TREE || tree_type == DUAL_TREE_LUMA) {
if (pred_mode_plt_flag) { if (pred_mode_plt_flag) {
avpriv_report_missing_feature(fc->log_ctx, "Palette"); if ((ret = hls_palette_coding(lc, tree_type)) < 0)
return AVERROR_PATCHWELCOME; return ret;
ff_vvc_set_intra_mvf(lc, false, PF_PLT, false);
} else { } else {
intra_luma_pred_modes(lc); intra_luma_pred_modes(lc);
ff_vvc_set_intra_mvf(lc, false, PF_INTRA, cu->ciip_flag); ff_vvc_set_intra_mvf(lc, false, PF_INTRA, cu->ciip_flag);
@ -1825,8 +2119,8 @@ static int intra_data(VVCLocalContext *lc)
} }
if ((tree_type == SINGLE_TREE || tree_type == DUAL_TREE_CHROMA) && sps->r->sps_chroma_format_idc) { 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) { if (pred_mode_plt_flag && tree_type == DUAL_TREE_CHROMA) {
avpriv_report_missing_feature(fc->log_ctx, "Palette"); if ((ret = hls_palette_coding(lc, tree_type)) < 0)
return AVERROR_PATCHWELCOME; return ret;
} else if (!pred_mode_plt_flag) { } else if (!pred_mode_plt_flag) {
if (!cu->act_enabled_flag) if (!cu->act_enabled_flag)
intra_chroma_pred_modes(lc); intra_chroma_pred_modes(lc);
@ -1839,14 +2133,11 @@ static int intra_data(VVCLocalContext *lc)
static int hls_coding_unit(VVCLocalContext *lc, int x0, int y0, int cb_width, int cb_height, static int hls_coding_unit(VVCLocalContext *lc, int x0, int y0, int cb_width, int cb_height,
int cqt_depth, const VVCTreeType tree_type, VVCModeType mode_type) int cqt_depth, const VVCTreeType tree_type, VVCModeType mode_type)
{ {
const VVCFrameContext *fc = lc->fc; const VVCFrameContext *fc = lc->fc;
const VVCSPS *sps = fc->ps.sps; const VVCSPS *sps = fc->ps.sps;
const H266RawSliceHeader *rsh = lc->sc->sh.r; const H266RawSliceHeader *rsh = lc->sc->sh.r;
const int hs = sps->hshift[CHROMA]; const int is_128 = cb_width > 64 || cb_height > 64;
const int vs = sps->vshift[CHROMA]; int ret = 0;
const int is_128 = cb_width > 64 || cb_height > 64;
int pred_mode_plt_flag = 0;
int ret = 0;
CodingUnit *cu = add_cu(lc, x0, y0, cb_width, cb_height, cqt_depth, tree_type); CodingUnit *cu = add_cu(lc, x0, y0, cb_width, cb_height, cqt_depth, tree_type);
@ -1859,16 +2150,6 @@ static int hls_coding_unit(VVCLocalContext *lc, int x0, int y0, int cb_width, in
mode_type = MODE_TYPE_INTRA; mode_type = MODE_TYPE_INTRA;
cu->pred_mode = pred_mode_decode(lc, tree_type, mode_type); cu->pred_mode = pred_mode_decode(lc, tree_type, mode_type);
if (cu->pred_mode == MODE_INTRA && sps->r->sps_palette_enabled_flag && !is_128 && !cu->skip_flag &&
mode_type != MODE_TYPE_INTER && ((cb_width * cb_height) >
(tree_type != DUAL_TREE_CHROMA ? 16 : (16 << hs << vs))) &&
(mode_type != MODE_TYPE_INTRA || tree_type != DUAL_TREE_CHROMA)) {
pred_mode_plt_flag = ff_vvc_pred_mode_plt_flag(lc);
if (pred_mode_plt_flag) {
avpriv_report_missing_feature(fc->log_ctx, "Palette");
return AVERROR_PATCHWELCOME;
}
}
if (cu->pred_mode == MODE_INTRA && sps->r->sps_act_enabled_flag && tree_type == SINGLE_TREE) { if (cu->pred_mode == MODE_INTRA && sps->r->sps_act_enabled_flag && tree_type == SINGLE_TREE) {
avpriv_report_missing_feature(fc->log_ctx, "Adaptive Color Transform"); avpriv_report_missing_feature(fc->log_ctx, "Adaptive Color Transform");
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
@ -1881,10 +2162,10 @@ static int hls_coding_unit(VVCLocalContext *lc, int x0, int y0, int cb_width, in
if (ret < 0) if (ret < 0)
return ret; return ret;
if (cu->pred_mode != MODE_INTRA && !pred_mode_plt_flag && !lc->cu->pu.general_merge_flag) if (cu->pred_mode != MODE_INTRA && cu->pred_mode != MODE_PLT && !lc->cu->pu.general_merge_flag)
cu->coded_flag = ff_vvc_cu_coded_flag(lc); cu->coded_flag = ff_vvc_cu_coded_flag(lc);
else else
cu->coded_flag = !(cu->skip_flag || pred_mode_plt_flag); cu->coded_flag = !(cu->skip_flag || cu->pred_mode == MODE_PLT);
if (cu->coded_flag) { if (cu->coded_flag) {
sbt_info(lc, sps); sbt_info(lc, sps);
@ -1902,7 +2183,7 @@ static int hls_coding_unit(VVCLocalContext *lc, int x0, int y0, int cb_width, in
cu->lfnst_idx = lfnst_idx_decode(lc); cu->lfnst_idx = lfnst_idx_decode(lc);
cu->mts_idx = mts_idx_decode(lc); cu->mts_idx = mts_idx_decode(lc);
set_qp_c(lc); set_qp_c(lc);
} else { } else if (cu->pred_mode != MODE_PLT) {
ret = skipped_transform_tree_unit(lc); ret = skipped_transform_tree_unit(lc);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@ -36,6 +36,7 @@
#define MIN_CU_SIZE 4 #define MIN_CU_SIZE 4
#define MIN_CU_LOG2 2 #define MIN_CU_LOG2 2
#define MAX_CU_DEPTH 7 #define MAX_CU_DEPTH 7
#define MAX_PALETTE_CU_SIZE 64
#define MAX_PARTS_IN_CTU ((MAX_CTU_SIZE >> MIN_CU_LOG2) * (MAX_CTU_SIZE >> MIN_CU_LOG2)) #define MAX_PARTS_IN_CTU ((MAX_CTU_SIZE >> MIN_CU_LOG2) * (MAX_CTU_SIZE >> MIN_CU_LOG2))
@ -224,6 +225,7 @@ typedef enum PredFlag {
PF_L1 = 0x2, PF_L1 = 0x2,
PF_BI = 0x3, PF_BI = 0x3,
PF_IBC = PF_L0 | 0x4, PF_IBC = PF_L0 | 0x4,
PF_PLT = 0x8,
} PredFlag; } PredFlag;
typedef enum IntraPredMode { typedef enum IntraPredMode {
@ -277,6 +279,11 @@ typedef struct PredictionUnit {
int cb_prof_flag[2]; int cb_prof_flag[2];
} PredictionUnit; } PredictionUnit;
typedef struct Palette {
uint8_t size;
uint16_t entries[VVC_MAX_NUM_PALETTE_PREDICTOR_SIZE];
} Palette;
typedef struct CodingUnit { typedef struct CodingUnit {
VVCTreeType tree_type; VVCTreeType tree_type;
int x0; int x0;
@ -326,6 +333,8 @@ typedef struct CodingUnit {
int8_t qp[4]; ///< QpY, Qp′Cb, Qp′Cr, Qp′CbCr int8_t qp[4]; ///< QpY, Qp′Cb, Qp′Cr, Qp′CbCr
Palette plt[VVC_MAX_SAMPLE_ARRAYS];
PredictionUnit pu; PredictionUnit pu;
struct CodingUnit *next; ///< RefStruct reference struct CodingUnit *next; ///< RefStruct reference
@ -356,6 +365,8 @@ typedef struct EntryPoint {
int stat_coeff[VVC_MAX_SAMPLE_ARRAYS]; ///< StatCoeff int stat_coeff[VVC_MAX_SAMPLE_ARRAYS]; ///< StatCoeff
Palette pp[VVC_MAX_SAMPLE_ARRAYS]; // PalettePredictor
VVCCabacState cabac_state[VVC_CONTEXTS]; VVCCabacState cabac_state[VVC_CONTEXTS];
CABACContext cc; CABACContext cc;

View File

@ -551,6 +551,9 @@ static int ep_init(EntryPoint *ep, const int ctu_addr, const int ctu_end, GetBit
ep->ctu_start = ctu_addr; ep->ctu_start = ctu_addr;
ep->ctu_end = ctu_end; ep->ctu_end = ctu_end;
for (int c_idx = LUMA; c_idx <= CR; c_idx++)
ep->pp[c_idx].size = 0;
return 0; return 0;
} }

View File

@ -145,7 +145,8 @@ static int derive_temporal_colocated_mvs(const VVCLocalContext *lc, MvField temp
RefPicList* refPicList = sc->rpl; RefPicList* refPicList = sc->rpl;
if (temp_col.pred_flag == PF_INTRA || if (temp_col.pred_flag == PF_INTRA ||
temp_col.pred_flag == PF_IBC) temp_col.pred_flag == PF_IBC ||
temp_col.pred_flag == PF_PLT)
return 0; return 0;
if (sb_flag){ if (sb_flag){

View File

@ -286,6 +286,7 @@ static void add_progress_listener(VVCFrame *ref, ProgressListener *l,
static void ep_init_wpp(EntryPoint *next, const EntryPoint *ep, const VVCSPS *sps) static void ep_init_wpp(EntryPoint *next, const EntryPoint *ep, const VVCSPS *sps)
{ {
memcpy(next->cabac_state, ep->cabac_state, sizeof(next->cabac_state)); memcpy(next->cabac_state, ep->cabac_state, sizeof(next->cabac_state));
memcpy(next->pp, ep->pp, sizeof(next->pp));
ff_vvc_ep_init_stat_coeff(next, sps->bit_depth, sps->r->sps_persistent_rice_adaptation_enabled_flag); ff_vvc_ep_init_stat_coeff(next, sps->bit_depth, sps->r->sps_persistent_rice_adaptation_enabled_flag);
} }