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"
44 #include "i965_encoder_api.h"
45 #include "i965_avc_encoder_common.h"
47 static struct intel_fraction
48 reduce_fraction(struct intel_fraction f)
50 unsigned int a = f.num, b = f.den, c;
55 return (struct intel_fraction) {
61 clear_border(struct object_surface *obj_surface)
63 int width[3], height[3], hstride[3], vstride[3]; /* in byte */
68 if (obj_surface->border_cleared)
69 return VA_STATUS_SUCCESS;
71 if (obj_surface->fourcc == VA_FOURCC_NV12) {
73 width[0] = width[1] = obj_surface->orig_width;
74 height[0] = obj_surface->orig_height;
75 height[1] = obj_surface->orig_height / 2;
76 hstride[0] = hstride[1] = obj_surface->width;
77 vstride[0] = obj_surface->height;
78 vstride[1] = obj_surface->height / 2;
82 return VA_STATUS_SUCCESS;
84 drm_intel_gem_bo_map_gtt(obj_surface->bo);
86 p = (unsigned char*)obj_surface->bo->virtual;
88 return VA_STATUS_ERROR_INVALID_SURFACE;
90 for (i = 0; i < planes; i++) {
96 for (j = 0; j < h; j++) {
97 memset(p + w, 0, hs - w);
101 for (/* nothing */; j < vs; j++) {
107 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
108 obj_surface->border_cleared = true;
109 return VA_STATUS_SUCCESS;
113 intel_encoder_check_yuv_surface(VADriverContextP ctx,
115 struct encode_state *encode_state,
116 struct intel_encoder_context *encoder_context)
118 struct i965_driver_data *i965 = i965_driver_data(ctx);
119 struct i965_surface src_surface, dst_surface;
120 struct object_surface *obj_surface;
123 int format = VA_RT_FORMAT_YUV420;
124 unsigned int fourcc = VA_FOURCC_NV12;
126 /* releae the temporary surface */
127 if (encoder_context->is_tmp_id) {
128 i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
129 encode_state->input_yuv_object = NULL;
132 encoder_context->is_tmp_id = 0;
133 obj_surface = SURFACE(encode_state->current_render_target);
134 assert(obj_surface && obj_surface->bo);
136 if (!obj_surface || !obj_surface->bo)
137 return VA_STATUS_ERROR_INVALID_PARAMETER;
139 if (VAProfileHEVCMain10 == profile &&
140 obj_surface->fourcc != VA_FOURCC_P010)
141 return VA_STATUS_ERROR_INVALID_PARAMETER;
143 if (obj_surface->fourcc == VA_FOURCC_NV12 ||
144 (VAProfileHEVCMain10 == profile &&
145 obj_surface->fourcc == VA_FOURCC_P010)) {
147 unsigned int tiling = 0, swizzle = 0;
148 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
150 if (tiling == I915_TILING_Y) {
151 encoder_context->input_yuv_surface = encode_state->current_render_target;
152 encode_state->input_yuv_object = obj_surface;
153 return clear_border(obj_surface);
157 if (VAProfileHEVCMain10 == profile) {
158 format = VA_RT_FORMAT_YUV420_10BPP;
159 fourcc = VA_FOURCC_P010;
164 rect.width = obj_surface->orig_width;
165 rect.height = obj_surface->orig_height;
167 src_surface.base = (struct object_base *)obj_surface;
168 src_surface.type = I965_SURFACE_TYPE_SURFACE;
169 src_surface.flags = I965_SURFACE_FLAG_FRAME;
171 status = i965_CreateSurfaces(ctx,
172 obj_surface->orig_width,
173 obj_surface->orig_height,
176 &encoder_context->input_yuv_surface);
177 ASSERT_RET(status == VA_STATUS_SUCCESS, status);
179 obj_surface = SURFACE(encoder_context->input_yuv_surface);
180 encode_state->input_yuv_object = obj_surface;
182 i965_check_alloc_surface_bo(ctx, obj_surface, 1, fourcc, SUBSAMPLE_YUV420);
184 dst_surface.base = (struct object_base *)obj_surface;
185 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
186 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
188 status = i965_image_processing(ctx,
193 assert(status == VA_STATUS_SUCCESS);
195 encoder_context->is_tmp_id = 1;
197 return clear_border(obj_surface);
202 intel_encoder_check_jpeg_yuv_surface(VADriverContextP ctx,
204 struct encode_state *encode_state,
205 struct intel_encoder_context *encoder_context)
207 struct i965_driver_data *i965 = i965_driver_data(ctx);
208 struct i965_surface src_surface, dst_surface;
209 struct object_surface *obj_surface;
212 int format = 0, fourcc = 0, subsample = 0;
214 /* releae the temporary surface */
215 if (encoder_context->is_tmp_id) {
216 i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
217 encode_state->input_yuv_object = NULL;
220 encoder_context->is_tmp_id = 0;
221 obj_surface = SURFACE(encode_state->current_render_target);
222 assert(obj_surface && obj_surface->bo);
224 if (!obj_surface || !obj_surface->bo)
225 return VA_STATUS_ERROR_INVALID_PARAMETER;
227 unsigned int tiling = 0, swizzle = 0;
229 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
231 if (tiling == I915_TILING_Y) {
232 if ((obj_surface->fourcc == VA_FOURCC_NV12) || (obj_surface->fourcc == VA_FOURCC_UYVY) ||
233 (obj_surface->fourcc == VA_FOURCC_YUY2) || (obj_surface->fourcc == VA_FOURCC_Y800) ||
234 (obj_surface->fourcc == VA_FOURCC_RGBA) || (obj_surface->fourcc == VA_FOURCC_444P)) {
235 encoder_context->input_yuv_surface = encode_state->current_render_target;
236 encode_state->input_yuv_object = obj_surface;
237 return VA_STATUS_SUCCESS;
243 rect.width = obj_surface->orig_width;
244 rect.height = obj_surface->orig_height;
246 src_surface.base = (struct object_base *)obj_surface;
247 src_surface.type = I965_SURFACE_TYPE_SURFACE;
248 src_surface.flags = I965_SURFACE_FLAG_FRAME;
250 switch (obj_surface->fourcc) {
253 fourcc = VA_FOURCC_YUY2;
254 format = VA_RT_FORMAT_YUV422;
255 subsample = SUBSAMPLE_YUV422H;
259 fourcc = VA_FOURCC_UYVY;
260 format = VA_RT_FORMAT_YUV422;
261 subsample = SUBSAMPLE_YUV422H;
265 fourcc = VA_FOURCC_Y800;
266 format = VA_RT_FORMAT_YUV400;
267 subsample = SUBSAMPLE_YUV400;
271 fourcc = VA_FOURCC_444P;
272 format = VA_RT_FORMAT_YUV444;
273 subsample = SUBSAMPLE_YUV444;
277 fourcc = VA_FOURCC_RGBA;
278 format = VA_RT_FORMAT_RGB32;
279 subsample = SUBSAMPLE_RGBX;
282 default: //All other scenarios will have NV12 format
283 fourcc = VA_FOURCC_NV12;
284 format = VA_RT_FORMAT_YUV420;
285 subsample = SUBSAMPLE_YUV420;
289 status = i965_CreateSurfaces(ctx,
290 obj_surface->orig_width,
291 obj_surface->orig_height,
294 &encoder_context->input_yuv_surface);
295 assert(status == VA_STATUS_SUCCESS);
297 if (status != VA_STATUS_SUCCESS)
300 obj_surface = SURFACE(encoder_context->input_yuv_surface);
301 encode_state->input_yuv_object = obj_surface;
303 i965_check_alloc_surface_bo(ctx, obj_surface, 1, fourcc, subsample);
305 dst_surface.base = (struct object_base *)obj_surface;
306 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
307 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
309 //The Y800 format is expected to be tiled.
310 //Linear Y800 is a corner case and needs code in the i965_image_processing.
311 if (obj_surface->fourcc != VA_FOURCC_Y800) {
312 status = i965_image_processing(ctx,
317 assert(status == VA_STATUS_SUCCESS);
320 encoder_context->is_tmp_id = 1;
322 return VA_STATUS_SUCCESS;
326 intel_encoder_check_brc_h264_sequence_parameter(VADriverContextP ctx,
327 struct encode_state *encode_state,
328 struct intel_encoder_context *encoder_context,
329 unsigned int *seq_bits_per_second)
331 VAEncSequenceParameterBufferH264 *seq_param = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
332 struct intel_fraction framerate;
333 unsigned short num_pframes_in_gop, num_bframes_in_gop;
335 if (!encoder_context->is_new_sequence)
336 return VA_STATUS_SUCCESS;
340 if (!seq_param->num_units_in_tick || !seq_param->time_scale) {
341 framerate = (struct intel_fraction) {
345 // for the highest layer
346 framerate = (struct intel_fraction) {
347 seq_param->time_scale, 2 * seq_param->num_units_in_tick
350 framerate = reduce_fraction(framerate);
352 encoder_context->brc.num_iframes_in_gop = 1; // Always 1
354 if (seq_param->intra_period == 0) { // E.g. IDRPP... / IDR(PBB)... (no IDR/I any more)
355 if (seq_param->ip_period == 0)
358 encoder_context->brc.gop_size = (framerate.num + framerate.den - 1) / framerate.den; // fake
359 num_pframes_in_gop = (encoder_context->brc.gop_size +
360 seq_param->ip_period - 1) / seq_param->ip_period - 1;
361 } else if (seq_param->intra_period == 1) { // E.g. IDRIII...
362 encoder_context->brc.gop_size = 1;
363 num_pframes_in_gop = 0;
365 if (seq_param->ip_period == 0)
368 encoder_context->brc.gop_size = seq_param->intra_period;
369 num_pframes_in_gop = (encoder_context->brc.gop_size +
370 seq_param->ip_period - 1) / seq_param->ip_period - 1;
373 num_bframes_in_gop = (encoder_context->brc.gop_size -
374 encoder_context->brc.num_iframes_in_gop - num_pframes_in_gop);
376 if (num_pframes_in_gop != encoder_context->brc.num_pframes_in_gop ||
377 num_bframes_in_gop != encoder_context->brc.num_bframes_in_gop ||
378 framerate.num != encoder_context->brc.framerate[encoder_context->layer.num_layers - 1].num ||
379 framerate.den != encoder_context->brc.framerate[encoder_context->layer.num_layers - 1].den) {
380 encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
381 encoder_context->brc.num_bframes_in_gop = num_bframes_in_gop;
382 encoder_context->brc.framerate[encoder_context->layer.num_layers - 1] = framerate;
383 encoder_context->brc.need_reset = 1;
386 if (!encoder_context->brc.hrd_buffer_size ||
387 !encoder_context->brc.hrd_initial_buffer_fullness) {
388 encoder_context->brc.hrd_buffer_size = seq_param->bits_per_second << 1;
389 encoder_context->brc.hrd_initial_buffer_fullness = seq_param->bits_per_second;
392 *seq_bits_per_second = seq_param->bits_per_second;
394 return VA_STATUS_SUCCESS;
397 return VA_STATUS_ERROR_INVALID_PARAMETER;
401 intel_encoder_check_brc_vp8_sequence_parameter(VADriverContextP ctx,
402 struct encode_state *encode_state,
403 struct intel_encoder_context *encoder_context,
404 unsigned int *seq_bits_per_second)
406 VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer;
407 unsigned int num_pframes_in_gop;
409 if (!encoder_context->is_new_sequence)
410 return VA_STATUS_SUCCESS;
414 encoder_context->brc.num_iframes_in_gop = 1;// Always 1
415 encoder_context->brc.num_bframes_in_gop = 0;// No B frame
417 if (seq_param->intra_period == 0) { // E.g. IPPP... (only one I frame in the stream)
418 encoder_context->brc.gop_size = 30; // fake
420 encoder_context->brc.gop_size = seq_param->intra_period;
423 num_pframes_in_gop = encoder_context->brc.gop_size - 1;
425 if (!encoder_context->brc.framerate[encoder_context->layer.num_layers - 1].num) {
426 // for the highest layer
427 encoder_context->brc.framerate[encoder_context->layer.num_layers - 1] = (struct intel_fraction) {
430 encoder_context->brc.need_reset = 1;
433 if (num_pframes_in_gop != encoder_context->brc.num_pframes_in_gop) {
434 encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
435 encoder_context->brc.need_reset = 1;
438 if (!encoder_context->brc.hrd_buffer_size ||
439 !encoder_context->brc.hrd_initial_buffer_fullness) {
440 encoder_context->brc.hrd_buffer_size = seq_param->bits_per_second << 1;
441 encoder_context->brc.hrd_initial_buffer_fullness = seq_param->bits_per_second;
442 encoder_context->brc.need_reset = 1;
445 *seq_bits_per_second = seq_param->bits_per_second;
447 return VA_STATUS_SUCCESS;
451 intel_encoder_check_brc_hevc_sequence_parameter(VADriverContextP ctx,
452 struct encode_state *encode_state,
453 struct intel_encoder_context *encoder_context,
454 unsigned int *seq_bits_per_second)
456 VAEncSequenceParameterBufferHEVC *seq_param = (VAEncSequenceParameterBufferHEVC*)encode_state->seq_param_ext->buffer;
457 struct intel_fraction framerate;
458 unsigned int gop_size, num_iframes_in_gop, num_pframes_in_gop, num_bframes_in_gop;
460 if (!encoder_context->is_new_sequence)
461 return VA_STATUS_SUCCESS;
463 return VA_STATUS_ERROR_INVALID_PARAMETER;
465 if (!seq_param->vui_time_scale || !seq_param->vui_num_units_in_tick)
466 framerate = (struct intel_fraction) {
470 framerate = (struct intel_fraction) {
471 seq_param->vui_time_scale, seq_param->vui_num_units_in_tick
473 framerate = reduce_fraction(framerate);
475 num_iframes_in_gop = 1;
476 if (seq_param->intra_period == 0) {
478 num_pframes_in_gop = -1;
479 } else if (seq_param->intra_period == 1) {
481 num_pframes_in_gop = 0;
483 gop_size = seq_param->intra_period;
484 num_pframes_in_gop = (seq_param->intra_period + seq_param->ip_period - 1) / seq_param->ip_period - 1;
486 num_bframes_in_gop = gop_size - num_iframes_in_gop - num_pframes_in_gop;
488 if (encoder_context->brc.framerate[0].num != framerate.num ||
489 encoder_context->brc.framerate[0].den != framerate.den) {
490 encoder_context->brc.framerate[0] = framerate;
491 encoder_context->brc.need_reset = 1;
494 if (encoder_context->brc.gop_size != gop_size ||
495 encoder_context->brc.num_iframes_in_gop != num_iframes_in_gop ||
496 encoder_context->brc.num_pframes_in_gop != num_pframes_in_gop ||
497 encoder_context->brc.num_bframes_in_gop != num_bframes_in_gop) {
498 encoder_context->brc.gop_size = gop_size;
499 encoder_context->brc.num_iframes_in_gop = num_iframes_in_gop;
500 encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
501 encoder_context->brc.num_bframes_in_gop = num_bframes_in_gop;
502 encoder_context->brc.need_reset = 1;
505 *seq_bits_per_second = seq_param->bits_per_second;
507 return VA_STATUS_SUCCESS;
511 intel_encoder_check_brc_vp9_sequence_parameter(VADriverContextP ctx,
512 struct encode_state *encode_state,
513 struct intel_encoder_context *encoder_context,
514 unsigned int *seq_bits_per_second)
516 VAEncSequenceParameterBufferVP9 *seq_param = (VAEncSequenceParameterBufferVP9*)encode_state->seq_param_ext->buffer;
517 unsigned int gop_size;
519 if (!encoder_context->is_new_sequence)
520 return VA_STATUS_SUCCESS;
522 return VA_STATUS_ERROR_INVALID_PARAMETER;
524 if (seq_param->intra_period == 0)
525 gop_size = -1; // Dummy value (infinity).
527 gop_size = seq_param->intra_period;
529 if (encoder_context->brc.gop_size != gop_size) {
530 encoder_context->brc.gop_size = gop_size;
531 encoder_context->brc.need_reset = 1;
534 *seq_bits_per_second = seq_param->bits_per_second;
536 return VA_STATUS_SUCCESS;
540 intel_encoder_check_brc_sequence_parameter(VADriverContextP ctx,
541 struct encode_state *encode_state,
542 struct intel_encoder_context *encoder_context,
543 unsigned int *seq_bits_per_second)
545 *seq_bits_per_second = 0;
547 switch (encoder_context->codec) {
550 return intel_encoder_check_brc_h264_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
553 return intel_encoder_check_brc_vp8_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
556 return intel_encoder_check_brc_hevc_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
559 return intel_encoder_check_brc_vp9_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
562 // TODO: other codecs
563 return VA_STATUS_SUCCESS;
568 intel_encoder_check_rate_control_parameter(VADriverContextP ctx,
569 struct intel_encoder_context *encoder_context,
570 VAEncMiscParameterRateControl *misc,
571 int *hl_bitrate_updated)
575 if (encoder_context->layer.num_layers >= 2)
576 temporal_id = misc->rc_flags.bits.temporal_id;
578 if (temporal_id >= encoder_context->layer.num_layers)
581 if (misc->rc_flags.bits.reset)
582 encoder_context->brc.need_reset = 1;
584 if (encoder_context->brc.bits_per_second[temporal_id] != misc->bits_per_second) {
585 encoder_context->brc.bits_per_second[temporal_id] = misc->bits_per_second;
586 encoder_context->brc.need_reset = 1;
589 if (encoder_context->brc.mb_rate_control[temporal_id] != misc->rc_flags.bits.mb_rate_control) {
590 encoder_context->brc.mb_rate_control[temporal_id] = misc->rc_flags.bits.mb_rate_control;
591 encoder_context->brc.need_reset = 1;
594 if (encoder_context->brc.target_percentage[temporal_id] != misc->target_percentage) {
595 encoder_context->brc.target_percentage[temporal_id] = misc->target_percentage;
596 encoder_context->brc.need_reset = 1;
599 if (encoder_context->brc.window_size != misc->window_size ||
600 encoder_context->brc.initial_qp != misc->initial_qp ||
601 encoder_context->brc.min_qp != misc->min_qp) {
602 encoder_context->brc.window_size = misc->window_size;
603 encoder_context->brc.initial_qp = misc->initial_qp;
604 encoder_context->brc.min_qp = misc->min_qp;
605 encoder_context->brc.need_reset = 1;
608 if (temporal_id == encoder_context->layer.num_layers - 1)
609 *hl_bitrate_updated = 1;
613 intel_encoder_check_hrd_parameter(VADriverContextP ctx,
614 struct intel_encoder_context *encoder_context,
615 VAEncMiscParameterHRD *misc)
617 if (encoder_context->brc.hrd_buffer_size != misc->buffer_size ||
618 encoder_context->brc.hrd_initial_buffer_fullness != misc->initial_buffer_fullness) {
619 encoder_context->brc.hrd_buffer_size = misc->buffer_size;
620 encoder_context->brc.hrd_initial_buffer_fullness = misc->initial_buffer_fullness;
621 encoder_context->brc.need_reset = 1;
626 intel_encoder_check_framerate_parameter(VADriverContextP ctx,
627 struct intel_encoder_context *encoder_context,
628 VAEncMiscParameterFrameRate *misc)
630 struct intel_fraction framerate;
633 if (encoder_context->layer.num_layers >= 2)
634 temporal_id = misc->framerate_flags.bits.temporal_id;
636 if (temporal_id >= encoder_context->layer.num_layers)
639 if (misc->framerate & 0xffff0000)
640 framerate = (struct intel_fraction) {
641 misc->framerate & 0xffff, misc->framerate >> 16 & 0xffff
644 framerate = (struct intel_fraction) {
647 framerate = reduce_fraction(framerate);
649 if (encoder_context->brc.framerate[temporal_id].num != framerate.num ||
650 encoder_context->brc.framerate[temporal_id].den != framerate.den) {
651 encoder_context->brc.framerate[temporal_id] = framerate;
652 encoder_context->brc.need_reset = 1;
657 intel_encoder_check_roi_parameter(VADriverContextP ctx,
658 struct intel_encoder_context *encoder_context,
659 VAEncMiscParameterBufferROI *misc)
663 encoder_context->brc.num_roi = MIN(misc->num_roi, I965_MAX_NUM_ROI_REGIONS);
664 encoder_context->brc.roi_max_delta_qp = misc->max_delta_qp;
665 encoder_context->brc.roi_min_delta_qp = misc->min_delta_qp;
666 encoder_context->brc.roi_value_is_qp_delta = 0;
668 if (encoder_context->rate_control_mode != VA_RC_CQP)
669 encoder_context->brc.roi_value_is_qp_delta = misc->roi_flags.bits.roi_value_is_qp_delta;
671 for (i = 0; i < encoder_context->brc.num_roi; i++) {
672 encoder_context->brc.roi[i].left = misc->roi->roi_rectangle.x;
673 encoder_context->brc.roi[i].right = encoder_context->brc.roi[i].left + misc->roi->roi_rectangle.width;
674 encoder_context->brc.roi[i].top = misc->roi->roi_rectangle.y;
675 encoder_context->brc.roi[i].bottom = encoder_context->brc.roi[i].top + misc->roi->roi_rectangle.height;
676 encoder_context->brc.roi[i].value = misc->roi->roi_value;
681 intel_encoder_check_brc_parameter(VADriverContextP ctx,
682 struct encode_state *encode_state,
683 struct intel_encoder_context *encoder_context)
686 VAEncMiscParameterBuffer *misc_param;
688 int hl_bitrate_updated = 0; // Indicate whether the bitrate for the highest level is changed in misc parameters
689 unsigned int seq_bits_per_second = 0;
691 if (encoder_context->rate_control_mode & (VA_RC_CBR | VA_RC_VBR)) {
692 ret = intel_encoder_check_brc_sequence_parameter(ctx, encode_state, encoder_context, &seq_bits_per_second);
698 for (i = 0; i < ARRAY_ELEMS(encode_state->misc_param); i++) {
699 for (j = 0; j < ARRAY_ELEMS(encode_state->misc_param[0]); j++) {
700 if (!encode_state->misc_param[i][j] || !encode_state->misc_param[i][j]->buffer)
703 misc_param = (VAEncMiscParameterBuffer *)encode_state->misc_param[i][j]->buffer;
705 if (!(encoder_context->rate_control_mode & (VA_RC_CBR | VA_RC_VBR))) {
706 if (misc_param->type != VAEncMiscParameterTypeROI)
710 switch (misc_param->type) {
711 case VAEncMiscParameterTypeFrameRate:
712 intel_encoder_check_framerate_parameter(ctx,
714 (VAEncMiscParameterFrameRate *)misc_param->data);
717 case VAEncMiscParameterTypeRateControl:
718 intel_encoder_check_rate_control_parameter(ctx,
720 (VAEncMiscParameterRateControl *)misc_param->data,
721 &hl_bitrate_updated);
724 case VAEncMiscParameterTypeHRD:
725 intel_encoder_check_hrd_parameter(ctx,
727 (VAEncMiscParameterHRD *)misc_param->data);
730 case VAEncMiscParameterTypeROI:
731 intel_encoder_check_roi_parameter(ctx,
733 (VAEncMiscParameterBufferROI *)misc_param->data);
742 if (!hl_bitrate_updated && seq_bits_per_second &&
743 encoder_context->brc.bits_per_second[encoder_context->layer.num_layers - 1] != seq_bits_per_second) {
745 encoder_context->brc.bits_per_second[encoder_context->layer.num_layers - 1] = seq_bits_per_second;
746 encoder_context->brc.need_reset = 1;
750 return VA_STATUS_SUCCESS;
754 intel_encoder_check_temporal_layer_structure(VADriverContextP ctx,
755 struct encode_state *encode_state,
756 struct intel_encoder_context *encoder_context)
758 VAEncMiscParameterBuffer* misc_param;
759 VAEncMiscParameterTemporalLayerStructure *tls_paramter;
760 unsigned int rate_control_mode = encoder_context->rate_control_mode;
763 if (!encoder_context->is_new_sequence) {
764 if (encoder_context->layer.num_layers > 1)
765 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];
767 encoder_context->layer.curr_frame_layer_id = 0;
769 return VA_STATUS_SUCCESS;
772 if (!(rate_control_mode & (VA_RC_CBR | VA_RC_VBR)))
773 return VA_STATUS_SUCCESS;
775 if (!encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0] ||
776 !encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0]->buffer)
777 return VA_STATUS_SUCCESS;
779 misc_param = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0]->buffer;
780 tls_paramter = (VAEncMiscParameterTemporalLayerStructure *)misc_param->data;
782 if (tls_paramter->number_of_layers <= 1)
783 return VA_STATUS_SUCCESS;
785 if (tls_paramter->number_of_layers > MAX_TEMPORAL_LAYERS)
786 return VA_STATUS_ERROR_INVALID_PARAMETER;
788 if (tls_paramter->periodicity > 32 || tls_paramter->periodicity <= 1)
789 return VA_STATUS_ERROR_INVALID_PARAMETER;
791 for (i = 0; i < tls_paramter->number_of_layers; i++) {
792 if (!encode_state->misc_param[VAEncMiscParameterTypeRateControl][i] ||
793 !encode_state->misc_param[VAEncMiscParameterTypeRateControl][i]->buffer ||
794 !encode_state->misc_param[VAEncMiscParameterTypeFrameRate][i] ||
795 !encode_state->misc_param[VAEncMiscParameterTypeFrameRate][i]->buffer) {
797 return VA_STATUS_ERROR_INVALID_PARAMETER;
801 encoder_context->layer.size_frame_layer_ids = tls_paramter->periodicity;
802 encoder_context->layer.num_layers = tls_paramter->number_of_layers;
804 for (i = 0; i < encoder_context->layer.size_frame_layer_ids; i++) {
805 if (tls_paramter->layer_id[i] >= tls_paramter->number_of_layers)
806 return VA_STATUS_ERROR_INVALID_PARAMETER;
808 encoder_context->layer.frame_layer_ids[i] = tls_paramter->layer_id[i];
811 if (encoder_context->is_new_sequence)
812 encoder_context->layer.curr_frame_layer_id = 0;
814 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];
816 return VA_STATUS_SUCCESS;
820 intel_encoder_check_misc_parameter(VADriverContextP ctx,
822 struct encode_state *encode_state,
823 struct intel_encoder_context *encoder_context)
825 struct i965_driver_data *i965 = i965_driver_data(ctx);
826 VAStatus ret = VA_STATUS_SUCCESS;
827 int min_width_height = I965_MIN_CODEC_ENC_RESOLUTION_WIDTH_HEIGHT;
829 if (encoder_context->frame_width_in_pixel > 0 &&
830 encoder_context->frame_height_in_pixel > 0) {
831 if (profile == VAProfileJPEGBaseline)
832 min_width_height = 1;
833 if (encoder_context->frame_width_in_pixel < min_width_height ||
834 encoder_context->frame_height_in_pixel < min_width_height)
835 return VA_STATUS_ERROR_INVALID_PARAMETER;
838 if (encode_state->misc_param[VAEncMiscParameterTypeQualityLevel][0] &&
839 encode_state->misc_param[VAEncMiscParameterTypeQualityLevel][0]->buffer) {
840 VAEncMiscParameterBuffer* pMiscParam = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeQualityLevel][0]->buffer;
841 VAEncMiscParameterBufferQualityLevel* param_quality_level = (VAEncMiscParameterBufferQualityLevel*)pMiscParam->data;
842 encoder_context->quality_level = param_quality_level->quality_level;
844 if (encoder_context->quality_level == 0) {
846 case VAProfileH264ConstrainedBaseline:
847 case VAProfileH264Main:
848 case VAProfileH264High:
849 case VAProfileH264MultiviewHigh:
850 case VAProfileH264StereoHigh:
851 if (IS_GEN9(i965->intel.device_info) ||
852 IS_GEN10(i965->intel.device_info))
853 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
856 case VAProfileHEVCMain:
857 case VAProfileHEVCMain10:
858 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_HEVC;
862 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
865 } else if (encoder_context->quality_level > encoder_context->quality_range) {
866 i965_log_info(ctx, "VAEncMiscParameterBufferQualityLevel.quality_level (%d) out of range (max %d).\n",
867 encoder_context->quality_level, encoder_context->quality_range);
868 ret = VA_STATUS_ERROR_INVALID_PARAMETER;
873 ret = intel_encoder_check_temporal_layer_structure(ctx, encode_state, encoder_context);
878 ret = intel_encoder_check_brc_parameter(ctx, encode_state, encoder_context);
885 intel_encoder_check_avc_parameter(VADriverContextP ctx,
886 struct encode_state *encode_state,
887 struct intel_encoder_context *encoder_context)
889 struct i965_driver_data *i965 = i965_driver_data(ctx);
890 struct object_surface *obj_surface;
891 struct object_buffer *obj_buffer;
892 VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
893 VAEncSequenceParameterBufferH264 *seq_param = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
896 if (seq_param->level_idc != encoder_context->codec_level &&
897 !i965_avc_level_is_valid(seq_param->level_idc)) {
898 i965_log_info(ctx, "VAEncSequenceParameterBufferH264.level_idc (%d) does not appear to be valid.\n",
899 seq_param->level_idc);
900 encoder_context->codec_level = seq_param->level_idc;
901 // Only print this the first time we see it, and continue anyway - this could be a correct future
902 // value or an unknown extension.
905 if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID) {
906 i965_log_info(ctx, "VAEncPictureParameterBufferH264.CurrPic.flags (%#x) is invalid.\n",
907 pic_param->CurrPic.flags);
911 obj_surface = SURFACE(pic_param->CurrPic.picture_id);
913 i965_log_info(ctx, "VAEncPictureParameterBufferH264.CurrPic.picture_id (%#x) is not a valid surface.\n",
914 pic_param->CurrPic.picture_id);
918 encode_state->reconstructed_object = obj_surface;
919 obj_buffer = BUFFER(pic_param->coded_buf);
920 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo) {
921 i965_log_info(ctx, "VAEncPictureParameterBufferH264.coded_buf (%#x) is not a valid buffer.\n",
922 pic_param->coded_buf);
926 if (encode_state->num_slice_params_ext > encoder_context->max_slice_or_seg_num) {
927 i965_log_info(ctx, "Too many slices in picture submission: %d, max supported is %d.\n",
928 encode_state->num_slice_params_ext, encoder_context->max_slice_or_seg_num);
932 encode_state->coded_buf_object = obj_buffer;
934 for (i = 0; i < 16; i++) {
935 if (pic_param->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID ||
936 pic_param->ReferenceFrames[i].picture_id == VA_INVALID_SURFACE)
939 obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id);
940 if (!obj_surface || !obj_surface->bo) {
941 i965_log_info(ctx, "VAEncPictureParameterBufferH264.ReferenceFrames[%d].picture_id (%#x)"
942 " is not a valid surface.\n", i, pic_param->ReferenceFrames[i].picture_id);
945 encode_state->reference_objects[i] = obj_surface;
950 encode_state->reference_objects[i] = NULL;
953 * A sequence consists of an IDR unit, followed by zero or more non-IDR unit, but not including any
954 * subsequent IDR unit, so idr_pic_flag can indicate the current frame is the start of a new
957 encoder_context->is_new_sequence = (pic_param->pic_fields.bits.idr_pic_flag && seq_param);
959 if (encoder_context->is_new_sequence) {
960 encoder_context->num_frames_in_sequence = 0;
961 encoder_context->frame_width_in_pixel = seq_param->picture_width_in_mbs * 16;
962 encoder_context->frame_height_in_pixel = seq_param->picture_height_in_mbs * 16;
965 return VA_STATUS_SUCCESS;
968 return VA_STATUS_ERROR_INVALID_PARAMETER;
972 intel_pre_encoder_check_avc_parameter(VADriverContextP ctx,
973 struct encode_state *encode_state,
974 struct intel_encoder_context *encoder_context)
976 struct i965_driver_data *i965 = i965_driver_data(ctx);
977 struct object_surface *obj_surface = NULL;
978 VAStatsStatisticsParameterH264 *stat_param_h264 = NULL;
979 VAStatsStatisticsParameter*stat_param = NULL;
981 if (!encode_state->stat_param_ext)
984 (VAStatsStatisticsParameterH264 *) encode_state->stat_param_ext->buffer;
985 stat_param = (VAStatsStatisticsParameter *)(&stat_param_h264->stats_params);
987 if (stat_param->input.flags == VA_PICTURE_STATS_INVALID)
990 obj_surface = SURFACE(encoder_context->input_yuv_surface);
995 /* FeiPreEncFixme: Since the driver is doing internal CSC for non NV12
996 input surfaces, this check may fail here */
997 /* Make sure the same input yuv has been provided in vaBeginPicture()
998 * and VAStatsStatisticsParameter */
999 if (obj_surface != SURFACE(stat_param->input.picture_id))
1003 /* There is no reconstructed object in preenc. Here we just assigning
1004 * the input yuv object to reconstructed object pointer inorder
1005 * to use the same encode code path later on */
1006 encode_state->reconstructed_object = obj_surface;
1008 encoder_context->frame_width_in_pixel = obj_surface->orig_width;
1009 encoder_context->frame_height_in_pixel = obj_surface->orig_height;
1011 /* PreEnc only supports maxium of 1 past and 1 future reference */
1012 if (stat_param->num_past_references > 1 || stat_param->num_future_references > 1)
1015 return VA_STATUS_SUCCESS;
1017 return VA_STATUS_ERROR_INVALID_PARAMETER;
1021 intel_encoder_check_mpeg2_parameter(VADriverContextP ctx,
1022 struct encode_state *encode_state,
1023 struct intel_encoder_context *encoder_context)
1025 struct i965_driver_data *i965 = i965_driver_data(ctx);
1026 VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
1027 VAEncSequenceParameterBufferMPEG2 *seq_param = NULL;
1028 struct object_surface *obj_surface;
1029 struct object_buffer *obj_buffer;
1032 if (encode_state->seq_param_ext &&
1033 encode_state->seq_param_ext->buffer)
1034 seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
1036 obj_surface = SURFACE(pic_param->reconstructed_picture);
1037 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
1042 encode_state->reconstructed_object = obj_surface;
1043 obj_buffer = BUFFER(pic_param->coded_buf);
1044 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
1046 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1049 encode_state->coded_buf_object = obj_buffer;
1051 if (pic_param->picture_type == VAEncPictureTypeIntra) {
1052 } else if (pic_param->picture_type == VAEncPictureTypePredictive) {
1053 assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
1054 obj_surface = SURFACE(pic_param->forward_reference_picture);
1055 assert(obj_surface && obj_surface->bo);
1057 if (!obj_surface || !obj_surface->bo)
1060 encode_state->reference_objects[i++] = obj_surface;
1061 } else if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
1062 assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
1063 obj_surface = SURFACE(pic_param->forward_reference_picture);
1064 assert(obj_surface && obj_surface->bo);
1066 if (!obj_surface || !obj_surface->bo)
1069 encode_state->reference_objects[i++] = obj_surface;
1071 assert(pic_param->backward_reference_picture != VA_INVALID_SURFACE);
1072 obj_surface = SURFACE(pic_param->backward_reference_picture);
1073 assert(obj_surface && obj_surface->bo);
1075 if (!obj_surface || !obj_surface->bo)
1078 encode_state->reference_objects[i++] = obj_surface;
1083 encode_state->reference_objects[i] = NULL;
1086 encoder_context->frame_width_in_pixel = seq_param->picture_width;
1087 encoder_context->frame_height_in_pixel = seq_param->picture_height;
1090 return VA_STATUS_SUCCESS;
1093 return VA_STATUS_ERROR_INVALID_PARAMETER;
1097 intel_encoder_check_jpeg_parameter(VADriverContextP ctx,
1098 struct encode_state *encode_state,
1099 struct intel_encoder_context *encoder_context)
1101 struct i965_driver_data *i965 = i965_driver_data(ctx);
1102 struct object_buffer *obj_buffer;
1103 VAEncPictureParameterBufferJPEG *pic_param = (VAEncPictureParameterBufferJPEG *)encode_state->pic_param_ext->buffer;
1106 assert(!(pic_param->pic_flags.bits.profile)); //Baseline profile is 0.
1108 obj_buffer = BUFFER(pic_param->coded_buf);
1109 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
1111 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1114 encode_state->coded_buf_object = obj_buffer;
1116 encoder_context->frame_width_in_pixel = pic_param->picture_width;
1117 encoder_context->frame_height_in_pixel = pic_param->picture_height;
1119 return VA_STATUS_SUCCESS;
1122 return VA_STATUS_ERROR_INVALID_PARAMETER;
1126 intel_encoder_check_vp8_parameter(VADriverContextP ctx,
1127 struct encode_state *encode_state,
1128 struct intel_encoder_context *encoder_context)
1130 struct i965_driver_data *i965 = i965_driver_data(ctx);
1131 VAEncPictureParameterBufferVP8 *pic_param = (VAEncPictureParameterBufferVP8 *)encode_state->pic_param_ext->buffer;
1132 VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer;
1133 struct object_surface *obj_surface;
1134 struct object_buffer *obj_buffer;
1136 int is_key_frame = !pic_param->pic_flags.bits.frame_type;
1138 obj_surface = SURFACE(pic_param->reconstructed_frame);
1139 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
1144 encode_state->reconstructed_object = obj_surface;
1145 obj_buffer = BUFFER(pic_param->coded_buf);
1146 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
1148 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1151 encode_state->coded_buf_object = obj_buffer;
1153 if (!is_key_frame) {
1154 assert(pic_param->ref_last_frame != VA_INVALID_SURFACE);
1155 obj_surface = SURFACE(pic_param->ref_last_frame);
1156 assert(obj_surface && obj_surface->bo);
1158 if (!obj_surface || !obj_surface->bo)
1161 encode_state->reference_objects[i++] = obj_surface;
1163 assert(pic_param->ref_gf_frame != VA_INVALID_SURFACE);
1164 obj_surface = SURFACE(pic_param->ref_gf_frame);
1165 assert(obj_surface && obj_surface->bo);
1167 if (!obj_surface || !obj_surface->bo)
1170 encode_state->reference_objects[i++] = obj_surface;
1172 assert(pic_param->ref_arf_frame != VA_INVALID_SURFACE);
1173 obj_surface = SURFACE(pic_param->ref_arf_frame);
1174 assert(obj_surface && obj_surface->bo);
1176 if (!obj_surface || !obj_surface->bo)
1179 encode_state->reference_objects[i++] = obj_surface;
1183 encode_state->reference_objects[i] = NULL;
1185 encoder_context->is_new_sequence = (is_key_frame && seq_param);
1187 if (encoder_context->is_new_sequence) {
1188 encoder_context->num_frames_in_sequence = 0;
1189 encoder_context->frame_width_in_pixel = seq_param->frame_width;
1190 encoder_context->frame_height_in_pixel = seq_param->frame_height;
1193 return VA_STATUS_SUCCESS;
1196 return VA_STATUS_ERROR_INVALID_PARAMETER;
1200 intel_encoder_check_hevc_parameter(VADriverContextP ctx,
1201 struct encode_state *encode_state,
1202 struct intel_encoder_context *encoder_context)
1204 struct i965_driver_data *i965 = i965_driver_data(ctx);
1205 struct object_surface *obj_surface;
1206 struct object_buffer *obj_buffer;
1207 VAEncPictureParameterBufferHEVC *pic_param = (VAEncPictureParameterBufferHEVC *)encode_state->pic_param_ext->buffer;
1208 VAEncSliceParameterBufferHEVC *slice_param;
1209 VAEncSequenceParameterBufferHEVC *seq_param;
1214 if (encode_state->seq_param_ext &&
1215 encode_state->seq_param_ext->buffer)
1216 seq_param = (VAEncSequenceParameterBufferHEVC *)(encode_state->seq_param_ext->buffer);
1218 if (pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID) {
1219 i965_log_info(ctx, "VAEncPictureParameterBufferHEVC.decoded_curr_pic.flags (%#x) is invalid.\n",
1220 pic_param->decoded_curr_pic.flags);
1224 obj_surface = SURFACE(pic_param->decoded_curr_pic.picture_id);
1226 i965_log_info(ctx, "VAEncPictureParameterBufferHEVC.decoded_curr_pic.picture_id (%#x) is not a valid surface.\n",
1227 pic_param->decoded_curr_pic.picture_id);
1231 encode_state->reconstructed_object = obj_surface;
1232 obj_buffer = BUFFER(pic_param->coded_buf);
1233 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo) {
1234 i965_log_info(ctx, "VAEncPictureParameterBufferHEVC.coded_buf (%#x) is not a valid buffer.\n",
1235 pic_param->coded_buf);
1239 if (encode_state->num_slice_params_ext > encoder_context->max_slice_or_seg_num) {
1240 i965_log_info(ctx, "Too many slices in picture submission: %d, max supported is %d.\n",
1241 encode_state->num_slice_params_ext, encoder_context->max_slice_or_seg_num);
1245 encode_state->coded_buf_object = obj_buffer;
1247 for (i = 0; i < 15; i++) {
1248 if (pic_param->reference_frames[i].flags & VA_PICTURE_HEVC_INVALID ||
1249 pic_param->reference_frames[i].picture_id == VA_INVALID_SURFACE)
1252 obj_surface = SURFACE(pic_param->reference_frames[i].picture_id);
1253 if (!obj_surface || !obj_surface->bo) {
1254 i965_log_info(ctx, "VAEncPictureParameterBufferHEVC.reference_frames[%d].picture_id (%#x)"
1255 " is not a valid surface.\n", i, pic_param->reference_frames[i].picture_id);
1258 encode_state->reference_objects[i] = obj_surface;
1263 encode_state->reference_objects[i] = NULL;
1265 for (i = 0; i < encode_state->num_slice_params_ext; i++) {
1266 slice_param = (VAEncSliceParameterBufferHEVC *)encode_state->slice_params_ext[i]->buffer;
1268 if (slice_param->slice_type != HEVC_SLICE_I &&
1269 slice_param->slice_type != HEVC_SLICE_P &&
1270 slice_param->slice_type != HEVC_SLICE_B)
1273 /* TODO: add more check here */
1276 encoder_context->is_new_sequence = (pic_param->pic_fields.bits.idr_pic_flag && seq_param);
1278 if (encoder_context->is_new_sequence) {
1279 encoder_context->num_frames_in_sequence = 0;
1280 encoder_context->frame_width_in_pixel = seq_param->pic_width_in_luma_samples;
1281 encoder_context->frame_height_in_pixel = seq_param->pic_height_in_luma_samples;
1284 return VA_STATUS_SUCCESS;
1287 return VA_STATUS_ERROR_INVALID_PARAMETER;
1291 intel_encoder_check_vp9_parameter(VADriverContextP ctx,
1292 struct encode_state *encode_state,
1293 struct intel_encoder_context *encoder_context)
1295 struct i965_driver_data *i965 = i965_driver_data(ctx);
1296 VAEncPictureParameterBufferVP9 *pic_param;
1297 VAEncSequenceParameterBufferVP9 *seq_param;
1298 struct object_surface *obj_surface;
1299 struct object_buffer *obj_buffer;
1301 int is_key_frame = 0;
1304 if (encode_state->pic_param_ext == NULL ||
1305 encode_state->pic_param_ext->buffer == NULL)
1306 return VA_STATUS_ERROR_INVALID_PARAMETER;
1309 if (encode_state->seq_param_ext &&
1310 encode_state->seq_param_ext->buffer)
1311 seq_param = (VAEncSequenceParameterBufferVP9 *)(encode_state->seq_param_ext->buffer);
1313 pic_param = (VAEncPictureParameterBufferVP9 *)encode_state->pic_param_ext->buffer;
1315 obj_surface = SURFACE(pic_param->reconstructed_frame);
1320 encode_state->reconstructed_object = obj_surface;
1321 obj_buffer = BUFFER(pic_param->coded_buf);
1323 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1326 encode_state->coded_buf_object = obj_buffer;
1328 is_key_frame = !pic_param->pic_flags.bits.frame_type;
1329 if (!is_key_frame && !pic_param->pic_flags.bits.intra_only) {
1330 /* slot 0 is for last reference frame */
1331 index = pic_param->ref_flags.bits.ref_last_idx;
1332 obj_surface = SURFACE(pic_param->reference_frames[index]);
1333 if (obj_surface && obj_surface->bo)
1334 encode_state->reference_objects[i++] = obj_surface;
1336 encode_state->reference_objects[i++] = NULL;
1338 /* slot 1 is for golden reference frame */
1339 index = pic_param->ref_flags.bits.ref_gf_idx;
1340 obj_surface = SURFACE(pic_param->reference_frames[index]);
1341 if (obj_surface && obj_surface->bo)
1342 encode_state->reference_objects[i++] = obj_surface;
1344 encode_state->reference_objects[i++] = NULL;
1346 /* slot 2 is alt reference frame */
1347 index = pic_param->ref_flags.bits.ref_arf_idx;
1348 obj_surface = SURFACE(pic_param->reference_frames[index]);
1349 if (obj_surface && obj_surface->bo)
1350 encode_state->reference_objects[i++] = obj_surface;
1352 encode_state->reference_objects[i++] = NULL;
1356 encode_state->reference_objects[i] = NULL;
1358 encoder_context->is_new_sequence = (is_key_frame && seq_param);
1360 encoder_context->frame_width_in_pixel = pic_param->frame_width_src;
1361 encoder_context->frame_height_in_pixel = pic_param->frame_height_src;
1363 return VA_STATUS_SUCCESS;
1366 return VA_STATUS_ERROR_INVALID_PARAMETER;
1371 intel_encoder_sanity_check_input(VADriverContextP ctx,
1373 struct encode_state *encode_state,
1374 struct intel_encoder_context *encoder_context)
1379 case VAProfileH264ConstrainedBaseline:
1380 case VAProfileH264Main:
1381 case VAProfileH264High:
1382 case VAProfileH264MultiviewHigh:
1383 case VAProfileH264StereoHigh: {
1384 if (!encoder_context->preenc_enabled) {
1385 vaStatus = intel_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
1386 if (vaStatus != VA_STATUS_SUCCESS)
1388 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1391 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1392 if (vaStatus != VA_STATUS_SUCCESS)
1395 vaStatus = intel_pre_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
1400 case VAProfileMPEG2Simple:
1401 case VAProfileMPEG2Main: {
1402 vaStatus = intel_encoder_check_mpeg2_parameter(ctx, encode_state, encoder_context);
1403 if (vaStatus != VA_STATUS_SUCCESS)
1405 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1409 case VAProfileJPEGBaseline: {
1410 vaStatus = intel_encoder_check_jpeg_parameter(ctx, encode_state, encoder_context);
1411 if (vaStatus != VA_STATUS_SUCCESS)
1413 vaStatus = intel_encoder_check_jpeg_yuv_surface(ctx, profile, encode_state, encoder_context);
1417 case VAProfileVP8Version0_3: {
1418 vaStatus = intel_encoder_check_vp8_parameter(ctx, encode_state, encoder_context);
1419 if (vaStatus != VA_STATUS_SUCCESS)
1421 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1425 case VAProfileHEVCMain:
1426 case VAProfileHEVCMain10: {
1427 vaStatus = intel_encoder_check_hevc_parameter(ctx, encode_state, encoder_context);
1428 if (vaStatus != VA_STATUS_SUCCESS)
1430 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1434 case VAProfileVP9Profile0: {
1435 vaStatus = intel_encoder_check_vp9_parameter(ctx, encode_state, encoder_context);
1436 if (vaStatus != VA_STATUS_SUCCESS)
1438 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1442 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1446 if (vaStatus == VA_STATUS_SUCCESS)
1447 vaStatus = intel_encoder_check_misc_parameter(ctx, profile, encode_state, encoder_context);
1454 intel_encoder_end_picture(VADriverContextP ctx,
1456 union codec_state *codec_state,
1457 struct hw_context *hw_context)
1459 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
1460 struct encode_state *encode_state = &codec_state->encode;
1463 vaStatus = intel_encoder_sanity_check_input(ctx, profile, encode_state, encoder_context);
1465 if (vaStatus != VA_STATUS_SUCCESS)
1468 encoder_context->mfc_brc_prepare(encode_state, encoder_context);
1470 /* VME or PAK stages are separately invoked if middleware configured the corresponding
1471 * FEI modes through confgiruation attributes. On the other hand, ENC_PAK mode
1472 * will invoke both VME and PAK similar to the non fei use case.
1473 * PreEnc always invoke the VME */
1474 if (encoder_context->fei_enabled || encoder_context->preenc_enabled) {
1475 if ((encoder_context->fei_function_mode == VA_FEI_FUNCTION_ENC) ||
1476 (encoder_context->preenc_enabled)) {
1477 if ((encoder_context->vme_context && encoder_context->vme_pipeline))
1478 return encoder_context->vme_pipeline(ctx, profile, encode_state, encoder_context);
1479 } else if (encoder_context->fei_function_mode == VA_FEI_FUNCTION_PAK) {
1480 if ((encoder_context->mfc_context && encoder_context->mfc_pipeline))
1481 return encoder_context->mfc_pipeline(ctx, profile, encode_state, encoder_context);
1483 /* Setting ENC and PAK as ENC|PAK is invalid */
1484 assert(encoder_context->fei_function_mode != (VA_FEI_FUNCTION_ENC | VA_FEI_FUNCTION_PAK));
1487 if ((encoder_context->vme_context && encoder_context->vme_pipeline)) {
1488 vaStatus = encoder_context->vme_pipeline(ctx, profile, encode_state, encoder_context);
1489 if (vaStatus != VA_STATUS_SUCCESS)
1493 assert(encoder_context->mfc_pipeline != NULL);
1494 encoder_context->mfc_pipeline(ctx, profile, encode_state, encoder_context);
1495 encoder_context->num_frames_in_sequence++;
1496 encoder_context->brc.need_reset = 0;
1498 * ROI is only available for the current frame, see the comment
1499 * for VAEncROI in va.h
1501 encoder_context->brc.num_roi = 0;
1503 return VA_STATUS_SUCCESS;
1507 intel_encoder_context_destroy(void *hw_context)
1509 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
1511 encoder_context->mfc_context_destroy(encoder_context->mfc_context);
1513 if (encoder_context->vme_context_destroy && encoder_context->vme_context)
1514 encoder_context->vme_context_destroy(encoder_context->vme_context);
1516 if (encoder_context->enc_priv_state) {
1517 free(encoder_context->enc_priv_state);
1518 encoder_context->enc_priv_state = NULL;
1521 if (encoder_context->is_tmp_id) {
1522 assert(encoder_context->input_yuv_surface != VA_INVALID_SURFACE);
1523 i965_DestroySurfaces(encoder_context->ctx, &encoder_context->input_yuv_surface, 1);
1524 encoder_context->is_tmp_id = 0;
1527 intel_batchbuffer_free(encoder_context->base.batch);
1528 free(encoder_context);
1533 intel_encoder_get_status(VADriverContextP ctx, struct hw_context *hw_context, void *buffer)
1535 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
1536 struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer;
1538 if (encoder_context->get_status)
1539 return encoder_context->get_status(ctx, encoder_context, coded_buffer_segment);
1541 return VA_STATUS_ERROR_UNIMPLEMENTED;
1544 typedef Bool(* hw_init_func)(VADriverContextP, struct intel_encoder_context *);
1546 static struct hw_context *
1547 intel_enc_hw_context_init(VADriverContextP ctx,
1548 struct object_config *obj_config,
1549 hw_init_func vme_context_init,
1550 hw_init_func mfc_context_init)
1552 struct i965_driver_data *i965 = i965_driver_data(ctx);
1553 struct intel_driver_data *intel = intel_driver_data(ctx);
1554 struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
1557 assert(encoder_context);
1558 encoder_context->base.destroy = intel_encoder_context_destroy;
1559 encoder_context->base.run = intel_encoder_end_picture;
1560 encoder_context->base.get_status = intel_encoder_get_status;
1561 encoder_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
1562 encoder_context->input_yuv_surface = VA_INVALID_SURFACE;
1563 encoder_context->is_tmp_id = 0;
1564 encoder_context->low_power_mode = 0;
1565 encoder_context->rate_control_mode = VA_RC_NONE;
1566 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
1567 encoder_context->quality_range = 1;
1568 encoder_context->layer.num_layers = 1;
1569 encoder_context->max_slice_or_seg_num = 1;
1570 encoder_context->ctx = ctx;
1572 if (obj_config->entrypoint == VAEntrypointEncSliceLP)
1573 encoder_context->low_power_mode = 1;
1575 switch (obj_config->profile) {
1576 case VAProfileMPEG2Simple:
1577 case VAProfileMPEG2Main:
1578 encoder_context->codec = CODEC_MPEG2;
1581 case VAProfileH264ConstrainedBaseline:
1582 case VAProfileH264Main:
1583 case VAProfileH264High:
1584 encoder_context->codec = CODEC_H264;
1586 if (obj_config->entrypoint == VAEntrypointEncSliceLP)
1587 encoder_context->quality_range = ENCODER_LP_QUALITY_RANGE;
1588 else if (IS_GEN9(i965->intel.device_info) ||
1589 IS_GEN10(i965->intel.device_info)) {
1590 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
1591 encoder_context->quality_range = ENCODER_QUALITY_RANGE_AVC;
1593 encoder_context->quality_range = ENCODER_QUALITY_RANGE;
1595 if (obj_config->entrypoint == VAEntrypointFEI) {
1596 encoder_context->fei_enabled = 1;
1597 /* check which attribute has been configured for FEI, this is
1598 * required for VME/PAK disable or enable as per user request */
1599 for (i = 0; i < obj_config->num_attribs; i++) {
1600 if (obj_config->attrib_list[i].type == VAConfigAttribFEIFunctionType)
1601 encoder_context->fei_function_mode = obj_config->attrib_list[i].value;
1605 if (obj_config->entrypoint == VAEntrypointStats)
1606 encoder_context->preenc_enabled = 1;
1610 case VAProfileH264StereoHigh:
1611 case VAProfileH264MultiviewHigh:
1612 if (IS_GEN9(i965->intel.device_info) ||
1613 IS_GEN10(i965->intel.device_info)) {
1614 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
1615 encoder_context->quality_range = ENCODER_QUALITY_RANGE_AVC;
1617 encoder_context->codec = CODEC_H264_MVC;
1620 case VAProfileJPEGBaseline:
1621 encoder_context->codec = CODEC_JPEG;
1624 case VAProfileVP8Version0_3:
1625 encoder_context->codec = CODEC_VP8;
1626 encoder_context->quality_range = ENCODER_QUALITY_RANGE;
1630 case VAProfileHEVCMain:
1631 case VAProfileHEVCMain10:
1632 encoder_context->codec = CODEC_HEVC;
1634 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_HEVC;
1635 encoder_context->quality_range = ENCODER_QUALITY_RANGE_HEVC;
1637 encoder_context->max_slice_or_seg_num = I965_MAX_NUM_SLICE;
1640 case VAProfileVP9Profile0:
1641 encoder_context->codec = CODEC_VP9;
1643 if (obj_config->entrypoint == VAEntrypointEncSliceLP) {
1644 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_VP9;
1645 encoder_context->quality_range = ENCODER_QUALITY_RANGE_VP9;
1651 /* Never get here */
1656 for (i = 0; i < obj_config->num_attribs; i++) {
1657 if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) {
1658 encoder_context->rate_control_mode = obj_config->attrib_list[i].value;
1660 if (encoder_context->codec == CODEC_MPEG2 &&
1661 encoder_context->rate_control_mode & VA_RC_CBR) {
1662 WARN_ONCE("Don't support CBR for MPEG-2 encoding\n");
1663 encoder_context->rate_control_mode &= ~VA_RC_CBR;
1666 if (obj_config->attrib_list[i].type == VAConfigAttribEncROI) {
1667 if (encoder_context->codec == CODEC_H264)
1668 encoder_context->context_roi = 1;
1670 if (obj_config->attrib_list[i].type == VAConfigAttribEncMaxSlices) {
1671 if (encoder_context->codec == CODEC_H264 ||
1672 encoder_context->codec == CODEC_HEVC)
1673 encoder_context->max_slice_or_seg_num = obj_config->attrib_list[i].value;
1677 if (vme_context_init) {
1678 vme_context_init(ctx, encoder_context);
1679 assert(!encoder_context->vme_context ||
1680 (encoder_context->vme_context_destroy && encoder_context->vme_pipeline));
1683 mfc_context_init(ctx, encoder_context);
1684 assert(encoder_context->mfc_context);
1685 assert(encoder_context->mfc_context_destroy);
1686 assert(encoder_context->mfc_pipeline);
1688 return (struct hw_context *)encoder_context;
1692 gen6_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1694 return intel_enc_hw_context_init(ctx, obj_config, gen6_vme_context_init, gen6_mfc_context_init);
1698 gen7_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1701 return intel_enc_hw_context_init(ctx, obj_config, gen7_vme_context_init, gen7_mfc_context_init);
1705 gen75_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1707 return intel_enc_hw_context_init(ctx, obj_config, gen75_vme_context_init, gen75_mfc_context_init);
1711 gen8_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1713 return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init);
1717 gen9_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1719 return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_mfc_context_init);