[FFmpeg-cvslog] dxva2_hevc: re-write reference frame handling
Hendrik Leppkes
git at videolan.org
Mon Jun 1 01:16:42 CEST 2015
ffmpeg | branch: master | Hendrik Leppkes <h.leppkes at gmail.com> | Thu May 28 18:25:37 2015 +0200| [902a55f7161ffea10e13c1e7df14022e2ed90514] | committer: Luca Barbato
dxva2_hevc: re-write reference frame handling
The old logic required an explicit clearing of the lists first and was
prone to overflow the DXVA2 struct in some circumstances.
Signed-off-by: Luca Barbato <lu_zero at gentoo.org>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=902a55f7161ffea10e13c1e7df14022e2ed90514
---
libavcodec/dxva2_hevc.c | 40 ++++++++++++++++++++++------------------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c
index a2abb97..5112bd2 100644
--- a/libavcodec/dxva2_hevc.c
+++ b/libavcodec/dxva2_hevc.c
@@ -57,7 +57,7 @@ static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *
DXVA_PicParams_HEVC *pp)
{
const HEVCFrame *current_picture = h->ref;
- int i, j, k;
+ int i, j;
memset(pp, 0, sizeof(*pp));
@@ -155,30 +155,34 @@ static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *
pp->log2_parallel_merge_level_minus2 = h->pps->log2_parallel_merge_level - 2;
pp->CurrPicOrderCntVal = h->poc;
- // empty the lists
- memset(&pp->RefPicList, 0xff, sizeof(pp->RefPicList));
- memset(&pp->RefPicSetStCurrBefore, 0xff, sizeof(pp->RefPicSetStCurrBefore));
- memset(&pp->RefPicSetStCurrAfter, 0xff, sizeof(pp->RefPicSetStCurrAfter));
- memset(&pp->RefPicSetLtCurr, 0xff, sizeof(pp->RefPicSetLtCurr));
-
// fill RefPicList from the DPB
- for (i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
- const HEVCFrame *frame = &h->DPB[i];
- if (frame != current_picture && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) {
- fill_picture_entry(&pp->RefPicList[j], ff_dxva2_get_surface_index(avctx, ctx, frame->frame), !!(frame->flags & HEVC_FRAME_FLAG_LONG_REF));
- pp->PicOrderCntValList[j] = frame->poc;
+ 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];
j++;
}
+
+ if (frame) {
+ fill_picture_entry(&pp->RefPicList[i], ff_dxva2_get_surface_index(avctx, ctx, frame->frame), !!(frame->flags & HEVC_FRAME_FLAG_LONG_REF));
+ pp->PicOrderCntValList[i] = frame->poc;
+ } else {
+ pp->RefPicList[i].bPicEntry = 0xff;
+ pp->PicOrderCntValList[i] = 0;
+ }
}
#define DO_REF_LIST(ref_idx, ref_list) { \
const RefPicList *rpl = &h->rps[ref_idx]; \
- av_assert0(rpl->nb_refs <= FF_ARRAY_ELEMS(pp->ref_list)); \
- for (j = 0, k = 0; j < rpl->nb_refs; j++) { \
- if (rpl->ref[j]) { \
- pp->ref_list[k] = get_refpic_index(pp, ff_dxva2_get_surface_index(avctx, ctx, rpl->ref[j]->frame)); \
- k++; \
- } \
+ for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->ref_list); i++) { \
+ const HEVCFrame *frame = NULL; \
+ while (!frame && j < rpl->nb_refs) \
+ frame = rpl->ref[j++]; \
+ if (frame) \
+ pp->ref_list[i] = get_refpic_index(pp, ff_dxva2_get_surface_index(avctx, ctx, frame->frame)); \
+ else \
+ pp->ref_list[i] = 0xff; \
} \
}
More information about the ffmpeg-cvslog
mailing list