Use the right parameters to initialize bit rate context
[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     int found;
272
273     for (i = 0, n = 0; i < ref_list_count; i++) {
274         const VAPictureH264 * const va_pic = &ref_list[i];
275
276         if (va_pic->flags & VA_PICTURE_H264_INVALID)
277             continue;
278
279         found = 0;
280         for (frame_idx = 0; frame_idx < MAX_GEN_REFERENCE_FRAMES; frame_idx++) {
281             const GenFrameStore * const fs = &frame_store[frame_idx];
282             if (fs->surface_id != VA_INVALID_ID &&
283                 fs->surface_id == va_pic->picture_id) {
284                 found = 1;
285                 break;
286             }
287         }
288
289         if (found) {
290             state[n++] = get_ref_idx_state_1(va_pic, frame_idx);
291         } else {
292             WARN_ONCE("Invalid Slice reference frame list !!!. It is not included in DPB \n");
293         }
294     }
295
296     for (; n < 32; n++)
297         state[n] = 0xff;
298 }
299
300 /* Emit Reference List Entries (Gen6+: SNB, IVB) */
301 static void
302 gen6_send_avc_ref_idx_state_1(
303     struct intel_batchbuffer         *batch,
304     unsigned int                      list,
305     const VAPictureH264              *ref_list,
306     unsigned int                      ref_list_count,
307     const GenFrameStore               frame_store[MAX_GEN_REFERENCE_FRAMES]
308 )
309 {
310     uint8_t ref_idx_state[32];
311
312     BEGIN_BCS_BATCH(batch, 10);
313     OUT_BCS_BATCH(batch, MFX_AVC_REF_IDX_STATE | (10 - 2));
314     OUT_BCS_BATCH(batch, list);
315     gen5_fill_avc_ref_idx_state(
316         ref_idx_state,
317         ref_list, ref_list_count,
318         frame_store
319     );
320     intel_batchbuffer_data(batch, ref_idx_state, sizeof(ref_idx_state));
321     ADVANCE_BCS_BATCH(batch);
322 }
323
324 void
325 gen6_send_avc_ref_idx_state(
326     struct intel_batchbuffer         *batch,
327     const VASliceParameterBufferH264 *slice_param,
328     const GenFrameStore               frame_store[MAX_GEN_REFERENCE_FRAMES]
329 )
330 {
331     if (slice_param->slice_type == SLICE_TYPE_I ||
332         slice_param->slice_type == SLICE_TYPE_SI)
333         return;
334
335     /* RefPicList0 */
336     gen6_send_avc_ref_idx_state_1(
337         batch, 0,
338         slice_param->RefPicList0, slice_param->num_ref_idx_l0_active_minus1 + 1,
339         frame_store
340     );
341
342     if (slice_param->slice_type != SLICE_TYPE_B)
343         return;
344
345     /* RefPicList1 */
346     gen6_send_avc_ref_idx_state_1(
347         batch, 1,
348         slice_param->RefPicList1, slice_param->num_ref_idx_l1_active_minus1 + 1,
349         frame_store
350     );
351 }
352
353 void
354 intel_update_avc_frame_store_index(VADriverContextP ctx,
355                                    struct decode_state *decode_state,
356                                    VAPictureParameterBufferH264 *pic_param,
357                                    GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES])
358 {
359     int i, j;
360
361     assert(MAX_GEN_REFERENCE_FRAMES == ARRAY_ELEMS(pic_param->ReferenceFrames));
362
363     for (i = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) {
364         int found = 0;
365
366         if (frame_store[i].surface_id == VA_INVALID_ID ||
367             frame_store[i].obj_surface == NULL)
368             continue;
369
370         assert(frame_store[i].frame_store_id != -1);
371
372         for (j = 0; j < MAX_GEN_REFERENCE_FRAMES; j++) {
373             VAPictureH264 *ref_pic = &pic_param->ReferenceFrames[j];
374             if (ref_pic->flags & VA_PICTURE_H264_INVALID)
375                 continue;
376
377             if (frame_store[i].surface_id == ref_pic->picture_id) {
378                 found = 1;
379                 break;
380             }
381         }
382
383         /* remove it from the internal DPB */
384         if (!found) {
385             struct object_surface *obj_surface = frame_store[i].obj_surface;
386             
387             obj_surface->flags &= ~SURFACE_REFERENCED;
388
389             if ((obj_surface->flags & SURFACE_ALL_MASK) == SURFACE_DISPLAYED) {
390                 dri_bo_unreference(obj_surface->bo);
391                 obj_surface->bo = NULL;
392                 obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
393             }
394
395             if (obj_surface->free_private_data)
396                 obj_surface->free_private_data(&obj_surface->private_data);
397
398             frame_store[i].surface_id = VA_INVALID_ID;
399             frame_store[i].frame_store_id = -1;
400             frame_store[i].obj_surface = NULL;
401         }
402     }
403
404     for (i = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) {
405         VAPictureH264 *ref_pic = &pic_param->ReferenceFrames[i];
406         int found = 0;
407
408         if (ref_pic->flags & VA_PICTURE_H264_INVALID ||
409             ref_pic->picture_id == VA_INVALID_SURFACE ||
410             decode_state->reference_objects[i] == NULL)
411             continue;
412
413         for (j = 0; j < MAX_GEN_REFERENCE_FRAMES; j++) {
414             if (frame_store[j].surface_id == ref_pic->picture_id) {
415                 found = 1;
416                 break;
417             }
418         }
419
420         /* add the new reference frame into the internal DPB */
421         if (!found) {
422             int frame_idx;
423             int slot_found;
424             struct object_surface *obj_surface = decode_state->reference_objects[i];
425
426             /* 
427              * Sometimes a dummy frame comes from the upper layer library, call i965_check_alloc_surface_bo()
428              * to ake sure the store buffer is allocated for this reference frame
429              */
430             i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N', 'V', '1', '2'), SUBSAMPLE_YUV420);
431
432             slot_found = 0;
433             frame_idx = -1;
434             /* Find a free frame store index */
435             for (j = 0; j < MAX_GEN_REFERENCE_FRAMES; j++) {
436                 if (frame_store[j].surface_id == VA_INVALID_ID ||
437                     frame_store[j].obj_surface == NULL) {
438                     frame_idx = j;
439                     slot_found = 1;
440                     break;
441                 }
442             }
443
444
445             if (slot_found) {
446                 frame_store[j].surface_id = ref_pic->picture_id;
447                 frame_store[j].frame_store_id = frame_idx;
448                 frame_store[j].obj_surface = obj_surface;
449             } else {
450                 WARN_ONCE("Not free slot for DPB reference list!!!\n");
451             }
452         }
453     }
454
455 }
456
457 void
458 intel_update_vc1_frame_store_index(VADriverContextP ctx,
459                                    struct decode_state *decode_state,
460                                    VAPictureParameterBufferVC1 *pic_param,
461                                    GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES])
462 {
463     struct object_surface *obj_surface;
464     int i;
465
466     obj_surface = decode_state->reference_objects[0];
467
468     if (pic_param->forward_reference_picture == VA_INVALID_ID ||
469         !obj_surface || 
470         !obj_surface->bo) {
471         frame_store[0].surface_id = VA_INVALID_ID;
472         frame_store[0].obj_surface = NULL;
473     } else {
474         frame_store[0].surface_id = pic_param->forward_reference_picture;
475         frame_store[0].obj_surface = obj_surface;
476     }
477
478     obj_surface = decode_state->reference_objects[1];
479
480     if (pic_param->backward_reference_picture == VA_INVALID_ID ||
481         !obj_surface || 
482         !obj_surface->bo) {
483         frame_store[1].surface_id = frame_store[0].surface_id;
484         frame_store[1].obj_surface = frame_store[0].obj_surface;
485     } else {
486         frame_store[1].surface_id = pic_param->backward_reference_picture;
487         frame_store[1].obj_surface = obj_surface;
488     }
489     for (i = 2; i < MAX_GEN_REFERENCE_FRAMES; i++) {
490         frame_store[i].surface_id = frame_store[i % 2].surface_id;
491         frame_store[i].obj_surface = frame_store[i % 2].obj_surface;
492     }
493
494 }
495
496 void
497 intel_update_vp8_frame_store_index(VADriverContextP ctx,
498                                    struct decode_state *decode_state,
499                                    VAPictureParameterBufferVP8 *pic_param,
500                                    GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES])
501 {
502     struct object_surface *obj_surface;
503     int i;
504
505     obj_surface = decode_state->reference_objects[0];
506
507     if (pic_param->last_ref_frame == VA_INVALID_ID ||
508         !obj_surface ||
509         !obj_surface->bo) {
510         frame_store[0].surface_id = VA_INVALID_ID;
511         frame_store[0].obj_surface = NULL;
512     } else {
513         frame_store[0].surface_id = pic_param->last_ref_frame;
514         frame_store[0].obj_surface = obj_surface;
515     }
516
517     obj_surface = decode_state->reference_objects[1];
518
519     if (pic_param->golden_ref_frame == VA_INVALID_ID ||
520         !obj_surface ||
521         !obj_surface->bo) {
522         frame_store[1].surface_id = frame_store[0].surface_id;
523         frame_store[1].obj_surface = frame_store[0].obj_surface;
524     } else {
525         frame_store[1].surface_id = pic_param->golden_ref_frame;
526         frame_store[1].obj_surface = obj_surface;
527     }
528
529     obj_surface = decode_state->reference_objects[2];
530
531     if (pic_param->alt_ref_frame == VA_INVALID_ID ||
532         !obj_surface ||
533         !obj_surface->bo) {
534         frame_store[2].surface_id = frame_store[0].surface_id;
535         frame_store[2].obj_surface = frame_store[0].obj_surface;
536     } else {
537         frame_store[2].surface_id = pic_param->alt_ref_frame;
538         frame_store[2].obj_surface = obj_surface;
539     }
540
541     for (i = 3; i < MAX_GEN_REFERENCE_FRAMES; i++) {
542         frame_store[i].surface_id = frame_store[i % 2].surface_id;
543         frame_store[i].obj_surface = frame_store[i % 2].obj_surface;
544     }
545
546 }
547
548 static VAStatus
549 intel_decoder_check_avc_parameter(VADriverContextP ctx,
550                                   struct decode_state *decode_state)
551 {
552     struct i965_driver_data *i965 = i965_driver_data(ctx);
553     VAPictureParameterBufferH264 *pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
554     struct object_surface *obj_surface; 
555     int i;
556
557     assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
558     assert(pic_param->CurrPic.picture_id != VA_INVALID_SURFACE);
559
560     if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID ||
561         pic_param->CurrPic.picture_id == VA_INVALID_SURFACE)
562         goto error;
563
564     assert(pic_param->CurrPic.picture_id == decode_state->current_render_target);
565
566     if (pic_param->CurrPic.picture_id != decode_state->current_render_target)
567         goto error;
568
569     for (i = 0; i < 16; i++) {
570         if (pic_param->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID ||
571             pic_param->ReferenceFrames[i].picture_id == VA_INVALID_SURFACE)
572             break;
573         else {
574             obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id);
575             assert(obj_surface);
576
577             if (!obj_surface)
578                 goto error;
579
580             if (!obj_surface->bo) { /* a reference frame  without store buffer */
581                 WARN_ONCE("Invalid reference frame!!!\n");
582             }
583
584             decode_state->reference_objects[i] = obj_surface;
585         }
586     }
587
588     for ( ; i < 16; i++)
589         decode_state->reference_objects[i] = NULL;
590
591     return VA_STATUS_SUCCESS;
592
593 error:
594     return VA_STATUS_ERROR_INVALID_PARAMETER;
595 }
596
597 static VAStatus
598 intel_decoder_check_mpeg2_parameter(VADriverContextP ctx,
599                                     struct decode_state *decode_state)
600 {
601     struct i965_driver_data *i965 = i965_driver_data(ctx);
602     VAPictureParameterBufferMPEG2 *pic_param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
603     struct object_surface *obj_surface; 
604     int i = 0;
605     
606     if (pic_param->picture_coding_type == MPEG_I_PICTURE) {
607     } else if (pic_param->picture_coding_type == MPEG_P_PICTURE) {
608         obj_surface = SURFACE(pic_param->forward_reference_picture);
609
610         if (!obj_surface || !obj_surface->bo)
611             decode_state->reference_objects[i++] = NULL;
612         else
613             decode_state->reference_objects[i++] = obj_surface;
614     } else if (pic_param->picture_coding_type == MPEG_B_PICTURE) {
615         obj_surface = SURFACE(pic_param->forward_reference_picture);
616
617         if (!obj_surface || !obj_surface->bo)
618             decode_state->reference_objects[i++] = NULL;
619         else
620             decode_state->reference_objects[i++] = obj_surface;
621
622         obj_surface = SURFACE(pic_param->backward_reference_picture);
623
624         if (!obj_surface || !obj_surface->bo)
625             decode_state->reference_objects[i++] = NULL;
626         else
627             decode_state->reference_objects[i++] = obj_surface;
628     } else
629         goto error;
630
631     for ( ; i < 16; i++)
632         decode_state->reference_objects[i] = NULL;
633
634     return VA_STATUS_SUCCESS;
635
636 error:
637     return VA_STATUS_ERROR_INVALID_PARAMETER;
638 }
639
640 static VAStatus
641 intel_decoder_check_vc1_parameter(VADriverContextP ctx,
642                                   struct decode_state *decode_state)
643 {
644     struct i965_driver_data *i965 = i965_driver_data(ctx);
645     VAPictureParameterBufferVC1 *pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
646     struct object_surface *obj_surface; 
647     int i = 0;
648     
649     if (pic_param->picture_fields.bits.picture_type == 0 ||
650         pic_param->picture_fields.bits.picture_type == 3) {
651     } else if (pic_param->picture_fields.bits.picture_type == 1 ||
652                pic_param->picture_fields.bits.picture_type == 4) {
653         obj_surface = SURFACE(pic_param->forward_reference_picture);
654
655         if (!obj_surface || !obj_surface->bo)
656             decode_state->reference_objects[i++] = NULL;
657         else
658             decode_state->reference_objects[i++] = obj_surface;
659     } else if (pic_param->picture_fields.bits.picture_type == 2) {
660         obj_surface = SURFACE(pic_param->forward_reference_picture);
661
662         if (!obj_surface || !obj_surface->bo)
663             decode_state->reference_objects[i++] = NULL;
664         else
665             decode_state->reference_objects[i++] = obj_surface;
666
667         obj_surface = SURFACE(pic_param->backward_reference_picture);
668
669         if (!obj_surface || !obj_surface->bo)
670             decode_state->reference_objects[i++] = NULL;
671         else
672             decode_state->reference_objects[i++] = obj_surface;
673     } else 
674         goto error;
675
676     for ( ; i < 16; i++)
677         decode_state->reference_objects[i] = NULL;
678
679     return VA_STATUS_SUCCESS;
680
681 error:
682     return VA_STATUS_ERROR_INVALID_PARAMETER;
683 }
684
685 static VAStatus
686 intel_decoder_check_vp8_parameter(VADriverContextP ctx,
687                                   struct decode_state *decode_state)
688 {
689     struct i965_driver_data *i965 = i965_driver_data(ctx);
690     VAPictureParameterBufferVP8 *pic_param = (VAPictureParameterBufferVP8 *)decode_state->pic_param->buffer;
691     struct object_surface *obj_surface; 
692     int i = 0;
693
694     if (pic_param->last_ref_frame != VA_INVALID_SURFACE) {
695         obj_surface = SURFACE(pic_param->last_ref_frame);
696
697         if (obj_surface && obj_surface->bo)
698             decode_state->reference_objects[i++] = obj_surface;
699         else
700             decode_state->reference_objects[i++] = NULL;
701     }
702
703     if (pic_param->golden_ref_frame != VA_INVALID_SURFACE) {
704         obj_surface = SURFACE(pic_param->golden_ref_frame);
705
706         if (obj_surface && obj_surface->bo)
707             decode_state->reference_objects[i++] = obj_surface;
708         else
709             decode_state->reference_objects[i++] = NULL;
710     }
711
712     if (pic_param->alt_ref_frame != VA_INVALID_SURFACE) {
713         obj_surface = SURFACE(pic_param->alt_ref_frame);
714
715         if (obj_surface && obj_surface->bo)
716             decode_state->reference_objects[i++] = obj_surface;
717         else
718             decode_state->reference_objects[i++] = NULL;
719     }
720
721     for ( ; i < 16; i++)
722         decode_state->reference_objects[i] = NULL;
723
724     return VA_STATUS_SUCCESS;
725 }
726
727 VAStatus
728 intel_decoder_sanity_check_input(VADriverContextP ctx,
729                                  VAProfile profile,
730                                  struct decode_state *decode_state)
731 {
732     struct i965_driver_data *i965 = i965_driver_data(ctx);
733     struct object_surface *obj_surface;
734     VAStatus vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
735
736     if (decode_state->current_render_target == VA_INVALID_SURFACE)
737         goto out;
738         
739     obj_surface = SURFACE(decode_state->current_render_target);
740
741     if (!obj_surface)
742         goto out;
743
744     decode_state->render_object = obj_surface;
745
746     switch (profile) {
747     case VAProfileMPEG2Simple:
748     case VAProfileMPEG2Main:
749         vaStatus = intel_decoder_check_mpeg2_parameter(ctx, decode_state);
750         break;
751         
752     case VAProfileH264ConstrainedBaseline:
753     case VAProfileH264Main:
754     case VAProfileH264High:
755         vaStatus = intel_decoder_check_avc_parameter(ctx, decode_state);
756         break;
757
758     case VAProfileVC1Simple:
759     case VAProfileVC1Main:
760     case VAProfileVC1Advanced:
761         vaStatus = intel_decoder_check_vc1_parameter(ctx, decode_state);
762         break;
763
764     case VAProfileJPEGBaseline:
765         vaStatus = VA_STATUS_SUCCESS;
766         break;
767
768     case VAProfileVP8Version0_3:
769         vaStatus = intel_decoder_check_vp8_parameter(ctx, decode_state);
770         break;
771
772     default:
773         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
774         break;
775     }
776
777 out:
778     return vaStatus;
779 }
780
781 /*
782  * Return the next slice paramter
783  *
784  * Input:
785  *      slice_param: the current slice
786  *      *group_idx & *element_idx the current slice position in slice groups
787  * Output:
788  *      Return the next slice parameter
789  *      *group_idx & *element_idx the next slice position in slice groups,
790  *      if the next slice is NULL, *group_idx & *element_idx will be ignored
791  */
792 VASliceParameterBufferMPEG2 *
793 intel_mpeg2_find_next_slice(struct decode_state *decode_state,
794                             VAPictureParameterBufferMPEG2 *pic_param,
795                             VASliceParameterBufferMPEG2 *slice_param,
796                             int *group_idx,
797                             int *element_idx)
798 {
799     VASliceParameterBufferMPEG2 *next_slice_param;
800     unsigned int width_in_mbs = ALIGN(pic_param->horizontal_size, 16) / 16;
801     int j = *group_idx, i = *element_idx + 1;
802
803     for (; j < decode_state->num_slice_params; j++) {
804         for (; i < decode_state->slice_params[j]->num_elements; i++) {
805             next_slice_param = ((VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer) + i;
806
807             if ((next_slice_param->slice_vertical_position * width_in_mbs + next_slice_param->slice_horizontal_position) >=
808                 (slice_param->slice_vertical_position * width_in_mbs + slice_param->slice_horizontal_position)) {
809                 *group_idx = j;
810                 *element_idx = i;
811
812                 return next_slice_param;
813             }
814         }
815
816         i = 0;
817     }
818
819     return NULL;
820 }