Start by moving the DPB to it. Only one context exists for now, so decoder behaviour should not change with this commit, but that will change in the future. --- libavcodec/dxva2_hevc.c | 7 ++-- libavcodec/hevc/hevcdec.c | 63 +++++++++++++++++------------- libavcodec/hevc/hevcdec.h | 19 +++++++--- libavcodec/hevc/refs.c | 80 +++++++++++++++++++++------------------ libavcodec/nvdec_hevc.c | 5 ++- libavcodec/vaapi_hevc.c | 14 ++++--- libavcodec/vdpau_hevc.c | 5 ++- libavcodec/vulkan_hevc.c | 17 +++++---- 8 files changed, 120 insertions(+), 90 deletions(-)
diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c index 97e51d15de..d01d1e76e8 100644 --- a/libavcodec/dxva2_hevc.c +++ b/libavcodec/dxva2_hevc.c @@ -61,6 +61,7 @@ void ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, AVDXVACo DXVA_PicParams_HEVC *pp) { const HEVCContext *h = avctx->priv_data; + const HEVCLayerContext *l = &h->layers[h->cur_layer]; const HEVCFrame *current_picture = h->cur_frame; const HEVCPPS *pps = h->pps; const HEVCSPS *sps = pps->sps; @@ -163,9 +164,9 @@ void ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, AVDXVACo // fill RefPicList from the DPB for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->RefPicList); i++) { const HEVCFrame *frame = NULL; - while (!frame && j < FF_ARRAY_ELEMS(h->DPB)) { - if (&h->DPB[j] != current_picture && (h->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) - frame = &h->DPB[j]; + while (!frame && j < FF_ARRAY_ELEMS(l->DPB)) { + if (&l->DPB[j] != current_picture && (l->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) + frame = &l->DPB[j]; j++; } diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index 4077ed3ac5..669c8f550b 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -2902,7 +2902,7 @@ static int set_side_data(HEVCContext *s) return 0; } -static int hevc_frame_start(HEVCContext *s) +static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l) { const HEVCPPS *const pps = s->ps.pps_list[s->sh.pps_id]; const HEVCSPS *const sps = pps->sps; @@ -2915,7 +2915,7 @@ static int hevc_frame_start(HEVCContext *s) if (s->ps.sps != sps) { enum AVPixelFormat pix_fmt; - ff_hevc_clear_refs(s); + ff_hevc_clear_refs(l); ret = set_sps(s, sps); if (ret < 0) @@ -2938,7 +2938,7 @@ static int hevc_frame_start(HEVCContext *s) memset(s->tab_slice_address, -1, pic_size_in_ctb * sizeof(*s->tab_slice_address)); if (IS_IDR(s)) - ff_hevc_clear_refs(s); + ff_hevc_clear_refs(l); s->slice_idx = 0; s->first_nal_type = s->nal_unit_type; @@ -2963,7 +2963,7 @@ static int hevc_frame_start(HEVCContext *s) s->local_ctx[0].end_of_tiles_x = pps->column_width[0] << sps->log2_ctb_size; if (new_sequence) { - ret = ff_hevc_output_frames(s, 0, 0, s->sh.no_output_of_prior_pics_flag); + ret = ff_hevc_output_frames(s, l, 0, 0, s->sh.no_output_of_prior_pics_flag); if (ret < 0) return ret; } @@ -2972,11 +2972,11 @@ static int hevc_frame_start(HEVCContext *s) if (ret < 0) return ret; - ret = ff_hevc_set_new_ref(s, s->poc); + ret = ff_hevc_set_new_ref(s, l, s->poc); if (ret < 0) goto fail; - ret = ff_hevc_frame_rps(s); + ret = ff_hevc_frame_rps(s, l); if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error constructing the frame RPS.\n"); goto fail; @@ -3020,7 +3020,7 @@ static int hevc_frame_start(HEVCContext *s) s->cur_frame->f->pict_type = 3 - s->sh.slice_type; - ret = ff_hevc_output_frames(s, sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics, + ret = ff_hevc_output_frames(s, l, sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics, sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering, 0); if (ret < 0) goto fail; @@ -3158,7 +3158,8 @@ static int hevc_frame_end(HEVCContext *s) return 0; } -static int decode_slice(HEVCContext *s, const H2645NAL *nal, GetBitContext *gb) +static int decode_slice(HEVCContext *s, HEVCLayerContext *l, + const H2645NAL *nal, GetBitContext *gb) { int ret; @@ -3183,7 +3184,7 @@ static int decode_slice(HEVCContext *s, const H2645NAL *nal, GetBitContext *gb) return AVERROR_INVALIDDATA; } - ret = hevc_frame_start(s); + ret = hevc_frame_start(s, l); if (ret < 0) return ret; } else if (!s->cur_frame) { @@ -3207,6 +3208,7 @@ static int decode_slice(HEVCContext *s, const H2645NAL *nal, GetBitContext *gb) static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) { + HEVCLayerContext *l = &s->layers[0]; GetBitContext gb = nal->gb; int ret; @@ -3264,7 +3266,7 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) case HEVC_NAL_RADL_R: case HEVC_NAL_RASL_N: case HEVC_NAL_RASL_R: - ret = decode_slice(s, nal, &gb); + ret = decode_slice(s, l, nal, &gb); if (ret < 0) goto fail; break; @@ -3427,7 +3429,7 @@ static int hevc_receive_frame(AVCodecContext *avctx, AVFrame *frame) av_packet_unref(avpkt); ret = ff_decode_get_packet(avctx, avpkt); if (ret == AVERROR_EOF) { - ret = ff_hevc_output_frames(s, 0, 0, 0); + ret = ff_hevc_output_frames(s, &s->layers[0], 0, 0, 0); if (ret < 0) return ret; goto do_output; @@ -3517,9 +3519,12 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) ff_container_fifo_free(&s->output_fifo); - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { - ff_hevc_unref_frame(&s->DPB[i], ~0); - av_frame_free(&s->DPB[i].frame_grain); + for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { + HEVCLayerContext *l = &s->layers[layer]; + for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + ff_hevc_unref_frame(&l->DPB[i], ~0); + av_frame_free(&l->DPB[i].frame_grain); + } } ff_hevc_ps_uninit(&s->ps); @@ -3540,7 +3545,6 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) static av_cold int hevc_init_context(AVCodecContext *avctx) { HEVCContext *s = avctx->priv_data; - int i; s->avctx = avctx; @@ -3557,10 +3561,13 @@ static av_cold int hevc_init_context(AVCodecContext *avctx) if (!s->output_fifo) return AVERROR(ENOMEM); - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { - s->DPB[i].frame_grain = av_frame_alloc(); - if (!s->DPB[i].frame_grain) - return AVERROR(ENOMEM); + for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { + HEVCLayerContext *l = &s->layers[layer]; + for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + l->DPB[i].frame_grain = av_frame_alloc(); + if (!l->DPB[i].frame_grain) + return AVERROR(ENOMEM); + } } s->md5_ctx = av_md5_alloc(); @@ -3583,14 +3590,18 @@ static int hevc_update_thread_context(AVCodecContext *dst, { HEVCContext *s = dst->priv_data; HEVCContext *s0 = src->priv_data; - int i, ret; + int ret; - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { - ff_hevc_unref_frame(&s->DPB[i], ~0); - if (s0->DPB[i].f) { - ret = hevc_ref_frame(&s->DPB[i], &s0->DPB[i]); - if (ret < 0) - return ret; + for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { + HEVCLayerContext *l = &s->layers[layer]; + const HEVCLayerContext *l0 = &s0->layers[layer]; + for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + ff_hevc_unref_frame(&l->DPB[i], ~0); + if (l0->DPB[i].f) { + ret = hevc_ref_frame(&l->DPB[i], &l0->DPB[i]); + if (ret < 0) + return ret; + } } } diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h index 656a3ab94b..aab09bfd94 100644 --- a/libavcodec/hevc/hevcdec.h +++ b/libavcodec/hevc/hevcdec.h @@ -438,6 +438,10 @@ typedef struct HEVCLocalContext { char padding[128]; } HEVCLocalContext; +typedef struct HEVCLayerContext { + HEVCFrame DPB[32]; +} HEVCLayerContext; + typedef struct HEVCContext { const AVClass *c; // needed by private avoptions AVCodecContext *avctx; @@ -445,6 +449,10 @@ typedef struct HEVCContext { HEVCLocalContext *local_ctx; unsigned nb_local_ctx; + HEVCLayerContext layers[1]; + // index in layers of the layer currently being decoded + unsigned cur_layer; + /** 1 if the independent slice segment header was successfully parsed */ uint8_t slice_initialized; @@ -470,7 +478,6 @@ typedef struct HEVCContext { int temporal_id; ///< temporal_id_plus1 - 1 HEVCFrame *cur_frame; HEVCFrame *collocated_ref; - HEVCFrame DPB[32]; int poc; int poc_tid0; int slice_idx; ///< number of the slice being currently decoded @@ -536,7 +543,7 @@ typedef struct HEVCContext { /** * Mark all frames in DPB as unused for reference. */ -void ff_hevc_clear_refs(HEVCContext *s); +void ff_hevc_clear_refs(HEVCLayerContext *l); /** * Drop all frames currently in DPB. @@ -549,7 +556,7 @@ const RefPicList *ff_hevc_get_ref_list(const HEVCContext *s, const HEVCFrame *fr /** * Construct the reference picture sets for the current frame. */ -int ff_hevc_frame_rps(HEVCContext *s); +int ff_hevc_frame_rps(HEVCContext *s, HEVCLayerContext *l); /** * Construct the reference picture list(s) for the current slice. @@ -597,7 +604,7 @@ int ff_hevc_res_scale_sign_flag(HEVCLocalContext *lc, int idx); */ int ff_hevc_frame_nb_refs(const SliceHeader *sh, const HEVCPPS *pps); -int ff_hevc_set_new_ref(HEVCContext *s, int poc); +int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc); static av_always_inline int ff_hevc_nal_is_nonref(enum HEVCNALUnitType type) { @@ -625,8 +632,8 @@ static av_always_inline int ff_hevc_nal_is_nonref(enum HEVCNALUnitType type) * @param max_dpb maximum number of any frames that can be present in the DPB * before output is triggered */ -int ff_hevc_output_frames(HEVCContext *s, unsigned max_output, - unsigned max_dpb, int discard); +int ff_hevc_output_frames(HEVCContext *s, HEVCLayerContext *l, + unsigned max_output, unsigned max_dpb, int discard); void ff_hevc_unref_frame(HEVCFrame *frame, int flags); diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c index 65abd09a21..4d123d6d8d 100644 --- a/libavcodec/hevc/refs.c +++ b/libavcodec/hevc/refs.c @@ -59,27 +59,29 @@ const RefPicList *ff_hevc_get_ref_list(const HEVCContext *s, return &ref->rpl_tab[ctb_addr_ts]->refPicList[0]; } -void ff_hevc_clear_refs(HEVCContext *s) +void ff_hevc_clear_refs(HEVCLayerContext *l) { int i; - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) - ff_hevc_unref_frame(&s->DPB[i], + for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) + ff_hevc_unref_frame(&l->DPB[i], HEVC_FRAME_FLAG_SHORT_REF | HEVC_FRAME_FLAG_LONG_REF); } void ff_hevc_flush_dpb(HEVCContext *s) { - int i; - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) - ff_hevc_unref_frame(&s->DPB[i], ~0); + for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { + HEVCLayerContext *l = &s->layers[layer]; + for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) + ff_hevc_unref_frame(&l->DPB[i], ~0); + } } -static HEVCFrame *alloc_frame(HEVCContext *s) +static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l) { int i, j, ret; - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { - HEVCFrame *frame = &s->DPB[i]; + for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + HEVCFrame *frame = &l->DPB[i]; if (frame->f) continue; @@ -123,14 +125,14 @@ fail: return NULL; } -int ff_hevc_set_new_ref(HEVCContext *s, int poc) +int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc) { HEVCFrame *ref; int i; /* check that this POC doesn't already exist */ - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { - HEVCFrame *frame = &s->DPB[i]; + for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + HEVCFrame *frame = &l->DPB[i]; if (frame->f && frame->poc == poc) { av_log(s->avctx, AV_LOG_ERROR, "Duplicate POC in a sequence: %d.\n", @@ -139,7 +141,7 @@ int ff_hevc_set_new_ref(HEVCContext *s, int poc) } } - ref = alloc_frame(s); + ref = alloc_frame(s, l); if (!ref) return AVERROR(ENOMEM); @@ -160,18 +162,18 @@ int ff_hevc_set_new_ref(HEVCContext *s, int poc) return 0; } -static void unref_missing_refs(HEVCContext *s) +static void unref_missing_refs(HEVCLayerContext *l) { - for (int i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { - HEVCFrame *frame = &s->DPB[i]; + for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + HEVCFrame *frame = &l->DPB[i]; if (frame->flags & HEVC_FRAME_FLAG_UNAVAILABLE) { ff_hevc_unref_frame(frame, ~0); } } } -int ff_hevc_output_frames(HEVCContext *s, unsigned max_output, - unsigned max_dpb, int discard) +int ff_hevc_output_frames(HEVCContext *s, HEVCLayerContext *l, + unsigned max_output, unsigned max_dpb, int discard) { while (1) { int nb_dpb = 0; @@ -179,8 +181,8 @@ int ff_hevc_output_frames(HEVCContext *s, unsigned max_output, int min_poc = INT_MAX; int i, min_idx, ret; - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { - HEVCFrame *frame = &s->DPB[i]; + for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + HEVCFrame *frame = &l->DPB[i]; if (frame->flags & HEVC_FRAME_FLAG_OUTPUT) { nb_output++; if (frame->poc < min_poc || nb_output == 1) { @@ -193,7 +195,7 @@ int ff_hevc_output_frames(HEVCContext *s, unsigned max_output, if (nb_output > max_output || (nb_output && nb_dpb > max_dpb)) { - HEVCFrame *frame = &s->DPB[min_idx]; + HEVCFrame *frame = &l->DPB[min_idx]; ret = discard ? 0 : ff_container_fifo_write(s->output_fifo, @@ -313,13 +315,14 @@ int ff_hevc_slice_rpl(HEVCContext *s) return 0; } -static HEVCFrame *find_ref_idx(HEVCContext *s, int poc, uint8_t use_msb) +static HEVCFrame *find_ref_idx(HEVCContext *s, HEVCLayerContext *l, + int poc, uint8_t use_msb) { int mask = use_msb ? ~0 : (1 << s->ps.sps->log2_max_poc_lsb) - 1; int i; - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { - HEVCFrame *ref = &s->DPB[i]; + for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + HEVCFrame *ref = &l->DPB[i]; if (ref->f) { if ((ref->poc & mask) == poc && (use_msb || ref->poc != s->poc)) return ref; @@ -338,12 +341,12 @@ static void mark_ref(HEVCFrame *frame, int flag) frame->flags |= flag; } -static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc) +static HEVCFrame *generate_missing_ref(HEVCContext *s, HEVCLayerContext *l, int poc) { HEVCFrame *frame; int i, y; - frame = alloc_frame(s); + frame = alloc_frame(s, l); if (!frame) return NULL; @@ -372,16 +375,17 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc) } /* add a reference with the given poc to the list and mark it as used in DPB */ -static int add_candidate_ref(HEVCContext *s, RefPicList *list, +static int add_candidate_ref(HEVCContext *s, HEVCLayerContext *l, + RefPicList *list, int poc, int ref_flag, uint8_t use_msb) { - HEVCFrame *ref = find_ref_idx(s, poc, use_msb); + HEVCFrame *ref = find_ref_idx(s, l, poc, use_msb); if (ref == s->cur_frame || list->nb_refs >= HEVC_MAX_REFS) return AVERROR_INVALIDDATA; if (!ref) { - ref = generate_missing_ref(s, poc); + ref = generate_missing_ref(s, l, poc); if (!ref) return AVERROR(ENOMEM); } @@ -394,7 +398,7 @@ static int add_candidate_ref(HEVCContext *s, RefPicList *list, return 0; } -int ff_hevc_frame_rps(HEVCContext *s) +int ff_hevc_frame_rps(HEVCContext *s, HEVCLayerContext *l) { const ShortTermRPS *short_rps = s->sh.short_term_rps; const LongTermRPS *long_rps = &s->sh.long_term_rps; @@ -406,11 +410,11 @@ int ff_hevc_frame_rps(HEVCContext *s) return 0; } - unref_missing_refs(s); + unref_missing_refs(l); /* clear the reference flags on all frames except the current one */ - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { - HEVCFrame *frame = &s->DPB[i]; + for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + HEVCFrame *frame = &l->DPB[i]; if (frame == s->cur_frame) continue; @@ -433,7 +437,8 @@ int ff_hevc_frame_rps(HEVCContext *s) else list = ST_CURR_AFT; - ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_SHORT_REF, 1); + ret = add_candidate_ref(s, l, &rps[list], poc, + HEVC_FRAME_FLAG_SHORT_REF, 1); if (ret < 0) goto fail; } @@ -443,15 +448,16 @@ int ff_hevc_frame_rps(HEVCContext *s) int poc = long_rps->poc[i]; int list = long_rps->used[i] ? LT_CURR : LT_FOLL; - ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_LONG_REF, long_rps->poc_msb_present[i]); + ret = add_candidate_ref(s, l, &rps[list], poc, + HEVC_FRAME_FLAG_LONG_REF, long_rps->poc_msb_present[i]); if (ret < 0) goto fail; } fail: /* release any frames that are now unused */ - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) - ff_hevc_unref_frame(&s->DPB[i], 0); + for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) + ff_hevc_unref_frame(&l->DPB[i], 0); return ret; } diff --git a/libavcodec/nvdec_hevc.c b/libavcodec/nvdec_hevc.c index ce66ddcfb7..6888507535 100644 --- a/libavcodec/nvdec_hevc.c +++ b/libavcodec/nvdec_hevc.c @@ -73,6 +73,7 @@ static int nvdec_hevc_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { const HEVCContext *s = avctx->priv_data; + const HEVCLayerContext *l = &s->layers[s->cur_layer]; const HEVCPPS *pps = s->pps; const HEVCSPS *sps = pps->sps; @@ -225,8 +226,8 @@ static int nvdec_hevc_start_frame(AVCodecContext *avctx, } dpb_size = 0; - for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { - const HEVCFrame *ref = &s->DPB[i]; + for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + const HEVCFrame *ref = &l->DPB[i]; if (!(ref->flags & (HEVC_FRAME_FLAG_SHORT_REF | HEVC_FRAME_FLAG_LONG_REF))) continue; if (dpb_size >= FF_ARRAY_ELEMS(ppc->RefPicIdx)) { diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c index ad4cd35b26..b97e7c0343 100644 --- a/libavcodec/vaapi_hevc.c +++ b/libavcodec/vaapi_hevc.c @@ -96,7 +96,8 @@ static int find_frame_rps_type(const HEVCContext *h, const HEVCFrame *pic) return 0; } -static void fill_vaapi_reference_frames(const HEVCContext *h, VAPictureParameterBufferHEVC *pp) +static void fill_vaapi_reference_frames(const HEVCContext *h, const HEVCLayerContext *l, + VAPictureParameterBufferHEVC *pp) { const HEVCFrame *current_picture = h->cur_frame; int i, j, rps_type; @@ -104,10 +105,10 @@ static void fill_vaapi_reference_frames(const HEVCContext *h, VAPictureParameter for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->ReferenceFrames); i++) { const HEVCFrame *frame = NULL; - while (!frame && j < FF_ARRAY_ELEMS(h->DPB)) { - if ((&h->DPB[j] != current_picture || h->pps->pps_curr_pic_ref_enabled_flag) && - (h->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) - frame = &h->DPB[j]; + while (!frame && j < FF_ARRAY_ELEMS(l->DPB)) { + if ((&l->DPB[j] != current_picture || h->pps->pps_curr_pic_ref_enabled_flag) && + (l->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) + frame = &l->DPB[j]; j++; } @@ -125,6 +126,7 @@ static int vaapi_hevc_start_frame(AVCodecContext *avctx, av_unused uint32_t size) { const HEVCContext *h = avctx->priv_data; + const HEVCLayerContext *l = &h->layers[h->cur_layer]; VAAPIDecodePictureHEVC *pic = h->cur_frame->hwaccel_picture_private; const HEVCPPS *pps = h->pps; const HEVCSPS *sps = pps->sps; @@ -208,7 +210,7 @@ static int vaapi_hevc_start_frame(AVCodecContext *avctx, }; fill_vaapi_pic(&pic_param->CurrPic, h->cur_frame, 0); - fill_vaapi_reference_frames(h, pic_param); + fill_vaapi_reference_frames(h, l, pic_param); if (pps->tiles_enabled_flag) { pic_param->num_tile_columns_minus1 = pps->num_tile_columns - 1; diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c index b9e922ecfc..e6232567e0 100644 --- a/libavcodec/vdpau_hevc.c +++ b/libavcodec/vdpau_hevc.c @@ -35,6 +35,7 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { HEVCContext *h = avctx->priv_data; + const HEVCLayerContext *l = &h->layers[h->cur_layer]; HEVCFrame *pic = h->cur_frame; struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; @@ -236,8 +237,8 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx, info->PicOrderCntVal[i] = 0; info->IsLongTerm[i] = 0; } - for (size_t i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) { - const HEVCFrame *frame = &h->DPB[i]; + for (size_t i = 0, j = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + const HEVCFrame *frame = &l->DPB[i]; if (frame != h->cur_frame && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) { if (j > 15) { diff --git a/libavcodec/vulkan_hevc.c b/libavcodec/vulkan_hevc.c index 5228e41ad5..f4c8da2d61 100644 --- a/libavcodec/vulkan_hevc.c +++ b/libavcodec/vulkan_hevc.c @@ -731,6 +731,7 @@ static int vk_hevc_start_frame(AVCodecContext *avctx, { int err; HEVCContext *h = avctx->priv_data; + HEVCLayerContext *l = &h->layers[h->cur_layer]; HEVCFrame *pic = h->cur_frame; FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data; HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private; @@ -762,8 +763,8 @@ static int vk_hevc_start_frame(AVCodecContext *avctx, }; /* Fill in references */ - for (int i = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) { - const HEVCFrame *ref = &h->DPB[i]; + for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + const HEVCFrame *ref = &l->DPB[i]; int idx = nb_refs; if (!(ref->flags & (HEVC_FRAME_FLAG_SHORT_REF | HEVC_FRAME_FLAG_LONG_REF))) @@ -790,8 +791,8 @@ static int vk_hevc_start_frame(AVCodecContext *avctx, memset(hp->h265pic.RefPicSetStCurrBefore, 0xff, 8); for (int i = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) { HEVCFrame *frame = h->rps[ST_CURR_BEF].ref[i]; - for (int j = 0; j < FF_ARRAY_ELEMS(h->DPB); j++) { - const HEVCFrame *ref = &h->DPB[j]; + for (int j = 0; j < FF_ARRAY_ELEMS(l->DPB); j++) { + const HEVCFrame *ref = &l->DPB[j]; if (ref == frame) { hp->h265pic.RefPicSetStCurrBefore[i] = j; break; @@ -801,8 +802,8 @@ static int vk_hevc_start_frame(AVCodecContext *avctx, memset(hp->h265pic.RefPicSetStCurrAfter, 0xff, 8); for (int i = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) { HEVCFrame *frame = h->rps[ST_CURR_AFT].ref[i]; - for (int j = 0; j < FF_ARRAY_ELEMS(h->DPB); j++) { - const HEVCFrame *ref = &h->DPB[j]; + for (int j = 0; j < FF_ARRAY_ELEMS(l->DPB); j++) { + const HEVCFrame *ref = &l->DPB[j]; if (ref == frame) { hp->h265pic.RefPicSetStCurrAfter[i] = j; break; @@ -812,8 +813,8 @@ static int vk_hevc_start_frame(AVCodecContext *avctx, memset(hp->h265pic.RefPicSetLtCurr, 0xff, 8); for (int i = 0; i < h->rps[LT_CURR].nb_refs; i++) { HEVCFrame *frame = h->rps[LT_CURR].ref[i]; - for (int j = 0; j < FF_ARRAY_ELEMS(h->DPB); j++) { - const HEVCFrame *ref = &h->DPB[j]; + for (int j = 0; j < FF_ARRAY_ELEMS(l->DPB); j++) { + const HEVCFrame *ref = &l->DPB[j]; if (ref == frame) { hp->h265pic.RefPicSetLtCurr[i] = j; break; -- 2.43.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".