Go to the documentation of this file.
   23 #include <stdatomic.h> 
  115     memset(t, 0, 
sizeof(*t));
 
  120     t->
rs    = ry * 
fc->ft->ctu_width + rx;
 
  149     if (ry != 
pps->ctb_to_row_bd[ry]) {
 
  151         return fc->tab.slice_idx[rs] != 
fc->tab.slice_idx[rs - ft->
ctu_width];
 
  159     static const uint8_t target_score[] =
 
  174         target = 2 + wpp - 1;                           
 
  183     return score == target + 1;
 
  261     if (
sps->r->sps_entropy_coding_sync_enabled_flag) {
 
  262         if (t->
rx == 
fc->ps.pps->ctb_to_col_bd[t->
rx]) {
 
  275         const int next_rx = next_rs % ft->
ctu_width;
 
  276         const int next_ry = next_rs / ft->
ctu_width;
 
  286         CTU *ctu = 
fc->tab.ctus + rs;
 
  287         for (
int lx = 0; lx < 2; lx++) {
 
  289                 const int y = ctu->
max_y[lx][
i];
 
  302     const int slice_idx = 
fc->tab.slice_idx[rs];
 
  316 #define ADD(dx, dy, stage) frame_thread_add_score(s, ft, t->rx + (dx), t->ry + (dy), stage) 
  366 #define CHECK(a, b)                         \ 
  377     CHECK(
a->fc->decode_order, 
b->fc->decode_order);             
 
  382         return a->rx < 
b->rx;
 
  385     CHECK(
a->rx + 
a->ry + 
a->stage, 
b->rx + 
b->ry + 
b->stage);    
 
  387     return a->ry < 
b->ry;
 
  404             const int progress = y == ft->
ctu_height ? INT_MAX : y * ctu_size;
 
  416     const int rs        = t->
rs;
 
  417     const CTU *ctu      = 
fc->tab.ctus + rs;
 
  437     const CTU *ctu      = 
fc->tab.ctus + rs;
 
  438     const int slice_idx = 
fc->tab.slice_idx[rs];
 
  440     if (slice_idx != -1) {
 
  441         lc->
sc = 
fc->slices[slice_idx];
 
  454     const int rs        = t->
rs;
 
  455     const int slice_idx = 
fc->tab.slice_idx[rs];
 
  457     if (slice_idx != -1) {
 
  458         lc->
sc = 
fc->slices[slice_idx];
 
  470     const int x0        = t->
rx * ctu_size;
 
  471     const int y0        = t->
ry * ctu_size;
 
  473     const int slice_idx = 
fc->tab.slice_idx[rs];
 
  475     if (slice_idx != -1) {
 
  476         lc->
sc = 
fc->slices[slice_idx];
 
  489     const int x0        = t->
rx * ctb_size;
 
  490     const int y0        = t->
ry * ctb_size;
 
  491     const int slice_idx = 
fc->tab.slice_idx[rs];
 
  493     if (slice_idx != -1) {
 
  494         lc->
sc = 
fc->slices[slice_idx];
 
  510     const int x0        = t->
rx * ctb_size;
 
  511     const int y0        = t->
ry * ctb_size;
 
  512     const int slice_idx = 
fc->tab.slice_idx[rs];
 
  514     if (slice_idx != -1) {
 
  515         lc->
sc = 
fc->slices[slice_idx];
 
  520         if (
fc->ps.sps->r->sps_sao_enabled_flag)
 
  531     const int rs        = t->
ry * 
fc->ps.pps->ctb_width + t->
rx;
 
  533     const int x0        = t->
rx * ctb_size;
 
  534     const int y0        = t->
ry * ctb_size;
 
  536     if (
fc->ps.sps->r->sps_sao_enabled_flag) {
 
  541     if (
fc->ps.sps->r->sps_alf_enabled_flag)
 
  552     const int x0        = t->
rx * ctu_size;
 
  553     const int y0        = t->
ry * ctu_size;
 
  555     if (
fc->ps.sps->r->sps_alf_enabled_flag) {
 
  556         const int slice_idx = 
CTB(
fc->tab.slice_idx, t->
rx, t->
ry);
 
  557         if (slice_idx != -1) {
 
  558             lc->
sc = 
fc->slices[slice_idx];
 
  568 #define VVC_THREAD_DEBUG 
  569 #ifdef VVC_THREAD_DEBUG 
  601 #ifdef VVC_THREAD_DEBUG 
  606         if ((
ret = 
run[stage](
s, lc, t)) < 0) {
 
  607 #ifdef COMPAT_ATOMICS_WIN32_STDATOMIC_H 
  614                 "frame %5d, %s(%3d, %3d) failed with %d\r\n",
 
  746     for (
int rs = 0; rs < ft->
ctu_count; rs++) {
 
  771     if (
fc->ps.ph.r->ph_temporal_mvp_enabled_flag || 
fc->ps.sps->r->sps_sbtmvp_enabled_flag) {
 
  773         const int first_col = t->
rx == 
fc->ps.pps->ctb_to_col_bd[t->
rx];
 
  774         if (col && first_col) {
 
  776             const int y = (t->
ry << 
fc->ps.sps->ctb_log2_size_y);
 
  796     for (
int i = 0; 
i < 
fc->nb_slices; 
i++) {
 
  798         for (
int j = 0; j < sc->
nb_eps; j++) {
 
  800             for (
int k = ep->
ctu_start; k < ep->ctu_end; k++) {
 
  824 #ifdef VVC_THREAD_DEBUG 
  
static uint8_t task_get_score(VVCTask *t, const VVCTaskStage stage)
 
void ff_vvc_sao_filter(VVCLocalContext *lc, int x, int y)
sao filter for the CTU
 
static void add_task(VVCContext *s, VVCTask *t)
 
static int ff_mutex_init(AVMutex *mutex, const void *attr)
 
#define atomic_store(object, desired)
 
void ff_vvc_lmcs_filter(const VVCLocalContext *lc, const int x, const int y)
lmcs filter for the CTU
 
static void listener_init(ProgressListener *l, VVCTask *t, VVCContext *s, const VVCProgress vp, const int y)
 
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 void task_init_parse(VVCTask *t, SliceContext *sc, EntryPoint *ep, const int ctu_idx)
 
void ff_vvc_report_frame_finished(VVCFrame *frame)
 
const static char * task_name[]
 
void ff_vvc_alf_filter(VVCLocalContext *lc, const int x0, const int y0)
alf filter for the CTU
 
static int run_parse(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
 
int ff_vvc_predict_inter(VVCLocalContext *lc, const int rs)
Loop entire CTU to predict all inter coding blocks.
 
static const OMX_CALLBACKTYPE callbacks
 
static int task_is_stage_ready(VVCTask *t, int add)
 
const H266RawSliceHeader * r
RefStruct reference.
 
static void schedule_next_parse(VVCContext *s, VVCFrameContext *fc, const SliceContext *sc, const VVCTask *t)
 
#define fc(width, name, range_min, range_max)
 
static int run_recon(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
 
static int ff_mutex_unlock(AVMutex *mutex)
 
static void schedule_inter(VVCContext *s, VVCFrameContext *fc, const SliceContext *sc, VVCTask *t, const int rs)
 
static int task_ready(const AVTask *_t, void *user_data)
 
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
 
#define atomic_fetch_sub(object, operand)
 
@ VVC_TASK_STAGE_DEBLOCK_V
 
AVExecutor * av_executor_alloc(const AVTaskCallbacks *cb, int thread_count)
Alloc executor.
 
void ff_vvc_report_progress(VVCFrame *frame, const VVCProgress vp, const int y)
 
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
 
#define FF_ARRAY_ELEMS(a)
 
atomic_int nb_scheduled_tasks
 
static void frame_thread_init_score(VVCFrameContext *fc)
 
static void parse_task_done(VVCContext *s, VVCFrameContext *fc, const int rx, const int ry)
 
static void progress_done(VVCProgressListener *_l, const int type)
 
VVCCabacState cabac_state[VVC_CONTEXTS]
 
static int ff_cond_wait(AVCond *cond, AVMutex *mutex)
 
#define av_assert0(cond)
assert() equivalent, that is always enabled.
 
int ff_vvc_coding_tree_unit(VVCLocalContext *lc, const int ctu_idx, const int rs, const int rx, const int ry)
parse a CTU
 
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
 
struct VVCFrameThread * ft
 
static void pixel_done(VVCProgressListener *l)
 
struct HEVCFrame * ref[HEVC_MAX_REFS]
 
atomic_int col_progress[VVC_PROGRESS_LAST]
 
int ff_vvc_frame_wait(VVCContext *s, VVCFrameContext *fc)
 
#define atomic_load(object)
 
static int run_lmcs(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
 
static void add_progress_listener(VVCFrame *ref, ProgressListener *l, VVCTask *t, VVCContext *s, const VVCProgress vp, const int y)
 
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 void task_init(VVCTask *t, VVCTaskStage stage, VVCFrameContext *fc, const int rx, const int ry)
 
static void submit_entry_point(VVCContext *s, VVCFrameThread *ft, SliceContext *sc, EntryPoint *ep)
 
void ff_vvc_frame_thread_free(VVCFrameContext *fc)
 
void ff_vvc_sao_copy_ctb_to_hv(VVCLocalContext *lc, const int rx, const int ry, const int last_row)
 
atomic_int nb_scheduled_listeners
 
static int ff_mutex_destroy(AVMutex *mutex)
 
#define atomic_compare_exchange_strong(object, expected, desired)
 
ProgressListener col_listener
 
ProgressListener listener[2][VVC_MAX_REF_ENTRIES]
 
static int run_deblock_v(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
 
static int FUNC() pps(CodedBitstreamContext *ctx, RWContext *rw, H264RawPPS *current)
 
void ff_vvc_deblock_vertical(const VVCLocalContext *lc, int x0, int y0)
vertical deblock filter for the CTU
 
static void report_frame_progress(VVCFrameContext *fc, const int ry, const VVCProgress idx)
 
void ff_vvc_alf_copy_ctu_to_hv(VVCLocalContext *lc, const int x0, const int y0)
 
static int FUNC() user_data(CodedBitstreamContext *ctx, RWContext *rw, MPEG2RawUserData *current)
 
static int run_alf(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
 
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
 
static uint8_t task_add_score(VVCTask *t, const VVCTaskStage stage)
 
int(* run_func)(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
 
const uint32_t * ctb_addr_in_curr_slice
CtbAddrInCurrSlice.
 
static int ff_mutex_lock(AVMutex *mutex)
 
static int is_first_row(const VVCFrameContext *fc, const int rx, const int ry)
 
void ff_vvc_ep_init_stat_coeff(EntryPoint *ep, const int bit_depth, const int persistent_rice_adaptation_enabled_flag)
 
void ff_vvc_decode_neighbour(VVCLocalContext *lc, const int x_ctb, const int y_ctb, const int rx, const int ry, const int rs)
 
int max_y[2][VVC_MAX_REF_ENTRIES]
 
static int task_priority_higher(const AVTask *_a, const AVTask *_b)
 
#define i(width, name, range_min, range_max)
 
static int run_sao(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
 
int ff_vvc_frame_thread_init(VVCFrameContext *fc)
 
void * av_calloc(size_t nmemb, size_t size)
 
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
 
void ff_vvc_executor_free(AVExecutor **e)
 
void av_executor_free(AVExecutor **executor)
Free executor.
 
int row_progress[VVC_PROGRESS_LAST]
 
static int task_run(AVTask *_t, void *local_context, void *user_data)
 
void ff_vvc_frame_submit(VVCContext *s, VVCFrameContext *fc)
 
void ff_vvc_deblock_horizontal(const VVCLocalContext *lc, int x0, int y0)
horizontal deblock filter for the CTU
 
void av_executor_execute(AVExecutor *e, AVTask *t)
Add task to executor.
 
#define atomic_fetch_add(object, operand)
 
int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const int ry)
reconstruct a CTU
 
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 run_inter(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
 
@ VVC_TASK_STAGE_DEBLOCK_H
 
static void task_run_stage(VVCTask *t, VVCContext *s, VVCLocalContext *lc)
 
static void check_colocation(VVCContext *s, VVCTask *t)
 
static void task_stage_done(const VVCTask *t, VVCContext *s)
 
static void sheduled_done(VVCFrameThread *ft, atomic_int *scheduled)
 
static int ff_cond_destroy(AVCond *cond)
 
#define ADD(dx, dy, stage)
 
progress_done_fn progress_done
 
static int run_deblock_h(VVCContext *s, VVCLocalContext *lc, VVCTask *t)
 
static int ff_cond_init(AVCond *cond, const void *attr)
 
AVExecutor * ff_vvc_executor_alloc(VVCContext *s, const int thread_count)
 
void ff_vvc_add_progress_listener(VVCFrame *frame, VVCProgressListener *l)
 
static int task_has_target_score(VVCTask *t, const VVCTaskStage stage, const uint8_t score)