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 extern Bool gen6_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
44 extern Bool gen6_vme_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
45 extern Bool gen7_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
48 intel_encoder_check_yuv_surface(VADriverContextP ctx,
50 struct encode_state *encode_state,
51 struct intel_encoder_context *encoder_context)
53 struct i965_driver_data *i965 = i965_driver_data(ctx);
54 struct i965_surface src_surface, dst_surface;
55 struct object_surface *obj_surface;
59 /* releae the temporary surface */
60 if (encoder_context->is_tmp_id) {
61 i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
62 encode_state->input_yuv_object = NULL;
65 encoder_context->is_tmp_id = 0;
66 obj_surface = SURFACE(encode_state->current_render_target);
67 assert(obj_surface && obj_surface->bo);
69 if (!obj_surface || !obj_surface->bo)
70 return VA_STATUS_ERROR_INVALID_PARAMETER;
72 if (obj_surface->fourcc == VA_FOURCC_NV12) {
73 unsigned int tiling = 0, swizzle = 0;
75 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
77 if (tiling == I915_TILING_Y) {
78 encoder_context->input_yuv_surface = encode_state->current_render_target;
79 encode_state->input_yuv_object = obj_surface;
80 return VA_STATUS_SUCCESS;
86 rect.width = obj_surface->orig_width;
87 rect.height = obj_surface->orig_height;
89 src_surface.base = (struct object_base *)obj_surface;
90 src_surface.type = I965_SURFACE_TYPE_SURFACE;
91 src_surface.flags = I965_SURFACE_FLAG_FRAME;
93 status = i965_CreateSurfaces(ctx,
94 obj_surface->orig_width,
95 obj_surface->orig_height,
98 &encoder_context->input_yuv_surface);
99 assert(status == VA_STATUS_SUCCESS);
101 if (status != VA_STATUS_SUCCESS)
104 obj_surface = SURFACE(encoder_context->input_yuv_surface);
105 encode_state->input_yuv_object = obj_surface;
107 i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
109 dst_surface.base = (struct object_base *)obj_surface;
110 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
111 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
113 status = i965_image_processing(ctx,
118 assert(status == VA_STATUS_SUCCESS);
120 encoder_context->is_tmp_id = 1;
122 return VA_STATUS_SUCCESS;
126 intel_encoder_check_misc_parameter(VADriverContextP ctx,
127 struct encode_state *encode_state,
128 struct intel_encoder_context *encoder_context)
131 if (encode_state->misc_param[VAEncMiscParameterTypeQualityLevel] &&
132 encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]->buffer) {
133 VAEncMiscParameterBuffer* pMiscParam = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]->buffer;
134 VAEncMiscParameterBufferQualityLevel* param_quality_level = (VAEncMiscParameterBufferQualityLevel*)pMiscParam->data;
135 encoder_context->quality_level = param_quality_level->quality_level;
137 if (encoder_context->quality_level == 0)
138 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
139 else if (encoder_context->quality_level > encoder_context->quality_range)
143 return VA_STATUS_SUCCESS;
146 return VA_STATUS_ERROR_INVALID_PARAMETER;
150 intel_encoder_check_avc_parameter(VADriverContextP ctx,
151 struct encode_state *encode_state,
152 struct intel_encoder_context *encoder_context)
154 struct i965_driver_data *i965 = i965_driver_data(ctx);
155 struct object_surface *obj_surface;
156 struct object_buffer *obj_buffer;
157 VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
160 assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
162 if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID)
165 obj_surface = SURFACE(pic_param->CurrPic.picture_id);
166 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
171 encode_state->reconstructed_object = obj_surface;
172 obj_buffer = BUFFER(pic_param->coded_buf);
173 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
175 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
178 encode_state->coded_buf_object = obj_buffer;
180 for (i = 0; i < 16; i++) {
181 if (pic_param->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID ||
182 pic_param->ReferenceFrames[i].picture_id == VA_INVALID_SURFACE)
185 obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id);
192 encode_state->reference_objects[i] = obj_surface;
194 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
199 encode_state->reference_objects[i] = NULL;
201 return VA_STATUS_SUCCESS;
204 return VA_STATUS_ERROR_INVALID_PARAMETER;
208 intel_encoder_check_mpeg2_parameter(VADriverContextP ctx,
209 struct encode_state *encode_state,
210 struct intel_encoder_context *encoder_context)
212 struct i965_driver_data *i965 = i965_driver_data(ctx);
213 VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
214 struct object_surface *obj_surface;
215 struct object_buffer *obj_buffer;
218 obj_surface = SURFACE(pic_param->reconstructed_picture);
219 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
224 encode_state->reconstructed_object = obj_surface;
225 obj_buffer = BUFFER(pic_param->coded_buf);
226 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
228 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
231 encode_state->coded_buf_object = obj_buffer;
233 if (pic_param->picture_type == VAEncPictureTypeIntra) {
234 } else if (pic_param->picture_type == VAEncPictureTypePredictive) {
235 assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
236 obj_surface = SURFACE(pic_param->forward_reference_picture);
237 assert(obj_surface && obj_surface->bo);
239 if (!obj_surface || !obj_surface->bo)
242 encode_state->reference_objects[i++] = obj_surface;
243 } else if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
244 assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
245 obj_surface = SURFACE(pic_param->forward_reference_picture);
246 assert(obj_surface && obj_surface->bo);
248 if (!obj_surface || !obj_surface->bo)
251 encode_state->reference_objects[i++] = obj_surface;
253 assert(pic_param->backward_reference_picture != VA_INVALID_SURFACE);
254 obj_surface = SURFACE(pic_param->backward_reference_picture);
255 assert(obj_surface && obj_surface->bo);
257 if (!obj_surface || !obj_surface->bo)
260 encode_state->reference_objects[i++] = obj_surface;
265 encode_state->reference_objects[i] = NULL;
267 return VA_STATUS_SUCCESS;
270 return VA_STATUS_ERROR_INVALID_PARAMETER;
274 intel_encoder_sanity_check_input(VADriverContextP ctx,
276 struct encode_state *encode_state,
277 struct intel_encoder_context *encoder_context)
282 case VAProfileH264ConstrainedBaseline:
283 case VAProfileH264Main:
284 case VAProfileH264High:
285 case VAProfileH264MultiviewHigh:
286 case VAProfileH264StereoHigh:
287 vaStatus = intel_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
290 case VAProfileMPEG2Simple:
291 case VAProfileMPEG2Main:
292 vaStatus = intel_encoder_check_mpeg2_parameter(ctx, encode_state, encoder_context);
296 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
300 if (vaStatus != VA_STATUS_SUCCESS)
303 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
305 if (vaStatus == VA_STATUS_SUCCESS)
306 vaStatus = intel_encoder_check_misc_parameter(ctx, encode_state, encoder_context);
313 intel_encoder_end_picture(VADriverContextP ctx,
315 union codec_state *codec_state,
316 struct hw_context *hw_context)
318 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
319 struct encode_state *encode_state = &codec_state->encode;
322 vaStatus = intel_encoder_sanity_check_input(ctx, profile, encode_state, encoder_context);
324 if (vaStatus != VA_STATUS_SUCCESS)
327 encoder_context->mfc_brc_prepare(encode_state, encoder_context);
329 vaStatus = encoder_context->vme_pipeline(ctx, profile, encode_state, encoder_context);
331 if (vaStatus == VA_STATUS_SUCCESS)
332 encoder_context->mfc_pipeline(ctx, profile, encode_state, encoder_context);
333 return VA_STATUS_SUCCESS;
337 intel_encoder_context_destroy(void *hw_context)
339 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
341 encoder_context->mfc_context_destroy(encoder_context->mfc_context);
342 encoder_context->vme_context_destroy(encoder_context->vme_context);
343 intel_batchbuffer_free(encoder_context->base.batch);
344 free(encoder_context);
347 typedef Bool (* hw_init_func)(VADriverContextP, struct intel_encoder_context *);
349 static struct hw_context *
350 intel_enc_hw_context_init(VADriverContextP ctx,
351 struct object_config *obj_config,
352 hw_init_func vme_context_init,
353 hw_init_func mfc_context_init)
355 struct intel_driver_data *intel = intel_driver_data(ctx);
356 struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
359 encoder_context->base.destroy = intel_encoder_context_destroy;
360 encoder_context->base.run = intel_encoder_end_picture;
361 encoder_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
362 encoder_context->input_yuv_surface = VA_INVALID_SURFACE;
363 encoder_context->is_tmp_id = 0;
364 encoder_context->rate_control_mode = VA_RC_NONE;
365 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
366 encoder_context->quality_range = 1;
368 switch (obj_config->profile) {
369 case VAProfileMPEG2Simple:
370 case VAProfileMPEG2Main:
371 encoder_context->codec = CODEC_MPEG2;
374 case VAProfileH264ConstrainedBaseline:
375 case VAProfileH264Main:
376 case VAProfileH264High:
377 encoder_context->codec = CODEC_H264;
378 encoder_context->quality_range = ENCODER_QUALITY_RANGE;
381 case VAProfileH264StereoHigh:
382 case VAProfileH264MultiviewHigh:
383 encoder_context->codec = CODEC_H264_MVC;
392 for (i = 0; i < obj_config->num_attribs; i++) {
393 if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) {
394 encoder_context->rate_control_mode = obj_config->attrib_list[i].value;
396 if (encoder_context->codec == CODEC_MPEG2 &&
397 encoder_context->rate_control_mode & VA_RC_CBR) {
398 WARN_ONCE("Don't support CBR for MPEG-2 encoding\n");
399 encoder_context->rate_control_mode &= ~VA_RC_CBR;
406 vme_context_init(ctx, encoder_context);
407 assert(encoder_context->vme_context);
408 assert(encoder_context->vme_context_destroy);
409 assert(encoder_context->vme_pipeline);
411 mfc_context_init(ctx, encoder_context);
412 assert(encoder_context->mfc_context);
413 assert(encoder_context->mfc_context_destroy);
414 assert(encoder_context->mfc_pipeline);
416 return (struct hw_context *)encoder_context;
420 gen6_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
422 return intel_enc_hw_context_init(ctx, obj_config, gen6_vme_context_init, gen6_mfc_context_init);
426 gen7_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
429 return intel_enc_hw_context_init(ctx, obj_config, gen7_vme_context_init, gen7_mfc_context_init);
433 gen75_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
435 return intel_enc_hw_context_init(ctx, obj_config, gen75_vme_context_init, gen75_mfc_context_init);
439 gen8_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
441 return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init);