OSDN Git Service

intel-vaapi-driver 1.8.1.pre1
[android-x86/hardware-intel-common-vaapi.git] / src / i965_encoder.c
1 /*
2  * Copyright © 2010 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
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Zhou Chang <chang.zhou@intel.com>
26  *
27  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33
34 #include "intel_batchbuffer.h"
35 #include "intel_driver.h"
36
37 #include "i965_defines.h"
38 #include "i965_drv_video.h"
39 #include "i965_encoder.h"
40 #include "gen6_vme.h"
41 #include "gen6_mfc.h"
42
43 #include "i965_post_processing.h"
44 #include "i965_encoder_api.h"
45
46 static struct intel_fraction
47 reduce_fraction(struct intel_fraction f)
48 {
49     unsigned int a = f.num, b = f.den, c;
50     while ((c = a % b)) {
51         a = b;
52         b = c;
53     }
54     return (struct intel_fraction) { f.num / b, f.den / b };
55 }
56
57 static VAStatus
58 clear_border(struct object_surface *obj_surface)
59 {
60     int width[3], height[3], hstride[3], vstride[3]; /* in byte */
61     int planes;
62     unsigned char* p;
63     int i,j;
64
65     if (obj_surface->border_cleared)
66         return VA_STATUS_SUCCESS;
67
68     if (obj_surface->fourcc == VA_FOURCC_NV12) {
69         planes = 2;
70         width[0] = width[1] = obj_surface->orig_width;
71         height[0] = obj_surface->orig_height;
72         height[1] = obj_surface->orig_height / 2;
73         hstride[0] = hstride[1] = obj_surface->width;
74         vstride[0]= obj_surface->height;
75         vstride[1] = obj_surface->height / 2;
76
77     } else {
78         /* todo add P010 */
79         return VA_STATUS_SUCCESS;
80     }
81     drm_intel_gem_bo_map_gtt(obj_surface->bo);
82
83     p = (unsigned char*)obj_surface->bo->virtual;
84     if (!p)
85         return VA_STATUS_ERROR_INVALID_SURFACE;
86
87     for (i = 0; i < planes; i++) {
88         int w = width[i];
89         int h = height[i];
90         int hs = hstride[i];
91         int vs = vstride[i];
92         /* right */
93         for (j = 0; j < h; j++) {
94             memset(p + w, 0, hs - w);
95             p += hs;
96         }
97         /* bottom */
98         for (/* nothing */; j < vs; j++) {
99             memset(p, 0, hs);
100             p += hs;
101         }
102
103     }
104     drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
105     obj_surface->border_cleared = true;
106     return VA_STATUS_SUCCESS;
107 }
108
109 static VAStatus
110 intel_encoder_check_yuv_surface(VADriverContextP ctx,
111                                 VAProfile profile,
112                                 struct encode_state *encode_state,
113                                 struct intel_encoder_context *encoder_context)
114 {
115     struct i965_driver_data *i965 = i965_driver_data(ctx);
116     struct i965_surface src_surface, dst_surface;
117     struct object_surface *obj_surface;
118     VAStatus status;
119     VARectangle rect;
120     int format = VA_RT_FORMAT_YUV420;
121     unsigned int fourcc = VA_FOURCC_NV12;
122
123     /* releae the temporary surface */
124     if (encoder_context->is_tmp_id) {
125         i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
126         encode_state->input_yuv_object = NULL;
127     }
128
129     encoder_context->is_tmp_id = 0;
130     obj_surface = SURFACE(encode_state->current_render_target);
131     assert(obj_surface && obj_surface->bo);
132
133     if (!obj_surface || !obj_surface->bo)
134         return VA_STATUS_ERROR_INVALID_PARAMETER;
135
136     if (VAProfileHEVCMain10 == profile &&
137         obj_surface->fourcc != VA_FOURCC_P010)
138         return VA_STATUS_ERROR_INVALID_PARAMETER;
139
140     if (obj_surface->fourcc == VA_FOURCC_NV12 ||
141         (VAProfileHEVCMain10 == profile &&
142         obj_surface->fourcc == VA_FOURCC_P010)) {
143
144         unsigned int tiling = 0, swizzle = 0;
145         dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
146
147         if (tiling == I915_TILING_Y) {
148             encoder_context->input_yuv_surface = encode_state->current_render_target;
149             encode_state->input_yuv_object = obj_surface;
150             return clear_border(obj_surface);
151         }
152     }
153
154     if (VAProfileHEVCMain10 == profile) {
155         format = VA_RT_FORMAT_YUV420_10BPP;
156         fourcc = VA_FOURCC_P010;
157     }
158
159     rect.x = 0;
160     rect.y = 0;
161     rect.width = obj_surface->orig_width;
162     rect.height = obj_surface->orig_height;
163     
164     src_surface.base = (struct object_base *)obj_surface;
165     src_surface.type = I965_SURFACE_TYPE_SURFACE;
166     src_surface.flags = I965_SURFACE_FLAG_FRAME;
167     
168     status = i965_CreateSurfaces(ctx,
169                                  obj_surface->orig_width,
170                                  obj_surface->orig_height,
171                                  format,
172                                  1,
173                                  &encoder_context->input_yuv_surface);
174     ASSERT_RET(status == VA_STATUS_SUCCESS, status);
175
176     obj_surface = SURFACE(encoder_context->input_yuv_surface);
177     encode_state->input_yuv_object = obj_surface;
178     assert(obj_surface);
179     i965_check_alloc_surface_bo(ctx, obj_surface, 1, fourcc, SUBSAMPLE_YUV420);
180     
181     dst_surface.base = (struct object_base *)obj_surface;
182     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
183     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
184
185     status = i965_image_processing(ctx,
186                                    &src_surface,
187                                    &rect,
188                                    &dst_surface,
189                                    &rect);
190     assert(status == VA_STATUS_SUCCESS);
191
192     encoder_context->is_tmp_id = 1;
193
194     return clear_border(obj_surface);
195 }
196
197
198 static VAStatus
199 intel_encoder_check_jpeg_yuv_surface(VADriverContextP ctx,
200                                 VAProfile profile,
201                                 struct encode_state *encode_state,
202                                 struct intel_encoder_context *encoder_context)
203 {
204     struct i965_driver_data *i965 = i965_driver_data(ctx);
205     struct i965_surface src_surface, dst_surface;
206     struct object_surface *obj_surface;
207     VAStatus status;
208     VARectangle rect;
209     int format=0, fourcc=0, subsample=0;
210
211     /* releae the temporary surface */
212     if (encoder_context->is_tmp_id) {
213         i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
214         encode_state->input_yuv_object = NULL;
215     }
216
217     encoder_context->is_tmp_id = 0;
218     obj_surface = SURFACE(encode_state->current_render_target);
219     assert(obj_surface && obj_surface->bo);
220
221     if (!obj_surface || !obj_surface->bo)
222         return VA_STATUS_ERROR_INVALID_PARAMETER;
223
224     unsigned int tiling = 0, swizzle = 0;
225
226     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
227
228     if (tiling == I915_TILING_Y) {
229         if( (obj_surface->fourcc==VA_FOURCC_NV12)  || (obj_surface->fourcc==VA_FOURCC_UYVY) ||
230             (obj_surface->fourcc==VA_FOURCC_YUY2)  || (obj_surface->fourcc==VA_FOURCC_Y800) ||
231             (obj_surface->fourcc==VA_FOURCC_RGBA)  || (obj_surface->fourcc==VA_FOURCC_444P) ) {
232             encoder_context->input_yuv_surface = encode_state->current_render_target;
233             encode_state->input_yuv_object = obj_surface;
234             return VA_STATUS_SUCCESS;
235         }
236     }
237
238     rect.x = 0;
239     rect.y = 0;
240     rect.width = obj_surface->orig_width;
241     rect.height = obj_surface->orig_height;
242
243     src_surface.base = (struct object_base *)obj_surface;
244     src_surface.type = I965_SURFACE_TYPE_SURFACE;
245     src_surface.flags = I965_SURFACE_FLAG_FRAME;
246
247     switch( obj_surface->fourcc) {
248
249         case VA_FOURCC_YUY2:
250             fourcc = VA_FOURCC_YUY2;
251             format = VA_RT_FORMAT_YUV422;
252             subsample = SUBSAMPLE_YUV422H;
253             break;
254
255         case VA_FOURCC_UYVY:
256             fourcc = VA_FOURCC_UYVY;
257             format = VA_RT_FORMAT_YUV422;
258             subsample = SUBSAMPLE_YUV422H;
259             break;
260
261         case VA_FOURCC_Y800:
262             fourcc = VA_FOURCC_Y800;
263             format = VA_RT_FORMAT_YUV400;
264             subsample = SUBSAMPLE_YUV400;
265             break;
266
267         case VA_FOURCC_444P:
268             fourcc = VA_FOURCC_444P;
269             format = VA_RT_FORMAT_YUV444;
270             subsample = SUBSAMPLE_YUV444;
271             break;
272
273         case VA_FOURCC_RGBA:
274             fourcc = VA_FOURCC_RGBA;
275             format = VA_RT_FORMAT_RGB32;
276             subsample = SUBSAMPLE_RGBX;
277             break;
278
279         default: //All other scenarios will have NV12 format
280             fourcc = VA_FOURCC_NV12;
281             format = VA_RT_FORMAT_YUV420;
282             subsample = SUBSAMPLE_YUV420;
283             break;
284     }
285
286     status = i965_CreateSurfaces(ctx,
287                                  obj_surface->orig_width,
288                                  obj_surface->orig_height,
289                                  format,
290                                  1,
291                                  &encoder_context->input_yuv_surface);
292     assert(status == VA_STATUS_SUCCESS);
293
294     if (status != VA_STATUS_SUCCESS)
295         return status;
296
297     obj_surface = SURFACE(encoder_context->input_yuv_surface);
298     encode_state->input_yuv_object = obj_surface;
299     assert(obj_surface);
300     i965_check_alloc_surface_bo(ctx, obj_surface, 1, fourcc, subsample);
301
302     dst_surface.base = (struct object_base *)obj_surface;
303     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
304     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
305
306     //The Y800 format is expected to be tiled.
307     //Linear Y800 is a corner case and needs code in the i965_image_processing.
308     if(obj_surface->fourcc != VA_FOURCC_Y800){
309         status = i965_image_processing(ctx,
310                                    &src_surface,
311                                    &rect,
312                                    &dst_surface,
313                                    &rect);
314         assert(status == VA_STATUS_SUCCESS);
315     }
316
317     encoder_context->is_tmp_id = 1;
318
319     return VA_STATUS_SUCCESS;
320 }
321
322 static VAStatus
323 intel_encoder_check_brc_h264_sequence_parameter(VADriverContextP ctx,
324                                                 struct encode_state *encode_state,
325                                                 struct intel_encoder_context *encoder_context,
326                                                 unsigned int *seq_bits_per_second)
327 {
328     VAEncSequenceParameterBufferH264 *seq_param = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
329     struct intel_fraction framerate;
330     unsigned short num_pframes_in_gop, num_bframes_in_gop;
331
332     if (!encoder_context->is_new_sequence)
333         return VA_STATUS_SUCCESS;
334
335     assert(seq_param);
336
337     if (!seq_param->num_units_in_tick || !seq_param->time_scale) {
338         framerate = (struct intel_fraction) { 30, 1 };
339     } else {
340         // for the highest layer
341         framerate = (struct intel_fraction) { seq_param->time_scale, 2 * seq_param->num_units_in_tick };
342     }
343     framerate = reduce_fraction(framerate);
344
345     encoder_context->brc.num_iframes_in_gop = 1; // Always 1
346
347     if (seq_param->intra_period == 0) { // E.g. IDRPP... / IDR(PBB)... (no IDR/I any more)
348         if (seq_param->ip_period == 0)
349             goto error;
350
351         encoder_context->brc.gop_size = (framerate.num + framerate.den - 1) / framerate.den; // fake
352         num_pframes_in_gop = (encoder_context->brc.gop_size +
353                               seq_param->ip_period - 1) / seq_param->ip_period - 1;
354     } else if (seq_param->intra_period == 1) { // E.g. IDRIII...
355         encoder_context->brc.gop_size = 1;
356         num_pframes_in_gop = 0;
357     } else {
358         if (seq_param->ip_period == 0)
359             goto error;
360
361         encoder_context->brc.gop_size = seq_param->intra_period;
362         num_pframes_in_gop = (encoder_context->brc.gop_size +
363                               seq_param->ip_period - 1) / seq_param->ip_period - 1;
364     }
365
366     num_bframes_in_gop = (encoder_context->brc.gop_size -
367                           encoder_context->brc.num_iframes_in_gop - num_pframes_in_gop);
368
369     if (num_pframes_in_gop != encoder_context->brc.num_pframes_in_gop ||
370         num_bframes_in_gop != encoder_context->brc.num_bframes_in_gop ||
371         framerate.num != encoder_context->brc.framerate[encoder_context->layer.num_layers - 1].num ||
372         framerate.den != encoder_context->brc.framerate[encoder_context->layer.num_layers - 1].den) {
373         encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
374         encoder_context->brc.num_bframes_in_gop = num_bframes_in_gop;
375         encoder_context->brc.framerate[encoder_context->layer.num_layers - 1] = framerate;
376         encoder_context->brc.need_reset = 1;
377     }
378
379     if (!encoder_context->brc.hrd_buffer_size ||
380         !encoder_context->brc.hrd_initial_buffer_fullness) {
381         encoder_context->brc.hrd_buffer_size = seq_param->bits_per_second << 1;
382         encoder_context->brc.hrd_initial_buffer_fullness = seq_param->bits_per_second;
383     }
384
385     *seq_bits_per_second = seq_param->bits_per_second;
386
387     return VA_STATUS_SUCCESS;
388
389 error:
390     return VA_STATUS_ERROR_INVALID_PARAMETER;
391 }
392
393 static VAStatus
394 intel_encoder_check_brc_vp8_sequence_parameter(VADriverContextP ctx,
395                                                struct encode_state *encode_state,
396                                                struct intel_encoder_context *encoder_context,
397                                                unsigned int *seq_bits_per_second)
398 {
399     VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer;
400     unsigned int num_pframes_in_gop;
401
402     if (!encoder_context->is_new_sequence)
403         return VA_STATUS_SUCCESS;
404
405     assert(seq_param);
406
407     encoder_context->brc.num_iframes_in_gop = 1;// Always 1
408     encoder_context->brc.num_bframes_in_gop = 0;// No B frame
409
410     if (seq_param->intra_period == 0) {         // E.g. IPPP... (only one I frame in the stream)
411         encoder_context->brc.gop_size = 30;     // fake
412     } else {
413         encoder_context->brc.gop_size = seq_param->intra_period;
414     }
415
416     num_pframes_in_gop = encoder_context->brc.gop_size - 1;
417
418     if (!encoder_context->brc.framerate[encoder_context->layer.num_layers - 1].num) {
419         // for the highest layer
420         encoder_context->brc.framerate[encoder_context->layer.num_layers - 1] = (struct intel_fraction) { 30, 1 };
421         encoder_context->brc.need_reset = 1;
422     }
423
424     if (num_pframes_in_gop != encoder_context->brc.num_pframes_in_gop) {
425         encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
426         encoder_context->brc.need_reset = 1;
427     }
428
429     if (!encoder_context->brc.hrd_buffer_size ||
430         !encoder_context->brc.hrd_initial_buffer_fullness) {
431         encoder_context->brc.hrd_buffer_size = seq_param->bits_per_second << 1;
432         encoder_context->brc.hrd_initial_buffer_fullness = seq_param->bits_per_second;
433         encoder_context->brc.need_reset = 1;
434     }
435
436     *seq_bits_per_second = seq_param->bits_per_second;
437
438     return VA_STATUS_SUCCESS;
439 }
440
441 static VAStatus
442 intel_encoder_check_brc_hevc_sequence_parameter(VADriverContextP ctx,
443                                                 struct encode_state *encode_state,
444                                                 struct intel_encoder_context *encoder_context,
445                                                 unsigned int *seq_bits_per_second)
446 {
447     VAEncSequenceParameterBufferHEVC *seq_param = (VAEncSequenceParameterBufferHEVC*)encode_state->seq_param_ext->buffer;
448     struct intel_fraction framerate;
449     unsigned int gop_size, num_iframes_in_gop, num_pframes_in_gop, num_bframes_in_gop;
450
451     if (!encoder_context->is_new_sequence)
452         return VA_STATUS_SUCCESS;
453     if (!seq_param)
454         return VA_STATUS_ERROR_INVALID_PARAMETER;
455
456     if (!seq_param->vui_time_scale || !seq_param->vui_num_units_in_tick)
457         framerate = (struct intel_fraction) { 30, 1 };
458     else
459         framerate = (struct intel_fraction) { seq_param->vui_time_scale, seq_param->vui_num_units_in_tick };
460     framerate = reduce_fraction(framerate);
461
462     num_iframes_in_gop = 1;
463     if (seq_param->intra_period == 0) {
464         gop_size = -1;
465         num_pframes_in_gop = -1;
466     } else if (seq_param->intra_period == 1) {
467         gop_size = 1;
468         num_pframes_in_gop = 0;
469     } else {
470         gop_size = seq_param->intra_period;
471         num_pframes_in_gop = (seq_param->intra_period + seq_param->ip_period - 1) / seq_param->ip_period - 1;
472     }
473     num_bframes_in_gop = gop_size - num_iframes_in_gop - num_pframes_in_gop;
474
475     if (encoder_context->brc.framerate[0].num != framerate.num ||
476         encoder_context->brc.framerate[0].den != framerate.den) {
477         encoder_context->brc.framerate[0] = framerate;
478         encoder_context->brc.need_reset = 1;
479     }
480
481     if (encoder_context->brc.gop_size != gop_size ||
482         encoder_context->brc.num_iframes_in_gop != num_iframes_in_gop ||
483         encoder_context->brc.num_pframes_in_gop != num_pframes_in_gop ||
484         encoder_context->brc.num_bframes_in_gop != num_bframes_in_gop) {
485         encoder_context->brc.gop_size = gop_size;
486         encoder_context->brc.num_iframes_in_gop = num_iframes_in_gop;
487         encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
488         encoder_context->brc.num_bframes_in_gop = num_bframes_in_gop;
489         encoder_context->brc.need_reset = 1;
490     }
491
492     *seq_bits_per_second = seq_param->bits_per_second;
493
494     return VA_STATUS_SUCCESS;
495 }
496
497 static VAStatus
498 intel_encoder_check_brc_vp9_sequence_parameter(VADriverContextP ctx,
499                                                struct encode_state *encode_state,
500                                                struct intel_encoder_context *encoder_context,
501                                                unsigned int *seq_bits_per_second)
502 {
503     VAEncSequenceParameterBufferVP9 *seq_param = (VAEncSequenceParameterBufferVP9*)encode_state->seq_param_ext->buffer;
504     unsigned int gop_size;
505
506     if (!encoder_context->is_new_sequence)
507         return VA_STATUS_SUCCESS;
508     if (!seq_param)
509         return VA_STATUS_ERROR_INVALID_PARAMETER;
510
511     if (seq_param->intra_period == 0)
512         gop_size = -1; // Dummy value (infinity).
513     else
514         gop_size = seq_param->intra_period;
515
516     if (encoder_context->brc.gop_size != gop_size) {
517         encoder_context->brc.gop_size = gop_size;
518         encoder_context->brc.need_reset = 1;
519     }
520
521     *seq_bits_per_second = seq_param->bits_per_second;
522
523     return VA_STATUS_SUCCESS;
524 }
525
526 static VAStatus
527 intel_encoder_check_brc_sequence_parameter(VADriverContextP ctx,
528                                            struct encode_state *encode_state,
529                                            struct intel_encoder_context *encoder_context,
530                                            unsigned int *seq_bits_per_second)
531 {
532     *seq_bits_per_second = 0;
533
534     switch (encoder_context->codec) {
535     case CODEC_H264:
536     case CODEC_H264_MVC:
537         return intel_encoder_check_brc_h264_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
538
539     case CODEC_VP8:
540         return intel_encoder_check_brc_vp8_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
541
542     case CODEC_HEVC:
543         return intel_encoder_check_brc_hevc_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
544
545     case CODEC_VP9:
546         return intel_encoder_check_brc_vp9_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
547
548     default:
549         // TODO: other codecs
550         return VA_STATUS_SUCCESS;
551     }
552 }
553
554 static void
555 intel_encoder_check_rate_control_parameter(VADriverContextP ctx,
556                                            struct intel_encoder_context *encoder_context,
557                                            VAEncMiscParameterRateControl *misc,
558                                            int *hl_bitrate_updated)
559 {
560     int temporal_id = 0;
561
562     if (encoder_context->layer.num_layers >= 2)
563         temporal_id = misc->rc_flags.bits.temporal_id;
564
565     if (temporal_id >= encoder_context->layer.num_layers)
566         return;
567
568     if (misc->rc_flags.bits.reset)
569         encoder_context->brc.need_reset = 1;
570
571     if (encoder_context->brc.bits_per_second[temporal_id] != misc->bits_per_second) {
572         encoder_context->brc.bits_per_second[temporal_id] = misc->bits_per_second;
573         encoder_context->brc.need_reset = 1;
574     }
575
576     if (encoder_context->brc.mb_rate_control[temporal_id] != misc->rc_flags.bits.mb_rate_control) {
577         encoder_context->brc.mb_rate_control[temporal_id] = misc->rc_flags.bits.mb_rate_control;
578         encoder_context->brc.need_reset = 1;
579     }
580
581     if (encoder_context->brc.target_percentage[temporal_id] != misc->target_percentage) {
582         encoder_context->brc.target_percentage[temporal_id] = misc->target_percentage;
583         encoder_context->brc.need_reset = 1;
584     }
585
586     if (encoder_context->brc.window_size != misc->window_size ||
587         encoder_context->brc.initial_qp  != misc->initial_qp ||
588         encoder_context->brc.min_qp      != misc->min_qp) {
589         encoder_context->brc.window_size = misc->window_size;
590         encoder_context->brc.initial_qp  = misc->initial_qp;
591         encoder_context->brc.min_qp      = misc->min_qp;
592         encoder_context->brc.need_reset = 1;
593     }
594
595     if (temporal_id == encoder_context->layer.num_layers - 1)
596         *hl_bitrate_updated = 1;
597 }
598
599 static void
600 intel_encoder_check_hrd_parameter(VADriverContextP ctx,
601                                   struct intel_encoder_context *encoder_context,
602                                   VAEncMiscParameterHRD *misc)
603 {
604     if (encoder_context->brc.hrd_buffer_size != misc->buffer_size ||
605         encoder_context->brc.hrd_initial_buffer_fullness != misc->initial_buffer_fullness) {
606         encoder_context->brc.hrd_buffer_size = misc->buffer_size;
607         encoder_context->brc.hrd_initial_buffer_fullness = misc->initial_buffer_fullness;
608         encoder_context->brc.need_reset = 1;
609     }
610 }
611
612 static void
613 intel_encoder_check_framerate_parameter(VADriverContextP ctx,
614                                         struct intel_encoder_context *encoder_context,
615                                         VAEncMiscParameterFrameRate *misc)
616 {
617     struct intel_fraction framerate;
618     int temporal_id = 0;
619
620     if (encoder_context->layer.num_layers >= 2)
621         temporal_id = misc->framerate_flags.bits.temporal_id;
622
623     if (temporal_id >= encoder_context->layer.num_layers)
624         return;
625
626     if (misc->framerate & 0xffff0000)
627         framerate = (struct intel_fraction) { misc->framerate & 0xffff, misc->framerate >> 16 & 0xffff };
628     else
629         framerate = (struct intel_fraction) { misc->framerate, 1 };
630     framerate = reduce_fraction(framerate);
631
632     if (encoder_context->brc.framerate[temporal_id].num != framerate.num ||
633         encoder_context->brc.framerate[temporal_id].den != framerate.den) {
634         encoder_context->brc.framerate[temporal_id] = framerate;
635         encoder_context->brc.need_reset = 1;
636     }
637 }
638
639 static void
640 intel_encoder_check_roi_parameter(VADriverContextP ctx,
641                                   struct intel_encoder_context *encoder_context,
642                                   VAEncMiscParameterBufferROI *misc)
643 {
644     int i = 0;
645
646     encoder_context->brc.num_roi = MIN(misc->num_roi, I965_MAX_NUM_ROI_REGIONS);
647     encoder_context->brc.roi_max_delta_qp = misc->max_delta_qp;
648     encoder_context->brc.roi_min_delta_qp = misc->min_delta_qp;
649     encoder_context->brc.roi_value_is_qp_delta = 0;
650
651     if (encoder_context->rate_control_mode != VA_RC_CQP)
652         encoder_context->brc.roi_value_is_qp_delta = misc->roi_flags.bits.roi_value_is_qp_delta;
653
654     for (i = 0; i <  encoder_context->brc.num_roi; i++) {
655         encoder_context->brc.roi[i].left = misc->roi->roi_rectangle.x;
656         encoder_context->brc.roi[i].right = encoder_context->brc.roi[i].left + misc->roi->roi_rectangle.width;
657         encoder_context->brc.roi[i].top = misc->roi->roi_rectangle.y;
658         encoder_context->brc.roi[i].bottom = encoder_context->brc.roi[i].top + misc->roi->roi_rectangle.height;
659         encoder_context->brc.roi[i].value = misc->roi->roi_value;
660     }
661 }
662
663 static VAStatus
664 intel_encoder_check_brc_parameter(VADriverContextP ctx,
665                                   struct encode_state *encode_state,
666                                   struct intel_encoder_context *encoder_context)
667 {
668     VAStatus ret;
669     VAEncMiscParameterBuffer *misc_param;
670     int i, j;
671     int hl_bitrate_updated = 0; // Indicate whether the bitrate for the highest level is changed in misc parameters
672     unsigned int seq_bits_per_second = 0;
673
674     if (!(encoder_context->rate_control_mode & (VA_RC_CBR | VA_RC_VBR)))
675         return VA_STATUS_SUCCESS;
676
677     ret = intel_encoder_check_brc_sequence_parameter(ctx, encode_state, encoder_context, &seq_bits_per_second);
678
679     if (ret)
680         return ret;
681
682     for (i = 0; i < ARRAY_ELEMS(encode_state->misc_param); i++) {
683         for (j = 0; j < ARRAY_ELEMS(encode_state->misc_param[0]); j++) {
684             if (!encode_state->misc_param[i][j] || !encode_state->misc_param[i][j]->buffer)
685                 continue;
686
687             misc_param = (VAEncMiscParameterBuffer *)encode_state->misc_param[i][j]->buffer;
688
689             switch (misc_param->type) {
690             case VAEncMiscParameterTypeFrameRate:
691                 intel_encoder_check_framerate_parameter(ctx,
692                                                         encoder_context,
693                                                         (VAEncMiscParameterFrameRate *)misc_param->data);
694                 break;
695
696             case VAEncMiscParameterTypeRateControl:
697                 intel_encoder_check_rate_control_parameter(ctx,
698                                                            encoder_context,
699                                                            (VAEncMiscParameterRateControl *)misc_param->data,
700                                                            &hl_bitrate_updated);
701                 break;
702
703             case VAEncMiscParameterTypeHRD:
704                 intel_encoder_check_hrd_parameter(ctx,
705                                                   encoder_context,
706                                                   (VAEncMiscParameterHRD *)misc_param->data);
707                 break;
708
709             case VAEncMiscParameterTypeROI:
710                 intel_encoder_check_roi_parameter(ctx,
711                                                   encoder_context,
712                                                   (VAEncMiscParameterBufferROI *)misc_param->data);
713                 break;
714
715             default:
716                 break;
717             }
718         }
719     }
720
721     if (!hl_bitrate_updated && seq_bits_per_second &&
722         encoder_context->brc.bits_per_second[encoder_context->layer.num_layers - 1] != seq_bits_per_second) {
723
724         encoder_context->brc.bits_per_second[encoder_context->layer.num_layers - 1] = seq_bits_per_second;
725         encoder_context->brc.need_reset = 1;
726
727     }
728
729     return VA_STATUS_SUCCESS;
730 }
731
732 static VAStatus
733 intel_encoder_check_temporal_layer_structure(VADriverContextP ctx,
734                                              struct encode_state *encode_state,
735                                              struct intel_encoder_context *encoder_context)
736 {
737     VAEncMiscParameterBuffer* misc_param;
738     VAEncMiscParameterTemporalLayerStructure *tls_paramter;
739     unsigned int rate_control_mode = encoder_context->rate_control_mode;
740     int i;
741
742     if (!encoder_context->is_new_sequence) {
743         if (encoder_context->layer.num_layers > 1)
744             encoder_context->layer.curr_frame_layer_id = encoder_context->layer.frame_layer_ids[(encoder_context->num_frames_in_sequence - 1) % encoder_context->layer.size_frame_layer_ids];
745         else
746             encoder_context->layer.curr_frame_layer_id = 0;
747
748         return VA_STATUS_SUCCESS;
749     }
750
751     if (!(rate_control_mode & (VA_RC_CBR | VA_RC_VBR)))
752         return VA_STATUS_SUCCESS;
753
754     if (!encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0] ||
755         !encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0]->buffer)
756         return VA_STATUS_SUCCESS;
757
758     misc_param = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0]->buffer;
759     tls_paramter = (VAEncMiscParameterTemporalLayerStructure *)misc_param->data;
760
761     if (tls_paramter->number_of_layers <= 1)
762         return VA_STATUS_SUCCESS;
763
764     if (tls_paramter->number_of_layers > MAX_TEMPORAL_LAYERS)
765         return VA_STATUS_ERROR_INVALID_PARAMETER;
766
767     if (tls_paramter->periodicity > 32 || tls_paramter->periodicity <= 1)
768         return VA_STATUS_ERROR_INVALID_PARAMETER;
769
770     for (i = 0; i < tls_paramter->number_of_layers; i++) {
771         if (!encode_state->misc_param[VAEncMiscParameterTypeRateControl][i] ||
772             !encode_state->misc_param[VAEncMiscParameterTypeRateControl][i]->buffer ||
773             !encode_state->misc_param[VAEncMiscParameterTypeFrameRate][i] ||
774             !encode_state->misc_param[VAEncMiscParameterTypeFrameRate][i]->buffer) {
775
776             return VA_STATUS_ERROR_INVALID_PARAMETER;
777         }
778     }
779
780     encoder_context->layer.size_frame_layer_ids = tls_paramter->periodicity;
781     encoder_context->layer.num_layers = tls_paramter->number_of_layers;
782
783     for (i = 0; i < encoder_context->layer.size_frame_layer_ids; i++) {
784         if (tls_paramter->layer_id[i] >= tls_paramter->number_of_layers)
785             return VA_STATUS_ERROR_INVALID_PARAMETER;
786
787         encoder_context->layer.frame_layer_ids[i] = tls_paramter->layer_id[i];
788     }
789
790     if (encoder_context->is_new_sequence)
791         encoder_context->layer.curr_frame_layer_id = 0;
792     else
793         encoder_context->layer.curr_frame_layer_id = encoder_context->layer.frame_layer_ids[(encoder_context->num_frames_in_sequence - 1) % encoder_context->layer.size_frame_layer_ids];
794
795     return VA_STATUS_SUCCESS;
796 }
797
798 static VAStatus
799 intel_encoder_check_misc_parameter(VADriverContextP ctx,
800                                   struct encode_state *encode_state,
801                                   struct intel_encoder_context *encoder_context)
802 {
803     VAStatus ret = VA_STATUS_SUCCESS;
804
805     if (encode_state->misc_param[VAEncMiscParameterTypeQualityLevel][0] &&
806         encode_state->misc_param[VAEncMiscParameterTypeQualityLevel][0]->buffer) {
807         VAEncMiscParameterBuffer* pMiscParam = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeQualityLevel][0]->buffer;
808         VAEncMiscParameterBufferQualityLevel* param_quality_level = (VAEncMiscParameterBufferQualityLevel*)pMiscParam->data;
809         encoder_context->quality_level = param_quality_level->quality_level;
810
811         if (encoder_context->quality_level == 0)
812             encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
813         else if (encoder_context->quality_level > encoder_context->quality_range) {
814             ret = VA_STATUS_ERROR_INVALID_PARAMETER;
815             goto out;
816         }
817     }
818
819     ret = intel_encoder_check_temporal_layer_structure(ctx, encode_state, encoder_context);
820
821     if (ret)
822         goto out;
823
824     ret = intel_encoder_check_brc_parameter(ctx, encode_state, encoder_context);
825
826 out:
827     return ret;
828 }
829
830 static VAStatus
831 intel_encoder_check_avc_parameter(VADriverContextP ctx,
832                                   struct encode_state *encode_state,
833                                   struct intel_encoder_context *encoder_context)
834 {
835     struct i965_driver_data *i965 = i965_driver_data(ctx);
836     struct object_surface *obj_surface; 
837     struct object_buffer *obj_buffer;
838     VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
839     VAEncSequenceParameterBufferH264 *seq_param = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
840     int i;
841
842     assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
843
844     if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID)
845         goto error;
846
847     obj_surface = SURFACE(pic_param->CurrPic.picture_id);
848     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
849     
850     if (!obj_surface)
851         goto error;
852
853     encode_state->reconstructed_object = obj_surface;
854     obj_buffer = BUFFER(pic_param->coded_buf);
855     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
856
857     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
858         goto error;
859
860     if (encode_state->num_slice_params_ext > encoder_context->max_slice_or_seg_num )
861         goto error;
862
863     encode_state->coded_buf_object = obj_buffer;
864
865     for (i = 0; i < 16; i++) {
866         if (pic_param->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID ||
867             pic_param->ReferenceFrames[i].picture_id == VA_INVALID_SURFACE)
868             break;
869         else {
870             obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id);
871             assert(obj_surface);
872
873             if (!obj_surface)
874                 goto error;
875
876             if (obj_surface->bo)
877                 encode_state->reference_objects[i] = obj_surface;
878             else
879                 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
880         }
881     }
882
883     for ( ; i < 16; i++)
884         encode_state->reference_objects[i] = NULL;
885
886     /*
887      * A sequence consists of an IDR unit, followed by zero or more non-IDR unit, but not including any
888      * subsequent IDR unit, so idr_pic_flag can indicate the current frame is the start of a new
889      * sequnce
890      */
891     encoder_context->is_new_sequence = (pic_param->pic_fields.bits.idr_pic_flag && seq_param);
892
893     if (encoder_context->is_new_sequence) {
894         encoder_context->num_frames_in_sequence = 0;
895         encoder_context->frame_width_in_pixel = seq_param->picture_width_in_mbs * 16;
896         encoder_context->frame_height_in_pixel = seq_param->picture_height_in_mbs * 16;
897     }
898
899     return VA_STATUS_SUCCESS;
900
901 error:
902     return VA_STATUS_ERROR_INVALID_PARAMETER;
903 }
904
905 static VAStatus
906 intel_encoder_check_mpeg2_parameter(VADriverContextP ctx,
907                                     struct encode_state *encode_state,
908                                     struct intel_encoder_context *encoder_context)
909 {
910     struct i965_driver_data *i965 = i965_driver_data(ctx);
911     VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
912     struct object_surface *obj_surface; 
913     struct object_buffer *obj_buffer;
914     int i = 0;
915     
916     obj_surface = SURFACE(pic_param->reconstructed_picture);
917     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
918     
919     if (!obj_surface)
920         goto error;
921     
922     encode_state->reconstructed_object = obj_surface;    
923     obj_buffer = BUFFER(pic_param->coded_buf);
924     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
925
926     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
927         goto error;
928
929     encode_state->coded_buf_object = obj_buffer;
930
931     if (pic_param->picture_type == VAEncPictureTypeIntra) {
932     } else if (pic_param->picture_type == VAEncPictureTypePredictive) {
933         assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
934         obj_surface = SURFACE(pic_param->forward_reference_picture);
935         assert(obj_surface && obj_surface->bo);
936
937         if (!obj_surface || !obj_surface->bo)
938             goto error;
939
940         encode_state->reference_objects[i++] = obj_surface;
941     } else if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
942         assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
943         obj_surface = SURFACE(pic_param->forward_reference_picture);
944         assert(obj_surface && obj_surface->bo);
945
946         if (!obj_surface || !obj_surface->bo)
947             goto error;
948
949         encode_state->reference_objects[i++] = obj_surface;
950
951         assert(pic_param->backward_reference_picture != VA_INVALID_SURFACE);
952         obj_surface = SURFACE(pic_param->backward_reference_picture);
953         assert(obj_surface && obj_surface->bo);
954
955         if (!obj_surface || !obj_surface->bo)
956             goto error;
957
958         encode_state->reference_objects[i++] = obj_surface;
959     } else 
960         goto error;
961
962     for ( ; i < 16; i++)
963         encode_state->reference_objects[i] = NULL;
964
965     return VA_STATUS_SUCCESS;
966
967 error:
968     return VA_STATUS_ERROR_INVALID_PARAMETER;
969 }
970
971 static VAStatus
972 intel_encoder_check_jpeg_parameter(VADriverContextP ctx,
973                                   struct encode_state *encode_state,
974                                   struct intel_encoder_context *encoder_context)
975 {
976     struct i965_driver_data *i965 = i965_driver_data(ctx);
977     struct object_buffer *obj_buffer;
978     VAEncPictureParameterBufferJPEG *pic_param = (VAEncPictureParameterBufferJPEG *)encode_state->pic_param_ext->buffer;
979
980
981     assert(!(pic_param->pic_flags.bits.profile)); //Baseline profile is 0.
982
983     obj_buffer = BUFFER(pic_param->coded_buf);
984     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
985
986     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
987         goto error;
988
989     encode_state->coded_buf_object = obj_buffer;
990
991     return VA_STATUS_SUCCESS;
992
993 error:
994     return VA_STATUS_ERROR_INVALID_PARAMETER;
995 }
996
997 static VAStatus
998 intel_encoder_check_vp8_parameter(VADriverContextP ctx,
999                                     struct encode_state *encode_state,
1000                                     struct intel_encoder_context *encoder_context)
1001 {
1002     struct i965_driver_data *i965 = i965_driver_data(ctx);
1003     VAEncPictureParameterBufferVP8 *pic_param = (VAEncPictureParameterBufferVP8 *)encode_state->pic_param_ext->buffer;
1004     VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer;
1005     struct object_surface *obj_surface;
1006     struct object_buffer *obj_buffer;
1007     int i = 0;
1008     int is_key_frame = !pic_param->pic_flags.bits.frame_type;
1009  
1010     obj_surface = SURFACE(pic_param->reconstructed_frame);
1011     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
1012     
1013     if (!obj_surface)
1014         goto error;
1015     
1016     encode_state->reconstructed_object = obj_surface;
1017     obj_buffer = BUFFER(pic_param->coded_buf);
1018     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
1019
1020     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1021         goto error;
1022
1023     encode_state->coded_buf_object = obj_buffer;
1024
1025     if (!is_key_frame) {
1026         assert(pic_param->ref_last_frame != VA_INVALID_SURFACE);
1027         obj_surface = SURFACE(pic_param->ref_last_frame);
1028         assert(obj_surface && obj_surface->bo);
1029
1030         if (!obj_surface || !obj_surface->bo)
1031             goto error;
1032
1033         encode_state->reference_objects[i++] = obj_surface;
1034
1035         assert(pic_param->ref_gf_frame != VA_INVALID_SURFACE);
1036         obj_surface = SURFACE(pic_param->ref_gf_frame);
1037         assert(obj_surface && obj_surface->bo);
1038
1039         if (!obj_surface || !obj_surface->bo)
1040             goto error;
1041
1042         encode_state->reference_objects[i++] = obj_surface;
1043
1044         assert(pic_param->ref_arf_frame != VA_INVALID_SURFACE);
1045         obj_surface = SURFACE(pic_param->ref_arf_frame);
1046         assert(obj_surface && obj_surface->bo);
1047
1048         if (!obj_surface || !obj_surface->bo)
1049             goto error;
1050
1051         encode_state->reference_objects[i++] = obj_surface;
1052     }
1053
1054     for ( ; i < 16; i++)
1055         encode_state->reference_objects[i] = NULL;
1056
1057     encoder_context->is_new_sequence = (is_key_frame && seq_param);
1058
1059     if (encoder_context->is_new_sequence) {
1060         encoder_context->num_frames_in_sequence = 0;
1061         encoder_context->frame_width_in_pixel = seq_param->frame_width;
1062         encoder_context->frame_height_in_pixel = seq_param->frame_height;
1063     }
1064
1065     return VA_STATUS_SUCCESS;
1066
1067 error:
1068     return VA_STATUS_ERROR_INVALID_PARAMETER;
1069 }
1070
1071 static VAStatus
1072 intel_encoder_check_hevc_parameter(VADriverContextP ctx,
1073                                   struct encode_state *encode_state,
1074                                   struct intel_encoder_context *encoder_context)
1075 {
1076     struct i965_driver_data *i965 = i965_driver_data(ctx);
1077     struct object_surface *obj_surface; 
1078     struct object_buffer *obj_buffer;
1079     VAEncPictureParameterBufferHEVC *pic_param = (VAEncPictureParameterBufferHEVC *)encode_state->pic_param_ext->buffer;
1080     VAEncSliceParameterBufferHEVC *slice_param;
1081     VAEncSequenceParameterBufferHEVC *seq_param;
1082     int i;
1083
1084     seq_param = NULL;
1085
1086     if (encode_state->seq_param_ext &&
1087         encode_state->seq_param_ext->buffer)
1088         seq_param = (VAEncSequenceParameterBufferHEVC *)(encode_state->seq_param_ext->buffer);
1089
1090     assert(!(pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID));
1091
1092     if (pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID)
1093         goto error;
1094
1095     obj_surface = SURFACE(pic_param->decoded_curr_pic.picture_id);
1096     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
1097     
1098     if (!obj_surface)
1099         goto error;
1100
1101     encode_state->reconstructed_object = obj_surface;
1102     obj_buffer = BUFFER(pic_param->coded_buf);
1103     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
1104
1105     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1106         goto error;
1107
1108     if (encode_state->num_slice_params_ext > encoder_context->max_slice_or_seg_num )
1109         goto error;
1110
1111     encode_state->coded_buf_object = obj_buffer;
1112
1113     for (i = 0; i < 15; i++) {
1114         if (pic_param->reference_frames[i].flags & VA_PICTURE_HEVC_INVALID ||
1115             pic_param->reference_frames[i].picture_id == VA_INVALID_SURFACE)
1116             break;
1117         else {
1118             obj_surface = SURFACE(pic_param->reference_frames[i].picture_id);
1119             assert(obj_surface);
1120
1121             if (!obj_surface)
1122                 goto error;
1123
1124             if (obj_surface->bo)
1125                 encode_state->reference_objects[i] = obj_surface;
1126             else
1127                 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
1128         }
1129     }
1130
1131     for ( ; i < 15; i++)
1132         encode_state->reference_objects[i] = NULL;
1133
1134     for (i = 0; i < encode_state->num_slice_params_ext; i++) {
1135         slice_param = (VAEncSliceParameterBufferHEVC *)encode_state->slice_params_ext[i]->buffer;
1136
1137         if (slice_param->slice_type != HEVC_SLICE_I &&
1138             slice_param->slice_type != HEVC_SLICE_P &&
1139             slice_param->slice_type != HEVC_SLICE_B)
1140             goto error;
1141
1142         /* TODO: add more check here */
1143     }
1144
1145     encoder_context->is_new_sequence = (pic_param->pic_fields.bits.idr_pic_flag && seq_param);
1146
1147     return VA_STATUS_SUCCESS;
1148
1149 error:
1150     return VA_STATUS_ERROR_INVALID_PARAMETER;
1151 }
1152
1153 static VAStatus
1154 intel_encoder_check_vp9_parameter(VADriverContextP ctx,
1155                                   struct encode_state *encode_state,
1156                                   struct intel_encoder_context *encoder_context)
1157 {
1158     struct i965_driver_data *i965 = i965_driver_data(ctx);
1159     VAEncPictureParameterBufferVP9 *pic_param;
1160     VAEncSequenceParameterBufferVP9 *seq_param;
1161     struct object_surface *obj_surface;
1162     struct object_buffer *obj_buffer;
1163     int i = 0;
1164     int is_key_frame = 0;
1165     int index;
1166
1167     if (encode_state->pic_param_ext == NULL ||
1168         encode_state->pic_param_ext->buffer == NULL)
1169         return VA_STATUS_ERROR_INVALID_PARAMETER;
1170
1171     seq_param = NULL;
1172     if (encode_state->seq_param_ext &&
1173         encode_state->seq_param_ext->buffer)
1174         seq_param = (VAEncSequenceParameterBufferVP9 *)(encode_state->seq_param_ext->buffer);
1175
1176     pic_param = (VAEncPictureParameterBufferVP9 *)encode_state->pic_param_ext->buffer;
1177
1178     obj_surface = SURFACE(pic_param->reconstructed_frame);
1179
1180     if (!obj_surface)
1181         goto error;
1182
1183     encode_state->reconstructed_object = obj_surface;
1184     obj_buffer = BUFFER(pic_param->coded_buf);
1185
1186     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1187         goto error;
1188
1189     encode_state->coded_buf_object = obj_buffer;
1190
1191     is_key_frame = !pic_param->pic_flags.bits.frame_type;
1192     if (!is_key_frame && !pic_param->pic_flags.bits.intra_only) {
1193         /* slot 0 is for last reference frame */
1194         index = pic_param->ref_flags.bits.ref_last_idx;
1195         obj_surface = SURFACE(pic_param->reference_frames[index]);
1196         if (obj_surface && obj_surface->bo)
1197             encode_state->reference_objects[i++] = obj_surface;
1198         else
1199             encode_state->reference_objects[i++] = NULL;
1200
1201         /* slot 1 is for golden reference frame */
1202         index = pic_param->ref_flags.bits.ref_gf_idx;
1203         obj_surface = SURFACE(pic_param->reference_frames[index]);
1204         if (obj_surface && obj_surface->bo)
1205             encode_state->reference_objects[i++] = obj_surface;
1206         else
1207             encode_state->reference_objects[i++] = NULL;
1208
1209         /* slot 2 is alt reference frame */
1210         index = pic_param->ref_flags.bits.ref_arf_idx;
1211         obj_surface = SURFACE(pic_param->reference_frames[index]);
1212         if (obj_surface && obj_surface->bo)
1213             encode_state->reference_objects[i++] = obj_surface;
1214         else
1215             encode_state->reference_objects[i++] = NULL;
1216     }
1217
1218     for ( ; i < 16; i++)
1219         encode_state->reference_objects[i] = NULL;
1220
1221     encoder_context->is_new_sequence = (is_key_frame && seq_param);
1222
1223     return VA_STATUS_SUCCESS;
1224
1225 error:
1226     return VA_STATUS_ERROR_INVALID_PARAMETER;
1227 }
1228
1229
1230 static VAStatus
1231 intel_encoder_sanity_check_input(VADriverContextP ctx,
1232                                  VAProfile profile,
1233                                  struct encode_state *encode_state,
1234                                  struct intel_encoder_context *encoder_context)
1235 {
1236     VAStatus vaStatus;
1237
1238     switch (profile) {
1239     case VAProfileH264ConstrainedBaseline:
1240     case VAProfileH264Main:
1241     case VAProfileH264High:
1242     case VAProfileH264MultiviewHigh:
1243     case VAProfileH264StereoHigh: {
1244         vaStatus = intel_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
1245         if (vaStatus != VA_STATUS_SUCCESS)
1246             goto out;
1247         vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1248         break;
1249     }
1250
1251     case VAProfileMPEG2Simple:
1252     case VAProfileMPEG2Main: {
1253         vaStatus = intel_encoder_check_mpeg2_parameter(ctx, encode_state, encoder_context);
1254         if (vaStatus != VA_STATUS_SUCCESS)
1255             goto out;
1256         vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1257         break;
1258     }
1259
1260     case VAProfileJPEGBaseline:  {
1261         vaStatus = intel_encoder_check_jpeg_parameter(ctx, encode_state, encoder_context);
1262         if (vaStatus != VA_STATUS_SUCCESS)
1263             goto out;
1264         vaStatus = intel_encoder_check_jpeg_yuv_surface(ctx, profile, encode_state, encoder_context);
1265         break;
1266     }
1267  
1268     case VAProfileVP8Version0_3: {
1269         vaStatus = intel_encoder_check_vp8_parameter(ctx, encode_state, encoder_context);
1270          if (vaStatus != VA_STATUS_SUCCESS)
1271             goto out;
1272         vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1273         break;
1274     }
1275
1276     case VAProfileHEVCMain:
1277     case VAProfileHEVCMain10:  {
1278         vaStatus = intel_encoder_check_hevc_parameter(ctx, encode_state, encoder_context);
1279         if (vaStatus != VA_STATUS_SUCCESS)
1280             goto out;
1281         vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1282         break;
1283     }
1284
1285     case VAProfileVP9Profile0: {
1286         vaStatus = intel_encoder_check_vp9_parameter(ctx, encode_state, encoder_context);
1287         if (vaStatus != VA_STATUS_SUCCESS)
1288             goto out;
1289         vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1290         break;
1291     }
1292     default:
1293         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1294         break;
1295     }
1296
1297     if (vaStatus == VA_STATUS_SUCCESS)
1298         vaStatus = intel_encoder_check_misc_parameter(ctx, encode_state, encoder_context);
1299
1300 out:    
1301     return vaStatus;
1302 }
1303  
1304 static VAStatus
1305 intel_encoder_end_picture(VADriverContextP ctx, 
1306                           VAProfile profile, 
1307                           union codec_state *codec_state,
1308                           struct hw_context *hw_context)
1309 {
1310     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
1311     struct encode_state *encode_state = &codec_state->encode;
1312     VAStatus vaStatus;
1313
1314     vaStatus = intel_encoder_sanity_check_input(ctx, profile, encode_state, encoder_context);
1315
1316     if (vaStatus != VA_STATUS_SUCCESS)
1317         return vaStatus;
1318
1319     encoder_context->mfc_brc_prepare(encode_state, encoder_context);
1320
1321     if((encoder_context->vme_context && encoder_context->vme_pipeline)) {
1322         vaStatus = encoder_context->vme_pipeline(ctx, profile, encode_state, encoder_context);
1323         if (vaStatus != VA_STATUS_SUCCESS)
1324             return vaStatus;
1325     }
1326
1327     encoder_context->mfc_pipeline(ctx, profile, encode_state, encoder_context);
1328     encoder_context->num_frames_in_sequence++;
1329     encoder_context->brc.need_reset = 0;
1330     /*
1331      * ROI is only available for the current frame, see the comment
1332      * for VAEncROI in va.h
1333      */
1334     encoder_context->brc.num_roi = 0;
1335
1336     return VA_STATUS_SUCCESS;
1337 }
1338
1339 static void
1340 intel_encoder_context_destroy(void *hw_context)
1341 {
1342     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
1343
1344     encoder_context->mfc_context_destroy(encoder_context->mfc_context);
1345
1346     if (encoder_context->vme_context_destroy && encoder_context->vme_context)
1347        encoder_context->vme_context_destroy(encoder_context->vme_context);
1348
1349     if (encoder_context->enc_priv_state) {
1350         free(encoder_context->enc_priv_state);
1351         encoder_context->enc_priv_state = NULL;
1352     }
1353
1354     intel_batchbuffer_free(encoder_context->base.batch);
1355     free(encoder_context);
1356 }
1357
1358
1359 static VAStatus
1360 intel_encoder_get_status(VADriverContextP ctx, struct hw_context *hw_context, void *buffer)
1361 {
1362     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
1363     struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer;
1364
1365     if (encoder_context->get_status)
1366         return encoder_context->get_status(ctx, encoder_context, coded_buffer_segment);
1367
1368     return VA_STATUS_ERROR_UNIMPLEMENTED;
1369 }
1370
1371 typedef Bool (* hw_init_func)(VADriverContextP, struct intel_encoder_context *);
1372
1373 static struct hw_context *
1374 intel_enc_hw_context_init(VADriverContextP ctx,
1375                           struct object_config *obj_config,
1376                           hw_init_func vme_context_init,
1377                           hw_init_func mfc_context_init)
1378 {
1379     struct i965_driver_data *i965 = i965_driver_data(ctx);
1380     struct intel_driver_data *intel = intel_driver_data(ctx);
1381     struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
1382     int i;
1383
1384     assert(encoder_context);
1385     encoder_context->base.destroy = intel_encoder_context_destroy;
1386     encoder_context->base.run = intel_encoder_end_picture;
1387     encoder_context->base.get_status = intel_encoder_get_status;
1388     encoder_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
1389     encoder_context->input_yuv_surface = VA_INVALID_SURFACE;
1390     encoder_context->is_tmp_id = 0;
1391     encoder_context->low_power_mode = 0;
1392     encoder_context->rate_control_mode = VA_RC_NONE;
1393     encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
1394     encoder_context->quality_range = 1;
1395     encoder_context->layer.num_layers = 1;
1396     encoder_context->max_slice_or_seg_num = 1;
1397
1398     if (obj_config->entrypoint == VAEntrypointEncSliceLP)
1399         encoder_context->low_power_mode = 1;
1400
1401     switch (obj_config->profile) {
1402     case VAProfileMPEG2Simple:
1403     case VAProfileMPEG2Main:
1404         encoder_context->codec = CODEC_MPEG2;
1405         break;
1406         
1407     case VAProfileH264ConstrainedBaseline:
1408     case VAProfileH264Main:
1409     case VAProfileH264High:
1410         encoder_context->codec = CODEC_H264;
1411
1412         if (obj_config->entrypoint == VAEntrypointEncSliceLP)
1413             encoder_context->quality_range = ENCODER_LP_QUALITY_RANGE;
1414         else if(IS_GEN9(i965->intel.device_info)){
1415             encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
1416             encoder_context->quality_range = ENCODER_QUALITY_RANGE_AVC;
1417         }
1418         else
1419             encoder_context->quality_range = ENCODER_QUALITY_RANGE;
1420         break;
1421
1422     case VAProfileH264StereoHigh:
1423     case VAProfileH264MultiviewHigh:
1424         if(IS_GEN9(i965->intel.device_info)){
1425             encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
1426             encoder_context->quality_range = ENCODER_QUALITY_RANGE_AVC;
1427         }
1428         encoder_context->codec = CODEC_H264_MVC;
1429         break;
1430         
1431     case VAProfileJPEGBaseline:
1432         encoder_context->codec = CODEC_JPEG;
1433         break;
1434
1435     case VAProfileVP8Version0_3:
1436         encoder_context->codec = CODEC_VP8;
1437         encoder_context->quality_range = ENCODER_QUALITY_RANGE;
1438
1439         break;
1440
1441     case VAProfileHEVCMain:
1442     case VAProfileHEVCMain10:
1443         encoder_context->codec = CODEC_HEVC;
1444         break;
1445
1446     case VAProfileVP9Profile0:
1447         encoder_context->codec = CODEC_VP9;
1448         break;
1449
1450     default:
1451         /* Never get here */
1452         assert(0);
1453         break;
1454     }
1455
1456     for (i = 0; i < obj_config->num_attribs; i++) {
1457         if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) {
1458             encoder_context->rate_control_mode = obj_config->attrib_list[i].value;
1459
1460             if (encoder_context->codec == CODEC_MPEG2 &&
1461                 encoder_context->rate_control_mode & VA_RC_CBR) {
1462                 WARN_ONCE("Don't support CBR for MPEG-2 encoding\n");
1463                 encoder_context->rate_control_mode &= ~VA_RC_CBR;
1464             }
1465         }
1466         if (obj_config->attrib_list[i].type == VAConfigAttribEncROI) {
1467             if (encoder_context->codec == CODEC_H264)
1468                 encoder_context->context_roi = 1;
1469         }
1470         if (obj_config->attrib_list[i].type == VAConfigAttribEncMaxSlices) {
1471             if (encoder_context->codec == CODEC_H264 ||
1472                 encoder_context->codec == CODEC_HEVC)
1473                 encoder_context->max_slice_or_seg_num = obj_config->attrib_list[i].value;
1474         }
1475     }
1476
1477     if (vme_context_init) {
1478         vme_context_init(ctx, encoder_context);
1479         assert(!encoder_context->vme_context ||
1480                (encoder_context->vme_context_destroy && encoder_context->vme_pipeline));
1481     }
1482
1483     mfc_context_init(ctx, encoder_context);
1484     assert(encoder_context->mfc_context);
1485     assert(encoder_context->mfc_context_destroy);
1486     assert(encoder_context->mfc_pipeline);
1487
1488     return (struct hw_context *)encoder_context;
1489 }
1490
1491 struct hw_context *
1492 gen6_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1493 {
1494     return intel_enc_hw_context_init(ctx, obj_config, gen6_vme_context_init, gen6_mfc_context_init);
1495 }
1496
1497 struct hw_context *
1498 gen7_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1499 {
1500
1501     return intel_enc_hw_context_init(ctx, obj_config, gen7_vme_context_init, gen7_mfc_context_init);
1502 }
1503
1504 struct hw_context *
1505 gen75_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1506 {
1507     return intel_enc_hw_context_init(ctx, obj_config, gen75_vme_context_init, gen75_mfc_context_init);
1508 }
1509
1510 struct hw_context *
1511 gen8_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1512 {
1513     return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init);
1514 }
1515
1516 struct hw_context *
1517 gen9_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1518 {
1519     return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_mfc_context_init);
1520 }