OSDN Git Service

Encoding: ROI support for CQP/CBR on Haswell/Ivy
[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 #include "gen9_mfc.h"
43 #include "gen9_vdenc.h"
44
45 #include "gen9_vp9_encapi.h"
46
47 extern Bool gen6_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
48 extern Bool gen6_vme_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
49 extern Bool gen7_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
50 extern Bool gen9_hcpe_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
51
52 static VAStatus
53 clear_border(struct object_surface *obj_surface)
54 {
55     int width[3], height[3], hstride[3], vstride[3]; /* in byte */
56     int planes;
57     unsigned char* p;
58     int i,j;
59
60     if (obj_surface->border_cleared)
61         return VA_STATUS_SUCCESS;
62
63     if (obj_surface->fourcc == VA_FOURCC_NV12) {
64         planes = 2;
65         width[0] = width[1] = obj_surface->orig_width;
66         height[0] = obj_surface->orig_height;
67         height[1] = obj_surface->orig_height / 2;
68         hstride[0] = hstride[1] = obj_surface->width;
69         vstride[0]= obj_surface->height;
70         vstride[1] = obj_surface->height / 2;
71
72     } else {
73         /* todo add P010 */
74         return VA_STATUS_SUCCESS;
75     }
76     drm_intel_gem_bo_map_gtt(obj_surface->bo);
77
78     p = (unsigned char*)obj_surface->bo->virtual;
79     if (!p)
80         return VA_STATUS_ERROR_INVALID_SURFACE;
81
82     for (i = 0; i < planes; i++) {
83         int w = width[i];
84         int h = height[i];
85         int hs = hstride[i];
86         int vs = vstride[i];
87         /* right */
88         for (j = 0; j < h; j++) {
89             memset(p + w, 0, hs - w);
90             p += hs;
91         }
92         /* bottom */
93         for (/* nothing */; j < vs; j++) {
94             memset(p, 0, hs);
95             p += hs;
96         }
97
98     }
99     drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
100     obj_surface->border_cleared = true;
101     return VA_STATUS_SUCCESS;
102 }
103
104 static VAStatus
105 intel_encoder_check_yuv_surface(VADriverContextP ctx,
106                                 VAProfile profile,
107                                 struct encode_state *encode_state,
108                                 struct intel_encoder_context *encoder_context)
109 {
110     struct i965_driver_data *i965 = i965_driver_data(ctx);
111     struct i965_surface src_surface, dst_surface;
112     struct object_surface *obj_surface;
113     VAStatus status;
114     VARectangle rect;
115
116     /* releae the temporary surface */
117     if (encoder_context->is_tmp_id) {
118         i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
119         encode_state->input_yuv_object = NULL;
120     }
121
122     encoder_context->is_tmp_id = 0;
123     obj_surface = SURFACE(encode_state->current_render_target);
124     assert(obj_surface && obj_surface->bo);
125
126     if (!obj_surface || !obj_surface->bo)
127         return VA_STATUS_ERROR_INVALID_PARAMETER;
128
129     if (obj_surface->fourcc == VA_FOURCC_NV12) {
130         unsigned int tiling = 0, swizzle = 0;
131
132         dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
133
134         if (tiling == I915_TILING_Y) {
135             encoder_context->input_yuv_surface = encode_state->current_render_target;
136             encode_state->input_yuv_object = obj_surface;
137             return clear_border(obj_surface);
138         }
139     }
140
141     rect.x = 0;
142     rect.y = 0;
143     rect.width = obj_surface->orig_width;
144     rect.height = obj_surface->orig_height;
145     
146     src_surface.base = (struct object_base *)obj_surface;
147     src_surface.type = I965_SURFACE_TYPE_SURFACE;
148     src_surface.flags = I965_SURFACE_FLAG_FRAME;
149     
150     status = i965_CreateSurfaces(ctx,
151                                  obj_surface->orig_width,
152                                  obj_surface->orig_height,
153                                  VA_RT_FORMAT_YUV420,
154                                  1,
155                                  &encoder_context->input_yuv_surface);
156     assert(status == VA_STATUS_SUCCESS);
157
158     if (status != VA_STATUS_SUCCESS)
159         return status;
160
161     obj_surface = SURFACE(encoder_context->input_yuv_surface);
162     encode_state->input_yuv_object = obj_surface;
163     assert(obj_surface);
164     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
165     
166     dst_surface.base = (struct object_base *)obj_surface;
167     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
168     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
169
170     status = i965_image_processing(ctx,
171                                    &src_surface,
172                                    &rect,
173                                    &dst_surface,
174                                    &rect);
175     assert(status == VA_STATUS_SUCCESS);
176
177     encoder_context->is_tmp_id = 1;
178
179     return clear_border(obj_surface);
180 }
181
182
183 static VAStatus
184 intel_encoder_check_jpeg_yuv_surface(VADriverContextP ctx,
185                                 VAProfile profile,
186                                 struct encode_state *encode_state,
187                                 struct intel_encoder_context *encoder_context)
188 {
189     struct i965_driver_data *i965 = i965_driver_data(ctx);
190     struct i965_surface src_surface, dst_surface;
191     struct object_surface *obj_surface;
192     VAStatus status;
193     VARectangle rect;
194     int format=0, fourcc=0, subsample=0;
195
196     /* releae the temporary surface */
197     if (encoder_context->is_tmp_id) {
198         i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
199         encode_state->input_yuv_object = NULL;
200     }
201
202     encoder_context->is_tmp_id = 0;
203     obj_surface = SURFACE(encode_state->current_render_target);
204     assert(obj_surface && obj_surface->bo);
205
206     if (!obj_surface || !obj_surface->bo)
207         return VA_STATUS_ERROR_INVALID_PARAMETER;
208
209     unsigned int tiling = 0, swizzle = 0;
210
211     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
212
213     if (tiling == I915_TILING_Y) {
214         if( (obj_surface->fourcc==VA_FOURCC_NV12)  || (obj_surface->fourcc==VA_FOURCC_UYVY) ||
215             (obj_surface->fourcc==VA_FOURCC_YUY2)  || (obj_surface->fourcc==VA_FOURCC_Y800) ||
216             (obj_surface->fourcc==VA_FOURCC_RGBA)  || (obj_surface->fourcc==VA_FOURCC_444P) ) {
217             encoder_context->input_yuv_surface = encode_state->current_render_target;
218             encode_state->input_yuv_object = obj_surface;
219             return VA_STATUS_SUCCESS;
220         }
221     }
222
223     rect.x = 0;
224     rect.y = 0;
225     rect.width = obj_surface->orig_width;
226     rect.height = obj_surface->orig_height;
227
228     src_surface.base = (struct object_base *)obj_surface;
229     src_surface.type = I965_SURFACE_TYPE_SURFACE;
230     src_surface.flags = I965_SURFACE_FLAG_FRAME;
231
232     switch( obj_surface->fourcc) {
233
234         case VA_FOURCC_YUY2:
235             fourcc = VA_FOURCC_YUY2;
236             format = VA_RT_FORMAT_YUV422;
237             subsample = SUBSAMPLE_YUV422H;
238             break;
239
240         case VA_FOURCC_UYVY:
241             fourcc = VA_FOURCC_UYVY;
242             format = VA_RT_FORMAT_YUV422;
243             subsample = SUBSAMPLE_YUV422H;
244             break;
245
246         case VA_FOURCC_Y800:
247             fourcc = VA_FOURCC_Y800;
248             format = VA_RT_FORMAT_YUV400;
249             subsample = SUBSAMPLE_YUV400;
250             break;
251
252         case VA_FOURCC_444P:
253             fourcc = VA_FOURCC_444P;
254             format = VA_RT_FORMAT_YUV444;
255             subsample = SUBSAMPLE_YUV444;
256             break;
257
258         case VA_FOURCC_RGBA:
259             fourcc = VA_FOURCC_RGBA;
260             format = VA_RT_FORMAT_RGB32;
261             subsample = SUBSAMPLE_RGBX;
262             break;
263
264         default: //All other scenarios will have NV12 format
265             fourcc = VA_FOURCC_NV12;
266             format = VA_RT_FORMAT_YUV420;
267             subsample = SUBSAMPLE_YUV420;
268             break;
269     }
270
271     status = i965_CreateSurfaces(ctx,
272                                  obj_surface->orig_width,
273                                  obj_surface->orig_height,
274                                  format,
275                                  1,
276                                  &encoder_context->input_yuv_surface);
277     assert(status == VA_STATUS_SUCCESS);
278
279     if (status != VA_STATUS_SUCCESS)
280         return status;
281
282     obj_surface = SURFACE(encoder_context->input_yuv_surface);
283     encode_state->input_yuv_object = obj_surface;
284     assert(obj_surface);
285     i965_check_alloc_surface_bo(ctx, obj_surface, 1, fourcc, subsample);
286
287     dst_surface.base = (struct object_base *)obj_surface;
288     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
289     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
290
291     //The Y800 format is expected to be tiled.
292     //Linear Y800 is a corner case and needs code in the i965_image_processing.
293     if(obj_surface->fourcc != VA_FOURCC_Y800){
294         status = i965_image_processing(ctx,
295                                    &src_surface,
296                                    &rect,
297                                    &dst_surface,
298                                    &rect);
299         assert(status == VA_STATUS_SUCCESS);
300     }
301
302     encoder_context->is_tmp_id = 1;
303
304     return VA_STATUS_SUCCESS;
305 }
306
307 static VAStatus
308 intel_encoder_check_misc_parameter(VADriverContextP ctx,
309                                   struct encode_state *encode_state,
310                                   struct intel_encoder_context *encoder_context)
311 {
312
313     if (encode_state->misc_param[VAEncMiscParameterTypeQualityLevel] &&
314         encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]->buffer) {
315         VAEncMiscParameterBuffer* pMiscParam = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]->buffer;
316         VAEncMiscParameterBufferQualityLevel* param_quality_level = (VAEncMiscParameterBufferQualityLevel*)pMiscParam->data;
317         encoder_context->quality_level = param_quality_level->quality_level;
318
319         if (encoder_context->quality_level == 0)
320             encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
321         else if (encoder_context->quality_level > encoder_context->quality_range)
322             goto error;
323    }
324
325     return VA_STATUS_SUCCESS;
326
327 error:
328     return VA_STATUS_ERROR_INVALID_PARAMETER;
329 }
330
331 static VAStatus
332 intel_encoder_check_avc_parameter(VADriverContextP ctx,
333                                   struct encode_state *encode_state,
334                                   struct intel_encoder_context *encoder_context)
335 {
336     struct i965_driver_data *i965 = i965_driver_data(ctx);
337     struct object_surface *obj_surface; 
338     struct object_buffer *obj_buffer;
339     VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
340     int i;
341
342     assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
343
344     if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID)
345         goto error;
346
347     obj_surface = SURFACE(pic_param->CurrPic.picture_id);
348     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
349     
350     if (!obj_surface)
351         goto error;
352
353     encode_state->reconstructed_object = obj_surface;
354     obj_buffer = BUFFER(pic_param->coded_buf);
355     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
356
357     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
358         goto error;
359
360     encode_state->coded_buf_object = obj_buffer;
361
362     for (i = 0; i < 16; i++) {
363         if (pic_param->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID ||
364             pic_param->ReferenceFrames[i].picture_id == VA_INVALID_SURFACE)
365             break;
366         else {
367             obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id);
368             assert(obj_surface);
369
370             if (!obj_surface)
371                 goto error;
372
373             if (obj_surface->bo)
374                 encode_state->reference_objects[i] = obj_surface;
375             else
376                 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
377         }
378     }
379
380     for ( ; i < 16; i++)
381         encode_state->reference_objects[i] = NULL;
382     
383     return VA_STATUS_SUCCESS;
384
385 error:
386     return VA_STATUS_ERROR_INVALID_PARAMETER;
387 }
388
389 static VAStatus
390 intel_encoder_check_mpeg2_parameter(VADriverContextP ctx,
391                                     struct encode_state *encode_state,
392                                     struct intel_encoder_context *encoder_context)
393 {
394     struct i965_driver_data *i965 = i965_driver_data(ctx);
395     VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
396     struct object_surface *obj_surface; 
397     struct object_buffer *obj_buffer;
398     int i = 0;
399     
400     obj_surface = SURFACE(pic_param->reconstructed_picture);
401     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
402     
403     if (!obj_surface)
404         goto error;
405     
406     encode_state->reconstructed_object = obj_surface;    
407     obj_buffer = BUFFER(pic_param->coded_buf);
408     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
409
410     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
411         goto error;
412
413     encode_state->coded_buf_object = obj_buffer;
414
415     if (pic_param->picture_type == VAEncPictureTypeIntra) {
416     } else if (pic_param->picture_type == VAEncPictureTypePredictive) {
417         assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
418         obj_surface = SURFACE(pic_param->forward_reference_picture);
419         assert(obj_surface && obj_surface->bo);
420
421         if (!obj_surface || !obj_surface->bo)
422             goto error;
423
424         encode_state->reference_objects[i++] = obj_surface;
425     } else if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
426         assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
427         obj_surface = SURFACE(pic_param->forward_reference_picture);
428         assert(obj_surface && obj_surface->bo);
429
430         if (!obj_surface || !obj_surface->bo)
431             goto error;
432
433         encode_state->reference_objects[i++] = obj_surface;
434
435         assert(pic_param->backward_reference_picture != VA_INVALID_SURFACE);
436         obj_surface = SURFACE(pic_param->backward_reference_picture);
437         assert(obj_surface && obj_surface->bo);
438
439         if (!obj_surface || !obj_surface->bo)
440             goto error;
441
442         encode_state->reference_objects[i++] = obj_surface;
443     } else 
444         goto error;
445
446     for ( ; i < 16; i++)
447         encode_state->reference_objects[i] = NULL;
448
449     return VA_STATUS_SUCCESS;
450
451 error:
452     return VA_STATUS_ERROR_INVALID_PARAMETER;
453 }
454
455 static VAStatus
456 intel_encoder_check_jpeg_parameter(VADriverContextP ctx,
457                                   struct encode_state *encode_state,
458                                   struct intel_encoder_context *encoder_context)
459 {
460     struct i965_driver_data *i965 = i965_driver_data(ctx);
461     struct object_buffer *obj_buffer;
462     VAEncPictureParameterBufferJPEG *pic_param = (VAEncPictureParameterBufferJPEG *)encode_state->pic_param_ext->buffer;
463
464
465     assert(!(pic_param->pic_flags.bits.profile)); //Baseline profile is 0.
466
467     obj_buffer = BUFFER(pic_param->coded_buf);
468     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
469
470     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
471         goto error;
472
473     encode_state->coded_buf_object = obj_buffer;
474
475     return VA_STATUS_SUCCESS;
476
477 error:
478     return VA_STATUS_ERROR_INVALID_PARAMETER;
479 }
480
481 static VAStatus
482 intel_encoder_check_vp8_parameter(VADriverContextP ctx,
483                                     struct encode_state *encode_state,
484                                     struct intel_encoder_context *encoder_context)
485 {
486     struct i965_driver_data *i965 = i965_driver_data(ctx);
487     VAEncPictureParameterBufferVP8 *pic_param = (VAEncPictureParameterBufferVP8 *)encode_state->pic_param_ext->buffer;
488     struct object_surface *obj_surface;
489     struct object_buffer *obj_buffer;
490     int i = 0;
491     int is_key_frame = !pic_param->pic_flags.bits.frame_type;
492  
493     obj_surface = SURFACE(pic_param->reconstructed_frame);
494     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
495     
496     if (!obj_surface)
497         goto error;
498     
499     encode_state->reconstructed_object = obj_surface;    
500     obj_buffer = BUFFER(pic_param->coded_buf);
501     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
502
503     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
504         goto error;
505
506     encode_state->coded_buf_object = obj_buffer;
507
508     if (!is_key_frame) {
509         assert(pic_param->ref_last_frame != VA_INVALID_SURFACE);
510         obj_surface = SURFACE(pic_param->ref_last_frame);
511         assert(obj_surface && obj_surface->bo);
512
513         if (!obj_surface || !obj_surface->bo)
514             goto error;
515
516         encode_state->reference_objects[i++] = obj_surface;
517
518         assert(pic_param->ref_gf_frame != VA_INVALID_SURFACE);
519         obj_surface = SURFACE(pic_param->ref_gf_frame);
520         assert(obj_surface && obj_surface->bo);
521
522         if (!obj_surface || !obj_surface->bo)
523             goto error;
524
525         encode_state->reference_objects[i++] = obj_surface;
526
527         assert(pic_param->ref_arf_frame != VA_INVALID_SURFACE);
528         obj_surface = SURFACE(pic_param->ref_arf_frame);
529         assert(obj_surface && obj_surface->bo);
530
531         if (!obj_surface || !obj_surface->bo)
532             goto error;
533
534         encode_state->reference_objects[i++] = obj_surface;
535     }
536
537     for ( ; i < 16; i++)
538         encode_state->reference_objects[i] = NULL;
539
540     return VA_STATUS_SUCCESS;
541
542 error:
543     return VA_STATUS_ERROR_INVALID_PARAMETER;
544 }
545
546 static VAStatus
547 intel_encoder_check_hevc_parameter(VADriverContextP ctx,
548                                   struct encode_state *encode_state,
549                                   struct intel_encoder_context *encoder_context)
550 {
551     struct i965_driver_data *i965 = i965_driver_data(ctx);
552     struct object_surface *obj_surface; 
553     struct object_buffer *obj_buffer;
554     VAEncPictureParameterBufferHEVC *pic_param = (VAEncPictureParameterBufferHEVC *)encode_state->pic_param_ext->buffer;
555     VAEncSliceParameterBufferHEVC *slice_param;
556     int i;
557
558     assert(!(pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID));
559
560     if (pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID)
561         goto error;
562
563     obj_surface = SURFACE(pic_param->decoded_curr_pic.picture_id);
564     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
565     
566     if (!obj_surface)
567         goto error;
568
569     encode_state->reconstructed_object = obj_surface;
570     obj_buffer = BUFFER(pic_param->coded_buf);
571     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
572
573     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
574         goto error;
575
576     encode_state->coded_buf_object = obj_buffer;
577
578     for (i = 0; i < 15; i++) {
579         if (pic_param->reference_frames[i].flags & VA_PICTURE_HEVC_INVALID ||
580             pic_param->reference_frames[i].picture_id == VA_INVALID_SURFACE)
581             break;
582         else {
583             obj_surface = SURFACE(pic_param->reference_frames[i].picture_id);
584             assert(obj_surface);
585
586             if (!obj_surface)
587                 goto error;
588
589             if (obj_surface->bo)
590                 encode_state->reference_objects[i] = obj_surface;
591             else
592                 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
593         }
594     }
595
596     for ( ; i < 15; i++)
597         encode_state->reference_objects[i] = NULL;
598
599     for (i = 0; i < encode_state->num_slice_params_ext; i++) {
600         slice_param = (VAEncSliceParameterBufferHEVC *)encode_state->slice_params_ext[i]->buffer;
601
602         if (slice_param->slice_type != HEVC_SLICE_I &&
603             slice_param->slice_type != HEVC_SLICE_P &&
604             slice_param->slice_type != HEVC_SLICE_B)
605             goto error;
606
607         /* TODO: add more check here */
608     }
609
610     return VA_STATUS_SUCCESS;
611
612 error:
613     return VA_STATUS_ERROR_INVALID_PARAMETER;
614 }
615
616 static VAStatus
617 intel_encoder_check_vp9_parameter(VADriverContextP ctx,
618                                   struct encode_state *encode_state,
619                                   struct intel_encoder_context *encoder_context)
620 {
621     struct i965_driver_data *i965 = i965_driver_data(ctx);
622     VAEncPictureParameterBufferVP9 *pic_param;
623     struct object_surface *obj_surface;
624     struct object_buffer *obj_buffer;
625     int i = 0;
626     int is_key_frame = 0;
627     int index;
628
629     if (encode_state->pic_param_ext == NULL ||
630         encode_state->pic_param_ext->buffer == NULL)
631         return VA_STATUS_ERROR_INVALID_PARAMETER;
632
633     pic_param = (VAEncPictureParameterBufferVP9 *)encode_state->pic_param_ext->buffer;
634
635     obj_surface = SURFACE(pic_param->reconstructed_frame);
636
637     if (!obj_surface)
638         goto error;
639
640     encode_state->reconstructed_object = obj_surface;
641     obj_buffer = BUFFER(pic_param->coded_buf);
642
643     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
644         goto error;
645
646     encode_state->coded_buf_object = obj_buffer;
647
648     is_key_frame = !pic_param->pic_flags.bits.frame_type;
649     if (!is_key_frame && !pic_param->pic_flags.bits.intra_only) {
650         /* slot 0 is for last reference frame */
651         index = pic_param->ref_flags.bits.ref_last_idx;
652         obj_surface = SURFACE(pic_param->reference_frames[index]);
653         if (obj_surface && obj_surface->bo)
654             encode_state->reference_objects[i++] = obj_surface;
655         else
656             encode_state->reference_objects[i++] = NULL;
657
658         /* slot 1 is for golden reference frame */
659         index = pic_param->ref_flags.bits.ref_gf_idx;
660         obj_surface = SURFACE(pic_param->reference_frames[index]);
661         if (obj_surface && obj_surface->bo)
662             encode_state->reference_objects[i++] = obj_surface;
663         else
664             encode_state->reference_objects[i++] = NULL;
665
666         /* slot 2 is alt reference frame */
667         index = pic_param->ref_flags.bits.ref_arf_idx;
668         obj_surface = SURFACE(pic_param->reference_frames[index]);
669         if (obj_surface && obj_surface->bo)
670             encode_state->reference_objects[i++] = obj_surface;
671         else
672             encode_state->reference_objects[i++] = NULL;
673     }
674
675     for ( ; i < 16; i++)
676         encode_state->reference_objects[i] = NULL;
677
678     return VA_STATUS_SUCCESS;
679
680 error:
681     return VA_STATUS_ERROR_INVALID_PARAMETER;
682 }
683
684
685 static VAStatus
686 intel_encoder_sanity_check_input(VADriverContextP ctx,
687                                  VAProfile profile,
688                                  struct encode_state *encode_state,
689                                  struct intel_encoder_context *encoder_context)
690 {
691     VAStatus vaStatus;
692
693     switch (profile) {
694     case VAProfileH264ConstrainedBaseline:
695     case VAProfileH264Main:
696     case VAProfileH264High:
697     case VAProfileH264MultiviewHigh:
698     case VAProfileH264StereoHigh: {
699         vaStatus = intel_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
700         if (vaStatus != VA_STATUS_SUCCESS)
701             goto out;
702         vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
703         break;
704     }
705
706     case VAProfileMPEG2Simple:
707     case VAProfileMPEG2Main: {
708         vaStatus = intel_encoder_check_mpeg2_parameter(ctx, encode_state, encoder_context);
709         if (vaStatus != VA_STATUS_SUCCESS)
710             goto out;
711         vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
712         break;
713     }
714
715     case VAProfileJPEGBaseline:  {
716         vaStatus = intel_encoder_check_jpeg_parameter(ctx, encode_state, encoder_context);
717         if (vaStatus != VA_STATUS_SUCCESS)
718             goto out;
719         vaStatus = intel_encoder_check_jpeg_yuv_surface(ctx, profile, encode_state, encoder_context);
720         break;
721     }
722  
723     case VAProfileVP8Version0_3: {
724         vaStatus = intel_encoder_check_vp8_parameter(ctx, encode_state, encoder_context);
725          if (vaStatus != VA_STATUS_SUCCESS)
726             goto out;
727         vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
728         break;
729     }
730
731     case VAProfileHEVCMain:  {
732         vaStatus = intel_encoder_check_hevc_parameter(ctx, encode_state, encoder_context);
733         if (vaStatus != VA_STATUS_SUCCESS)
734             goto out;
735         vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
736         break;
737     }
738
739     case VAProfileVP9Profile0: {
740         vaStatus = intel_encoder_check_vp9_parameter(ctx, encode_state, encoder_context);
741         if (vaStatus != VA_STATUS_SUCCESS)
742             goto out;
743         break;
744     }
745     default:
746         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
747         break;
748     }
749
750     if (vaStatus == VA_STATUS_SUCCESS)
751         vaStatus = intel_encoder_check_misc_parameter(ctx, encode_state, encoder_context);
752
753 out:    
754     return vaStatus;
755 }
756  
757 static VAStatus
758 intel_encoder_end_picture(VADriverContextP ctx, 
759                           VAProfile profile, 
760                           union codec_state *codec_state,
761                           struct hw_context *hw_context)
762 {
763     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
764     struct encode_state *encode_state = &codec_state->encode;
765     VAStatus vaStatus;
766
767     vaStatus = intel_encoder_sanity_check_input(ctx, profile, encode_state, encoder_context);
768
769     if (vaStatus != VA_STATUS_SUCCESS)
770         return vaStatus;
771
772     encoder_context->mfc_brc_prepare(encode_state, encoder_context);
773
774     if((encoder_context->vme_context && encoder_context->vme_pipeline)) {
775         vaStatus = encoder_context->vme_pipeline(ctx, profile, encode_state, encoder_context);
776         if (vaStatus != VA_STATUS_SUCCESS)
777             return vaStatus;
778     }
779
780     encoder_context->mfc_pipeline(ctx, profile, encode_state, encoder_context);
781
782     return VA_STATUS_SUCCESS;
783 }
784
785 static void
786 intel_encoder_context_destroy(void *hw_context)
787 {
788     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
789
790     encoder_context->mfc_context_destroy(encoder_context->mfc_context);
791
792     if (encoder_context->vme_context_destroy && encoder_context->vme_context)
793        encoder_context->vme_context_destroy(encoder_context->vme_context);
794
795     if (encoder_context->enc_priv_state) {
796         free(encoder_context->enc_priv_state);
797         encoder_context->enc_priv_state = NULL;
798     }
799
800     intel_batchbuffer_free(encoder_context->base.batch);
801     free(encoder_context);
802 }
803
804
805 static VAStatus
806 intel_encoder_get_status(VADriverContextP ctx, struct hw_context *hw_context, void *buffer)
807 {
808     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
809     struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer;
810
811     if (encoder_context->get_status)
812         return encoder_context->get_status(ctx, encoder_context, coded_buffer_segment);
813
814     return VA_STATUS_ERROR_UNIMPLEMENTED;
815 }
816
817 typedef Bool (* hw_init_func)(VADriverContextP, struct intel_encoder_context *);
818
819 static struct hw_context *
820 intel_enc_hw_context_init(VADriverContextP ctx,
821                           struct object_config *obj_config,
822                           hw_init_func vme_context_init,
823                           hw_init_func mfc_context_init)
824 {
825     struct intel_driver_data *intel = intel_driver_data(ctx);
826     struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
827     int i;
828
829     assert(encoder_context);
830     encoder_context->base.destroy = intel_encoder_context_destroy;
831     encoder_context->base.run = intel_encoder_end_picture;
832     encoder_context->base.get_status = intel_encoder_get_status;
833     encoder_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
834     encoder_context->input_yuv_surface = VA_INVALID_SURFACE;
835     encoder_context->is_tmp_id = 0;
836     encoder_context->low_power_mode = 0;
837     encoder_context->rate_control_mode = VA_RC_NONE;
838     encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
839     encoder_context->quality_range = 1;
840
841     switch (obj_config->profile) {
842     case VAProfileMPEG2Simple:
843     case VAProfileMPEG2Main:
844         encoder_context->codec = CODEC_MPEG2;
845         break;
846         
847     case VAProfileH264ConstrainedBaseline:
848     case VAProfileH264Main:
849     case VAProfileH264High:
850         encoder_context->codec = CODEC_H264;
851
852         if (obj_config->entrypoint == VAEntrypointEncSliceLP)
853             encoder_context->quality_range = ENCODER_LP_QUALITY_RANGE;
854         else
855             encoder_context->quality_range = ENCODER_QUALITY_RANGE;
856         break;
857
858     case VAProfileH264StereoHigh:
859     case VAProfileH264MultiviewHigh:
860         encoder_context->codec = CODEC_H264_MVC;
861         break;
862         
863     case VAProfileJPEGBaseline:
864         encoder_context->codec = CODEC_JPEG;
865         break;
866
867     case VAProfileVP8Version0_3:
868         encoder_context->codec = CODEC_VP8;
869         break;
870
871     case VAProfileHEVCMain:
872         encoder_context->codec = CODEC_HEVC;
873         break;
874
875     case VAProfileVP9Profile0:
876         encoder_context->codec = CODEC_VP9;
877         break;
878
879     default:
880         /* Never get here */
881         assert(0);
882         break;
883     }
884
885     for (i = 0; i < obj_config->num_attribs; i++) {
886         if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) {
887             encoder_context->rate_control_mode = obj_config->attrib_list[i].value;
888
889             if (encoder_context->codec == CODEC_MPEG2 &&
890                 encoder_context->rate_control_mode & VA_RC_CBR) {
891                 WARN_ONCE("Don't support CBR for MPEG-2 encoding\n");
892                 encoder_context->rate_control_mode &= ~VA_RC_CBR;
893             }
894         }
895         if (obj_config->attrib_list[i].type == VAConfigAttribEncROI) {
896             if (encoder_context->codec == CODEC_H264)
897                 encoder_context->context_roi = 1;
898         }
899     }
900
901     if (vme_context_init) {
902         vme_context_init(ctx, encoder_context);
903
904         if (obj_config->profile != VAProfileJPEGBaseline) {
905             assert(encoder_context->vme_context);
906             assert(encoder_context->vme_context_destroy);
907             assert(encoder_context->vme_pipeline);
908         }
909     } else {
910         encoder_context->low_power_mode = 1;
911     }
912
913     mfc_context_init(ctx, encoder_context);
914     assert(encoder_context->mfc_context);
915     assert(encoder_context->mfc_context_destroy);
916     assert(encoder_context->mfc_pipeline);
917
918     return (struct hw_context *)encoder_context;
919 }
920
921 struct hw_context *
922 gen6_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
923 {
924     return intel_enc_hw_context_init(ctx, obj_config, gen6_vme_context_init, gen6_mfc_context_init);
925 }
926
927 struct hw_context *
928 gen7_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
929 {
930
931     return intel_enc_hw_context_init(ctx, obj_config, gen7_vme_context_init, gen7_mfc_context_init);
932 }
933
934 struct hw_context *
935 gen75_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
936 {
937     return intel_enc_hw_context_init(ctx, obj_config, gen75_vme_context_init, gen75_mfc_context_init);
938 }
939
940 struct hw_context *
941 gen8_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
942 {
943     return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init);
944 }
945
946 struct hw_context *
947 gen9_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
948 {
949     if (obj_config->entrypoint == VAEntrypointEncSliceLP) {
950         return intel_enc_hw_context_init(ctx, obj_config, NULL, gen9_vdenc_context_init);
951     } else {
952         if (obj_config->profile == VAProfileHEVCMain) {
953             return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_hcpe_context_init);
954         } else if (obj_config->profile == VAProfileJPEGBaseline)
955             return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init);
956         else if (obj_config->profile == VAProfileVP9Profile0)
957             return intel_enc_hw_context_init(ctx, obj_config,
958                                              gen9_vp9_vme_context_init,
959                                              gen9_vp9_pak_context_init);
960         else
961             return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_mfc_context_init);
962     }
963 }