summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2014-09-10 13:20:53 +0200
committerEmil Velikov <emil.l.velikov@gmail.com>2014-09-17 01:14:25 +0100
commit768fac116dcbc25f36bdfde83b8507493641c714 (patch)
tree8957abf8e4b30bb9dea94e61b21cc6c40f42db63 /src
parent4027062a3ce5fd4130b3a66498f69464170a276d (diff)
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 <maarten.lankhorst@canonical.com> Cc: "10.2 10.3" <mesa-stable@lists.freedesktop.org> (cherry picked from commit a41aad843108cec1901c88a76d5ceb4ede2e062b)
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c39
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv98_video_vp.c1
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c1
3 files changed, 37 insertions, 4 deletions
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);
}