add998d98ef5cc9e8801b4c8c30dca819696c48d
[mesa.git] / src / gallium / drivers / nouveau / nouveau_vp3_video_vp.c
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 uint32_t pad5[0x10]; // 5c...9c non-inclusive, but WHY?
82
83 uint32_t intra[0x10]; // 9c
84 uint32_t non_intra[0x10]; // bc
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 u24; // nfi ac8 ?
118 uint32_t bucket_size; // 28 bucket size
119 uint32_t inter_ring_data_size; // 2c
120
121 unsigned f0 : 1; // 0 0x01: into 640 shifted by 3, 540 shifted by 5, half size something?
122 unsigned f1 : 1; // 1 0x02: into vuc ofs 56
123 unsigned weighted_pred_flag : 1; // 2 0x04
124 unsigned f3 : 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 f7 : 1; // 7 0x80: nfi yet
129
130 signed log2_max_frame_num_minus4 : 4; // 31 0..3
131 unsigned u31_45 : 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 // 0x00223102
148 // nfi (needs: top_is_reference, bottom_is_reference, is_long_term, maybe some other state that was saved..
149 unsigned fifo_idx : 7; // 00 0..6
150 unsigned tmp_idx : 5; // 00 7..11
151 unsigned unk12 : 1; // 00 12 not seen yet, but set, maybe top_is_reference
152 unsigned unk13 : 1; // 00 13 not seen yet, but set, maybe bottom_is_reference?
153 unsigned unk14 : 1; // 00 14 skipped?
154 unsigned notseenyet : 1; // 00 15 pad?
155 unsigned unk16 : 1; // 00 16
156 unsigned unk17 : 4; // 00 17..20
157 unsigned unk21 : 4; // 00 21..24
158 unsigned pad : 7; // 00 d25..31
159
160 uint32_t field_order_cnt[2]; // 04,08
161 uint32_t frame_idx; // 0c
162 } refs[0x10];
163
164 uint8_t m4x4[6][16]; // 140
165 uint8_t m8x8[2][64]; // 1a0
166 uint32_t u220; // 220 number of extra reorder_list to append?
167 uint8_t u224[0x20]; // 224..244 reorder_list append ?
168 uint8_t nfi244[0xb0]; // add some pad to make sure nulls are read
169 };
170
171 static void
172 nouveau_vp3_handle_references(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *refs[16], unsigned seq, struct nouveau_vp3_video_buffer *target)
173 {
174 unsigned h264 = u_reduce_video_profile(dec->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC;
175 unsigned i, idx, empty_spot = dec->base.max_references + 1;
176 for (i = 0; i < dec->base.max_references; ++i) {
177 if (!refs[i])
178 continue;
179
180 idx = refs[i]->valid_ref;
181 //debug_printf("ref[%i] %p in slot %i\n", i, refs[i], idx);
182 assert(target != refs[i] ||
183 (h264 && empty_spot &&
184 (!dec->refs[idx].decoded_bottom || !dec->refs[idx].decoded_top)));
185 if (target == refs[i])
186 empty_spot = 0;
187
188 if (dec->refs[idx].vidbuf != refs[i]) {
189 debug_printf("%p is not a real ref\n", refs[i]);
190 // FIXME: Maybe do m2mf copy here if a application really depends on it?
191 continue;
192 }
193
194 assert(dec->refs[idx].vidbuf == refs[i]);
195 dec->refs[idx].last_used = seq;
196 }
197 if (!empty_spot)
198 return;
199
200 /* Try to find a real empty spot first, there should be one..
201 */
202 for (i = 0; i < dec->base.max_references + 1; ++i) {
203 if (dec->refs[i].last_used < seq) {
204 if (!dec->refs[i].vidbuf) {
205 empty_spot = i;
206 break;
207 }
208 if (empty_spot < dec->base.max_references+1 &&
209 dec->refs[empty_spot].last_used < dec->refs[i].last_used)
210 continue;
211 empty_spot = i;
212 }
213 }
214 assert(empty_spot < dec->base.max_references+1);
215 dec->refs[empty_spot].last_used = seq;
216 // debug_printf("Kicked %p to add %p to slot %i\n", dec->refs[empty_spot].vidbuf, target, i);
217 dec->refs[empty_spot].vidbuf = target;
218 dec->refs[empty_spot].decoded_bottom = dec->refs[empty_spot].decoded_top = 0;
219 target->valid_ref = empty_spot;
220 }
221
222 static uint32_t
223 nouveau_vp3_fill_picparm_mpeg12_vp(struct nouveau_vp3_decoder *dec,
224 struct pipe_mpeg12_picture_desc *desc,
225 struct nouveau_vp3_video_buffer *refs[16],
226 unsigned *is_ref,
227 char *map)
228 {
229 struct mpeg12_picparm_vp pic_vp_stub = {}, *pic_vp = &pic_vp_stub;
230 uint32_t i, ret = 0x01010, ring; // !async_shutdown << 16 | watchdog << 12 | irq_record << 4 | unk;
231 assert(!(dec->base.width & 0xf));
232 *is_ref = desc->picture_coding_type <= 2;
233
234 if (dec->base.profile == PIPE_VIDEO_PROFILE_MPEG1)
235 pic_vp->picture_structure = 3;
236 else
237 pic_vp->picture_structure = desc->picture_structure;
238
239 assert(desc->picture_structure != 4);
240 if (desc->picture_structure == 4) // Untested, but should work
241 ret |= 0x100;
242 pic_vp->width = mb(dec->base.width);
243 pic_vp->height = mb(dec->base.height);
244 pic_vp->unk08 = pic_vp->unk04 = (dec->base.width+0xf)&~0xf; // Stride
245
246 nouveau_vp3_ycbcr_offsets(dec, &pic_vp->ofs[1], &pic_vp->ofs[3], &pic_vp->ofs[4]);
247 pic_vp->ofs[5] = pic_vp->ofs[3];
248 pic_vp->ofs[0] = pic_vp->ofs[2] = 0;
249 nouveau_vp3_inter_sizes(dec, 1, &ring, &pic_vp->bucket_size, &pic_vp->inter_ring_data_size);
250
251 pic_vp->alternate_scan = desc->alternate_scan;
252 pic_vp->pad2[0] = pic_vp->pad2[1] = pic_vp->pad2[2] = 0;
253 pic_vp->unk30 = desc->picture_structure < 3 && (desc->picture_structure == 2 - desc->top_field_first);
254 pic_vp->unk3a = (desc->picture_coding_type == 1);
255 for (i = 0; i < 4; ++i)
256 pic_vp->f_code[i] = desc->f_code[i/2][i%2] + 1; // FU
257 pic_vp->picture_coding_type = desc->picture_coding_type;
258 pic_vp->intra_dc_precision = desc->intra_dc_precision;
259 pic_vp->q_scale_type = desc->q_scale_type;
260 pic_vp->top_field_first = desc->top_field_first;
261 pic_vp->full_pel_forward_vector = desc->full_pel_forward_vector;
262 pic_vp->full_pel_backward_vector = desc->full_pel_backward_vector;
263 memcpy(pic_vp->intra_quantizer_matrix, desc->intra_matrix, 0x40);
264 memcpy(pic_vp->non_intra_quantizer_matrix, desc->non_intra_matrix, 0x40);
265 memcpy(map, pic_vp, sizeof(*pic_vp));
266 refs[0] = (struct nouveau_vp3_video_buffer *)desc->ref[0];
267 refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)desc->ref[1];
268 return ret | (dec->base.profile != PIPE_VIDEO_PROFILE_MPEG1);
269 }
270
271 static uint32_t
272 nouveau_vp3_fill_picparm_mpeg4_vp(struct nouveau_vp3_decoder *dec,
273 struct pipe_mpeg4_picture_desc *desc,
274 struct nouveau_vp3_video_buffer *refs[16],
275 unsigned *is_ref,
276 char *map)
277 {
278 struct mpeg4_picparm_vp pic_vp_stub = {}, *pic_vp = &pic_vp_stub;
279 uint32_t ring, ret = 0x01014; // !async_shutdown << 16 | watchdog << 12 | irq_record << 4 | unk;
280 assert(!(dec->base.width & 0xf));
281 *is_ref = desc->vop_coding_type <= 1;
282
283 pic_vp->width = dec->base.width;
284 pic_vp->height = mb(dec->base.height)<<4;
285 pic_vp->unk0c = pic_vp->unk08 = mb(dec->base.width)<<4; // Stride
286
287 nouveau_vp3_ycbcr_offsets(dec, &pic_vp->ofs[1], &pic_vp->ofs[3], &pic_vp->ofs[4]);
288 pic_vp->ofs[5] = pic_vp->ofs[3];
289 pic_vp->ofs[0] = pic_vp->ofs[2] = 0;
290 pic_vp->pad1 = pic_vp->pad2 = 0;
291 nouveau_vp3_inter_sizes(dec, 1, &ring, &pic_vp->bucket_size, &pic_vp->inter_ring_data_size);
292
293 pic_vp->trd[0] = desc->trd[0];
294 pic_vp->trd[1] = desc->trd[1];
295 pic_vp->trb[0] = desc->trb[0];
296 pic_vp->trb[1] = desc->trb[1];
297 pic_vp->u48 = 0; // Codec?
298 pic_vp->pad1 = pic_vp->pad2 = 0;
299 pic_vp->f_code_fw = desc->vop_fcode_forward;
300 pic_vp->f_code_bw = desc->vop_fcode_backward;
301 pic_vp->interlaced = desc->interlaced;
302 pic_vp->quant_type = desc->quant_type;
303 pic_vp->quarter_sample = desc->quarter_sample;
304 pic_vp->short_video_header = desc->short_video_header;
305 pic_vp->u54 = 0;
306 pic_vp->vop_coding_type = desc->vop_coding_type;
307 pic_vp->rounding_control = desc->rounding_control;
308 pic_vp->alternate_vertical_scan_flag = desc->alternate_vertical_scan_flag;
309 pic_vp->top_field_first = desc->top_field_first;
310
311 memcpy(pic_vp->intra, desc->intra_matrix, 0x40);
312 memcpy(pic_vp->non_intra, desc->non_intra_matrix, 0x40);
313 memcpy(map, pic_vp, sizeof(*pic_vp));
314 refs[0] = (struct nouveau_vp3_video_buffer *)desc->ref[0];
315 refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)desc->ref[1];
316 return ret;
317 }
318
319 static uint32_t
320 nouveau_vp3_fill_picparm_h264_vp(struct nouveau_vp3_decoder *dec,
321 const struct pipe_h264_picture_desc *d,
322 struct nouveau_vp3_video_buffer *refs[16],
323 unsigned *is_ref,
324 char *map)
325 {
326 struct h264_picparm_vp stub_h = {}, *h = &stub_h;
327 unsigned ring, i, j = 0;
328 assert(offsetof(struct h264_picparm_vp, u224) == 0x224);
329 *is_ref = d->is_reference;
330 dec->last_frame_num = d->frame_num;
331
332 h->width = mb(dec->base.width);
333 h->height = mb(dec->base.height);
334 h->stride1 = h->stride2 = mb(dec->base.width)*16;
335 nouveau_vp3_ycbcr_offsets(dec, &h->ofs[1], &h->ofs[3], &h->ofs[4]);
336 h->ofs[5] = h->ofs[3];
337 h->ofs[0] = h->ofs[2] = 0;
338 h->u24 = dec->tmp_stride >> 8;
339 assert(h->u24);
340 nouveau_vp3_inter_sizes(dec, 1, &ring, &h->bucket_size, &h->inter_ring_data_size);
341
342 h->u220 = 0;
343 h->f0 = d->mb_adaptive_frame_field_flag;
344 h->f1 = d->direct_8x8_inference_flag;
345 h->weighted_pred_flag = d->weighted_pred_flag;
346 h->f3 = d->constrained_intra_pred_flag;
347 h->is_reference = d->is_reference;
348 h->interlace = d->field_pic_flag;
349 h->bottom_field_flag = d->bottom_field_flag;
350 h->f7 = 0; // TODO: figure out when set..
351 h->log2_max_frame_num_minus4 = d->log2_max_frame_num_minus4;
352 h->u31_45 = 1;
353
354 h->pic_order_cnt_type = d->pic_order_cnt_type;
355 h->pic_init_qp_minus26 = d->pic_init_qp_minus26;
356 h->chroma_qp_index_offset = d->chroma_qp_index_offset;
357 h->second_chroma_qp_index_offset = d->second_chroma_qp_index_offset;
358 h->weighted_bipred_idc = d->weighted_bipred_idc;
359 h->tmp_idx = 0; // set in h264_vp_refs below
360 h->fifo_dec_index = 0; // always set to 0 to be fifo compatible with other codecs
361 h->frame_number = d->frame_num;
362 h->u34_3030 = h->u34_3131 = 0;
363 h->field_order_cnt[0] = d->field_order_cnt[0];
364 h->field_order_cnt[1] = d->field_order_cnt[1];
365 memset(h->refs, 0, sizeof(h->refs));
366 memcpy(h->m4x4, d->scaling_lists_4x4, sizeof(h->m4x4));
367 memcpy(h->m8x8, d->scaling_lists_8x8, sizeof(h->m8x8));
368 h->u220 = 0;
369 for (i = 0; i < d->num_ref_frames; ++i) {
370 if (!d->ref[i])
371 break;
372 refs[j] = (struct nouveau_vp3_video_buffer *)d->ref[i];
373 h->refs[j].fifo_idx = j + 1;
374 h->refs[j].tmp_idx = refs[j]->valid_ref;
375 h->refs[j].field_order_cnt[0] = d->field_order_cnt_list[i][0];
376 h->refs[j].field_order_cnt[1] = d->field_order_cnt_list[i][1];
377 h->refs[j].frame_idx = d->frame_num_list[i];
378 if (!dec->refs[refs[j]->valid_ref].field_pic_flag) {
379 h->refs[j].unk12 = d->top_is_reference[i];
380 h->refs[j].unk13 = d->bottom_is_reference[i];
381 }
382 h->refs[j].unk14 = 0;
383 h->refs[j].notseenyet = 0;
384 h->refs[j].unk16 = dec->refs[refs[j]->valid_ref].field_pic_flag;
385 h->refs[j].unk17 = dec->refs[refs[j]->valid_ref].decoded_top &&
386 d->top_is_reference[i];
387 h->refs[j].unk21 = dec->refs[refs[j]->valid_ref].decoded_bottom &&
388 d->bottom_is_reference[i];
389 h->refs[j].pad = 0;
390 assert(!d->is_long_term[i]);
391 j++;
392 }
393 for (; i < 16; ++i)
394 assert(!d->ref[i]);
395 assert(d->num_ref_frames <= dec->base.max_references);
396
397 for (; i < d->num_ref_frames; ++i)
398 h->refs[j].unk16 = d->field_pic_flag;
399 *(struct h264_picparm_vp *)map = *h;
400
401 return 0x1113;
402 }
403
404 static void
405 nouveau_vp3_fill_picparm_h264_vp_refs(struct nouveau_vp3_decoder *dec,
406 struct pipe_h264_picture_desc *d,
407 struct nouveau_vp3_video_buffer *refs[16],
408 struct nouveau_vp3_video_buffer *target,
409 char *map)
410 {
411 struct h264_picparm_vp *h = (struct h264_picparm_vp *)map;
412 assert(dec->refs[target->valid_ref].vidbuf == target);
413 // debug_printf("Target: %p\n", target);
414
415 h->tmp_idx = target->valid_ref;
416 dec->refs[target->valid_ref].field_pic_flag = d->field_pic_flag;
417 if (!d->field_pic_flag || d->bottom_field_flag)
418 dec->refs[target->valid_ref].decoded_bottom = 1;
419 if (!d->field_pic_flag || !d->bottom_field_flag)
420 dec->refs[target->valid_ref].decoded_top = 1;
421 }
422
423 static uint32_t
424 nouveau_vp3_fill_picparm_vc1_vp(struct nouveau_vp3_decoder *dec,
425 struct pipe_vc1_picture_desc *d,
426 struct nouveau_vp3_video_buffer *refs[16],
427 unsigned *is_ref,
428 char *map)
429 {
430 struct vc1_picparm_vp *vc = (struct vc1_picparm_vp *)map;
431 unsigned ring;
432 assert(dec->base.profile != PIPE_VIDEO_PROFILE_VC1_SIMPLE);
433 *is_ref = d->picture_type <= 1;
434
435 nouveau_vp3_ycbcr_offsets(dec, &vc->ofs[1], &vc->ofs[3], &vc->ofs[4]);
436 vc->ofs[5] = vc->ofs[3];
437 vc->ofs[0] = vc->ofs[2] = 0;
438 vc->width = dec->base.width;
439 vc->height = mb(dec->base.height)<<4;
440 vc->unk0c = vc->unk10 = mb(dec->base.width)<<4; // Stride
441 vc->pad = vc->pad2 = 0;
442 nouveau_vp3_inter_sizes(dec, 1, &ring, &vc->bucket_size, &vc->inter_ring_data_size);
443 vc->profile = dec->base.profile - PIPE_VIDEO_PROFILE_VC1_SIMPLE;
444 vc->loopfilter = d->loopfilter;
445 vc->fastuvmc = d->fastuvmc;
446 vc->dquant = d->dquant;
447 vc->overlap = d->overlap;
448 vc->quantizer = d->quantizer;
449 vc->u36 = 0; // ? No idea what this one is..
450 refs[0] = (struct nouveau_vp3_video_buffer *)d->ref[0];
451 refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)d->ref[1];
452 return 0x12;
453 }
454
455 void nouveau_vp3_vp_caps(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
456 struct nouveau_vp3_video_buffer *target, unsigned comm_seq,
457 unsigned *caps, unsigned *is_ref,
458 struct nouveau_vp3_video_buffer *refs[16])
459 {
460 struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];
461 enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);
462 char *vp = bsp_bo->map + VP_OFFSET;
463
464 switch (codec){
465 case PIPE_VIDEO_FORMAT_MPEG12:
466 *caps = nouveau_vp3_fill_picparm_mpeg12_vp(dec, desc.mpeg12, refs, is_ref, vp);
467 nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
468 return;
469 case PIPE_VIDEO_FORMAT_MPEG4:
470 *caps = nouveau_vp3_fill_picparm_mpeg4_vp(dec, desc.mpeg4, refs, is_ref, vp);
471 nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
472 return;
473 case PIPE_VIDEO_FORMAT_VC1: {
474 *caps = nouveau_vp3_fill_picparm_vc1_vp(dec, desc.vc1, refs, is_ref, vp);
475 nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
476 return;
477 }
478 case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
479 *caps = nouveau_vp3_fill_picparm_h264_vp(dec, desc.h264, refs, is_ref, vp);
480 nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
481 nouveau_vp3_fill_picparm_h264_vp_refs(dec, desc.h264, refs, target, vp);
482 return;
483 }
484 default: assert(0); return;
485 }
486 }