2 * Copyright © 2010 Intel Corporation
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
25 * Zhou Chang <chang.zhou@intel.com>
34 #include "intel_batchbuffer.h"
35 #include "intel_driver.h"
37 #include "i965_defines.h"
38 #include "i965_drv_video.h"
39 #include "i965_encoder.h"
43 #include "gen9_vdenc.h"
45 #include "gen9_vp9_encapi.h"
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);
53 clear_border(struct object_surface *obj_surface)
55 int width[3], height[3], hstride[3], vstride[3]; /* in byte */
60 if (obj_surface->border_cleared)
61 return VA_STATUS_SUCCESS;
63 if (obj_surface->fourcc == VA_FOURCC_NV12) {
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;
74 return VA_STATUS_SUCCESS;
76 drm_intel_gem_bo_map_gtt(obj_surface->bo);
78 p = (unsigned char*)obj_surface->bo->virtual;
80 return VA_STATUS_ERROR_INVALID_SURFACE;
82 for (i = 0; i < planes; i++) {
88 for (j = 0; j < h; j++) {
89 memset(p + w, 0, hs - w);
93 for (/* nothing */; j < vs; j++) {
99 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
100 obj_surface->border_cleared = true;
101 return VA_STATUS_SUCCESS;
105 intel_encoder_check_yuv_surface(VADriverContextP ctx,
107 struct encode_state *encode_state,
108 struct intel_encoder_context *encoder_context)
110 struct i965_driver_data *i965 = i965_driver_data(ctx);
111 struct i965_surface src_surface, dst_surface;
112 struct object_surface *obj_surface;
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;
122 encoder_context->is_tmp_id = 0;
123 obj_surface = SURFACE(encode_state->current_render_target);
124 assert(obj_surface && obj_surface->bo);
126 if (!obj_surface || !obj_surface->bo)
127 return VA_STATUS_ERROR_INVALID_PARAMETER;
129 if (obj_surface->fourcc == VA_FOURCC_NV12) {
130 unsigned int tiling = 0, swizzle = 0;
132 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
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);
143 rect.width = obj_surface->orig_width;
144 rect.height = obj_surface->orig_height;
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;
150 status = i965_CreateSurfaces(ctx,
151 obj_surface->orig_width,
152 obj_surface->orig_height,
155 &encoder_context->input_yuv_surface);
156 assert(status == VA_STATUS_SUCCESS);
158 if (status != VA_STATUS_SUCCESS)
161 obj_surface = SURFACE(encoder_context->input_yuv_surface);
162 encode_state->input_yuv_object = obj_surface;
164 i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
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;
170 status = i965_image_processing(ctx,
175 assert(status == VA_STATUS_SUCCESS);
177 encoder_context->is_tmp_id = 1;
179 return clear_border(obj_surface);
184 intel_encoder_check_jpeg_yuv_surface(VADriverContextP ctx,
186 struct encode_state *encode_state,
187 struct intel_encoder_context *encoder_context)
189 struct i965_driver_data *i965 = i965_driver_data(ctx);
190 struct i965_surface src_surface, dst_surface;
191 struct object_surface *obj_surface;
194 int format=0, fourcc=0, subsample=0;
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;
202 encoder_context->is_tmp_id = 0;
203 obj_surface = SURFACE(encode_state->current_render_target);
204 assert(obj_surface && obj_surface->bo);
206 if (!obj_surface || !obj_surface->bo)
207 return VA_STATUS_ERROR_INVALID_PARAMETER;
209 unsigned int tiling = 0, swizzle = 0;
211 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
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;
225 rect.width = obj_surface->orig_width;
226 rect.height = obj_surface->orig_height;
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;
232 switch( obj_surface->fourcc) {
235 fourcc = VA_FOURCC_YUY2;
236 format = VA_RT_FORMAT_YUV422;
237 subsample = SUBSAMPLE_YUV422H;
241 fourcc = VA_FOURCC_UYVY;
242 format = VA_RT_FORMAT_YUV422;
243 subsample = SUBSAMPLE_YUV422H;
247 fourcc = VA_FOURCC_Y800;
248 format = VA_RT_FORMAT_YUV400;
249 subsample = SUBSAMPLE_YUV400;
253 fourcc = VA_FOURCC_444P;
254 format = VA_RT_FORMAT_YUV444;
255 subsample = SUBSAMPLE_YUV444;
259 fourcc = VA_FOURCC_RGBA;
260 format = VA_RT_FORMAT_RGB32;
261 subsample = SUBSAMPLE_RGBX;
264 default: //All other scenarios will have NV12 format
265 fourcc = VA_FOURCC_NV12;
266 format = VA_RT_FORMAT_YUV420;
267 subsample = SUBSAMPLE_YUV420;
271 status = i965_CreateSurfaces(ctx,
272 obj_surface->orig_width,
273 obj_surface->orig_height,
276 &encoder_context->input_yuv_surface);
277 assert(status == VA_STATUS_SUCCESS);
279 if (status != VA_STATUS_SUCCESS)
282 obj_surface = SURFACE(encoder_context->input_yuv_surface);
283 encode_state->input_yuv_object = obj_surface;
285 i965_check_alloc_surface_bo(ctx, obj_surface, 1, fourcc, subsample);
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;
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,
299 assert(status == VA_STATUS_SUCCESS);
302 encoder_context->is_tmp_id = 1;
304 return VA_STATUS_SUCCESS;
308 intel_encoder_check_misc_parameter(VADriverContextP ctx,
309 struct encode_state *encode_state,
310 struct intel_encoder_context *encoder_context)
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;
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)
325 return VA_STATUS_SUCCESS;
328 return VA_STATUS_ERROR_INVALID_PARAMETER;
332 intel_encoder_check_avc_parameter(VADriverContextP ctx,
333 struct encode_state *encode_state,
334 struct intel_encoder_context *encoder_context)
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;
342 assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
344 if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID)
347 obj_surface = SURFACE(pic_param->CurrPic.picture_id);
348 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
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);
357 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
360 encode_state->coded_buf_object = obj_buffer;
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)
367 obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id);
374 encode_state->reference_objects[i] = obj_surface;
376 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
381 encode_state->reference_objects[i] = NULL;
383 return VA_STATUS_SUCCESS;
386 return VA_STATUS_ERROR_INVALID_PARAMETER;
390 intel_encoder_check_mpeg2_parameter(VADriverContextP ctx,
391 struct encode_state *encode_state,
392 struct intel_encoder_context *encoder_context)
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;
400 obj_surface = SURFACE(pic_param->reconstructed_picture);
401 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
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);
410 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
413 encode_state->coded_buf_object = obj_buffer;
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);
421 if (!obj_surface || !obj_surface->bo)
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);
430 if (!obj_surface || !obj_surface->bo)
433 encode_state->reference_objects[i++] = obj_surface;
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);
439 if (!obj_surface || !obj_surface->bo)
442 encode_state->reference_objects[i++] = obj_surface;
447 encode_state->reference_objects[i] = NULL;
449 return VA_STATUS_SUCCESS;
452 return VA_STATUS_ERROR_INVALID_PARAMETER;
456 intel_encoder_check_jpeg_parameter(VADriverContextP ctx,
457 struct encode_state *encode_state,
458 struct intel_encoder_context *encoder_context)
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;
465 assert(!(pic_param->pic_flags.bits.profile)); //Baseline profile is 0.
467 obj_buffer = BUFFER(pic_param->coded_buf);
468 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
470 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
473 encode_state->coded_buf_object = obj_buffer;
475 return VA_STATUS_SUCCESS;
478 return VA_STATUS_ERROR_INVALID_PARAMETER;
482 intel_encoder_check_vp8_parameter(VADriverContextP ctx,
483 struct encode_state *encode_state,
484 struct intel_encoder_context *encoder_context)
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;
491 int is_key_frame = !pic_param->pic_flags.bits.frame_type;
493 obj_surface = SURFACE(pic_param->reconstructed_frame);
494 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
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);
503 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
506 encode_state->coded_buf_object = obj_buffer;
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);
513 if (!obj_surface || !obj_surface->bo)
516 encode_state->reference_objects[i++] = obj_surface;
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);
522 if (!obj_surface || !obj_surface->bo)
525 encode_state->reference_objects[i++] = obj_surface;
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);
531 if (!obj_surface || !obj_surface->bo)
534 encode_state->reference_objects[i++] = obj_surface;
538 encode_state->reference_objects[i] = NULL;
540 return VA_STATUS_SUCCESS;
543 return VA_STATUS_ERROR_INVALID_PARAMETER;
547 intel_encoder_check_hevc_parameter(VADriverContextP ctx,
548 struct encode_state *encode_state,
549 struct intel_encoder_context *encoder_context)
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;
558 assert(!(pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID));
560 if (pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID)
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 */
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);
573 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
576 encode_state->coded_buf_object = obj_buffer;
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)
583 obj_surface = SURFACE(pic_param->reference_frames[i].picture_id);
590 encode_state->reference_objects[i] = obj_surface;
592 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
597 encode_state->reference_objects[i] = NULL;
599 for (i = 0; i < encode_state->num_slice_params_ext; i++) {
600 slice_param = (VAEncSliceParameterBufferHEVC *)encode_state->slice_params_ext[i]->buffer;
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)
607 /* TODO: add more check here */
610 return VA_STATUS_SUCCESS;
613 return VA_STATUS_ERROR_INVALID_PARAMETER;
617 intel_encoder_check_vp9_parameter(VADriverContextP ctx,
618 struct encode_state *encode_state,
619 struct intel_encoder_context *encoder_context)
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;
626 int is_key_frame = 0;
629 if (encode_state->pic_param_ext == NULL ||
630 encode_state->pic_param_ext->buffer == NULL)
631 return VA_STATUS_ERROR_INVALID_PARAMETER;
633 pic_param = (VAEncPictureParameterBufferVP9 *)encode_state->pic_param_ext->buffer;
635 obj_surface = SURFACE(pic_param->reconstructed_frame);
640 encode_state->reconstructed_object = obj_surface;
641 obj_buffer = BUFFER(pic_param->coded_buf);
643 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
646 encode_state->coded_buf_object = obj_buffer;
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;
656 encode_state->reference_objects[i++] = NULL;
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;
664 encode_state->reference_objects[i++] = NULL;
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;
672 encode_state->reference_objects[i++] = NULL;
676 encode_state->reference_objects[i] = NULL;
678 return VA_STATUS_SUCCESS;
681 return VA_STATUS_ERROR_INVALID_PARAMETER;
686 intel_encoder_sanity_check_input(VADriverContextP ctx,
688 struct encode_state *encode_state,
689 struct intel_encoder_context *encoder_context)
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)
702 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
706 case VAProfileMPEG2Simple:
707 case VAProfileMPEG2Main: {
708 vaStatus = intel_encoder_check_mpeg2_parameter(ctx, encode_state, encoder_context);
709 if (vaStatus != VA_STATUS_SUCCESS)
711 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
715 case VAProfileJPEGBaseline: {
716 vaStatus = intel_encoder_check_jpeg_parameter(ctx, encode_state, encoder_context);
717 if (vaStatus != VA_STATUS_SUCCESS)
719 vaStatus = intel_encoder_check_jpeg_yuv_surface(ctx, profile, encode_state, encoder_context);
723 case VAProfileVP8Version0_3: {
724 vaStatus = intel_encoder_check_vp8_parameter(ctx, encode_state, encoder_context);
725 if (vaStatus != VA_STATUS_SUCCESS)
727 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
731 case VAProfileHEVCMain: {
732 vaStatus = intel_encoder_check_hevc_parameter(ctx, encode_state, encoder_context);
733 if (vaStatus != VA_STATUS_SUCCESS)
735 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
739 case VAProfileVP9Profile0: {
740 vaStatus = intel_encoder_check_vp9_parameter(ctx, encode_state, encoder_context);
741 if (vaStatus != VA_STATUS_SUCCESS)
746 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
750 if (vaStatus == VA_STATUS_SUCCESS)
751 vaStatus = intel_encoder_check_misc_parameter(ctx, encode_state, encoder_context);
758 intel_encoder_end_picture(VADriverContextP ctx,
760 union codec_state *codec_state,
761 struct hw_context *hw_context)
763 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
764 struct encode_state *encode_state = &codec_state->encode;
767 vaStatus = intel_encoder_sanity_check_input(ctx, profile, encode_state, encoder_context);
769 if (vaStatus != VA_STATUS_SUCCESS)
772 encoder_context->mfc_brc_prepare(encode_state, encoder_context);
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)
780 encoder_context->mfc_pipeline(ctx, profile, encode_state, encoder_context);
782 return VA_STATUS_SUCCESS;
786 intel_encoder_context_destroy(void *hw_context)
788 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
790 encoder_context->mfc_context_destroy(encoder_context->mfc_context);
792 if (encoder_context->vme_context_destroy && encoder_context->vme_context)
793 encoder_context->vme_context_destroy(encoder_context->vme_context);
795 if (encoder_context->enc_priv_state) {
796 free(encoder_context->enc_priv_state);
797 encoder_context->enc_priv_state = NULL;
800 intel_batchbuffer_free(encoder_context->base.batch);
801 free(encoder_context);
806 intel_encoder_get_status(VADriverContextP ctx, struct hw_context *hw_context, void *buffer)
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;
811 if (encoder_context->get_status)
812 return encoder_context->get_status(ctx, encoder_context, coded_buffer_segment);
814 return VA_STATUS_ERROR_UNIMPLEMENTED;
817 typedef Bool (* hw_init_func)(VADriverContextP, struct intel_encoder_context *);
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)
825 struct intel_driver_data *intel = intel_driver_data(ctx);
826 struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
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;
841 switch (obj_config->profile) {
842 case VAProfileMPEG2Simple:
843 case VAProfileMPEG2Main:
844 encoder_context->codec = CODEC_MPEG2;
847 case VAProfileH264ConstrainedBaseline:
848 case VAProfileH264Main:
849 case VAProfileH264High:
850 encoder_context->codec = CODEC_H264;
852 if (obj_config->entrypoint == VAEntrypointEncSliceLP)
853 encoder_context->quality_range = ENCODER_LP_QUALITY_RANGE;
855 encoder_context->quality_range = ENCODER_QUALITY_RANGE;
858 case VAProfileH264StereoHigh:
859 case VAProfileH264MultiviewHigh:
860 encoder_context->codec = CODEC_H264_MVC;
863 case VAProfileJPEGBaseline:
864 encoder_context->codec = CODEC_JPEG;
867 case VAProfileVP8Version0_3:
868 encoder_context->codec = CODEC_VP8;
871 case VAProfileHEVCMain:
872 encoder_context->codec = CODEC_HEVC;
875 case VAProfileVP9Profile0:
876 encoder_context->codec = CODEC_VP9;
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;
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;
895 if (obj_config->attrib_list[i].type == VAConfigAttribEncROI) {
896 if (encoder_context->codec == CODEC_H264)
897 encoder_context->context_roi = 1;
901 if (vme_context_init) {
902 vme_context_init(ctx, encoder_context);
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);
910 encoder_context->low_power_mode = 1;
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);
918 return (struct hw_context *)encoder_context;
922 gen6_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
924 return intel_enc_hw_context_init(ctx, obj_config, gen6_vme_context_init, gen6_mfc_context_init);
928 gen7_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
931 return intel_enc_hw_context_init(ctx, obj_config, gen7_vme_context_init, gen7_mfc_context_init);
935 gen75_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
937 return intel_enc_hw_context_init(ctx, obj_config, gen75_vme_context_init, gen75_mfc_context_init);
941 gen8_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
943 return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init);
947 gen9_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
949 if (obj_config->entrypoint == VAEntrypointEncSliceLP) {
950 return intel_enc_hw_context_init(ctx, obj_config, NULL, gen9_vdenc_context_init);
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);
961 return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_mfc_context_init);