Go to the documentation of this file.
23 #include <stdatomic.h>
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;
292 if (
sps->r->sps_entropy_coding_sync_enabled_flag) {
293 if (t->
rx ==
fc->ps.pps->ctb_to_col_bd[t->
rx]) {
306 const int next_rx = next_rs % ft->
ctu_width;
307 const int next_ry = next_rs / ft->
ctu_width;
317 CTU *ctu =
fc->tab.ctus + rs;
318 for (
int lx = 0; lx < 2; lx++) {
320 int y = ctu->
max_y[lx][
i];
325 y = y * refp->
scale[1] >> 14;
337 const int slice_idx =
fc->tab.slice_idx[rs];
351 #define ADD(dx, dy, stage) frame_thread_add_score(s, ft, t->rx + (dx), t->ry + (dy), stage)
402 if (
fc->ps.ph.r->ph_temporal_mvp_enabled_flag ||
fc->ps.sps->r->sps_sbtmvp_enabled_flag) {
404 const int first_col = t->
rx ==
fc->ps.pps->ctb_to_col_bd[t->
rx];
405 if (col && first_col) {
407 const int y = (t->
ry <<
fc->ps.sps->ctb_log2_size_y);
432 for (
int i = 0;
i <
fc->nb_slices;
i++) {
434 for (
int j = 0; j < sc->
nb_eps; j++) {
436 for (
int k = ep->
ctu_start; k < ep->ctu_end; k++) {
467 const int progress = y == ft->
ctu_height ? INT_MAX : y * ctu_size;
477 const int rs = t->
rs;
478 const CTU *ctu =
fc->tab.ctus + rs;
503 const CTU *ctu =
fc->tab.ctus + t->
rs;
526 const int x0 = t->
rx * ctu_size;
527 const int y0 = t->
ry * ctu_size;
539 const int x0 = t->
rx * ctb_size;
540 const int y0 = t->
ry * ctb_size;
555 const int x0 = t->
rx * ctb_size;
556 const int y0 = t->
ry * ctb_size;
562 if (
fc->ps.sps->r->sps_sao_enabled_flag)
573 const int x0 = t->
rx * ctb_size;
574 const int y0 = t->
ry * ctb_size;
576 if (
fc->ps.sps->r->sps_sao_enabled_flag) {
581 if (
fc->ps.sps->r->sps_alf_enabled_flag)
592 const int x0 = t->
rx * ctu_size;
593 const int y0 = t->
ry * ctu_size;
595 if (
fc->ps.sps->r->sps_alf_enabled_flag) {
604 #define VVC_THREAD_DEBUG
605 #ifdef VVC_THREAD_DEBUG
641 #ifdef VVC_THREAD_DEBUG
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 #ifdef VVC_THREAD_DEBUG
int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const int ry)
reconstruct a CTU
static int run_deblock_h(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static int ff_mutex_init(AVMutex *mutex, const void *attr)
static void parse_task_done(VVCContext *s, VVCFrameContext *fc, const int rx, const int ry)
#define atomic_store(object, desired)
void ff_vvc_sao_filter(VVCLocalContext *lc, int x0, int y0)
sao filter for the CTU
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static int run_sao(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
#define atomic_fetch_add(object, operand)
void ff_vvc_report_frame_finished(VVCFrame *frame)
static void listener_init(ProgressListener *l, VVCTask *t, VVCContext *s, const VVCProgress vp, const int y)
static void frame_thread_init_score(VVCFrameContext *fc)
int ff_vvc_predict_inter(VVCLocalContext *lc, const int rs)
Loop entire CTU to predict all inter coding blocks.
static const OMX_CALLBACKTYPE callbacks
@ VVC_TASK_STAGE_DEBLOCK_V
void ff_vvc_deblock_vertical(const VVCLocalContext *lc, const int x0, const int y0, const int rs)
vertical deblock filter for the CTU
static int run_lmcs(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static int task_init_parse(VVCTask *t, SliceContext *sc, EntryPoint *ep, const int ctu_idx)
void ff_vvc_alf_copy_ctu_to_hv(VVCLocalContext *lc, const int x0, const int y0)
FFExecutor * ff_vvc_executor_alloc(VVCContext *s, const int thread_count)
const H266RawSliceHeader * r
RefStruct reference.
#define fc(width, name, range_min, range_max)
#define atomic_fetch_sub(object, operand)
static void task_run_stage(VVCTask *t, VVCContext *s, VVCLocalContext *lc)
static int run_parse(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
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_report_progress(VVCFrame *frame, const VVCProgress vp, const int y)
static void add_progress_listener(VVCFrame *ref, ProgressListener *l, VVCTask *t, VVCContext *s, const VVCProgress vp, const int y)
static void progress_done(VVCProgressListener *_l, const int type)
static int ff_mutex_unlock(AVMutex *mutex)
int ff_vvc_coding_tree_unit(VVCLocalContext *lc, const int ctu_idx, const int rs, const int rx, const int ry)
parse a CTU
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
const static char * task_name[]
#define ADD(dx, dy, stage)
void ff_vvc_executor_free(FFExecutor **e)
void ff_executor_free(FFExecutor **executor)
Free executor.
int ff_vvc_frame_submit(VVCContext *s, VVCFrameContext *fc)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define FF_ARRAY_ELEMS(a)
atomic_int nb_scheduled_tasks
VVCRefPic refs[VVC_MAX_REF_ENTRIES]
int ff_vvc_frame_wait(VVCContext *s, VVCFrameContext *fc)
VVCCabacState cabac_state[VVC_CONTEXTS]
static int ff_cond_wait(AVCond *cond, AVMutex *mutex)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
struct VVCFrameThread * ft
void ff_executor_execute(FFExecutor *e, FFTask *t)
Add task to executor.
atomic_int col_progress[VVC_PROGRESS_LAST]
#define atomic_load(object)
static void sheduled_done(VVCFrameThread *ft, atomic_int *scheduled)
int(* run_func)(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
int ff_vvc_frame_thread_init(VVCFrameContext *fc)
static int task_has_target_score(VVCTask *t, const VVCTaskStage stage, const uint8_t score)
@ VVC_TASK_STAGE_DEBLOCK_H
int is_scaled
RprConstraintsActiveFlag.
atomic_int nb_scheduled_listeners
FFExecutor * ff_executor_alloc(const FFTaskCallbacks *cb, int thread_count)
Alloc executor.
void ff_vvc_alf_filter(VVCLocalContext *lc, const int x0, const int y0)
alf filter for the CTU
static int ff_mutex_destroy(AVMutex *mutex)
ProgressListener col_listener
void ff_vvc_decode_neighbour(VVCLocalContext *lc, const int x_ctb, const int y_ctb, const int rx, const int ry, const int rs)
ProgressListener listener[2][VVC_MAX_REF_ENTRIES]
static int run_init(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
void ff_vvc_lmcs_filter(const VVCLocalContext *lc, const int x, const int y)
lmcs filter for the CTU
static void pixel_done(VVCProgressListener *l)
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_frame_thread_free(VVCFrameContext *fc)
static void schedule_inter(VVCContext *s, VVCFrameContext *fc, const SliceContext *sc, VVCTask *t, const int rs)
static int FUNC() user_data(CodedBitstreamContext *ctx, RWContext *rw, MPEG2RawUserData *current)
static int run_alf(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
const uint32_t * ctb_addr_in_curr_slice
CtbAddrInCurrSlice.
static int ff_mutex_lock(AVMutex *mutex)
static int zero(InterplayACMContext *s, unsigned ind, unsigned col)
static uint8_t task_add_score(VVCTask *t, const VVCTaskStage stage)
int max_y[2][VVC_MAX_REF_ENTRIES]
static uint8_t task_get_score(VVCTask *t, const VVCTaskStage stage)
static void task_init(VVCTask *t, VVCTaskStage stage, VVCFrameContext *fc, const int rx, const int ry)
#define i(width, name, range_min, range_max)
static void submit_entry_point(VVCContext *s, VVCFrameThread *ft, SliceContext *sc, EntryPoint *ep)
static int task_is_stage_ready(VVCTask *t, int add)
static void report_frame_progress(VVCFrameContext *fc, const int ry, const VVCProgress idx)
void * av_calloc(size_t nmemb, size_t size)
static int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected, intptr_t desired)
static int run_deblock_bs(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
static int run_deblock_v(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
static void task_stage_done(const VVCTask *t, VVCContext *s)
static int run_recon(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
int row_progress[VVC_PROGRESS_LAST]
static void frame_thread_add_score(VVCContext *s, VVCFrameThread *ft, const int rx, const int ry, const VVCTaskStage stage)
static void mv_done(VVCProgressListener *l)
static int ref[MAX_W *MAX_W]
static int ff_cond_signal(AVCond *cond)
uint8_t sps_entropy_coding_sync_enabled_flag
atomic_uchar score[VVC_TASK_STAGE_LAST]
atomic_uchar target_inter_score
static int ff_cond_destroy(AVCond *cond)
progress_done_fn progress_done
static void add_task(VVCContext *s, VVCTask *t)
static int run_inter(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
void ff_vvc_sao_copy_ctb_to_hv(VVCLocalContext *lc, const int rx, const int ry, const int last_row)
static int ff_cond_init(AVCond *cond, const void *attr)
int ff_vvc_per_frame_init(VVCFrameContext *fc)
@ VVC_TASK_STAGE_DEBLOCK_BS
void ff_vvc_ep_init_stat_coeff(EntryPoint *ep, const int bit_depth, const int persistent_rice_adaptation_enabled_flag)
static int is_first_row(const VVCFrameContext *fc, const int rx, const int ry)
static int task_run(FFTask *_t, void *local_context, void *user_data)
static void check_colocation(VVCContext *s, VVCTask *t)
void ff_vvc_add_progress_listener(VVCFrame *frame, VVCProgressListener *l)
int scale[2]
RefPicScale[].
static void schedule_next_parse(VVCContext *s, VVCFrameContext *fc, const SliceContext *sc, const VVCTask *t)