From 768fac116dcbc25f36bdfde83b8507493641c714 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 10 Sep 2014 13:20:53 +0200 Subject: nouveau: rework reference frame handling Fixes a regression from "nouveau/vdec: small fixes to h264 handling" New picking order for frames: 1. Vidbuf pointer matches. 2. Take the first kicked ref. 3. If that fails, take a ref that has a different last_used. Signed-off-by: Maarten Lankhorst Cc: "10.2 10.3" (cherry picked from commit a41aad843108cec1901c88a76d5ceb4ede2e062b) --- src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c | 39 ++++++++++++++++++++-- src/gallium/drivers/nouveau/nv50/nv98_video_vp.c | 1 - src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c | 1 - 3 files changed, 37 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c b/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c index 06d7046995b..edbc82b8dc8 100644 --- a/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c +++ b/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c @@ -196,11 +196,15 @@ nouveau_vp3_handle_references(struct nouveau_vp3_decoder *dec, struct nouveau_vp /* Try to find a real empty spot first, there should be one.. */ for (i = 0; i < dec->base.max_references + 1; ++i) { - if (dec->refs[i].last_used != seq) { + if (dec->refs[i].vidbuf == target) { empty_spot = i; break; - } + } else if (!dec->refs[i].last_used) { + empty_spot = i; + } else if (empty_spot == ~0U && dec->refs[i].last_used != seq) + empty_spot = i; } + assert(empty_spot < dec->base.max_references+1); dec->refs[empty_spot].last_used = seq; // debug_printf("Kicked %p to add %p to slot %i\n", dec->refs[empty_spot].vidbuf, target, empty_spot); @@ -463,14 +467,45 @@ void nouveau_vp3_vp_caps(struct nouveau_vp3_decoder *dec, union pipe_desc desc, case PIPE_VIDEO_FORMAT_MPEG12: *caps = nouveau_vp3_fill_picparm_mpeg12_vp(dec, desc.mpeg12, refs, is_ref, vp); nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target); + switch (desc.mpeg12->picture_structure) { + case PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_TOP: + dec->refs[target->valid_ref].decoded_top = 1; + break; + case PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_BOTTOM: + dec->refs[target->valid_ref].decoded_bottom = 1; + break; + default: + dec->refs[target->valid_ref].decoded_top = 1; + dec->refs[target->valid_ref].decoded_bottom = 1; + break; + } return; case PIPE_VIDEO_FORMAT_MPEG4: *caps = nouveau_vp3_fill_picparm_mpeg4_vp(dec, desc.mpeg4, refs, is_ref, vp); nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target); + // XXX: Correct? + if (!desc.mpeg4->interlaced) { + dec->refs[target->valid_ref].decoded_top = 1; + dec->refs[target->valid_ref].decoded_bottom = 1; + } else if (desc.mpeg4->top_field_first) { + if (!dec->refs[target->valid_ref].decoded_top) + dec->refs[target->valid_ref].decoded_top = 1; + else + dec->refs[target->valid_ref].decoded_bottom = 1; + } else { + if (!dec->refs[target->valid_ref].decoded_bottom) + dec->refs[target->valid_ref].decoded_bottom = 1; + else + dec->refs[target->valid_ref].decoded_top = 1; + } return; case PIPE_VIDEO_FORMAT_VC1: { *caps = nouveau_vp3_fill_picparm_vc1_vp(dec, desc.vc1, refs, is_ref, vp); nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target); + if (desc.vc1->frame_coding_mode == 3) + debug_printf("Field-Interlaced possibly incorrectly handled\n"); + dec->refs[target->valid_ref].decoded_top = 1; + dec->refs[target->valid_ref].decoded_bottom = 1; return; } case PIPE_VIDEO_FORMAT_MPEG4_AVC: { diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c index 9cdb40ba025..e74abe286af 100644 --- a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c +++ b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c @@ -59,7 +59,6 @@ static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32 static void nv98_decoder_kick_ref(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *target) { - dec->refs[target->valid_ref].vidbuf = NULL; dec->refs[target->valid_ref].last_used = 0; // debug_printf("Unreffed %p\n", target); } diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c index 07170a0e4c3..33c73750d8b 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c @@ -59,7 +59,6 @@ static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32 static void nvc0_decoder_kick_ref(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *target) { - dec->refs[target->valid_ref].vidbuf = NULL; dec->refs[target->valid_ref].last_used = 0; // debug_printf("Unreffed %p\n", target); } -- cgit v1.2.3