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 "i965_post_processing.h"
45 static struct intel_fraction
46 reduce_fraction(struct intel_fraction f)
48 unsigned int a = f.num, b = f.den, c;
53 return (struct intel_fraction) { f.num / b, f.den / b };
57 clear_border(struct object_surface *obj_surface)
59 int width[3], height[3], hstride[3], vstride[3]; /* in byte */
64 if (obj_surface->border_cleared)
65 return VA_STATUS_SUCCESS;
67 if (obj_surface->fourcc == VA_FOURCC_NV12) {
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;
78 return VA_STATUS_SUCCESS;
80 drm_intel_gem_bo_map_gtt(obj_surface->bo);
82 p = (unsigned char*)obj_surface->bo->virtual;
84 return VA_STATUS_ERROR_INVALID_SURFACE;
86 for (i = 0; i < planes; i++) {
92 for (j = 0; j < h; j++) {
93 memset(p + w, 0, hs - w);
97 for (/* nothing */; j < vs; j++) {
103 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
104 obj_surface->border_cleared = true;
105 return VA_STATUS_SUCCESS;
109 intel_encoder_check_yuv_surface(VADriverContextP ctx,
111 struct encode_state *encode_state,
112 struct intel_encoder_context *encoder_context)
114 struct i965_driver_data *i965 = i965_driver_data(ctx);
115 struct i965_surface src_surface, dst_surface;
116 struct object_surface *obj_surface;
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;
126 encoder_context->is_tmp_id = 0;
127 obj_surface = SURFACE(encode_state->current_render_target);
128 assert(obj_surface && obj_surface->bo);
130 if (!obj_surface || !obj_surface->bo)
131 return VA_STATUS_ERROR_INVALID_PARAMETER;
133 if (VAProfileHEVCMain10 == profile &&
134 obj_surface->fourcc != VA_FOURCC_P010)
135 return VA_STATUS_ERROR_INVALID_PARAMETER;
137 if (obj_surface->fourcc == VA_FOURCC_NV12 ||
138 (VAProfileHEVCMain10 == profile &&
139 obj_surface->fourcc == VA_FOURCC_P010)) {
141 unsigned int tiling = 0, swizzle = 0;
142 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
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);
153 rect.width = obj_surface->orig_width;
154 rect.height = obj_surface->orig_height;
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;
160 status = i965_CreateSurfaces(ctx,
161 obj_surface->orig_width,
162 obj_surface->orig_height,
165 &encoder_context->input_yuv_surface);
166 ASSERT_RET(status == VA_STATUS_SUCCESS, status);
168 obj_surface = SURFACE(encoder_context->input_yuv_surface);
169 encode_state->input_yuv_object = obj_surface;
171 i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
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;
177 status = i965_image_processing(ctx,
182 assert(status == VA_STATUS_SUCCESS);
184 encoder_context->is_tmp_id = 1;
186 return clear_border(obj_surface);
191 intel_encoder_check_jpeg_yuv_surface(VADriverContextP ctx,
193 struct encode_state *encode_state,
194 struct intel_encoder_context *encoder_context)
196 struct i965_driver_data *i965 = i965_driver_data(ctx);
197 struct i965_surface src_surface, dst_surface;
198 struct object_surface *obj_surface;
201 int format=0, fourcc=0, subsample=0;
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;
209 encoder_context->is_tmp_id = 0;
210 obj_surface = SURFACE(encode_state->current_render_target);
211 assert(obj_surface && obj_surface->bo);
213 if (!obj_surface || !obj_surface->bo)
214 return VA_STATUS_ERROR_INVALID_PARAMETER;
216 unsigned int tiling = 0, swizzle = 0;
218 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
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;
232 rect.width = obj_surface->orig_width;
233 rect.height = obj_surface->orig_height;
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;
239 switch( obj_surface->fourcc) {
242 fourcc = VA_FOURCC_YUY2;
243 format = VA_RT_FORMAT_YUV422;
244 subsample = SUBSAMPLE_YUV422H;
248 fourcc = VA_FOURCC_UYVY;
249 format = VA_RT_FORMAT_YUV422;
250 subsample = SUBSAMPLE_YUV422H;
254 fourcc = VA_FOURCC_Y800;
255 format = VA_RT_FORMAT_YUV400;
256 subsample = SUBSAMPLE_YUV400;
260 fourcc = VA_FOURCC_444P;
261 format = VA_RT_FORMAT_YUV444;
262 subsample = SUBSAMPLE_YUV444;
266 fourcc = VA_FOURCC_RGBA;
267 format = VA_RT_FORMAT_RGB32;
268 subsample = SUBSAMPLE_RGBX;
271 default: //All other scenarios will have NV12 format
272 fourcc = VA_FOURCC_NV12;
273 format = VA_RT_FORMAT_YUV420;
274 subsample = SUBSAMPLE_YUV420;
278 status = i965_CreateSurfaces(ctx,
279 obj_surface->orig_width,
280 obj_surface->orig_height,
283 &encoder_context->input_yuv_surface);
284 assert(status == VA_STATUS_SUCCESS);
286 if (status != VA_STATUS_SUCCESS)
289 obj_surface = SURFACE(encoder_context->input_yuv_surface);
290 encode_state->input_yuv_object = obj_surface;
292 i965_check_alloc_surface_bo(ctx, obj_surface, 1, fourcc, subsample);
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;
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,
306 assert(status == VA_STATUS_SUCCESS);
309 encoder_context->is_tmp_id = 1;
311 return VA_STATUS_SUCCESS;
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)
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;
324 if (!encoder_context->is_new_sequence)
325 return VA_STATUS_SUCCESS;
329 if (!seq_param->num_units_in_tick || !seq_param->time_scale) {
330 framerate = (struct intel_fraction) { 30, 1 };
332 // for the highest layer
333 framerate = (struct intel_fraction) { seq_param->time_scale, 2 * seq_param->num_units_in_tick };
335 framerate = reduce_fraction(framerate);
337 encoder_context->brc.num_iframes_in_gop = 1; // Always 1
339 if (seq_param->intra_period == 0) { // E.g. IDRPP... / IDR(PBB)... (no IDR/I any more)
340 if (seq_param->ip_period == 0)
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;
350 if (seq_param->ip_period == 0)
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;
358 num_bframes_in_gop = (encoder_context->brc.gop_size -
359 encoder_context->brc.num_iframes_in_gop - num_pframes_in_gop);
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;
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;
377 *seq_bits_per_second = seq_param->bits_per_second;
379 return VA_STATUS_SUCCESS;
382 return VA_STATUS_ERROR_INVALID_PARAMETER;
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)
391 VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer;
392 unsigned int num_pframes_in_gop;
394 if (!encoder_context->is_new_sequence)
395 return VA_STATUS_SUCCESS;
399 encoder_context->brc.num_iframes_in_gop = 1;// Always 1
400 encoder_context->brc.num_bframes_in_gop = 0;// No B frame
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
405 encoder_context->brc.gop_size = seq_param->intra_period;
408 num_pframes_in_gop = encoder_context->brc.gop_size - 1;
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;
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;
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;
428 *seq_bits_per_second = seq_param->bits_per_second;
430 return VA_STATUS_SUCCESS;
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)
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;
443 if (!encoder_context->is_new_sequence)
444 return VA_STATUS_SUCCESS;
446 return VA_STATUS_ERROR_INVALID_PARAMETER;
448 if (!seq_param->vui_time_scale || !seq_param->vui_num_units_in_tick)
449 framerate = (struct intel_fraction) { 30, 1 };
451 framerate = (struct intel_fraction) { seq_param->vui_time_scale, seq_param->vui_num_units_in_tick };
452 framerate = reduce_fraction(framerate);
454 num_iframes_in_gop = 1;
455 if (seq_param->intra_period == 0) {
457 num_pframes_in_gop = -1;
458 } else if (seq_param->intra_period == 1) {
460 num_pframes_in_gop = 0;
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;
465 num_bframes_in_gop = gop_size - num_iframes_in_gop - num_pframes_in_gop;
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;
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;
484 *seq_bits_per_second = seq_param->bits_per_second;
486 return VA_STATUS_SUCCESS;
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)
495 VAEncSequenceParameterBufferVP9 *seq_param = (VAEncSequenceParameterBufferVP9*)encode_state->seq_param_ext->buffer;
496 unsigned int gop_size;
498 if (!encoder_context->is_new_sequence)
499 return VA_STATUS_SUCCESS;
501 return VA_STATUS_ERROR_INVALID_PARAMETER;
503 if (seq_param->intra_period == 0)
504 gop_size = -1; // Dummy value (infinity).
506 gop_size = seq_param->intra_period;
508 if (encoder_context->brc.gop_size != gop_size) {
509 encoder_context->brc.gop_size = gop_size;
510 encoder_context->brc.need_reset = 1;
513 *seq_bits_per_second = seq_param->bits_per_second;
515 return VA_STATUS_SUCCESS;
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)
524 *seq_bits_per_second = 0;
526 switch (encoder_context->codec) {
529 return intel_encoder_check_brc_h264_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
532 return intel_encoder_check_brc_vp8_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
535 return intel_encoder_check_brc_hevc_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
538 return intel_encoder_check_brc_vp9_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
541 // TODO: other codecs
542 return VA_STATUS_SUCCESS;
547 intel_encoder_check_rate_control_parameter(VADriverContextP ctx,
548 struct intel_encoder_context *encoder_context,
549 VAEncMiscParameterRateControl *misc,
550 int *hl_bitrate_updated)
554 if (encoder_context->layer.num_layers >= 2)
555 temporal_id = misc->rc_flags.bits.temporal_id;
557 if (temporal_id >= encoder_context->layer.num_layers)
560 if (misc->rc_flags.bits.reset)
561 encoder_context->brc.need_reset = 1;
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;
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;
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;
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;
587 if (temporal_id == encoder_context->layer.num_layers - 1)
588 *hl_bitrate_updated = 1;
592 intel_encoder_check_hrd_parameter(VADriverContextP ctx,
593 struct intel_encoder_context *encoder_context,
594 VAEncMiscParameterHRD *misc)
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;
605 intel_encoder_check_framerate_parameter(VADriverContextP ctx,
606 struct intel_encoder_context *encoder_context,
607 VAEncMiscParameterFrameRate *misc)
609 struct intel_fraction framerate;
612 if (encoder_context->layer.num_layers >= 2)
613 temporal_id = misc->framerate_flags.bits.temporal_id;
615 if (temporal_id >= encoder_context->layer.num_layers)
618 if (misc->framerate & 0xffff0000)
619 framerate = (struct intel_fraction) { misc->framerate & 0xffff, misc->framerate >> 16 & 0xffff };
621 framerate = (struct intel_fraction) { misc->framerate, 1 };
622 framerate = reduce_fraction(framerate);
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;
632 intel_encoder_check_roi_parameter(VADriverContextP ctx,
633 struct intel_encoder_context *encoder_context,
634 VAEncMiscParameterBufferROI *misc)
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;
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;
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;
656 intel_encoder_check_brc_parameter(VADriverContextP ctx,
657 struct encode_state *encode_state,
658 struct intel_encoder_context *encoder_context)
661 VAEncMiscParameterBuffer *misc_param;
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;
666 if (!(encoder_context->rate_control_mode & (VA_RC_CBR | VA_RC_VBR)))
667 return VA_STATUS_SUCCESS;
669 ret = intel_encoder_check_brc_sequence_parameter(ctx, encode_state, encoder_context, &seq_bits_per_second);
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)
679 misc_param = (VAEncMiscParameterBuffer *)encode_state->misc_param[i][j]->buffer;
681 switch (misc_param->type) {
682 case VAEncMiscParameterTypeFrameRate:
683 intel_encoder_check_framerate_parameter(ctx,
685 (VAEncMiscParameterFrameRate *)misc_param->data);
688 case VAEncMiscParameterTypeRateControl:
689 intel_encoder_check_rate_control_parameter(ctx,
691 (VAEncMiscParameterRateControl *)misc_param->data,
692 &hl_bitrate_updated);
695 case VAEncMiscParameterTypeHRD:
696 intel_encoder_check_hrd_parameter(ctx,
698 (VAEncMiscParameterHRD *)misc_param->data);
701 case VAEncMiscParameterTypeROI:
702 intel_encoder_check_roi_parameter(ctx,
704 (VAEncMiscParameterBufferROI *)misc_param->data);
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) {
716 encoder_context->brc.bits_per_second[encoder_context->layer.num_layers - 1] = seq_bits_per_second;
717 encoder_context->brc.need_reset = 1;
721 return VA_STATUS_SUCCESS;
725 intel_encoder_check_temporal_layer_structure(VADriverContextP ctx,
726 struct encode_state *encode_state,
727 struct intel_encoder_context *encoder_context)
729 VAEncMiscParameterBuffer* misc_param;
730 VAEncMiscParameterTemporalLayerStructure *tls_paramter;
731 unsigned int rate_control_mode = encoder_context->rate_control_mode;
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];
738 encoder_context->layer.curr_frame_layer_id = 0;
740 return VA_STATUS_SUCCESS;
743 if (!(rate_control_mode & (VA_RC_CBR | VA_RC_VBR)))
744 return VA_STATUS_SUCCESS;
746 if (!encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0] ||
747 !encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0]->buffer)
748 return VA_STATUS_SUCCESS;
750 misc_param = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0]->buffer;
751 tls_paramter = (VAEncMiscParameterTemporalLayerStructure *)misc_param->data;
753 if (tls_paramter->number_of_layers <= 1)
754 return VA_STATUS_SUCCESS;
756 if (tls_paramter->number_of_layers > MAX_TEMPORAL_LAYERS)
757 return VA_STATUS_ERROR_INVALID_PARAMETER;
759 if (tls_paramter->periodicity > 32 || tls_paramter->periodicity <= 1)
760 return VA_STATUS_ERROR_INVALID_PARAMETER;
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) {
768 return VA_STATUS_ERROR_INVALID_PARAMETER;
772 encoder_context->layer.size_frame_layer_ids = tls_paramter->periodicity;
773 encoder_context->layer.num_layers = tls_paramter->number_of_layers;
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;
779 encoder_context->layer.frame_layer_ids[i] = tls_paramter->layer_id[i];
782 if (encoder_context->is_new_sequence)
783 encoder_context->layer.curr_frame_layer_id = 0;
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];
787 return VA_STATUS_SUCCESS;
791 intel_encoder_check_misc_parameter(VADriverContextP ctx,
792 struct encode_state *encode_state,
793 struct intel_encoder_context *encoder_context)
795 VAStatus ret = VA_STATUS_SUCCESS;
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;
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;
811 ret = intel_encoder_check_temporal_layer_structure(ctx, encode_state, encoder_context);
816 ret = intel_encoder_check_brc_parameter(ctx, encode_state, encoder_context);
823 intel_encoder_check_avc_parameter(VADriverContextP ctx,
824 struct encode_state *encode_state,
825 struct intel_encoder_context *encoder_context)
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;
834 assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
836 if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID)
839 obj_surface = SURFACE(pic_param->CurrPic.picture_id);
840 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
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);
849 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
852 encode_state->coded_buf_object = obj_buffer;
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)
859 obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id);
866 encode_state->reference_objects[i] = obj_surface;
868 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
873 encode_state->reference_objects[i] = NULL;
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
880 encoder_context->is_new_sequence = (pic_param->pic_fields.bits.idr_pic_flag && seq_param);
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;
888 return VA_STATUS_SUCCESS;
891 return VA_STATUS_ERROR_INVALID_PARAMETER;
895 intel_encoder_check_mpeg2_parameter(VADriverContextP ctx,
896 struct encode_state *encode_state,
897 struct intel_encoder_context *encoder_context)
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;
905 obj_surface = SURFACE(pic_param->reconstructed_picture);
906 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
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);
915 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
918 encode_state->coded_buf_object = obj_buffer;
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);
926 if (!obj_surface || !obj_surface->bo)
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);
935 if (!obj_surface || !obj_surface->bo)
938 encode_state->reference_objects[i++] = obj_surface;
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);
944 if (!obj_surface || !obj_surface->bo)
947 encode_state->reference_objects[i++] = obj_surface;
952 encode_state->reference_objects[i] = NULL;
954 return VA_STATUS_SUCCESS;
957 return VA_STATUS_ERROR_INVALID_PARAMETER;
961 intel_encoder_check_jpeg_parameter(VADriverContextP ctx,
962 struct encode_state *encode_state,
963 struct intel_encoder_context *encoder_context)
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;
970 assert(!(pic_param->pic_flags.bits.profile)); //Baseline profile is 0.
972 obj_buffer = BUFFER(pic_param->coded_buf);
973 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
975 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
978 encode_state->coded_buf_object = obj_buffer;
980 return VA_STATUS_SUCCESS;
983 return VA_STATUS_ERROR_INVALID_PARAMETER;
987 intel_encoder_check_vp8_parameter(VADriverContextP ctx,
988 struct encode_state *encode_state,
989 struct intel_encoder_context *encoder_context)
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;
997 int is_key_frame = !pic_param->pic_flags.bits.frame_type;
999 obj_surface = SURFACE(pic_param->reconstructed_frame);
1000 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
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);
1009 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1012 encode_state->coded_buf_object = obj_buffer;
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);
1019 if (!obj_surface || !obj_surface->bo)
1022 encode_state->reference_objects[i++] = obj_surface;
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);
1028 if (!obj_surface || !obj_surface->bo)
1031 encode_state->reference_objects[i++] = obj_surface;
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);
1037 if (!obj_surface || !obj_surface->bo)
1040 encode_state->reference_objects[i++] = obj_surface;
1043 for ( ; i < 16; i++)
1044 encode_state->reference_objects[i] = NULL;
1046 encoder_context->is_new_sequence = (is_key_frame && seq_param);
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;
1054 return VA_STATUS_SUCCESS;
1057 return VA_STATUS_ERROR_INVALID_PARAMETER;
1061 intel_encoder_check_hevc_parameter(VADriverContextP ctx,
1062 struct encode_state *encode_state,
1063 struct intel_encoder_context *encoder_context)
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;
1075 if (encode_state->seq_param_ext &&
1076 encode_state->seq_param_ext->buffer)
1077 seq_param = (VAEncSequenceParameterBufferHEVC *)(encode_state->seq_param_ext->buffer);
1079 assert(!(pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID));
1081 if (pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID)
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 */
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);
1094 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1097 encode_state->coded_buf_object = obj_buffer;
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)
1104 obj_surface = SURFACE(pic_param->reference_frames[i].picture_id);
1105 assert(obj_surface);
1110 if (obj_surface->bo)
1111 encode_state->reference_objects[i] = obj_surface;
1113 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
1117 for ( ; i < 15; i++)
1118 encode_state->reference_objects[i] = NULL;
1120 for (i = 0; i < encode_state->num_slice_params_ext; i++) {
1121 slice_param = (VAEncSliceParameterBufferHEVC *)encode_state->slice_params_ext[i]->buffer;
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)
1128 /* TODO: add more check here */
1131 encoder_context->is_new_sequence = (pic_param->pic_fields.bits.idr_pic_flag && seq_param);
1133 return VA_STATUS_SUCCESS;
1136 return VA_STATUS_ERROR_INVALID_PARAMETER;
1140 intel_encoder_check_vp9_parameter(VADriverContextP ctx,
1141 struct encode_state *encode_state,
1142 struct intel_encoder_context *encoder_context)
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;
1150 int is_key_frame = 0;
1153 if (encode_state->pic_param_ext == NULL ||
1154 encode_state->pic_param_ext->buffer == NULL)
1155 return VA_STATUS_ERROR_INVALID_PARAMETER;
1158 if (encode_state->seq_param_ext &&
1159 encode_state->seq_param_ext->buffer)
1160 seq_param = (VAEncSequenceParameterBufferVP9 *)(encode_state->seq_param_ext->buffer);
1162 pic_param = (VAEncPictureParameterBufferVP9 *)encode_state->pic_param_ext->buffer;
1164 obj_surface = SURFACE(pic_param->reconstructed_frame);
1169 encode_state->reconstructed_object = obj_surface;
1170 obj_buffer = BUFFER(pic_param->coded_buf);
1172 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1175 encode_state->coded_buf_object = obj_buffer;
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;
1185 encode_state->reference_objects[i++] = NULL;
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;
1193 encode_state->reference_objects[i++] = NULL;
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;
1201 encode_state->reference_objects[i++] = NULL;
1204 for ( ; i < 16; i++)
1205 encode_state->reference_objects[i] = NULL;
1207 encoder_context->is_new_sequence = (is_key_frame && seq_param);
1209 return VA_STATUS_SUCCESS;
1212 return VA_STATUS_ERROR_INVALID_PARAMETER;
1217 intel_encoder_sanity_check_input(VADriverContextP ctx,
1219 struct encode_state *encode_state,
1220 struct intel_encoder_context *encoder_context)
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)
1233 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1237 case VAProfileMPEG2Simple:
1238 case VAProfileMPEG2Main: {
1239 vaStatus = intel_encoder_check_mpeg2_parameter(ctx, encode_state, encoder_context);
1240 if (vaStatus != VA_STATUS_SUCCESS)
1242 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1246 case VAProfileJPEGBaseline: {
1247 vaStatus = intel_encoder_check_jpeg_parameter(ctx, encode_state, encoder_context);
1248 if (vaStatus != VA_STATUS_SUCCESS)
1250 vaStatus = intel_encoder_check_jpeg_yuv_surface(ctx, profile, encode_state, encoder_context);
1254 case VAProfileVP8Version0_3: {
1255 vaStatus = intel_encoder_check_vp8_parameter(ctx, encode_state, encoder_context);
1256 if (vaStatus != VA_STATUS_SUCCESS)
1258 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1262 case VAProfileHEVCMain:
1263 case VAProfileHEVCMain10: {
1264 vaStatus = intel_encoder_check_hevc_parameter(ctx, encode_state, encoder_context);
1265 if (vaStatus != VA_STATUS_SUCCESS)
1267 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1271 case VAProfileVP9Profile0: {
1272 vaStatus = intel_encoder_check_vp9_parameter(ctx, encode_state, encoder_context);
1273 if (vaStatus != VA_STATUS_SUCCESS)
1275 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1279 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1283 if (vaStatus == VA_STATUS_SUCCESS)
1284 vaStatus = intel_encoder_check_misc_parameter(ctx, encode_state, encoder_context);
1291 intel_encoder_end_picture(VADriverContextP ctx,
1293 union codec_state *codec_state,
1294 struct hw_context *hw_context)
1296 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
1297 struct encode_state *encode_state = &codec_state->encode;
1300 vaStatus = intel_encoder_sanity_check_input(ctx, profile, encode_state, encoder_context);
1302 if (vaStatus != VA_STATUS_SUCCESS)
1305 encoder_context->mfc_brc_prepare(encode_state, encoder_context);
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)
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;
1317 * ROI is only available for the current frame, see the comment
1318 * for VAEncROI in va.h
1320 encoder_context->brc.num_roi = 0;
1322 return VA_STATUS_SUCCESS;
1326 intel_encoder_context_destroy(void *hw_context)
1328 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
1330 encoder_context->mfc_context_destroy(encoder_context->mfc_context);
1332 if (encoder_context->vme_context_destroy && encoder_context->vme_context)
1333 encoder_context->vme_context_destroy(encoder_context->vme_context);
1335 if (encoder_context->enc_priv_state) {
1336 free(encoder_context->enc_priv_state);
1337 encoder_context->enc_priv_state = NULL;
1340 intel_batchbuffer_free(encoder_context->base.batch);
1341 free(encoder_context);
1346 intel_encoder_get_status(VADriverContextP ctx, struct hw_context *hw_context, void *buffer)
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;
1351 if (encoder_context->get_status)
1352 return encoder_context->get_status(ctx, encoder_context, coded_buffer_segment);
1354 return VA_STATUS_ERROR_UNIMPLEMENTED;
1357 typedef Bool (* hw_init_func)(VADriverContextP, struct intel_encoder_context *);
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)
1365 struct intel_driver_data *intel = intel_driver_data(ctx);
1366 struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
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;
1382 if (obj_config->entrypoint == VAEntrypointEncSliceLP)
1383 encoder_context->low_power_mode = 1;
1385 switch (obj_config->profile) {
1386 case VAProfileMPEG2Simple:
1387 case VAProfileMPEG2Main:
1388 encoder_context->codec = CODEC_MPEG2;
1391 case VAProfileH264ConstrainedBaseline:
1392 case VAProfileH264Main:
1393 case VAProfileH264High:
1394 encoder_context->codec = CODEC_H264;
1396 if (obj_config->entrypoint == VAEntrypointEncSliceLP)
1397 encoder_context->quality_range = ENCODER_LP_QUALITY_RANGE;
1399 encoder_context->quality_range = ENCODER_QUALITY_RANGE;
1402 case VAProfileH264StereoHigh:
1403 case VAProfileH264MultiviewHigh:
1404 encoder_context->codec = CODEC_H264_MVC;
1407 case VAProfileJPEGBaseline:
1408 encoder_context->codec = CODEC_JPEG;
1411 case VAProfileVP8Version0_3:
1412 encoder_context->codec = CODEC_VP8;
1415 case VAProfileHEVCMain:
1416 case VAProfileHEVCMain10:
1417 encoder_context->codec = CODEC_HEVC;
1420 case VAProfileVP9Profile0:
1421 encoder_context->codec = CODEC_VP9;
1425 /* Never get here */
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;
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;
1440 if (obj_config->attrib_list[i].type == VAConfigAttribEncROI) {
1441 if (encoder_context->codec == CODEC_H264)
1442 encoder_context->context_roi = 1;
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));
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);
1457 return (struct hw_context *)encoder_context;
1461 gen6_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1463 return intel_enc_hw_context_init(ctx, obj_config, gen6_vme_context_init, gen6_mfc_context_init);
1467 gen7_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1470 return intel_enc_hw_context_init(ctx, obj_config, gen7_vme_context_init, gen7_mfc_context_init);
1474 gen75_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1476 return intel_enc_hw_context_init(ctx, obj_config, gen75_vme_context_init, gen75_mfc_context_init);
1480 gen8_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1482 return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init);
1486 gen9_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1488 return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_mfc_context_init);