VEBOX/bdw: set downsample method
[platform/upstream/libva-intel-driver.git] / src / i965_decoder_utils.c
1 /*
2  * Copyright (C) 2006-2012 Intel Corporation
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 (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23
24 #include "sysdeps.h"
25
26 #include <alloca.h>
27
28 #include "intel_batchbuffer.h"
29 #include "i965_drv_video.h"
30 #include "i965_decoder_utils.h"
31 #include "i965_defines.h"
32
33 /* Set reference surface if backing store exists */
34 static inline int
35 set_ref_frame(
36     struct i965_driver_data *i965,
37     GenFrameStore           *ref_frame,
38     VASurfaceID              va_surface,
39     struct object_surface   *obj_surface
40 )
41 {
42     if (va_surface == VA_INVALID_ID)
43         return 0;
44
45     if (!obj_surface || !obj_surface->bo)
46         return 0;
47
48     ref_frame->surface_id = va_surface;
49     ref_frame->obj_surface = obj_surface;
50     return 1;
51 }
52
53 /* Check wether codec layer incorrectly fills in slice_vertical_position */
54 int
55 mpeg2_wa_slice_vertical_position(
56     struct decode_state           *decode_state,
57     VAPictureParameterBufferMPEG2 *pic_param
58 )
59 {
60     unsigned int i, j, mb_height, vpos, last_vpos = 0;
61
62     /* Assume progressive sequence if we got a progressive frame */
63     if (pic_param->picture_coding_extension.bits.progressive_frame)
64         return 0;
65
66     /* Wait for a field coded picture */
67     if (pic_param->picture_coding_extension.bits.picture_structure == MPEG_FRAME)
68         return -1;
69
70     assert(decode_state && decode_state->slice_params);
71
72     mb_height = (pic_param->vertical_size + 31) / 32;
73
74     for (j = 0; j < decode_state->num_slice_params; j++) {
75         struct buffer_store * const buffer_store =
76             decode_state->slice_params[j];
77
78         for (i = 0; i < buffer_store->num_elements; i++) {
79             VASliceParameterBufferMPEG2 * const slice_param =
80                 ((VASliceParameterBufferMPEG2 *)buffer_store->buffer) + i;
81
82             vpos = slice_param->slice_vertical_position;
83             if (vpos >= mb_height || vpos == last_vpos + 2) {
84                 WARN_ONCE("codec layer incorrectly fills in MPEG-2 slice_vertical_position. Workaround applied\n");
85                 return 1;
86             }
87             last_vpos = vpos;
88         }
89     }
90     return 0;
91 }
92
93 /* Build MPEG-2 reference frames array */
94 void
95 mpeg2_set_reference_surfaces(
96     VADriverContextP               ctx,
97     GenFrameStore                  ref_frames[MAX_GEN_REFERENCE_FRAMES],
98     struct decode_state           *decode_state,
99     VAPictureParameterBufferMPEG2 *pic_param
100 )
101 {
102     struct i965_driver_data * const i965 = i965_driver_data(ctx);
103     VASurfaceID va_surface;
104     unsigned pic_structure, is_second_field, n = 0;
105     struct object_surface *obj_surface;
106
107     pic_structure = pic_param->picture_coding_extension.bits.picture_structure;
108     is_second_field = pic_structure != MPEG_FRAME &&
109         !pic_param->picture_coding_extension.bits.is_first_field;
110
111     ref_frames[0].surface_id = VA_INVALID_ID;
112     ref_frames[0].obj_surface = NULL;
113
114     /* Reference frames are indexed by frame store ID  (0:top, 1:bottom) */
115     switch (pic_param->picture_coding_type) {
116     case MPEG_P_PICTURE:
117         if (is_second_field && pic_structure == MPEG_BOTTOM_FIELD) {
118             va_surface = decode_state->current_render_target;
119             obj_surface = decode_state->render_object;
120             n += set_ref_frame(i965, &ref_frames[n], va_surface, obj_surface);
121         }
122         va_surface = pic_param->forward_reference_picture;
123         obj_surface = decode_state->reference_objects[0];
124         n += set_ref_frame(i965, &ref_frames[n], va_surface, obj_surface);
125         break;
126
127     case MPEG_B_PICTURE:
128         va_surface = pic_param->forward_reference_picture;
129         obj_surface = decode_state->reference_objects[0];
130         n += set_ref_frame(i965, &ref_frames[n], va_surface, obj_surface);
131         va_surface = pic_param->backward_reference_picture;
132         obj_surface = decode_state->reference_objects[1];
133         n += set_ref_frame(i965, &ref_frames[n], va_surface, obj_surface);
134         break;
135     }
136
137     while (n != 2) {
138         ref_frames[n].obj_surface = ref_frames[0].obj_surface;
139         ref_frames[n++].surface_id = ref_frames[0].surface_id;
140     }
141
142     if (pic_param->picture_coding_extension.bits.progressive_frame)
143         return;
144
145     ref_frames[2].surface_id = VA_INVALID_ID;
146     ref_frames[2].obj_surface = NULL;
147
148     /* Bottom field pictures used as reference */
149     switch (pic_param->picture_coding_type) {
150     case MPEG_P_PICTURE:
151         if (is_second_field && pic_structure == MPEG_TOP_FIELD) {
152             va_surface = decode_state->current_render_target;
153             obj_surface = decode_state->render_object;
154             n += set_ref_frame(i965, &ref_frames[n], va_surface, obj_surface);
155         }
156         va_surface = pic_param->forward_reference_picture;
157         obj_surface = decode_state->reference_objects[0];
158         n += set_ref_frame(i965, &ref_frames[n], va_surface, obj_surface);
159         break;
160
161     case MPEG_B_PICTURE:
162         va_surface = pic_param->forward_reference_picture;
163         obj_surface = decode_state->reference_objects[0];
164         n += set_ref_frame(i965, &ref_frames[n], va_surface, obj_surface);
165         va_surface = pic_param->backward_reference_picture;
166         obj_surface = decode_state->reference_objects[1];
167         n += set_ref_frame(i965, &ref_frames[n], va_surface, obj_surface);
168         break;
169     }
170
171     while (n != 4) {
172         ref_frames[n].obj_surface = ref_frames[2].obj_surface;
173         ref_frames[n++].surface_id = ref_frames[2].surface_id;
174     }
175 }
176
177 /* Generate flat scaling matrices for H.264 decoding */
178 void
179 avc_gen_default_iq_matrix(VAIQMatrixBufferH264 *iq_matrix)
180 {
181     /* Flat_4x4_16 */
182     memset(&iq_matrix->ScalingList4x4, 16, sizeof(iq_matrix->ScalingList4x4));
183
184     /* Flat_8x8_16 */
185     memset(&iq_matrix->ScalingList8x8, 16, sizeof(iq_matrix->ScalingList8x8));
186 }
187
188 /* Get first macroblock bit offset for BSD, minus EPB count (AVC) */
189 /* XXX: slice_data_bit_offset does not account for EPB */
190 unsigned int
191 avc_get_first_mb_bit_offset(
192     dri_bo                     *slice_data_bo,
193     VASliceParameterBufferH264 *slice_param,
194     unsigned int                mode_flag
195 )
196 {
197     unsigned int slice_data_bit_offset = slice_param->slice_data_bit_offset;
198
199     if (mode_flag == ENTROPY_CABAC)
200         slice_data_bit_offset = ALIGN(slice_data_bit_offset, 0x8);
201     return slice_data_bit_offset;
202 }
203
204 /* Get first macroblock bit offset for BSD, with EPB count (AVC) */
205 /* XXX: slice_data_bit_offset does not account for EPB */
206 unsigned int
207 avc_get_first_mb_bit_offset_with_epb(
208     dri_bo                     *slice_data_bo,
209     VASliceParameterBufferH264 *slice_param,
210     unsigned int                mode_flag
211 )
212 {
213     unsigned int in_slice_data_bit_offset = slice_param->slice_data_bit_offset;
214     unsigned int out_slice_data_bit_offset;
215     unsigned int i, j, n, buf_size, data_size, header_size;
216     uint8_t *buf;
217     int ret;
218
219     header_size = slice_param->slice_data_bit_offset / 8;
220     data_size   = slice_param->slice_data_size - slice_param->slice_data_offset;
221     buf_size    = (header_size * 3 + 1) / 2; // Max possible header size (x1.5)
222
223     if (buf_size > data_size)
224         buf_size = data_size;
225
226     buf = alloca(buf_size);
227     ret = dri_bo_get_subdata(
228         slice_data_bo, slice_param->slice_data_offset,
229         buf_size, buf
230     );
231     assert(ret == 0);
232
233     for (i = 2, j = 2, n = 0; i < buf_size && j < header_size; i++, j++) {
234         if (buf[i] == 0x03 && buf[i - 1] == 0x00 && buf[i - 2] == 0x00)
235             i += 2, j++, n++;
236     }
237
238     out_slice_data_bit_offset = in_slice_data_bit_offset + n * 8;
239
240     if (mode_flag == ENTROPY_CABAC)
241         out_slice_data_bit_offset = ALIGN(out_slice_data_bit_offset, 0x8);
242     return out_slice_data_bit_offset;
243 }
244
245 static inline uint8_t
246 get_ref_idx_state_1(const VAPictureH264 *va_pic, unsigned int frame_store_id)
247 {
248     const unsigned int is_long_term =
249         !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE);
250     const unsigned int is_top_field =
251         !!(va_pic->flags & VA_PICTURE_H264_TOP_FIELD);
252     const unsigned int is_bottom_field =
253         !!(va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD);
254
255     return ((is_long_term                         << 6) |
256             ((is_top_field ^ is_bottom_field ^ 1) << 5) |
257             (frame_store_id                       << 1) |
258             ((is_top_field ^ 1) & is_bottom_field));
259 }
260
261 /* Fill in Reference List Entries (Gen5+: ILK, SNB, IVB) */
262 void
263 gen5_fill_avc_ref_idx_state(
264     uint8_t             state[32],
265     const VAPictureH264 ref_list[32],
266     unsigned int        ref_list_count,
267     const GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES]
268 )
269 {
270     unsigned int i, n, frame_idx;
271
272     for (i = 0, n = 0; i < ref_list_count; i++) {
273         const VAPictureH264 * const va_pic = &ref_list[i];
274
275         if (va_pic->flags & VA_PICTURE_H264_INVALID)
276             continue;
277
278         for (frame_idx = 0; frame_idx < MAX_GEN_REFERENCE_FRAMES; frame_idx++) {
279             const GenFrameStore * const fs = &frame_store[frame_idx];
280             if (fs->surface_id != VA_INVALID_ID &&
281                 fs->surface_id == va_pic->picture_id) {
282                 assert(frame_idx == fs->frame_store_id);
283                 break;
284             }
285         }
286         assert(frame_idx < MAX_GEN_REFERENCE_FRAMES);
287         state[n++] = get_ref_idx_state_1(va_pic, frame_idx);
288     }
289
290     for (; n < 32; n++)
291         state[n] = 0xff;
292 }
293
294 /* Emit Reference List Entries (Gen6+: SNB, IVB) */
295 static void
296 gen6_send_avc_ref_idx_state_1(
297     struct intel_batchbuffer         *batch,
298     unsigned int                      list,
299     const VAPictureH264              *ref_list,
300     unsigned int                      ref_list_count,
301     const GenFrameStore               frame_store[MAX_GEN_REFERENCE_FRAMES]
302 )
303 {
304     uint8_t ref_idx_state[32];
305
306     BEGIN_BCS_BATCH(batch, 10);
307     OUT_BCS_BATCH(batch, MFX_AVC_REF_IDX_STATE | (10 - 2));
308     OUT_BCS_BATCH(batch, list);
309     gen5_fill_avc_ref_idx_state(
310         ref_idx_state,
311         ref_list, ref_list_count,
312         frame_store
313     );
314     intel_batchbuffer_data(batch, ref_idx_state, sizeof(ref_idx_state));
315     ADVANCE_BCS_BATCH(batch);
316 }
317
318 void
319 gen6_send_avc_ref_idx_state(
320     struct intel_batchbuffer         *batch,
321     const VASliceParameterBufferH264 *slice_param,
322     const GenFrameStore               frame_store[MAX_GEN_REFERENCE_FRAMES]
323 )
324 {
325     if (slice_param->slice_type == SLICE_TYPE_I ||
326         slice_param->slice_type == SLICE_TYPE_SI)
327         return;
328
329     /* RefPicList0 */
330     gen6_send_avc_ref_idx_state_1(
331         batch, 0,
332         slice_param->RefPicList0, slice_param->num_ref_idx_l0_active_minus1 + 1,
333         frame_store
334     );
335
336     if (slice_param->slice_type != SLICE_TYPE_B)
337         return;
338
339     /* RefPicList1 */
340     gen6_send_avc_ref_idx_state_1(
341         batch, 1,
342         slice_param->RefPicList1, slice_param->num_ref_idx_l1_active_minus1 + 1,
343         frame_store
344     );
345 }
346
347 void
348 intel_update_avc_frame_store_index(VADriverContextP ctx,
349                                    struct decode_state *decode_state,
350                                    VAPictureParameterBufferH264 *pic_param,
351                                    GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES])
352 {
353     int i, j;
354
355     assert(MAX_GEN_REFERENCE_FRAMES == ARRAY_ELEMS(pic_param->ReferenceFrames));
356
357     for (i = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) {
358         int found = 0;
359
360         if (frame_store[i].surface_id == VA_INVALID_ID ||
361             frame_store[i].obj_surface == NULL)
362             continue;
363
364         assert(frame_store[i].frame_store_id != -1);
365
366         for (j = 0; j < MAX_GEN_REFERENCE_FRAMES; j++) {
367             VAPictureH264 *ref_pic = &pic_param->ReferenceFrames[j];
368             if (ref_pic->flags & VA_PICTURE_H264_INVALID)
369                 continue;
370
371             if (frame_store[i].surface_id == ref_pic->picture_id) {
372                 found = 1;
373                 break;
374             }
375         }
376
377         /* remove it from the internal DPB */
378         if (!found) {
379             struct object_surface *obj_surface = frame_store[i].obj_surface;
380             
381             obj_surface->flags &= ~SURFACE_REFERENCED;
382
383             if ((obj_surface->flags & SURFACE_ALL_MASK) == SURFACE_DISPLAYED) {
384                 dri_bo_unreference(obj_surface->bo);
385                 obj_surface->bo = NULL;
386                 obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
387             }
388
389             if (obj_surface->free_private_data)
390                 obj_surface->free_private_data(&obj_surface->private_data);
391
392             frame_store[i].surface_id = VA_INVALID_ID;
393             frame_store[i].frame_store_id = -1;
394             frame_store[i].obj_surface = NULL;
395         }
396     }
397
398     for (i = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) {
399         VAPictureH264 *ref_pic = &pic_param->ReferenceFrames[i];
400         int found = 0;
401
402         if (ref_pic->flags & VA_PICTURE_H264_INVALID ||
403             ref_pic->picture_id == VA_INVALID_SURFACE ||
404             decode_state->reference_objects[i] == NULL)
405             continue;
406
407         for (j = 0; j < MAX_GEN_REFERENCE_FRAMES; j++) {
408             if (frame_store[j].surface_id == ref_pic->picture_id) {
409                 found = 1;
410                 break;
411             }
412         }
413
414         /* add the new reference frame into the internal DPB */
415         if (!found) {
416             int frame_idx;
417             struct object_surface *obj_surface = decode_state->reference_objects[i];
418
419             /* 
420              * Sometimes a dummy frame comes from the upper layer library, call i965_check_alloc_surface_bo()
421              * to ake sure the store buffer is allocated for this reference frame
422              */
423             i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N', 'V', '1', '2'), SUBSAMPLE_YUV420);
424
425             /* Find a free frame store index */
426             for (frame_idx = 0; frame_idx < MAX_GEN_REFERENCE_FRAMES; frame_idx++) {
427                 for (j = 0; j < MAX_GEN_REFERENCE_FRAMES; j++) {
428                     if (frame_store[j].surface_id == VA_INVALID_ID ||
429                         frame_store[j].obj_surface == NULL)
430                         continue;
431
432                     if (frame_store[j].frame_store_id == frame_idx) /* the store index is in use */
433                         break;
434                 }
435
436                 if (j == MAX_GEN_REFERENCE_FRAMES)
437                     break;
438             }
439
440             assert(frame_idx < MAX_GEN_REFERENCE_FRAMES);
441
442             for (j = 0; j < MAX_GEN_REFERENCE_FRAMES; j++) {
443                 if (frame_store[j].surface_id == VA_INVALID_ID ||
444                     frame_store[j].obj_surface == NULL) {
445                     frame_store[j].surface_id = ref_pic->picture_id;
446                     frame_store[j].frame_store_id = frame_idx;
447                     frame_store[j].obj_surface = obj_surface;
448                     break;
449                 }
450             }
451         }
452     }
453
454     /* sort */
455     for (i = 0; i < MAX_GEN_REFERENCE_FRAMES - 1; i++) {
456         if (frame_store[i].surface_id != VA_INVALID_ID &&
457             frame_store[i].obj_surface != NULL &&
458             frame_store[i].frame_store_id == i)
459             continue;
460
461         for (j = i + 1; j < MAX_GEN_REFERENCE_FRAMES; j++) {
462             if (frame_store[j].surface_id != VA_INVALID_ID &&
463                 frame_store[j].obj_surface != NULL &&
464                 frame_store[j].frame_store_id == i) {
465                 VASurfaceID id = frame_store[i].surface_id;
466                 int frame_idx = frame_store[i].frame_store_id;
467                 struct object_surface *obj_surface = frame_store[i].obj_surface;
468
469                 frame_store[i].surface_id = frame_store[j].surface_id;
470                 frame_store[i].frame_store_id = frame_store[j].frame_store_id;
471                 frame_store[i].obj_surface = frame_store[j].obj_surface;
472                 frame_store[j].surface_id = id;
473                 frame_store[j].frame_store_id = frame_idx;
474                 frame_store[j].obj_surface = obj_surface;
475                 break;
476             }
477         }
478     }
479 }
480
481 void
482 intel_update_vc1_frame_store_index(VADriverContextP ctx,
483                                    struct decode_state *decode_state,
484                                    VAPictureParameterBufferVC1 *pic_param,
485                                    GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES])
486 {
487     struct object_surface *obj_surface;
488     int i;
489
490     obj_surface = decode_state->reference_objects[0];
491
492     if (pic_param->forward_reference_picture == VA_INVALID_ID ||
493         !obj_surface || 
494         !obj_surface->bo) {
495         frame_store[0].surface_id = VA_INVALID_ID;
496         frame_store[0].obj_surface = NULL;
497     } else {
498         frame_store[0].surface_id = pic_param->forward_reference_picture;
499         frame_store[0].obj_surface = obj_surface;
500     }
501
502     obj_surface = decode_state->reference_objects[1];
503
504     if (pic_param->backward_reference_picture == VA_INVALID_ID ||
505         !obj_surface || 
506         !obj_surface->bo) {
507         frame_store[1].surface_id = frame_store[0].surface_id;
508         frame_store[1].obj_surface = frame_store[0].obj_surface;
509     } else {
510         frame_store[1].surface_id = pic_param->backward_reference_picture;
511         frame_store[1].obj_surface = obj_surface;
512     }
513     for (i = 2; i < MAX_GEN_REFERENCE_FRAMES; i++) {
514         frame_store[i].surface_id = frame_store[i % 2].surface_id;
515         frame_store[i].obj_surface = frame_store[i % 2].obj_surface;
516     }
517
518 }
519
520 static VAStatus
521 intel_decoder_check_avc_parameter(VADriverContextP ctx,
522                                   struct decode_state *decode_state)
523 {
524     struct i965_driver_data *i965 = i965_driver_data(ctx);
525     VAPictureParameterBufferH264 *pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
526     struct object_surface *obj_surface; 
527     int i;
528
529     assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
530     assert(pic_param->CurrPic.picture_id != VA_INVALID_SURFACE);
531
532     if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID ||
533         pic_param->CurrPic.picture_id == VA_INVALID_SURFACE)
534         goto error;
535
536     assert(pic_param->CurrPic.picture_id == decode_state->current_render_target);
537
538     if (pic_param->CurrPic.picture_id != decode_state->current_render_target)
539         goto error;
540
541     for (i = 0; i < 16; i++) {
542         if (pic_param->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID ||
543             pic_param->ReferenceFrames[i].picture_id == VA_INVALID_SURFACE)
544             break;
545         else {
546             obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id);
547             assert(obj_surface);
548
549             if (!obj_surface)
550                 goto error;
551
552             if (!obj_surface->bo) { /* a reference frame  without store buffer */
553                 WARN_ONCE("Invalid reference frame!!!\n");
554             }
555
556             decode_state->reference_objects[i] = obj_surface;
557         }
558     }
559
560     for ( ; i < 16; i++)
561         decode_state->reference_objects[i] = NULL;
562
563     return VA_STATUS_SUCCESS;
564
565 error:
566     return VA_STATUS_ERROR_INVALID_PARAMETER;
567 }
568
569 static VAStatus
570 intel_decoder_check_mpeg2_parameter(VADriverContextP ctx,
571                                     struct decode_state *decode_state)
572 {
573     struct i965_driver_data *i965 = i965_driver_data(ctx);
574     VAPictureParameterBufferMPEG2 *pic_param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
575     struct object_surface *obj_surface; 
576     int i = 0;
577     
578     if (pic_param->picture_coding_type == MPEG_I_PICTURE) {
579     } else if (pic_param->picture_coding_type == MPEG_P_PICTURE) {
580         obj_surface = SURFACE(pic_param->forward_reference_picture);
581
582         if (!obj_surface || !obj_surface->bo)
583             decode_state->reference_objects[i++] = NULL;
584         else
585             decode_state->reference_objects[i++] = obj_surface;
586     } else if (pic_param->picture_coding_type == MPEG_B_PICTURE) {
587         obj_surface = SURFACE(pic_param->forward_reference_picture);
588
589         if (!obj_surface || !obj_surface->bo)
590             decode_state->reference_objects[i++] = NULL;
591         else
592             decode_state->reference_objects[i++] = obj_surface;
593
594         obj_surface = SURFACE(pic_param->backward_reference_picture);
595
596         if (!obj_surface || !obj_surface->bo)
597             decode_state->reference_objects[i++] = NULL;
598         else
599             decode_state->reference_objects[i++] = obj_surface;
600     } else
601         goto error;
602
603     for ( ; i < 16; i++)
604         decode_state->reference_objects[i] = NULL;
605
606     return VA_STATUS_SUCCESS;
607
608 error:
609     return VA_STATUS_ERROR_INVALID_PARAMETER;
610 }
611
612 static VAStatus
613 intel_decoder_check_vc1_parameter(VADriverContextP ctx,
614                                   struct decode_state *decode_state)
615 {
616     struct i965_driver_data *i965 = i965_driver_data(ctx);
617     VAPictureParameterBufferVC1 *pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
618     struct object_surface *obj_surface; 
619     int i = 0;
620     
621     if (pic_param->picture_fields.bits.picture_type == 0 ||
622         pic_param->picture_fields.bits.picture_type == 3) {
623     } else if (pic_param->picture_fields.bits.picture_type == 1 ||
624                pic_param->picture_fields.bits.picture_type == 4) {
625         obj_surface = SURFACE(pic_param->forward_reference_picture);
626
627         if (!obj_surface || !obj_surface->bo)
628             decode_state->reference_objects[i++] = NULL;
629         else
630             decode_state->reference_objects[i++] = obj_surface;
631     } else if (pic_param->picture_fields.bits.picture_type == 2) {
632         obj_surface = SURFACE(pic_param->forward_reference_picture);
633
634         if (!obj_surface || !obj_surface->bo)
635             decode_state->reference_objects[i++] = NULL;
636         else
637             decode_state->reference_objects[i++] = obj_surface;
638
639         obj_surface = SURFACE(pic_param->backward_reference_picture);
640
641         if (!obj_surface || !obj_surface->bo)
642             decode_state->reference_objects[i++] = NULL;
643         else
644             decode_state->reference_objects[i++] = obj_surface;
645     } else 
646         goto error;
647
648     for ( ; i < 16; i++)
649         decode_state->reference_objects[i] = NULL;
650
651     return VA_STATUS_SUCCESS;
652
653 error:
654     return VA_STATUS_ERROR_INVALID_PARAMETER;
655 }
656
657 static VAStatus
658 intel_decoder_check_vp8_parameter(VADriverContextP ctx,
659                                   struct decode_state *decode_state)
660 {
661     struct i965_driver_data *i965 = i965_driver_data(ctx);
662     VAPictureParameterBufferVP8 *pic_param = (VAPictureParameterBufferVP8 *)decode_state->pic_param->buffer;
663     struct object_surface *obj_surface; 
664     int i = 0;
665
666     if (pic_param->last_ref_frame != VA_INVALID_SURFACE) {
667         obj_surface = SURFACE(pic_param->last_ref_frame);
668
669         if (obj_surface && obj_surface->bo)
670             decode_state->reference_objects[i++] = obj_surface;
671         else
672             decode_state->reference_objects[i++] = NULL;
673     }
674
675     if (pic_param->golden_ref_frame != VA_INVALID_SURFACE) {
676         obj_surface = SURFACE(pic_param->golden_ref_frame);
677
678         if (obj_surface && obj_surface->bo)
679             decode_state->reference_objects[i++] = obj_surface;
680         else
681             decode_state->reference_objects[i++] = NULL;
682     }
683
684     if (pic_param->alt_ref_frame != VA_INVALID_SURFACE) {
685         obj_surface = SURFACE(pic_param->alt_ref_frame);
686
687         if (obj_surface && obj_surface->bo)
688             decode_state->reference_objects[i++] = obj_surface;
689         else
690             decode_state->reference_objects[i++] = NULL;
691     }
692
693     for ( ; i < 16; i++)
694         decode_state->reference_objects[i] = NULL;
695
696     return VA_STATUS_SUCCESS;
697 }
698
699 VAStatus
700 intel_decoder_sanity_check_input(VADriverContextP ctx,
701                                  VAProfile profile,
702                                  struct decode_state *decode_state)
703 {
704     struct i965_driver_data *i965 = i965_driver_data(ctx);
705     struct object_surface *obj_surface;
706     VAStatus vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
707
708     if (decode_state->current_render_target == VA_INVALID_SURFACE)
709         goto out;
710         
711     obj_surface = SURFACE(decode_state->current_render_target);
712
713     if (!obj_surface)
714         goto out;
715
716     decode_state->render_object = obj_surface;
717
718     switch (profile) {
719     case VAProfileMPEG2Simple:
720     case VAProfileMPEG2Main:
721         vaStatus = intel_decoder_check_mpeg2_parameter(ctx, decode_state);
722         break;
723         
724     case VAProfileH264ConstrainedBaseline:
725     case VAProfileH264Main:
726     case VAProfileH264High:
727         vaStatus = intel_decoder_check_avc_parameter(ctx, decode_state);
728         break;
729
730     case VAProfileVC1Simple:
731     case VAProfileVC1Main:
732     case VAProfileVC1Advanced:
733         vaStatus = intel_decoder_check_vc1_parameter(ctx, decode_state);
734         break;
735
736     case VAProfileJPEGBaseline:
737         vaStatus = VA_STATUS_SUCCESS;
738         break;
739
740     case VAProfileVP8Version0_3:
741         vaStatus = intel_decoder_check_vp8_parameter(ctx, decode_state);
742         break;
743
744     default:
745         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
746         break;
747     }
748
749 out:
750     return vaStatus;
751 }
752
753 /*
754  * Return the next slice paramter
755  *
756  * Input:
757  *      slice_param: the current slice
758  *      *group_idx & *element_idx the current slice position in slice groups
759  * Output:
760  *      Return the next slice parameter
761  *      *group_idx & *element_idx the next slice position in slice groups,
762  *      if the next slice is NULL, *group_idx & *element_idx will be ignored
763  */
764 VASliceParameterBufferMPEG2 *
765 intel_mpeg2_find_next_slice(struct decode_state *decode_state,
766                             VAPictureParameterBufferMPEG2 *pic_param,
767                             VASliceParameterBufferMPEG2 *slice_param,
768                             int *group_idx,
769                             int *element_idx)
770 {
771     VASliceParameterBufferMPEG2 *next_slice_param;
772     unsigned int width_in_mbs = ALIGN(pic_param->horizontal_size, 16) / 16;
773     int j = *group_idx, i = *element_idx + 1;
774
775     for (; j < decode_state->num_slice_params; j++) {
776         for (; i < decode_state->slice_params[j]->num_elements; i++) {
777             next_slice_param = ((VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer) + i;
778
779             if ((next_slice_param->slice_vertical_position * width_in_mbs + next_slice_param->slice_horizontal_position) >=
780                 (slice_param->slice_vertical_position * width_in_mbs + slice_param->slice_horizontal_position)) {
781                 *group_idx = j;
782                 *element_idx = i;
783
784                 return next_slice_param;
785             }
786         }
787
788         i = 0;
789     }
790
791     return NULL;
792 }