107#define PRIORITY_LOWEST 2
112 const int priorities[] = {
134 memset(t, 0,
sizeof(*t));
139 t->
rs = ry *
fc->ft->ctu_width + rx;
174 if (ry !=
pps->ctb_to_row_bd[ry]) {
176 return fc->tab.slice_idx[rs] !=
fc->tab.slice_idx[rs - ft->
ctu_width];
184 static const uint8_t target_score[] =
204 const int no_prev_stage = t->
rs > 0;
205 target = 2 + wpp - no_prev_stage;
214 return score == target + 1;
289 memcpy(next->
pp, ep->
pp,
sizeof(next->
pp));
299 if (
sps->r->sps_entropy_coding_sync_enabled_flag) {
300 if (t->
rx ==
fc->ps.pps->ctb_to_col_bd[t->
rx]) {
311 const int next_rx = next_rs % ft->
ctu_width;
312 const int next_ry = next_rs / ft->
ctu_width;
322 CTU *ctu =
fc->tab.ctus + rs;
323 for (
int lx = 0; lx < 2; lx++) {
325 int y = ctu->
max_y[lx][
i];
330 y = y * refp->
scale[1] >> 14;
342 const int slice_idx =
fc->tab.slice_idx[rs];
356#define ADD(dx, dy, stage) frame_thread_add_score(s, ft, t->rx + (dx), t->ry + (dy), stage)
407 if (
fc->ps.ph.r->ph_temporal_mvp_enabled_flag ||
fc->ps.sps->r->sps_sbtmvp_enabled_flag) {
409 const int first_col = t->
rx ==
fc->ps.pps->ctb_to_col_bd[t->
rx];
410 if (col && first_col) {
412 const int y = (t->
ry <<
fc->ps.sps->ctb_log2_size_y);
437 for (
int i = 0;
i <
fc->nb_slices;
i++) {
439 for (
int j = 0; j < sc->
nb_eps; j++) {
441 for (
int k = ep->
ctu_start; k < ep->ctu_end; k++) {
472 const int progress = y == ft->
ctu_height ? INT_MAX : y * ctu_size;
482 const int rs = t->
rs;
483 const CTU *ctu =
fc->tab.ctus + rs;
508 const CTU *ctu =
fc->tab.ctus + t->
rs;
531 const int x0 = t->
rx * ctu_size;
532 const int y0 = t->
ry * ctu_size;
544 const int x0 = t->
rx * ctb_size;
545 const int y0 = t->
ry * ctb_size;
560 const int x0 = t->
rx * ctb_size;
561 const int y0 = t->
ry * ctb_size;
567 if (
fc->ps.sps->r->sps_sao_enabled_flag)
578 const int x0 = t->
rx * ctb_size;
579 const int y0 = t->
ry * ctb_size;
581 if (
fc->ps.sps->r->sps_sao_enabled_flag) {
586 if (
fc->ps.sps->r->sps_alf_enabled_flag)
597 const int x0 = t->
rx * ctu_size;
598 const int y0 = t->
ry * ctu_size;
600 if (
fc->ps.sps->r->sps_alf_enabled_flag) {
648 if ((ret =
run[stage](
s, lc, t)) < 0) {
649#ifdef COMPAT_ATOMICS_WIN32_STDATOMIC_H
656 "frame %5d, %s(%3d, %3d) failed with %d\r\n",
787 for (
int rs = 0; rs < ft->
ctu_count; rs++) {
812 for (
int i = 0;
i <
fc->nb_slices;
i++) {
814 for (
int j = 0; j < sc->
nb_eps; j++) {
816 for (
int k = ep->
ctu_start; k < ep->ctu_end; k++) {
825 for (
int rs = 0; rs < ft->
ctu_count; rs++) {
828 av_log(
s->avctx,
AV_LOG_ERROR,
"frame %5d, CTU(%d, %d) not belong to any slice\r\n", (
int)
fc->decode_order, t->
rx, t->
ry);
849 ff_dlog(
s->avctx,
"frame %5d done\r\n", (
int)
fc->decode_order);
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define i(width, name, range_min, range_max)
static int FUNC sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
static int FUNC user_data(CodedBitstreamContext *ctx, RWContext *rw, MPEG2RawUserData *current)
int ff_vvc_coding_tree_unit(VVCLocalContext *lc, const int ctu_idx, const int rs, const int rx, const int ry)
parse a CTU
void ff_vvc_decode_neighbour(VVCLocalContext *lc, const int x_ctb, const int y_ctb, const int rx, const int ry, const int rs)
void ff_vvc_ep_init_stat_coeff(EntryPoint *ep, const int bit_depth, const int persistent_rice_adaptation_enabled_flag)
static const uint16_t fc[]
#define atomic_store(object, desired)
#define atomic_load(object)
static int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected, intptr_t desired)
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int ff_vvc_predict_inter(VVCLocalContext *lc, const int rs)
Loop entire CTU to predict all inter coding blocks.
static int zero(InterplayACMContext *s, unsigned ind, unsigned col)
int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const int ry)
reconstruct a CTU
#define u(width, name, range_min, range_max)
av_cold FFExecutor * ff_executor_alloc(const FFTaskCallbacks *cb, int thread_count)
Alloc executor.
void ff_executor_execute(FFExecutor *e, FFTask *t)
Add task to executor.
av_cold void ff_executor_free(FFExecutor **executor)
Free executor.
static int ff_cond_wait(AVCond *cond, AVMutex *mutex)
static int ff_mutex_unlock(AVMutex *mutex)
static int ff_cond_destroy(AVCond *cond)
static int ff_mutex_lock(AVMutex *mutex)
static int ff_mutex_destroy(AVMutex *mutex)
static int ff_cond_init(AVCond *cond, const void *attr)
static int ff_cond_signal(AVCond *cond)
static int ff_mutex_init(AVMutex *mutex, const void *attr)
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
#define FF_ARRAY_ELEMS(a)
int max_y[2][VVC_MAX_REF_ENTRIES]
VVCCabacState cabac_state[VVC_CONTEXTS]
Palette pp[VVC_MAX_SAMPLE_ARRAYS]
uint8_t sps_entropy_coding_sync_enabled_flag
VVCRefPic refs[VVC_MAX_REF_ENTRIES]
struct VVCFrameThread * ft
atomic_int nb_scheduled_listeners
int row_progress[VVC_PROGRESS_LAST]
atomic_int nb_scheduled_tasks
progress_done_fn progress_done
int scale[2]
RefPicScale[].
int is_scaled
RprConstraintsActiveFlag.
atomic_int col_progress[VVC_PROGRESS_LAST]
const H266RawSliceHeader * r
RefStruct reference.
const uint32_t * ctb_addr_in_curr_slice
CtbAddrInCurrSlice.
union VVCTask::@127034350030133313172177151122341207253055002140 u
atomic_uchar target_inter_score
atomic_uchar score[VVC_TASK_STAGE_LAST]
ProgressListener listener[2][VVC_MAX_REF_ENTRIES]
ProgressListener col_listener
static int ref[MAX_W *MAX_W]
static int run_init(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
void ff_vvc_frame_thread_free(VVCFrameContext *fc)
static int run_inter(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
#define ADD(dx, dy, stage)
static void add_progress_listener(VVCFrame *ref, ProgressListener *l, VVCTask *t, VVCContext *s, const VVCProgress vp, const int y)
static void ep_init_wpp(EntryPoint *next, const EntryPoint *ep, const VVCSPS *sps)
static void frame_thread_init_score(VVCFrameContext *fc)
int ff_vvc_frame_thread_init(VVCFrameContext *fc)
av_cold FFExecutor * ff_vvc_executor_alloc(VVCContext *s, const int thread_count)
static void listener_init(ProgressListener *l, VVCTask *t, VVCContext *s, const VVCProgress vp, const int y)
int ff_vvc_frame_wait(VVCContext *s, VVCFrameContext *fc)
static void mv_done(VVCProgressListener *l)
static void progress_done(VVCProgressListener *_l, const int type)
@ VVC_TASK_STAGE_DEBLOCK_H
@ VVC_TASK_STAGE_DEBLOCK_V
@ VVC_TASK_STAGE_DEBLOCK_BS
static void task_stage_done(const VVCTask *t, VVCContext *s)
static uint8_t task_add_score(VVCTask *t, const VVCTaskStage stage)
int ff_vvc_frame_submit(VVCContext *s, VVCFrameContext *fc)
static uint8_t task_get_score(VVCTask *t, const VVCTaskStage stage)
static int run_deblock_bs(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static void pixel_done(VVCProgressListener *l)
static void schedule_next_parse(VVCContext *s, VVCFrameContext *fc, const SliceContext *sc, const VVCTask *t)
int(* run_func)(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static void sheduled_done(VVCFrameThread *ft, atomic_int *scheduled)
static int run_alf(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static int run_recon(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static int run_parse(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
av_cold void ff_vvc_executor_free(FFExecutor **e)
static void parse_task_done(VVCContext *s, VVCFrameContext *fc, const int rx, const int ry)
static void check_colocation(VVCContext *s, VVCTask *t)
static void frame_thread_add_score(VVCContext *s, VVCFrameThread *ft, const int rx, const int ry, const VVCTaskStage stage)
static void schedule_inter(VVCContext *s, VVCFrameContext *fc, const SliceContext *sc, VVCTask *t, const int rs)
static const char * task_name[]
static int task_init_parse(VVCTask *t, SliceContext *sc, EntryPoint *ep, const int ctu_idx)
static void task_run_stage(VVCTask *t, VVCContext *s, VVCLocalContext *lc)
static int task_is_stage_ready(VVCTask *t, int add)
static void submit_entry_point(VVCContext *s, VVCFrameThread *ft, SliceContext *sc, EntryPoint *ep)
static int run_sao(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static int task_run(FFTask *_t, void *local_context, void *user_data)
static void report_frame_progress(VVCFrameContext *fc, const int ry, const VVCProgress idx)
static int run_lmcs(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static int task_has_target_score(VVCTask *t, const VVCTaskStage stage, const uint8_t score)
static void task_init(VVCTask *t, VVCTaskStage stage, VVCFrameContext *fc, const int rx, const int ry)
static int run_deblock_h(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static int run_deblock_v(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static int is_first_row(const VVCFrameContext *fc, const int rx, const int ry)
static void add_task(VVCContext *s, VVCTask *t)
int ff_vvc_per_frame_init(VVCFrameContext *fc)
void ff_vvc_lmcs_filter(const VVCLocalContext *lc, const int x, const int y)
lmcs filter for the CTU
void ff_vvc_deblock_horizontal(const VVCLocalContext *lc, const int x0, const int y0, const int rs)
horizontal deblock filter for the CTU
void ff_vvc_deblock_vertical(const VVCLocalContext *lc, const int x0, const int y0, const int rs)
vertical deblock filter for the CTU
void ff_vvc_alf_filter(VVCLocalContext *lc, const int x0, const int y0)
alf filter for the CTU
void ff_vvc_sao_copy_ctb_to_hv(VVCLocalContext *lc, const int rx, const int ry, const int last_row)
void ff_vvc_alf_copy_ctu_to_hv(VVCLocalContext *lc, const int x0, const int y0)
void ff_vvc_deblock_bs(VVCLocalContext *lc, const int rx, const int ry, const int rs)
derive boundary strength for the CTU
void ff_vvc_sao_filter(VVCLocalContext *lc, int x0, int y0)
sao filter for the CTU
void ff_vvc_add_progress_listener(VVCFrame *frame, VVCProgressListener *l)
void ff_vvc_report_frame_finished(VVCFrame *frame)
void ff_vvc_report_progress(VVCFrame *frame, const VVCProgress vp, const int y)
#define atomic_fetch_sub(object, operand)
#define atomic_fetch_add(object, operand)