OSDN Git Service

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