From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH v3 05/14] vvcdec: add reference management Date: Sun, 15 Oct 2023 11:45:50 +0200 Message-ID: <AS8P250MB074401689A106D89620078888FD0A@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM> (raw) In-Reply-To: <TYSPR06MB643397EF3A2D8F4121A3E95EAAEBA@TYSPR06MB6433.apcprd06.prod.outlook.com> Nuo Mi: > --- > libavcodec/vvc/Makefile | 3 +- > libavcodec/vvc/vvc_refs.c | 526 ++++++++++++++++++++++++++++++++++++++ > libavcodec/vvc/vvc_refs.h | 47 ++++ > 3 files changed, 575 insertions(+), 1 deletion(-) > create mode 100644 libavcodec/vvc/vvc_refs.c > create mode 100644 libavcodec/vvc/vvc_refs.h > > diff --git a/libavcodec/vvc/Makefile b/libavcodec/vvc/Makefile > index 64c9ea9688..6eb181784b 100644 > --- a/libavcodec/vvc/Makefile > +++ b/libavcodec/vvc/Makefile > @@ -5,4 +5,5 @@ OBJS-$(CONFIG_VVC_DECODER) += vvc/vvcdec.o \ > vvc/vvc_cabac.o \ > vvc/vvc_ctu.o \ > vvc/vvc_data.o \ > - vvc/vvc_ps.o > + vvc/vvc_ps.o \ > + vvc/vvc_refs.o > diff --git a/libavcodec/vvc/vvc_refs.c b/libavcodec/vvc/vvc_refs.c > new file mode 100644 > index 0000000000..010f1892ed > --- /dev/null > +++ b/libavcodec/vvc/vvc_refs.c > @@ -0,0 +1,526 @@ > +/* > + * VVC reference management > + * > + * Copyright (C) 2023 Nuo Mi > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include <stdatomic.h> > + > +#include "libavutil/thread.h" > + > +#include "vvc_refs.h" > + > +#define VVC_FRAME_FLAG_OUTPUT (1 << 0) > +#define VVC_FRAME_FLAG_SHORT_REF (1 << 1) > +#define VVC_FRAME_FLAG_LONG_REF (1 << 2) > +#define VVC_FRAME_FLAG_BUMPING (1 << 3) > + > +typedef struct FrameProgress { > + atomic_int progress[VVC_PROGRESS_LAST]; > + AVMutex lock; > +} FrameProgress; > + > +void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags) > +{ > + /* frame->frame can be NULL if context init failed */ > + if (!frame->frame || !frame->frame->buf[0]) > + return; > + > + frame->flags &= ~flags; > + if (!frame->flags) { > + ff_thread_release_ext_buffer(fc->avctx, &frame->tf); > + > + av_buffer_unref(&frame->progress_buf); > + > + av_buffer_unref(&frame->tab_dmvr_mvf_buf); > + frame->tab_dmvr_mvf = NULL; > + > + av_buffer_unref(&frame->rpl_buf); > + av_buffer_unref(&frame->rpl_tab_buf); > + frame->rpl_tab = NULL; > + > + frame->collocated_ref = NULL; > + } > +} > + > +const RefPicList *ff_vvc_get_ref_list(const VVCFrameContext *fc, const VVCFrame *ref, int x0, int y0) > +{ > + int x_cb = x0 >> fc->ps.sps->ctb_log2_size_y; > + int y_cb = y0 >> fc->ps.sps->ctb_log2_size_y; > + int pic_width_cb = fc->ps.pps->ctb_width; > + int ctb_addr_rs = y_cb * pic_width_cb + x_cb; > + > + return (const RefPicList *)ref->rpl_tab[ctb_addr_rs]; > +} > + > +void ff_vvc_clear_refs(VVCFrameContext *fc) > +{ > + int i; > + for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) > + ff_vvc_unref_frame(fc, &fc->DPB[i], > + VVC_FRAME_FLAG_SHORT_REF | VVC_FRAME_FLAG_LONG_REF); > +} > + > +static void free_progress(void *opaque, uint8_t *data) > +{ > + ff_mutex_destroy(&((FrameProgress*)data)->lock); > + av_free(data); > +} > + > +static AVBufferRef *alloc_progress(void) > +{ > + int ret; > + AVBufferRef *buf; > + FrameProgress *p = av_mallocz(sizeof(FrameProgress)); > + > + if (!p) > + return NULL; > + > + ret = ff_mutex_init(&p->lock, NULL); > + if (ret) { > + av_free(p); > + return NULL; > + } > + buf = av_buffer_create((void*)p, sizeof(*p), free_progress, NULL, 0); > + if (!buf) > + free_progress(NULL, (void*)p); > + return buf; > +} > + > +static VVCFrame *alloc_frame(VVCContext *s, VVCFrameContext *fc) > +{ > + const VVCPPS *pps = fc->ps.pps; > + int i, j, ret; > + for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) { > + VVCFrame *frame = &fc->DPB[i]; > + if (frame->frame->buf[0]) > + continue; > + > + ret = ff_thread_get_ext_buffer(fc->avctx, &frame->tf, > + AV_GET_BUFFER_FLAG_REF); > + if (ret < 0) > + return NULL; > + > + frame->rpl_buf = av_buffer_allocz(s->current_frame.nb_units * sizeof(RefPicListTab)); > + if (!frame->rpl_buf) > + goto fail; > + > + frame->tab_dmvr_mvf_buf = av_buffer_pool_get(fc->tab_dmvr_mvf_pool); > + if (!frame->tab_dmvr_mvf_buf) > + goto fail; > + frame->tab_dmvr_mvf = (MvField *)frame->tab_dmvr_mvf_buf->data; > + //fixme: remove this > + memset(frame->tab_dmvr_mvf, 0, frame->tab_dmvr_mvf_buf->size); This stuff here would benefit a lot from the (not yet merged) RefStruct pool API. There is even a flag to zero pool entries automatically so you don't have to. > + > + frame->rpl_tab_buf = av_buffer_pool_get(fc->rpl_tab_pool); > + if (!frame->rpl_tab_buf) > + goto fail; > + frame->rpl_tab = (RefPicListTab **)frame->rpl_tab_buf->data; > + frame->ctb_count = pps->ctb_width * pps->ctb_height; > + for (j = 0; j < frame->ctb_count; j++) > + frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf->data; > + > + > + frame->progress_buf = alloc_progress(); > + if (!frame->progress_buf) > + goto fail; > + > + return frame; > +fail: > + ff_vvc_unref_frame(fc, frame, ~0); > + return NULL; > + } > + av_log(s->avctx, AV_LOG_ERROR, "Error allocating frame, DPB full.\n"); > + return NULL; > +} > + > +int ff_vvc_set_new_ref(VVCContext *s, VVCFrameContext *fc, AVFrame **frame) > +{ > + const VVCPH *ph= &fc->ps.ph; > + const int poc = ph->poc; > + VVCFrame *ref; > + int i; > + > + /* check that this POC doesn't already exist */ > + for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) { > + VVCFrame *frame = &fc->DPB[i]; > + > + if (frame->frame->buf[0] && frame->sequence == s->seq_decode && > + frame->poc == poc) { > + av_log(s->avctx, AV_LOG_ERROR, "Duplicate POC in a sequence: %d.\n", > + poc); > + return AVERROR_INVALIDDATA; > + } > + } > + > + ref = alloc_frame(s, fc); > + if (!ref) > + return AVERROR(ENOMEM); > + > + *frame = ref->frame; > + fc->ref = ref; > + > + if (s->no_output_before_recovery_flag && (IS_RASL(s) || !GDR_IS_RECOVERED(s))) > + ref->flags = 0; > + else if (ph->r->ph_pic_output_flag) > + ref->flags = VVC_FRAME_FLAG_OUTPUT; > + > + if (!ph->r->ph_non_ref_pic_flag) > + ref->flags |= VVC_FRAME_FLAG_SHORT_REF; > + > + ref->poc = poc; > + ref->sequence = s->seq_decode; > + ref->frame->crop_left = fc->ps.pps->r->pps_conf_win_left_offset; > + ref->frame->crop_right = fc->ps.pps->r->pps_conf_win_right_offset; > + ref->frame->crop_top = fc->ps.pps->r->pps_conf_win_top_offset; > + ref->frame->crop_bottom = fc->ps.pps->r->pps_conf_win_bottom_offset; > + > + return 0; > +} > + > +int ff_vvc_output_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *out, const int no_output_of_prior_pics_flag, int flush) > +{ > + const VVCSPS *sps = fc->ps.sps; > + do { > + int nb_output = 0; > + int min_poc = INT_MAX; > + int i, min_idx, ret; > + > + if (no_output_of_prior_pics_flag) { > + for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) { > + VVCFrame *frame = &fc->DPB[i]; > + if (!(frame->flags & VVC_FRAME_FLAG_BUMPING) && frame->poc != fc->ps.ph.poc && > + frame->sequence == s->seq_output) { > + ff_vvc_unref_frame(fc, frame, VVC_FRAME_FLAG_OUTPUT); > + } > + } > + } > + > + for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) { > + VVCFrame *frame = &fc->DPB[i]; > + if ((frame->flags & VVC_FRAME_FLAG_OUTPUT) && > + frame->sequence == s->seq_output) { > + nb_output++; > + if (frame->poc < min_poc || nb_output == 1) { > + min_poc = frame->poc; > + min_idx = i; > + } > + } > + } > + > + /* wait for more frames before output */ > + if (!flush && s->seq_output == s->seq_decode && sps && > + nb_output <= sps->r->sps_dpb_params.dpb_max_dec_pic_buffering_minus1[sps->r->sps_max_sublayers_minus1] + 1) > + return 0; > + > + if (nb_output) { > + VVCFrame *frame = &fc->DPB[min_idx]; > + > + ret = av_frame_ref(out, frame->frame); > + if (frame->flags & VVC_FRAME_FLAG_BUMPING) > + ff_vvc_unref_frame(fc, frame, VVC_FRAME_FLAG_OUTPUT | VVC_FRAME_FLAG_BUMPING); > + else > + ff_vvc_unref_frame(fc, frame, VVC_FRAME_FLAG_OUTPUT); > + if (ret < 0) > + return ret; > + > + av_log(s->avctx, AV_LOG_DEBUG, > + "Output frame with POC %d.\n", frame->poc); > + return 1; > + } > + > + if (s->seq_output != s->seq_decode) > + s->seq_output = (s->seq_output + 1) & 0xff; > + else > + break; > + } while (1); > + return 0; > +} > + > +void ff_vvc_bump_frame(VVCContext *s, VVCFrameContext *fc) > +{ > + const VVCSPS *sps = fc->ps.sps; > + const int poc = fc->ps.ph.poc; > + int dpb = 0; > + int min_poc = INT_MAX; > + int i; > + > + for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) { > + VVCFrame *frame = &fc->DPB[i]; > + if ((frame->flags) && > + frame->sequence == s->seq_output && > + frame->poc != poc) { > + dpb++; > + } > + } > + > + if (sps && dpb >= sps->r->sps_dpb_params.dpb_max_dec_pic_buffering_minus1[sps->r->sps_max_sublayers_minus1] + 1) { > + for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) { > + VVCFrame *frame = &fc->DPB[i]; > + if ((frame->flags) && > + frame->sequence == s->seq_output && > + frame->poc != poc) { > + if (frame->flags == VVC_FRAME_FLAG_OUTPUT && frame->poc < min_poc) { > + min_poc = frame->poc; > + } > + } > + } > + > + for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) { > + VVCFrame *frame = &fc->DPB[i]; > + if (frame->flags & VVC_FRAME_FLAG_OUTPUT && > + frame->sequence == s->seq_output && > + frame->poc <= min_poc) { > + frame->flags |= VVC_FRAME_FLAG_BUMPING; > + } > + } > + > + dpb--; > + } > +} > + > +static VVCFrame *find_ref_idx(VVCContext *s, VVCFrameContext *fc, int poc, uint8_t use_msb) > +{ > + int mask = use_msb ? ~0 : fc->ps.sps->max_pic_order_cnt_lsb - 1; > + int i; > + > + for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) { > + VVCFrame *ref = &fc->DPB[i]; > + if (ref->frame->buf[0] && ref->sequence == s->seq_decode) { > + if ((ref->poc & mask) == poc) > + return ref; > + } > + } > + return NULL; > +} > + > +static void mark_ref(VVCFrame *frame, int flag) > +{ > + frame->flags &= ~(VVC_FRAME_FLAG_LONG_REF | VVC_FRAME_FLAG_SHORT_REF); > + frame->flags |= flag; > +} > + > +static VVCFrame *generate_missing_ref(VVCContext *s, VVCFrameContext *fc, int poc) > +{ > + const VVCSPS *sps = fc->ps.sps; > + VVCFrame *frame; > + int i, y; > + > + frame = alloc_frame(s, fc); > + if (!frame) > + return NULL; > + > + if (!s->avctx->hwaccel) { > + if (!sps->pixel_shift) { > + for (i = 0; frame->frame->buf[i]; i++) > + memset(frame->frame->buf[i]->data, 1 << (sps->bit_depth - 1), > + frame->frame->buf[i]->size); > + } else { > + for (i = 0; frame->frame->data[i]; i++) > + for (y = 0; y < (sps->height >> sps->vshift[i]); y++) { > + uint8_t *dst = frame->frame->data[i] + y * frame->frame->linesize[i]; > + AV_WN16(dst, 1 << (sps->bit_depth - 1)); > + av_memcpy_backptr(dst + 2, 2, 2*(sps->width >> sps->hshift[i]) - 2); > + } > + } > + } > + > + frame->poc = poc; > + frame->sequence = s->seq_decode; > + frame->flags = 0; > + > + ff_vvc_report_frame_finished(frame); > + > + return frame; > +} > + > +/* add a reference with the given poc to the list and mark it as used in DPB */ > +static int add_candidate_ref(VVCContext *s, VVCFrameContext *fc, RefPicList *list, > + int poc, int ref_flag, uint8_t use_msb) > +{ > + VVCFrame *ref = find_ref_idx(s, fc, poc, use_msb); > + > + if (ref == fc->ref || list->nb_refs >= VVC_MAX_REF_ENTRIES) > + return AVERROR_INVALIDDATA; > + > + if (!ref) { > + ref = generate_missing_ref(s, fc, poc); > + if (!ref) > + return AVERROR(ENOMEM); > + } > + > + list->list[list->nb_refs] = poc; > + list->ref[list->nb_refs] = ref; > + list->isLongTerm[list->nb_refs] = ref_flag & VVC_FRAME_FLAG_LONG_REF; > + list->nb_refs++; > + > + mark_ref(ref, ref_flag); > + return 0; > +} > + > +static int init_slice_rpl(const VVCFrameContext *fc, SliceContext *sc) > +{ > + VVCFrame *frame = fc->ref; > + const VVCSH *sh = &sc->sh; > + > + if (sc->slice_idx >= frame->rpl_buf->size / sizeof(RefPicListTab)) > + return AVERROR_INVALIDDATA; > + > + for (int i = 0; i < sh->num_ctus_in_curr_slice; i++) { > + const int rs = sh->ctb_addr_in_curr_slice[i]; > + frame->rpl_tab[rs] = (RefPicListTab *)frame->rpl_buf->data + sc->slice_idx; > + } > + > + sc->rpl = (RefPicList *)frame->rpl_tab[sh->ctb_addr_in_curr_slice[0]]; > + > + return 0; > +} > + > +static int delta_poc_st(const H266RefPicListStruct *rpls, > + const int lx, const int i, const VVCSPS *sps) > +{ > + int abs_delta_poc_st = rpls->abs_delta_poc_st[i]; > + if (!((sps->r->sps_weighted_pred_flag || > + sps->r->sps_weighted_bipred_flag) && i != 0)) > + abs_delta_poc_st++; > + return (1 - 2 * rpls->strp_entry_sign_flag[i]) * abs_delta_poc_st; > +} > + > +static int poc_lt(int *prev_delta_poc_msb, const int poc, const H266RefPicLists *ref_lists, > + const int lx, const int j, const int max_poc_lsb) > +{ > + const H266RefPicListStruct *rpls = ref_lists->rpl_ref_list + lx; > + int lt_poc = rpls->ltrp_in_header_flag ? ref_lists->poc_lsb_lt[lx][j] : rpls->rpls_poc_lsb_lt[j]; > + > + if (ref_lists->delta_poc_msb_cycle_present_flag[lx][j]) { > + const uint32_t delta = ref_lists->delta_poc_msb_cycle_lt[lx][j] + *prev_delta_poc_msb; > + lt_poc += poc - delta * max_poc_lsb - (poc & (max_poc_lsb - 1)); > + *prev_delta_poc_msb = delta; > + } > + return lt_poc; > +} > + > +int ff_vvc_slice_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc) > +{ > + const VVCSPS *sps = fc->ps.sps; > + const H266RawPPS *pps = fc->ps.pps->r; > + const VVCPH *ph = &fc->ps.ph; > + const H266RawSliceHeader *rsh = sc->sh.r; > + const int max_poc_lsb = sps->max_pic_order_cnt_lsb; > + const H266RefPicLists *ref_lists = > + pps->pps_rpl_info_in_ph_flag ? &ph->r->ph_ref_pic_lists : &rsh->sh_ref_pic_lists; > + int ret = 0; > + > + ret = init_slice_rpl(fc, sc); > + if (ret < 0) > + return ret; > + > + for (int lx = L0; lx <= L1; lx++) { > + const H266RefPicListStruct *rpls = ref_lists->rpl_ref_list + lx; > + RefPicList *rpl = sc->rpl + lx; > + int poc_base = ph->poc; > + int prev_delta_poc_msb = 0; > + > + rpl->nb_refs = 0; > + for (int i = 0, j = 0; i < rpls->num_ref_entries; i++) { > + int poc; > + if (!rpls->inter_layer_ref_pic_flag[i]) { > + int use_msb = 1; > + int ref_flag; > + if (rpls->st_ref_pic_flag[i]) { > + poc = poc_base + delta_poc_st(rpls, lx, i, sps); > + poc_base = poc; > + ref_flag = VVC_FRAME_FLAG_SHORT_REF; > + } else { > + use_msb = ref_lists->delta_poc_msb_cycle_present_flag[lx][j]; > + poc = poc_lt(&prev_delta_poc_msb, ph->poc, ref_lists, lx, j, max_poc_lsb); > + ref_flag = VVC_FRAME_FLAG_LONG_REF; > + j++; > + } > + ret = add_candidate_ref(s, fc, rpl, poc, ref_flag, use_msb); > + if (ret < 0) > + goto fail; > + } else { > + avpriv_request_sample(fc->avctx, "Inter layer ref"); > + ret = AVERROR_PATCHWELCOME; > + goto fail; > + } > + } > + if ((!rsh->sh_collocated_from_l0_flag) == lx && > + rsh->sh_collocated_ref_idx < rpl->nb_refs) > + fc->ref->collocated_ref = rpl->ref[rsh->sh_collocated_ref_idx]; > + } > +fail: > + return ret; > +} > + > +int ff_vvc_frame_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc) > +{ > + int i, ret = 0; > + > + /* clear the reference flags on all frames except the current one */ > + for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) { > + VVCFrame *frame = &fc->DPB[i]; > + > + if (frame == fc->ref) > + continue; > + > + mark_ref(frame, 0); > + } > + > + if ((ret = ff_vvc_slice_rpl(s, fc, sc)) < 0) > + goto fail; > + > +fail: > + /* release any frames that are now unused */ > + for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) > + ff_vvc_unref_frame(fc, &fc->DPB[i], 0); > + return ret; > +} > + > +void ff_vvc_report_frame_finished(VVCFrame *frame) > +{ > + ff_vvc_report_progress(frame, VVC_PROGRESS_MV, INT_MAX); > + ff_vvc_report_progress(frame, VVC_PROGRESS_PIXEL, INT_MAX); > +} > + > +void ff_vvc_report_progress(VVCFrame *frame, const VVCProgress vp, const int y) > +{ > + FrameProgress *p = (FrameProgress*)frame->progress_buf->data; > + > + ff_mutex_lock(&p->lock); > + > + av_assert0(p->progress[vp] < y || p->progress[vp] == INT_MAX); > + p->progress[vp] = y; > + > + ff_mutex_unlock(&p->lock); > +} > + > +int ff_vvc_check_progress(VVCFrame *frame, const VVCProgress vp, const int y) > +{ > + int ready ; > + FrameProgress *p = (FrameProgress*)frame->progress_buf->data; > + > + ff_mutex_lock(&p->lock); > + > + ready = p->progress[vp] > y + 1; > + > + ff_mutex_unlock(&p->lock); > + return ready; > +} > diff --git a/libavcodec/vvc/vvc_refs.h b/libavcodec/vvc/vvc_refs.h > new file mode 100644 > index 0000000000..1bba2ca34a > --- /dev/null > +++ b/libavcodec/vvc/vvc_refs.h > @@ -0,0 +1,47 @@ > +/* > + * VVC reference management > + * > + * Copyright (C) 2023 Nuo Mi > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#ifndef AVCODEC_VVC_REFS_H > +#define AVCODEC_VVC_REFS_H > + > +#include "vvcdec.h" > + > +int ff_vvc_output_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *out, int no_output_of_prior_pics_flag, int flush); > +void ff_vvc_bump_frame(VVCContext *s, VVCFrameContext *fc); > +int ff_vvc_set_new_ref(VVCContext *s, VVCFrameContext *fc, AVFrame **frame); > +const RefPicList *ff_vvc_get_ref_list(const VVCFrameContext *fc, const VVCFrame *ref, int x0, int y0); > +int ff_vvc_frame_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc); > +int ff_vvc_slice_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc); > +void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags); > +void ff_vvc_clear_refs(VVCFrameContext *fc); > + > +typedef enum VVCProgress{ > + VVC_PROGRESS_MV, > + VVC_PROGRESS_PIXEL, > + VVC_PROGRESS_LAST, > +} VVCProgress; > + > +void ff_vvc_report_frame_finished(VVCFrame *frame); > +void ff_vvc_report_progress(VVCFrame *frame, VVCProgress vp, int y); > +int ff_vvc_check_progress(VVCFrame *frame, VVCProgress vp, int y); > + > +#endif // AVCODEC_VVC_REFS_H _______________________________________________ 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".
next prev parent reply other threads:[~2023-10-15 9:44 UTC|newest] Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <20230902160741.19197-1-nuomi2021@gmail.com> 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 02/14] vvcdec: add vvc_data Nuo Mi 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 03/14] vvcdec: add parameter parser for sps, pps, ph, sh Nuo Mi 2023-09-05 13:07 ` [FFmpeg-devel] [PATCH v4] " Nuo Mi 2023-10-15 8:54 ` [FFmpeg-devel] [PATCH v3 03/14] " Andreas Rheinhardt 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 04/14] vvcdec: add cabac decoder Nuo Mi 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 05/14] vvcdec: add reference management Nuo Mi 2023-10-15 9:45 ` Andreas Rheinhardt [this message] 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 06/14] vvcdec: add motion vector decoder Nuo Mi 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 07/14] vvcdec: add inter prediction Nuo Mi 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 08/14] vvcdec: add inv transform 1d Nuo Mi 2023-10-15 9:49 ` Andreas Rheinhardt 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 09/14] vvcdec: add intra prediction Nuo Mi 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 10/14] vvcdec: add LMCS, Deblocking, SAO, and ALF filters Nuo Mi 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 11/14] vvcdec: add dsp init and inv transform Nuo Mi 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 12/14] vvcdec: add CTU parser Nuo Mi 2023-10-15 10:17 ` Andreas Rheinhardt 2023-10-15 10:31 ` Nuo Mi 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 13/14] vvcdec: add CTU thread logical Nuo Mi 2023-09-02 16:07 ` [FFmpeg-devel] [PATCH v3 14/14] vvcdec: add full vvc decoder Nuo Mi 2023-09-02 16:14 ` Nuo Mi 2023-09-04 14:28 ` Michael Niedermayer 2023-09-04 14:34 ` Michael Niedermayer 2023-09-05 13:16 ` Nuo Mi 2023-10-15 1:26 ` Nuo Mi
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=AS8P250MB074401689A106D89620078888FD0A@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM \ --to=andreas.rheinhardt@outlook.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
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