1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

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@gentoo.org>
This commit is contained in:
Hendrik Leppkes 2015-05-28 18:25:37 +02:00 committed by Luca Barbato
parent 35818b8aaf
commit 902a55f716

View File

@ -57,7 +57,7 @@ static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *
DXVA_PicParams_HEVC *pp) DXVA_PicParams_HEVC *pp)
{ {
const HEVCFrame *current_picture = h->ref; const HEVCFrame *current_picture = h->ref;
int i, j, k; int i, j;
memset(pp, 0, sizeof(*pp)); 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->log2_parallel_merge_level_minus2 = h->pps->log2_parallel_merge_level - 2;
pp->CurrPicOrderCntVal = h->poc; 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 // fill RefPicList from the DPB
for (i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) { for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->RefPicList); i++) {
const HEVCFrame *frame = &h->DPB[i]; const HEVCFrame *frame = NULL;
if (frame != current_picture && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) { while (!frame && j < FF_ARRAY_ELEMS(h->DPB)) {
fill_picture_entry(&pp->RefPicList[j], ff_dxva2_get_surface_index(avctx, ctx, frame->frame), !!(frame->flags & HEVC_FRAME_FLAG_LONG_REF)); if (&h->DPB[j] != current_picture && (h->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF)))
pp->PicOrderCntValList[j] = frame->poc; frame = &h->DPB[j];
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) { \ #define DO_REF_LIST(ref_idx, ref_list) { \
const RefPicList *rpl = &h->rps[ref_idx]; \ const RefPicList *rpl = &h->rps[ref_idx]; \
av_assert0(rpl->nb_refs <= FF_ARRAY_ELEMS(pp->ref_list)); \ for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->ref_list); i++) { \
for (j = 0, k = 0; j < rpl->nb_refs; j++) { \ const HEVCFrame *frame = NULL; \
if (rpl->ref[j]) { \ while (!frame && j < rpl->nb_refs) \
pp->ref_list[k] = get_refpic_index(pp, ff_dxva2_get_surface_index(avctx, ctx, rpl->ref[j]->frame)); \ frame = rpl->ref[j++]; \
k++; \ 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; \
} \ } \
} }