summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nouveau/nouveau_vp3_video.h1
-rw-r--r--src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c39
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv98_video_vp.c4
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c4
4 files changed, 24 insertions, 24 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.h b/src/gallium/drivers/nouveau/nouveau_vp3_video.h
index 88c14ec60ff..5c1af7104fc 100644
--- a/src/gallium/drivers/nouveau/nouveau_vp3_video.h
+++ b/src/gallium/drivers/nouveau/nouveau_vp3_video.h
@@ -107,6 +107,7 @@ struct nouveau_vp3_decoder {
unsigned field_pic_flag : 1;
unsigned decoded_top : 1;
unsigned decoded_bottom : 1;
+ unsigned decoded_first : 1;
} refs[17];
unsigned fence_seq, fw_sizes, last_frame_num, tmp_stride, ref_stride;
diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c b/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c
index 1130d100390..1dcb99c1b52 100644
--- a/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c
+++ b/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c
@@ -169,19 +169,14 @@ struct h264_picparm_vp { // 700..a00
static void
nouveau_vp3_handle_references(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *refs[16], unsigned seq, struct nouveau_vp3_video_buffer *target)
{
- unsigned h264 = u_reduce_video_profile(dec->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC;
- unsigned i, idx, empty_spot = dec->base.max_references + 1;
+ unsigned i, idx, empty_spot = ~0;
+
for (i = 0; i < dec->base.max_references; ++i) {
if (!refs[i])
continue;
idx = refs[i]->valid_ref;
//debug_printf("ref[%i] %p in slot %i\n", i, refs[i], idx);
- assert(target != refs[i] ||
- (h264 && empty_spot &&
- (!dec->refs[idx].decoded_bottom || !dec->refs[idx].decoded_top)));
- if (target == refs[i])
- empty_spot = 0;
if (dec->refs[idx].vidbuf != refs[i]) {
debug_printf("%p is not a real ref\n", refs[i]);
@@ -192,26 +187,23 @@ nouveau_vp3_handle_references(struct nouveau_vp3_decoder *dec, struct nouveau_vp
assert(dec->refs[idx].vidbuf == refs[i]);
dec->refs[idx].last_used = seq;
}
- if (!empty_spot)
+
+ if (dec->refs[target->valid_ref].vidbuf == target) {
+ dec->refs[target->valid_ref].last_used = seq;
return;
+ }
/* 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) {
- empty_spot = i;
- break;
- }
- if (empty_spot < dec->base.max_references+1 &&
- dec->refs[empty_spot].last_used < dec->refs[i].last_used)
- continue;
+ if (dec->refs[i].last_used != seq) {
empty_spot = i;
+ break;
}
}
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, i);
+// debug_printf("Kicked %p to add %p to slot %i\n", dec->refs[empty_spot].vidbuf, target, empty_spot);
dec->refs[empty_spot].vidbuf = target;
dec->refs[empty_spot].decoded_bottom = dec->refs[empty_spot].decoded_top = 0;
target->valid_ref = empty_spot;
@@ -335,7 +327,7 @@ nouveau_vp3_fill_picparm_h264_vp(struct nouveau_vp3_decoder *dec,
h->ofs[0] = h->ofs[2] = 0;
h->tmp_stride = dec->tmp_stride >> 8;
assert(h->tmp_stride);
- nouveau_vp3_inter_sizes(dec, 1, &ring, &h->bucket_size, &h->inter_ring_data_size);
+ nouveau_vp3_inter_sizes(dec, d->slice_count, &ring, &h->bucket_size, &h->inter_ring_data_size);
h->u220 = 0;
h->mb_adaptive_frame_field_flag = d->pps->sps->mb_adaptive_frame_field_flag;
@@ -345,7 +337,8 @@ nouveau_vp3_fill_picparm_h264_vp(struct nouveau_vp3_decoder *dec,
h->is_reference = d->is_reference;
h->interlace = d->field_pic_flag;
h->bottom_field_flag = d->bottom_field_flag;
- h->second_field = 0; // TODO: figure out when set..
+ h->second_field = 0; // set in nouveau_vp3_fill_picparm_h264_vp_refs
+
h->log2_max_frame_num_minus4 = d->pps->sps->log2_max_frame_num_minus4;
h->chroma_format_idc = 1;
@@ -360,7 +353,6 @@ nouveau_vp3_fill_picparm_h264_vp(struct nouveau_vp3_decoder *dec,
h->u34_3030 = h->u34_3131 = 0;
h->field_order_cnt[0] = d->field_order_cnt[0];
h->field_order_cnt[1] = d->field_order_cnt[1];
- memset(h->refs, 0, sizeof(h->refs));
memcpy(h->m4x4, d->pps->ScalingList4x4, sizeof(h->m4x4));
memcpy(h->m8x8, d->pps->ScalingList8x8, sizeof(h->m8x8));
h->u220 = 0;
@@ -370,6 +362,7 @@ nouveau_vp3_fill_picparm_h264_vp(struct nouveau_vp3_decoder *dec,
refs[j] = (struct nouveau_vp3_video_buffer *)d->ref[i];
h->refs[j].fifo_idx = j + 1;
h->refs[j].tmp_idx = refs[j]->valid_ref;
+ assert(dec->refs[refs[j]->valid_ref].vidbuf == refs[j]);
h->refs[j].field_order_cnt[0] = d->field_order_cnt_list[i][0];
h->refs[j].field_order_cnt[1] = d->field_order_cnt_list[i][1];
h->refs[j].frame_idx = d->frame_num_list[i];
@@ -411,6 +404,12 @@ nouveau_vp3_fill_picparm_h264_vp_refs(struct nouveau_vp3_decoder *dec,
assert(dec->refs[target->valid_ref].vidbuf == target);
// debug_printf("Target: %p\n", target);
+ if (!dec->refs[target->valid_ref].decoded_top &&
+ !dec->refs[target->valid_ref].decoded_bottom)
+ dec->refs[target->valid_ref].decoded_first = d->bottom_field_flag;
+ else if (dec->refs[target->valid_ref].decoded_first != d->bottom_field_flag)
+ h->second_field = 1;
+
h->tmp_idx = target->valid_ref;
dec->refs[target->valid_ref].field_pic_flag = d->field_pic_flag;
if (!d->field_pic_flag || d->bottom_field_flag)
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
index 9b756ea73f5..9cdb40ba025 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
@@ -39,7 +39,7 @@ static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32
debug_printf("parse_endpos[%i] = { @ %08x}\n", i, comm->parse_endpos[i]);
#endif
debug_printf("mb_y = %u\n", comm->mb_y[idx]);
- if (comm->status_vp[idx] == 1)
+ if (comm->status_vp[idx] <= 1)
return;
if ((comm->pvp_stage & 0xff) != 0xff) {
@@ -112,7 +112,7 @@ nv98_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
else
pic_addr[i] = null_addr;
}
- if (!is_ref)
+ if (!is_ref && (dec->refs[target->valid_ref].decoded_top && dec->refs[target->valid_ref].decoded_bottom))
nv98_decoder_kick_ref(dec, target);
nouveau_pushbuf_space(push, 8 + 3 * (codec != PIPE_VIDEO_FORMAT_MPEG12) +
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
index 0d152b9624f..07170a0e4c3 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
@@ -39,7 +39,7 @@ static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32
debug_printf("parse_endpos[%i] = { @ %08x}\n", i, comm->parse_endpos[i]);
#endif
debug_printf("mb_y = %u\n", comm->mb_y[idx]);
- if (comm->status_vp[idx] == 1)
+ if (comm->status_vp[idx] <= 1)
return;
if ((comm->pvp_stage & 0xff) != 0xff) {
@@ -112,7 +112,7 @@ nvc0_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
else
pic_addr[i] = null_addr;
}
- if (!is_ref)
+ if (!is_ref && (dec->refs[target->valid_ref].decoded_top && dec->refs[target->valid_ref].decoded_bottom))
nvc0_decoder_kick_ref(dec, target);
nouveau_pushbuf_space(push, 8 + 3 * (codec != PIPE_VIDEO_FORMAT_MPEG12) +