Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c
4570 views
1
/*
2
* Copyright 2011-2013 Maarten Lankhorst
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice shall be included in
12
* all copies or substantial portions of the Software.
13
*
14
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
* OTHER DEALINGS IN THE SOFTWARE.
21
*/
22
23
#include "nouveau_vp3_video.h"
24
25
struct mpeg12_picparm_vp {
26
uint16_t width; // 00 in mb units
27
uint16_t height; // 02 in mb units
28
29
uint32_t unk04; // 04 stride for Y?
30
uint32_t unk08; // 08 stride for CbCr?
31
32
uint32_t ofs[6]; // 1c..20 ofs
33
uint32_t bucket_size; // 24
34
uint32_t inter_ring_data_size; // 28
35
uint16_t unk2c; // 2c
36
uint16_t alternate_scan; // 2e
37
uint16_t unk30; // 30 not seen set yet
38
uint16_t picture_structure; // 32
39
uint16_t pad2[3];
40
uint16_t unk3a; // 3a set on I frame?
41
42
uint32_t f_code[4]; // 3c
43
uint32_t picture_coding_type; // 4c
44
uint32_t intra_dc_precision; // 50
45
uint32_t q_scale_type; // 54
46
uint32_t top_field_first; // 58
47
uint32_t full_pel_forward_vector; // 5c
48
uint32_t full_pel_backward_vector; // 60
49
uint8_t intra_quantizer_matrix[0x40]; // 64
50
uint8_t non_intra_quantizer_matrix[0x40]; // a4
51
};
52
53
struct mpeg4_picparm_vp {
54
uint32_t width; // 00 in normal units
55
uint32_t height; // 04 in normal units
56
uint32_t unk08; // stride 1
57
uint32_t unk0c; // stride 2
58
uint32_t ofs[6]; // 10..24 ofs
59
uint32_t bucket_size; // 28
60
uint32_t pad1; // 2c, pad
61
uint32_t pad2; // 30
62
uint32_t inter_ring_data_size; // 34
63
64
uint32_t trd[2]; // 38, 3c
65
uint32_t trb[2]; // 40, 44
66
uint32_t u48; // XXX codec selection? Should test with different values of VdpDecoderProfile
67
uint16_t f_code_fw; // 4c
68
uint16_t f_code_bw; // 4e
69
uint8_t interlaced; // 50
70
71
uint8_t quant_type; // bool, written to 528
72
uint8_t quarter_sample; // bool, written to 548
73
uint8_t short_video_header; // bool, negated written to 528 shifted by 1
74
uint8_t u54; // bool, written to 0x740
75
uint8_t vop_coding_type; // 55
76
uint8_t rounding_control; // 56
77
uint8_t alternate_vertical_scan_flag; // 57 bool
78
uint8_t top_field_first; // bool, written to vuc
79
80
uint8_t pad4[3]; // 59, 5a, 5b, contains garbage on blob
81
82
uint32_t intra[0x10]; // 5c
83
uint32_t non_intra[0x10]; // 9c
84
uint32_t pad5[0x10]; // bc what does this do?
85
// udc..uff pad?
86
};
87
88
// Full version, with data pumped from BSP
89
struct vc1_picparm_vp {
90
uint32_t bucket_size; // 00
91
uint32_t pad; // 04
92
93
uint32_t inter_ring_data_size; // 08
94
uint32_t unk0c; // stride 1
95
uint32_t unk10; // stride 2
96
uint32_t ofs[6]; // 14..28 ofs
97
98
uint16_t width; // 2c
99
uint16_t height; // 2e
100
101
uint8_t profile; // 30 0 = simple, 1 = main, 2 = advanced
102
uint8_t loopfilter; // 31 written into vuc
103
uint8_t fastuvmc; // 32, written into vuc
104
uint8_t dquant; // 33
105
106
uint8_t overlap; // 34
107
uint8_t quantizer; // 35
108
uint8_t u36; // 36, bool
109
uint8_t pad2; // 37, to align to 0x38
110
};
111
112
struct h264_picparm_vp { // 700..a00
113
uint16_t width, height;
114
uint32_t stride1, stride2; // 04 08
115
uint32_t ofs[6]; // 0c..24 in-image offset
116
117
uint32_t tmp_stride;
118
uint32_t bucket_size; // 28 bucket size
119
uint32_t inter_ring_data_size; // 2c
120
121
unsigned mb_adaptive_frame_field_flag : 1; // 0
122
unsigned direct_8x8_inference_flag : 1; // 1 0x02: into vuc ofs 56
123
unsigned weighted_pred_flag : 1; // 2 0x04
124
unsigned constrained_intra_pred_flag : 1; // 3 0x08: into vuc ofs 68
125
unsigned is_reference : 1; // 4
126
unsigned interlace : 1; // 5 field_pic_flag
127
unsigned bottom_field_flag : 1; // 6
128
unsigned second_field : 1; // 7 0x80: nfi yet
129
130
signed log2_max_frame_num_minus4 : 4; // 31 0..3
131
unsigned chroma_format_idc : 2; // 31 4..5
132
unsigned pic_order_cnt_type : 2; // 31 6..7
133
signed pic_init_qp_minus26 : 6; // 32 0..5
134
signed chroma_qp_index_offset : 5; // 32 6..10
135
signed second_chroma_qp_index_offset : 5; // 32 11..15
136
137
unsigned weighted_bipred_idc : 2; // 34 0..1
138
unsigned fifo_dec_index : 7; // 34 2..8
139
unsigned tmp_idx : 5; // 34 9..13
140
unsigned frame_number : 16; // 34 14..29
141
unsigned u34_3030 : 1; // 34 30..30 pp.u34[30:30]
142
unsigned u34_3131 : 1; // 34 31..31 pad?
143
144
uint32_t field_order_cnt[2]; // 38, 3c
145
146
struct { // 40
147
unsigned fifo_idx : 7; // 00 0..6
148
unsigned tmp_idx : 5; // 00 7..11
149
unsigned top_is_reference : 1; // 00 12
150
unsigned bottom_is_reference : 1; // 00 13
151
unsigned is_long_term : 1; // 00 14
152
unsigned notseenyet : 1; // 00 15 pad?
153
unsigned field_pic_flag : 1; // 00 16
154
unsigned top_field_marking : 4; // 00 17..20
155
unsigned bottom_field_marking : 4; // 00 21..24
156
unsigned pad : 7; // 00 d25..31
157
158
uint32_t field_order_cnt[2]; // 04,08
159
uint32_t frame_idx; // 0c
160
} refs[0x10];
161
162
uint8_t m4x4[6][16]; // 140
163
uint8_t m8x8[2][64]; // 1a0
164
uint32_t u220; // 220 number of extra reorder_list to append?
165
uint8_t u224[0x20]; // 224..244 reorder_list append ?
166
uint8_t nfi244[0xb0]; // add some pad to make sure nulls are read
167
};
168
169
static void
170
nouveau_vp3_handle_references(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *refs[16], unsigned seq, struct nouveau_vp3_video_buffer *target)
171
{
172
unsigned i, idx, empty_spot = ~0;
173
174
for (i = 0; i < dec->base.max_references; ++i) {
175
if (!refs[i])
176
continue;
177
178
idx = refs[i]->valid_ref;
179
//debug_printf("ref[%i] %p in slot %i\n", i, refs[i], idx);
180
181
if (dec->refs[idx].vidbuf != refs[i]) {
182
debug_printf("%p is not a real ref\n", refs[i]);
183
// FIXME: Maybe do m2mf copy here if a application really depends on it?
184
continue;
185
}
186
187
assert(dec->refs[idx].vidbuf == refs[i]);
188
dec->refs[idx].last_used = seq;
189
}
190
191
if (dec->refs[target->valid_ref].vidbuf == target) {
192
dec->refs[target->valid_ref].last_used = seq;
193
return;
194
}
195
196
/* Try to find a real empty spot first, there should be one..
197
*/
198
for (i = 0; i < dec->base.max_references + 1; ++i) {
199
if (dec->refs[i].vidbuf == target) {
200
empty_spot = i;
201
break;
202
} else if (!dec->refs[i].last_used) {
203
empty_spot = i;
204
} else if (empty_spot == ~0U && dec->refs[i].last_used != seq)
205
empty_spot = i;
206
}
207
208
assert(empty_spot < dec->base.max_references+1);
209
dec->refs[empty_spot].last_used = seq;
210
// debug_printf("Kicked %p to add %p to slot %i\n", dec->refs[empty_spot].vidbuf, target, empty_spot);
211
dec->refs[empty_spot].vidbuf = target;
212
dec->refs[empty_spot].decoded_bottom = dec->refs[empty_spot].decoded_top = 0;
213
target->valid_ref = empty_spot;
214
}
215
216
static uint32_t
217
nouveau_vp3_fill_picparm_mpeg12_vp(struct nouveau_vp3_decoder *dec,
218
struct pipe_mpeg12_picture_desc *desc,
219
struct nouveau_vp3_video_buffer *refs[16],
220
unsigned *is_ref,
221
char *map)
222
{
223
struct mpeg12_picparm_vp pic_vp_stub = {}, *pic_vp = &pic_vp_stub;
224
uint32_t i, ret = 0x01010, ring; // !async_shutdown << 16 | watchdog << 12 | irq_record << 4 | unk;
225
assert(!(dec->base.width & 0xf));
226
*is_ref = desc->picture_coding_type <= 2;
227
228
if (dec->base.profile == PIPE_VIDEO_PROFILE_MPEG1)
229
pic_vp->picture_structure = 3;
230
else
231
pic_vp->picture_structure = desc->picture_structure;
232
233
assert(desc->picture_structure != 4);
234
if (desc->picture_structure == 4) // Untested, but should work
235
ret |= 0x100;
236
pic_vp->width = mb(dec->base.width);
237
pic_vp->height = mb(dec->base.height);
238
pic_vp->unk08 = pic_vp->unk04 = (dec->base.width+0xf)&~0xf; // Stride
239
240
nouveau_vp3_ycbcr_offsets(dec, &pic_vp->ofs[1], &pic_vp->ofs[3], &pic_vp->ofs[4]);
241
pic_vp->ofs[5] = pic_vp->ofs[3];
242
pic_vp->ofs[0] = pic_vp->ofs[2] = 0;
243
nouveau_vp3_inter_sizes(dec, 1, &ring, &pic_vp->bucket_size, &pic_vp->inter_ring_data_size);
244
245
pic_vp->alternate_scan = desc->alternate_scan;
246
pic_vp->pad2[0] = pic_vp->pad2[1] = pic_vp->pad2[2] = 0;
247
pic_vp->unk30 = desc->picture_structure < 3 && (desc->picture_structure == 2 - desc->top_field_first);
248
pic_vp->unk3a = (desc->picture_coding_type == 1);
249
for (i = 0; i < 4; ++i)
250
pic_vp->f_code[i] = desc->f_code[i/2][i%2] + 1; // FU
251
pic_vp->picture_coding_type = desc->picture_coding_type;
252
pic_vp->intra_dc_precision = desc->intra_dc_precision;
253
pic_vp->q_scale_type = desc->q_scale_type;
254
pic_vp->top_field_first = desc->top_field_first;
255
pic_vp->full_pel_forward_vector = desc->full_pel_forward_vector;
256
pic_vp->full_pel_backward_vector = desc->full_pel_backward_vector;
257
memcpy(pic_vp->intra_quantizer_matrix, desc->intra_matrix, 0x40);
258
memcpy(pic_vp->non_intra_quantizer_matrix, desc->non_intra_matrix, 0x40);
259
memcpy(map, pic_vp, sizeof(*pic_vp));
260
refs[0] = (struct nouveau_vp3_video_buffer *)desc->ref[0];
261
refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)desc->ref[1];
262
return ret | (dec->base.profile != PIPE_VIDEO_PROFILE_MPEG1);
263
}
264
265
static uint32_t
266
nouveau_vp3_fill_picparm_mpeg4_vp(struct nouveau_vp3_decoder *dec,
267
struct pipe_mpeg4_picture_desc *desc,
268
struct nouveau_vp3_video_buffer *refs[16],
269
unsigned *is_ref,
270
char *map)
271
{
272
struct mpeg4_picparm_vp pic_vp_stub = {}, *pic_vp = &pic_vp_stub;
273
uint32_t ring, ret = 0x01014; // !async_shutdown << 16 | watchdog << 12 | irq_record << 4 | unk;
274
*is_ref = desc->vop_coding_type <= 1;
275
276
pic_vp->width = dec->base.width;
277
pic_vp->height = mb(dec->base.height)<<4;
278
pic_vp->unk0c = pic_vp->unk08 = mb(dec->base.width)<<4; // Stride
279
280
nouveau_vp3_ycbcr_offsets(dec, &pic_vp->ofs[1], &pic_vp->ofs[3], &pic_vp->ofs[4]);
281
pic_vp->ofs[5] = pic_vp->ofs[3];
282
pic_vp->ofs[0] = pic_vp->ofs[2] = 0;
283
pic_vp->pad1 = pic_vp->pad2 = 0;
284
nouveau_vp3_inter_sizes(dec, 1, &ring, &pic_vp->bucket_size, &pic_vp->inter_ring_data_size);
285
286
pic_vp->trd[0] = desc->trd[0];
287
pic_vp->trd[1] = desc->trd[1];
288
pic_vp->trb[0] = desc->trb[0];
289
pic_vp->trb[1] = desc->trb[1];
290
pic_vp->u48 = 0; // Codec?
291
pic_vp->pad1 = pic_vp->pad2 = 0;
292
pic_vp->f_code_fw = desc->vop_fcode_forward;
293
pic_vp->f_code_bw = desc->vop_fcode_backward;
294
pic_vp->interlaced = desc->interlaced;
295
pic_vp->quant_type = desc->quant_type;
296
pic_vp->quarter_sample = desc->quarter_sample;
297
pic_vp->short_video_header = desc->short_video_header;
298
pic_vp->u54 = 0;
299
pic_vp->vop_coding_type = desc->vop_coding_type;
300
pic_vp->rounding_control = desc->rounding_control;
301
pic_vp->alternate_vertical_scan_flag = desc->alternate_vertical_scan_flag;
302
pic_vp->top_field_first = desc->top_field_first;
303
304
memcpy(pic_vp->intra, desc->intra_matrix, 0x40);
305
memcpy(pic_vp->non_intra, desc->non_intra_matrix, 0x40);
306
memcpy(map, pic_vp, sizeof(*pic_vp));
307
refs[0] = (struct nouveau_vp3_video_buffer *)desc->ref[0];
308
refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)desc->ref[1];
309
return ret;
310
}
311
312
static uint32_t
313
nouveau_vp3_fill_picparm_h264_vp(struct nouveau_vp3_decoder *dec,
314
const struct pipe_h264_picture_desc *d,
315
struct nouveau_vp3_video_buffer *refs[16],
316
unsigned *is_ref,
317
char *map)
318
{
319
struct h264_picparm_vp stub_h = {}, *h = &stub_h;
320
unsigned ring, i, j = 0;
321
assert(offsetof(struct h264_picparm_vp, u224) == 0x224);
322
*is_ref = d->is_reference;
323
dec->last_frame_num = d->frame_num;
324
325
h->width = mb(dec->base.width);
326
h->height = mb(dec->base.height);
327
h->stride1 = h->stride2 = mb(dec->base.width)*16;
328
nouveau_vp3_ycbcr_offsets(dec, &h->ofs[1], &h->ofs[3], &h->ofs[4]);
329
h->ofs[5] = h->ofs[3];
330
h->ofs[0] = h->ofs[2] = 0;
331
h->tmp_stride = dec->tmp_stride >> 8;
332
assert(h->tmp_stride);
333
nouveau_vp3_inter_sizes(dec, d->slice_count, &ring, &h->bucket_size, &h->inter_ring_data_size);
334
335
h->u220 = 0;
336
h->mb_adaptive_frame_field_flag = d->pps->sps->mb_adaptive_frame_field_flag;
337
h->direct_8x8_inference_flag = d->pps->sps->direct_8x8_inference_flag;
338
h->weighted_pred_flag = d->pps->weighted_pred_flag;
339
h->constrained_intra_pred_flag = d->pps->constrained_intra_pred_flag;
340
h->is_reference = d->is_reference;
341
h->interlace = d->field_pic_flag;
342
h->bottom_field_flag = d->bottom_field_flag;
343
h->second_field = 0; // set in nouveau_vp3_fill_picparm_h264_vp_refs
344
345
h->log2_max_frame_num_minus4 = d->pps->sps->log2_max_frame_num_minus4;
346
h->chroma_format_idc = 1;
347
348
h->pic_order_cnt_type = d->pps->sps->pic_order_cnt_type;
349
h->pic_init_qp_minus26 = d->pps->pic_init_qp_minus26;
350
h->chroma_qp_index_offset = d->pps->chroma_qp_index_offset;
351
h->second_chroma_qp_index_offset = d->pps->second_chroma_qp_index_offset;
352
h->weighted_bipred_idc = d->pps->weighted_bipred_idc;
353
h->tmp_idx = 0; // set in h264_vp_refs below
354
h->fifo_dec_index = 0; // always set to 0 to be fifo compatible with other codecs
355
h->frame_number = d->frame_num;
356
h->u34_3030 = h->u34_3131 = 0;
357
h->field_order_cnt[0] = d->field_order_cnt[0];
358
h->field_order_cnt[1] = d->field_order_cnt[1];
359
memcpy(h->m4x4, d->pps->ScalingList4x4, sizeof(h->m4x4));
360
memcpy(h->m8x8, d->pps->ScalingList8x8, sizeof(h->m8x8));
361
h->u220 = 0;
362
for (i = 0; i < d->num_ref_frames; ++i) {
363
if (!d->ref[i])
364
break;
365
refs[j] = (struct nouveau_vp3_video_buffer *)d->ref[i];
366
h->refs[j].fifo_idx = j + 1;
367
h->refs[j].tmp_idx = refs[j]->valid_ref;
368
assert(dec->refs[refs[j]->valid_ref].vidbuf == refs[j]);
369
h->refs[j].field_order_cnt[0] = d->field_order_cnt_list[i][0];
370
h->refs[j].field_order_cnt[1] = d->field_order_cnt_list[i][1];
371
h->refs[j].frame_idx = d->frame_num_list[i];
372
if (!dec->refs[refs[j]->valid_ref].field_pic_flag) {
373
h->refs[j].top_is_reference = d->top_is_reference[i];
374
h->refs[j].bottom_is_reference = d->bottom_is_reference[i];
375
}
376
h->refs[j].is_long_term = d->is_long_term[i];
377
h->refs[j].notseenyet = 0;
378
h->refs[j].field_pic_flag = dec->refs[refs[j]->valid_ref].field_pic_flag;
379
h->refs[j].top_field_marking =
380
dec->refs[refs[j]->valid_ref].decoded_top && d->top_is_reference[i] ?
381
1 + d->is_long_term[i] : 0;
382
h->refs[j].bottom_field_marking =
383
dec->refs[refs[j]->valid_ref].decoded_bottom && d->bottom_is_reference[i] ?
384
1 + d->is_long_term[i] : 0;
385
h->refs[j].pad = 0;
386
j++;
387
}
388
for (; i < 16; ++i)
389
assert(!d->ref[i]);
390
assert(d->num_ref_frames <= dec->base.max_references);
391
392
for (; i < d->num_ref_frames; ++i)
393
h->refs[j].field_pic_flag = d->field_pic_flag;
394
*(struct h264_picparm_vp *)map = *h;
395
396
return 0x1113;
397
}
398
399
static void
400
nouveau_vp3_fill_picparm_h264_vp_refs(struct nouveau_vp3_decoder *dec,
401
struct pipe_h264_picture_desc *d,
402
struct nouveau_vp3_video_buffer *refs[16],
403
struct nouveau_vp3_video_buffer *target,
404
char *map)
405
{
406
struct h264_picparm_vp *h = (struct h264_picparm_vp *)map;
407
assert(dec->refs[target->valid_ref].vidbuf == target);
408
// debug_printf("Target: %p\n", target);
409
410
if (!dec->refs[target->valid_ref].decoded_top &&
411
!dec->refs[target->valid_ref].decoded_bottom)
412
dec->refs[target->valid_ref].decoded_first = d->bottom_field_flag;
413
else if (dec->refs[target->valid_ref].decoded_first != d->bottom_field_flag)
414
h->second_field = 1;
415
416
h->tmp_idx = target->valid_ref;
417
dec->refs[target->valid_ref].field_pic_flag = d->field_pic_flag;
418
if (!d->field_pic_flag || d->bottom_field_flag)
419
dec->refs[target->valid_ref].decoded_bottom = 1;
420
if (!d->field_pic_flag || !d->bottom_field_flag)
421
dec->refs[target->valid_ref].decoded_top = 1;
422
}
423
424
static uint32_t
425
nouveau_vp3_fill_picparm_vc1_vp(struct nouveau_vp3_decoder *dec,
426
struct pipe_vc1_picture_desc *d,
427
struct nouveau_vp3_video_buffer *refs[16],
428
unsigned *is_ref,
429
char *map)
430
{
431
struct vc1_picparm_vp *vc = (struct vc1_picparm_vp *)map;
432
unsigned ring;
433
assert(dec->base.profile != PIPE_VIDEO_PROFILE_VC1_SIMPLE);
434
*is_ref = d->picture_type <= 1;
435
436
nouveau_vp3_ycbcr_offsets(dec, &vc->ofs[1], &vc->ofs[3], &vc->ofs[4]);
437
vc->ofs[5] = vc->ofs[3];
438
vc->ofs[0] = vc->ofs[2] = 0;
439
vc->width = dec->base.width;
440
vc->height = mb(dec->base.height)<<4;
441
vc->unk0c = vc->unk10 = mb(dec->base.width)<<4; // Stride
442
vc->pad = vc->pad2 = 0;
443
nouveau_vp3_inter_sizes(dec, 1, &ring, &vc->bucket_size, &vc->inter_ring_data_size);
444
vc->profile = dec->base.profile - PIPE_VIDEO_PROFILE_VC1_SIMPLE;
445
vc->loopfilter = d->loopfilter;
446
vc->fastuvmc = d->fastuvmc;
447
vc->dquant = d->dquant;
448
vc->overlap = d->overlap;
449
vc->quantizer = d->quantizer;
450
vc->u36 = 0; // ? No idea what this one is..
451
refs[0] = (struct nouveau_vp3_video_buffer *)d->ref[0];
452
refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)d->ref[1];
453
return 0x12;
454
}
455
456
void nouveau_vp3_vp_caps(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
457
struct nouveau_vp3_video_buffer *target, unsigned comm_seq,
458
unsigned *caps, unsigned *is_ref,
459
struct nouveau_vp3_video_buffer *refs[16])
460
{
461
struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];
462
enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);
463
char *vp = bsp_bo->map + VP_OFFSET;
464
465
switch (codec){
466
case PIPE_VIDEO_FORMAT_MPEG12:
467
*caps = nouveau_vp3_fill_picparm_mpeg12_vp(dec, desc.mpeg12, refs, is_ref, vp);
468
nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
469
switch (desc.mpeg12->picture_structure) {
470
case PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_TOP:
471
dec->refs[target->valid_ref].decoded_top = 1;
472
break;
473
case PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_BOTTOM:
474
dec->refs[target->valid_ref].decoded_bottom = 1;
475
break;
476
default:
477
dec->refs[target->valid_ref].decoded_top = 1;
478
dec->refs[target->valid_ref].decoded_bottom = 1;
479
break;
480
}
481
return;
482
case PIPE_VIDEO_FORMAT_MPEG4:
483
*caps = nouveau_vp3_fill_picparm_mpeg4_vp(dec, desc.mpeg4, refs, is_ref, vp);
484
nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
485
// XXX: Correct?
486
if (!desc.mpeg4->interlaced) {
487
dec->refs[target->valid_ref].decoded_top = 1;
488
dec->refs[target->valid_ref].decoded_bottom = 1;
489
} else if (desc.mpeg4->top_field_first) {
490
if (!dec->refs[target->valid_ref].decoded_top)
491
dec->refs[target->valid_ref].decoded_top = 1;
492
else
493
dec->refs[target->valid_ref].decoded_bottom = 1;
494
} else {
495
if (!dec->refs[target->valid_ref].decoded_bottom)
496
dec->refs[target->valid_ref].decoded_bottom = 1;
497
else
498
dec->refs[target->valid_ref].decoded_top = 1;
499
}
500
return;
501
case PIPE_VIDEO_FORMAT_VC1: {
502
*caps = nouveau_vp3_fill_picparm_vc1_vp(dec, desc.vc1, refs, is_ref, vp);
503
nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
504
if (desc.vc1->frame_coding_mode == 3)
505
debug_printf("Field-Interlaced possibly incorrectly handled\n");
506
dec->refs[target->valid_ref].decoded_top = 1;
507
dec->refs[target->valid_ref].decoded_bottom = 1;
508
return;
509
}
510
case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
511
*caps = nouveau_vp3_fill_picparm_h264_vp(dec, desc.h264, refs, is_ref, vp);
512
nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
513
nouveau_vp3_fill_picparm_h264_vp_refs(dec, desc.h264, refs, target, vp);
514
return;
515
}
516
default: assert(0); return;
517
}
518
}
519
520