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"
46 static struct intel_fraction
47 reduce_fraction(struct intel_fraction f)
49 unsigned int a = f.num, b = f.den, c;
54 return (struct intel_fraction) {
60 clear_border(struct object_surface *obj_surface)
62 int width[3], height[3], hstride[3], vstride[3]; /* in byte */
67 if (obj_surface->border_cleared)
68 return VA_STATUS_SUCCESS;
70 if (obj_surface->fourcc == VA_FOURCC_NV12) {
72 width[0] = width[1] = obj_surface->orig_width;
73 height[0] = obj_surface->orig_height;
74 height[1] = obj_surface->orig_height / 2;
75 hstride[0] = hstride[1] = obj_surface->width;
76 vstride[0] = obj_surface->height;
77 vstride[1] = obj_surface->height / 2;
81 return VA_STATUS_SUCCESS;
83 drm_intel_gem_bo_map_gtt(obj_surface->bo);
85 p = (unsigned char*)obj_surface->bo->virtual;
87 return VA_STATUS_ERROR_INVALID_SURFACE;
89 for (i = 0; i < planes; i++) {
95 for (j = 0; j < h; j++) {
96 memset(p + w, 0, hs - w);
100 for (/* nothing */; j < vs; j++) {
106 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
107 obj_surface->border_cleared = true;
108 return VA_STATUS_SUCCESS;
112 intel_encoder_check_yuv_surface(VADriverContextP ctx,
114 struct encode_state *encode_state,
115 struct intel_encoder_context *encoder_context)
117 struct i965_driver_data *i965 = i965_driver_data(ctx);
118 struct i965_surface src_surface, dst_surface;
119 struct object_surface *obj_surface;
122 int format = VA_RT_FORMAT_YUV420;
123 unsigned int fourcc = VA_FOURCC_NV12;
125 /* releae the temporary surface */
126 if (encoder_context->is_tmp_id) {
127 i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
128 encode_state->input_yuv_object = NULL;
131 encoder_context->is_tmp_id = 0;
132 obj_surface = SURFACE(encode_state->current_render_target);
133 assert(obj_surface && obj_surface->bo);
135 if (!obj_surface || !obj_surface->bo)
136 return VA_STATUS_ERROR_INVALID_PARAMETER;
138 if (VAProfileHEVCMain10 == profile &&
139 obj_surface->fourcc != VA_FOURCC_P010)
140 return VA_STATUS_ERROR_INVALID_PARAMETER;
142 if (obj_surface->fourcc == VA_FOURCC_NV12 ||
143 (VAProfileHEVCMain10 == profile &&
144 obj_surface->fourcc == VA_FOURCC_P010)) {
146 unsigned int tiling = 0, swizzle = 0;
147 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
149 if (tiling == I915_TILING_Y) {
150 encoder_context->input_yuv_surface = encode_state->current_render_target;
151 encode_state->input_yuv_object = obj_surface;
152 return clear_border(obj_surface);
156 if (VAProfileHEVCMain10 == profile) {
157 format = VA_RT_FORMAT_YUV420_10BPP;
158 fourcc = VA_FOURCC_P010;
163 rect.width = obj_surface->orig_width;
164 rect.height = obj_surface->orig_height;
166 src_surface.base = (struct object_base *)obj_surface;
167 src_surface.type = I965_SURFACE_TYPE_SURFACE;
168 src_surface.flags = I965_SURFACE_FLAG_FRAME;
170 status = i965_CreateSurfaces(ctx,
171 obj_surface->orig_width,
172 obj_surface->orig_height,
175 &encoder_context->input_yuv_surface);
176 ASSERT_RET(status == VA_STATUS_SUCCESS, status);
178 obj_surface = SURFACE(encoder_context->input_yuv_surface);
179 encode_state->input_yuv_object = obj_surface;
181 i965_check_alloc_surface_bo(ctx, obj_surface, 1, fourcc, SUBSAMPLE_YUV420);
183 dst_surface.base = (struct object_base *)obj_surface;
184 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
185 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
187 status = i965_image_processing(ctx,
192 assert(status == VA_STATUS_SUCCESS);
194 encoder_context->is_tmp_id = 1;
196 return clear_border(obj_surface);
201 intel_encoder_check_jpeg_yuv_surface(VADriverContextP ctx,
203 struct encode_state *encode_state,
204 struct intel_encoder_context *encoder_context)
206 struct i965_driver_data *i965 = i965_driver_data(ctx);
207 struct i965_surface src_surface, dst_surface;
208 struct object_surface *obj_surface;
211 int format = 0, fourcc = 0, subsample = 0;
213 /* releae the temporary surface */
214 if (encoder_context->is_tmp_id) {
215 i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
216 encode_state->input_yuv_object = NULL;
219 encoder_context->is_tmp_id = 0;
220 obj_surface = SURFACE(encode_state->current_render_target);
221 assert(obj_surface && obj_surface->bo);
223 if (!obj_surface || !obj_surface->bo)
224 return VA_STATUS_ERROR_INVALID_PARAMETER;
226 unsigned int tiling = 0, swizzle = 0;
228 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
230 if (tiling == I915_TILING_Y) {
231 if ((obj_surface->fourcc == VA_FOURCC_NV12) || (obj_surface->fourcc == VA_FOURCC_UYVY) ||
232 (obj_surface->fourcc == VA_FOURCC_YUY2) || (obj_surface->fourcc == VA_FOURCC_Y800) ||
233 (obj_surface->fourcc == VA_FOURCC_RGBA) || (obj_surface->fourcc == VA_FOURCC_444P)) {
234 encoder_context->input_yuv_surface = encode_state->current_render_target;
235 encode_state->input_yuv_object = obj_surface;
236 return VA_STATUS_SUCCESS;
242 rect.width = obj_surface->orig_width;
243 rect.height = obj_surface->orig_height;
245 src_surface.base = (struct object_base *)obj_surface;
246 src_surface.type = I965_SURFACE_TYPE_SURFACE;
247 src_surface.flags = I965_SURFACE_FLAG_FRAME;
249 switch (obj_surface->fourcc) {
252 fourcc = VA_FOURCC_YUY2;
253 format = VA_RT_FORMAT_YUV422;
254 subsample = SUBSAMPLE_YUV422H;
258 fourcc = VA_FOURCC_UYVY;
259 format = VA_RT_FORMAT_YUV422;
260 subsample = SUBSAMPLE_YUV422H;
264 fourcc = VA_FOURCC_Y800;
265 format = VA_RT_FORMAT_YUV400;
266 subsample = SUBSAMPLE_YUV400;
270 fourcc = VA_FOURCC_444P;
271 format = VA_RT_FORMAT_YUV444;
272 subsample = SUBSAMPLE_YUV444;
276 fourcc = VA_FOURCC_RGBA;
277 format = VA_RT_FORMAT_RGB32;
278 subsample = SUBSAMPLE_RGBX;
281 default: //All other scenarios will have NV12 format
282 fourcc = VA_FOURCC_NV12;
283 format = VA_RT_FORMAT_YUV420;
284 subsample = SUBSAMPLE_YUV420;
288 status = i965_CreateSurfaces(ctx,
289 obj_surface->orig_width,
290 obj_surface->orig_height,
293 &encoder_context->input_yuv_surface);
294 assert(status == VA_STATUS_SUCCESS);
296 if (status != VA_STATUS_SUCCESS)
299 obj_surface = SURFACE(encoder_context->input_yuv_surface);
300 encode_state->input_yuv_object = obj_surface;
302 i965_check_alloc_surface_bo(ctx, obj_surface, 1, fourcc, subsample);
304 dst_surface.base = (struct object_base *)obj_surface;
305 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
306 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
308 //The Y800 format is expected to be tiled.
309 //Linear Y800 is a corner case and needs code in the i965_image_processing.
310 if (obj_surface->fourcc != VA_FOURCC_Y800) {
311 status = i965_image_processing(ctx,
316 assert(status == VA_STATUS_SUCCESS);
319 encoder_context->is_tmp_id = 1;
321 return VA_STATUS_SUCCESS;
325 intel_encoder_check_brc_h264_sequence_parameter(VADriverContextP ctx,
326 struct encode_state *encode_state,
327 struct intel_encoder_context *encoder_context,
328 unsigned int *seq_bits_per_second)
330 VAEncSequenceParameterBufferH264 *seq_param = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
331 struct intel_fraction framerate;
332 unsigned short num_pframes_in_gop, num_bframes_in_gop;
334 if (!encoder_context->is_new_sequence)
335 return VA_STATUS_SUCCESS;
339 if (!seq_param->num_units_in_tick || !seq_param->time_scale) {
340 framerate = (struct intel_fraction) {
344 // for the highest layer
345 framerate = (struct intel_fraction) {
346 seq_param->time_scale, 2 * seq_param->num_units_in_tick
349 framerate = reduce_fraction(framerate);
351 encoder_context->brc.num_iframes_in_gop = 1; // Always 1
353 if (seq_param->intra_period == 0) { // E.g. IDRPP... / IDR(PBB)... (no IDR/I any more)
354 if (seq_param->ip_period == 0)
357 encoder_context->brc.gop_size = (framerate.num + framerate.den - 1) / framerate.den; // fake
358 num_pframes_in_gop = (encoder_context->brc.gop_size +
359 seq_param->ip_period - 1) / seq_param->ip_period - 1;
360 } else if (seq_param->intra_period == 1) { // E.g. IDRIII...
361 encoder_context->brc.gop_size = 1;
362 num_pframes_in_gop = 0;
364 if (seq_param->ip_period == 0)
367 encoder_context->brc.gop_size = seq_param->intra_period;
368 num_pframes_in_gop = (encoder_context->brc.gop_size +
369 seq_param->ip_period - 1) / seq_param->ip_period - 1;
372 num_bframes_in_gop = (encoder_context->brc.gop_size -
373 encoder_context->brc.num_iframes_in_gop - num_pframes_in_gop);
375 if (num_pframes_in_gop != encoder_context->brc.num_pframes_in_gop ||
376 num_bframes_in_gop != encoder_context->brc.num_bframes_in_gop ||
377 framerate.num != encoder_context->brc.framerate[encoder_context->layer.num_layers - 1].num ||
378 framerate.den != encoder_context->brc.framerate[encoder_context->layer.num_layers - 1].den) {
379 encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
380 encoder_context->brc.num_bframes_in_gop = num_bframes_in_gop;
381 encoder_context->brc.framerate[encoder_context->layer.num_layers - 1] = framerate;
382 encoder_context->brc.need_reset = 1;
385 if (!encoder_context->brc.hrd_buffer_size ||
386 !encoder_context->brc.hrd_initial_buffer_fullness) {
387 encoder_context->brc.hrd_buffer_size = seq_param->bits_per_second << 1;
388 encoder_context->brc.hrd_initial_buffer_fullness = seq_param->bits_per_second;
391 *seq_bits_per_second = seq_param->bits_per_second;
393 return VA_STATUS_SUCCESS;
396 return VA_STATUS_ERROR_INVALID_PARAMETER;
400 intel_encoder_check_brc_vp8_sequence_parameter(VADriverContextP ctx,
401 struct encode_state *encode_state,
402 struct intel_encoder_context *encoder_context,
403 unsigned int *seq_bits_per_second)
405 VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer;
406 unsigned int num_pframes_in_gop;
408 if (!encoder_context->is_new_sequence)
409 return VA_STATUS_SUCCESS;
413 encoder_context->brc.num_iframes_in_gop = 1;// Always 1
414 encoder_context->brc.num_bframes_in_gop = 0;// No B frame
416 if (seq_param->intra_period == 0) { // E.g. IPPP... (only one I frame in the stream)
417 encoder_context->brc.gop_size = 30; // fake
419 encoder_context->brc.gop_size = seq_param->intra_period;
422 num_pframes_in_gop = encoder_context->brc.gop_size - 1;
424 if (!encoder_context->brc.framerate[encoder_context->layer.num_layers - 1].num) {
425 // for the highest layer
426 encoder_context->brc.framerate[encoder_context->layer.num_layers - 1] = (struct intel_fraction) {
429 encoder_context->brc.need_reset = 1;
432 if (num_pframes_in_gop != encoder_context->brc.num_pframes_in_gop) {
433 encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
434 encoder_context->brc.need_reset = 1;
437 if (!encoder_context->brc.hrd_buffer_size ||
438 !encoder_context->brc.hrd_initial_buffer_fullness) {
439 encoder_context->brc.hrd_buffer_size = seq_param->bits_per_second << 1;
440 encoder_context->brc.hrd_initial_buffer_fullness = seq_param->bits_per_second;
441 encoder_context->brc.need_reset = 1;
444 *seq_bits_per_second = seq_param->bits_per_second;
446 return VA_STATUS_SUCCESS;
450 intel_encoder_check_brc_hevc_sequence_parameter(VADriverContextP ctx,
451 struct encode_state *encode_state,
452 struct intel_encoder_context *encoder_context,
453 unsigned int *seq_bits_per_second)
455 VAEncSequenceParameterBufferHEVC *seq_param = (VAEncSequenceParameterBufferHEVC*)encode_state->seq_param_ext->buffer;
456 struct intel_fraction framerate;
457 unsigned int gop_size, num_iframes_in_gop, num_pframes_in_gop, num_bframes_in_gop;
459 if (!encoder_context->is_new_sequence)
460 return VA_STATUS_SUCCESS;
462 return VA_STATUS_ERROR_INVALID_PARAMETER;
464 if (!seq_param->vui_time_scale || !seq_param->vui_num_units_in_tick)
465 framerate = (struct intel_fraction) {
469 framerate = (struct intel_fraction) {
470 seq_param->vui_time_scale, seq_param->vui_num_units_in_tick
472 framerate = reduce_fraction(framerate);
474 num_iframes_in_gop = 1;
475 if (seq_param->intra_period == 0) {
477 num_pframes_in_gop = -1;
478 } else if (seq_param->intra_period == 1) {
480 num_pframes_in_gop = 0;
482 gop_size = seq_param->intra_period;
483 num_pframes_in_gop = (seq_param->intra_period + seq_param->ip_period - 1) / seq_param->ip_period - 1;
485 num_bframes_in_gop = gop_size - num_iframes_in_gop - num_pframes_in_gop;
487 if (encoder_context->brc.framerate[0].num != framerate.num ||
488 encoder_context->brc.framerate[0].den != framerate.den) {
489 encoder_context->brc.framerate[0] = framerate;
490 encoder_context->brc.need_reset = 1;
493 if (encoder_context->brc.gop_size != gop_size ||
494 encoder_context->brc.num_iframes_in_gop != num_iframes_in_gop ||
495 encoder_context->brc.num_pframes_in_gop != num_pframes_in_gop ||
496 encoder_context->brc.num_bframes_in_gop != num_bframes_in_gop) {
497 encoder_context->brc.gop_size = gop_size;
498 encoder_context->brc.num_iframes_in_gop = num_iframes_in_gop;
499 encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
500 encoder_context->brc.num_bframes_in_gop = num_bframes_in_gop;
501 encoder_context->brc.need_reset = 1;
504 *seq_bits_per_second = seq_param->bits_per_second;
506 return VA_STATUS_SUCCESS;
510 intel_encoder_check_brc_vp9_sequence_parameter(VADriverContextP ctx,
511 struct encode_state *encode_state,
512 struct intel_encoder_context *encoder_context,
513 unsigned int *seq_bits_per_second)
515 VAEncSequenceParameterBufferVP9 *seq_param = (VAEncSequenceParameterBufferVP9*)encode_state->seq_param_ext->buffer;
516 unsigned int gop_size;
518 if (!encoder_context->is_new_sequence)
519 return VA_STATUS_SUCCESS;
521 return VA_STATUS_ERROR_INVALID_PARAMETER;
523 if (seq_param->intra_period == 0)
524 gop_size = -1; // Dummy value (infinity).
526 gop_size = seq_param->intra_period;
528 if (encoder_context->brc.gop_size != gop_size) {
529 encoder_context->brc.gop_size = gop_size;
530 encoder_context->brc.need_reset = 1;
533 *seq_bits_per_second = seq_param->bits_per_second;
535 return VA_STATUS_SUCCESS;
539 intel_encoder_check_brc_sequence_parameter(VADriverContextP ctx,
540 struct encode_state *encode_state,
541 struct intel_encoder_context *encoder_context,
542 unsigned int *seq_bits_per_second)
544 *seq_bits_per_second = 0;
546 switch (encoder_context->codec) {
549 return intel_encoder_check_brc_h264_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
552 return intel_encoder_check_brc_vp8_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
555 return intel_encoder_check_brc_hevc_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
558 return intel_encoder_check_brc_vp9_sequence_parameter(ctx, encode_state, encoder_context, seq_bits_per_second);
561 // TODO: other codecs
562 return VA_STATUS_SUCCESS;
567 intel_encoder_check_rate_control_parameter(VADriverContextP ctx,
568 struct intel_encoder_context *encoder_context,
569 VAEncMiscParameterRateControl *misc,
570 int *hl_bitrate_updated)
574 if (encoder_context->layer.num_layers >= 2)
575 temporal_id = misc->rc_flags.bits.temporal_id;
577 if (temporal_id >= encoder_context->layer.num_layers)
580 if (misc->rc_flags.bits.reset)
581 encoder_context->brc.need_reset = 1;
583 if (encoder_context->brc.bits_per_second[temporal_id] != misc->bits_per_second) {
584 encoder_context->brc.bits_per_second[temporal_id] = misc->bits_per_second;
585 encoder_context->brc.need_reset = 1;
588 if (encoder_context->brc.mb_rate_control[temporal_id] != misc->rc_flags.bits.mb_rate_control) {
589 encoder_context->brc.mb_rate_control[temporal_id] = misc->rc_flags.bits.mb_rate_control;
590 encoder_context->brc.need_reset = 1;
593 if (encoder_context->brc.target_percentage[temporal_id] != misc->target_percentage) {
594 encoder_context->brc.target_percentage[temporal_id] = misc->target_percentage;
595 encoder_context->brc.need_reset = 1;
598 if (encoder_context->brc.window_size != misc->window_size ||
599 encoder_context->brc.initial_qp != misc->initial_qp ||
600 encoder_context->brc.min_qp != misc->min_qp) {
601 encoder_context->brc.window_size = misc->window_size;
602 encoder_context->brc.initial_qp = misc->initial_qp;
603 encoder_context->brc.min_qp = misc->min_qp;
604 encoder_context->brc.need_reset = 1;
607 if (temporal_id == encoder_context->layer.num_layers - 1)
608 *hl_bitrate_updated = 1;
612 intel_encoder_check_hrd_parameter(VADriverContextP ctx,
613 struct intel_encoder_context *encoder_context,
614 VAEncMiscParameterHRD *misc)
616 if (encoder_context->brc.hrd_buffer_size != misc->buffer_size ||
617 encoder_context->brc.hrd_initial_buffer_fullness != misc->initial_buffer_fullness) {
618 encoder_context->brc.hrd_buffer_size = misc->buffer_size;
619 encoder_context->brc.hrd_initial_buffer_fullness = misc->initial_buffer_fullness;
620 encoder_context->brc.need_reset = 1;
625 intel_encoder_check_framerate_parameter(VADriverContextP ctx,
626 struct intel_encoder_context *encoder_context,
627 VAEncMiscParameterFrameRate *misc)
629 struct intel_fraction framerate;
632 if (encoder_context->layer.num_layers >= 2)
633 temporal_id = misc->framerate_flags.bits.temporal_id;
635 if (temporal_id >= encoder_context->layer.num_layers)
638 if (misc->framerate & 0xffff0000)
639 framerate = (struct intel_fraction) {
640 misc->framerate & 0xffff, misc->framerate >> 16 & 0xffff
643 framerate = (struct intel_fraction) {
646 framerate = reduce_fraction(framerate);
648 if (encoder_context->brc.framerate[temporal_id].num != framerate.num ||
649 encoder_context->brc.framerate[temporal_id].den != framerate.den) {
650 encoder_context->brc.framerate[temporal_id] = framerate;
651 encoder_context->brc.need_reset = 1;
656 intel_encoder_check_roi_parameter(VADriverContextP ctx,
657 struct intel_encoder_context *encoder_context,
658 VAEncMiscParameterBufferROI *misc)
662 encoder_context->brc.num_roi = MIN(misc->num_roi, I965_MAX_NUM_ROI_REGIONS);
663 encoder_context->brc.roi_max_delta_qp = misc->max_delta_qp;
664 encoder_context->brc.roi_min_delta_qp = misc->min_delta_qp;
665 encoder_context->brc.roi_value_is_qp_delta = 0;
667 if (encoder_context->rate_control_mode != VA_RC_CQP)
668 encoder_context->brc.roi_value_is_qp_delta = misc->roi_flags.bits.roi_value_is_qp_delta;
670 for (i = 0; i < encoder_context->brc.num_roi; i++) {
671 encoder_context->brc.roi[i].left = misc->roi->roi_rectangle.x;
672 encoder_context->brc.roi[i].right = encoder_context->brc.roi[i].left + misc->roi->roi_rectangle.width;
673 encoder_context->brc.roi[i].top = misc->roi->roi_rectangle.y;
674 encoder_context->brc.roi[i].bottom = encoder_context->brc.roi[i].top + misc->roi->roi_rectangle.height;
675 encoder_context->brc.roi[i].value = misc->roi->roi_value;
680 intel_encoder_check_brc_parameter(VADriverContextP ctx,
681 struct encode_state *encode_state,
682 struct intel_encoder_context *encoder_context)
685 VAEncMiscParameterBuffer *misc_param;
687 int hl_bitrate_updated = 0; // Indicate whether the bitrate for the highest level is changed in misc parameters
688 unsigned int seq_bits_per_second = 0;
690 if (!(encoder_context->rate_control_mode & (VA_RC_CBR | VA_RC_VBR)))
691 return VA_STATUS_SUCCESS;
693 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 switch (misc_param->type) {
706 case VAEncMiscParameterTypeFrameRate:
707 intel_encoder_check_framerate_parameter(ctx,
709 (VAEncMiscParameterFrameRate *)misc_param->data);
712 case VAEncMiscParameterTypeRateControl:
713 intel_encoder_check_rate_control_parameter(ctx,
715 (VAEncMiscParameterRateControl *)misc_param->data,
716 &hl_bitrate_updated);
719 case VAEncMiscParameterTypeHRD:
720 intel_encoder_check_hrd_parameter(ctx,
722 (VAEncMiscParameterHRD *)misc_param->data);
725 case VAEncMiscParameterTypeROI:
726 intel_encoder_check_roi_parameter(ctx,
728 (VAEncMiscParameterBufferROI *)misc_param->data);
737 if (!hl_bitrate_updated && seq_bits_per_second &&
738 encoder_context->brc.bits_per_second[encoder_context->layer.num_layers - 1] != seq_bits_per_second) {
740 encoder_context->brc.bits_per_second[encoder_context->layer.num_layers - 1] = seq_bits_per_second;
741 encoder_context->brc.need_reset = 1;
745 return VA_STATUS_SUCCESS;
749 intel_encoder_check_temporal_layer_structure(VADriverContextP ctx,
750 struct encode_state *encode_state,
751 struct intel_encoder_context *encoder_context)
753 VAEncMiscParameterBuffer* misc_param;
754 VAEncMiscParameterTemporalLayerStructure *tls_paramter;
755 unsigned int rate_control_mode = encoder_context->rate_control_mode;
758 if (!encoder_context->is_new_sequence) {
759 if (encoder_context->layer.num_layers > 1)
760 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];
762 encoder_context->layer.curr_frame_layer_id = 0;
764 return VA_STATUS_SUCCESS;
767 if (!(rate_control_mode & (VA_RC_CBR | VA_RC_VBR)))
768 return VA_STATUS_SUCCESS;
770 if (!encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0] ||
771 !encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0]->buffer)
772 return VA_STATUS_SUCCESS;
774 misc_param = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeTemporalLayerStructure][0]->buffer;
775 tls_paramter = (VAEncMiscParameterTemporalLayerStructure *)misc_param->data;
777 if (tls_paramter->number_of_layers <= 1)
778 return VA_STATUS_SUCCESS;
780 if (tls_paramter->number_of_layers > MAX_TEMPORAL_LAYERS)
781 return VA_STATUS_ERROR_INVALID_PARAMETER;
783 if (tls_paramter->periodicity > 32 || tls_paramter->periodicity <= 1)
784 return VA_STATUS_ERROR_INVALID_PARAMETER;
786 for (i = 0; i < tls_paramter->number_of_layers; i++) {
787 if (!encode_state->misc_param[VAEncMiscParameterTypeRateControl][i] ||
788 !encode_state->misc_param[VAEncMiscParameterTypeRateControl][i]->buffer ||
789 !encode_state->misc_param[VAEncMiscParameterTypeFrameRate][i] ||
790 !encode_state->misc_param[VAEncMiscParameterTypeFrameRate][i]->buffer) {
792 return VA_STATUS_ERROR_INVALID_PARAMETER;
796 encoder_context->layer.size_frame_layer_ids = tls_paramter->periodicity;
797 encoder_context->layer.num_layers = tls_paramter->number_of_layers;
799 for (i = 0; i < encoder_context->layer.size_frame_layer_ids; i++) {
800 if (tls_paramter->layer_id[i] >= tls_paramter->number_of_layers)
801 return VA_STATUS_ERROR_INVALID_PARAMETER;
803 encoder_context->layer.frame_layer_ids[i] = tls_paramter->layer_id[i];
806 if (encoder_context->is_new_sequence)
807 encoder_context->layer.curr_frame_layer_id = 0;
809 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];
811 return VA_STATUS_SUCCESS;
815 intel_encoder_check_misc_parameter(VADriverContextP ctx,
816 struct encode_state *encode_state,
817 struct intel_encoder_context *encoder_context)
819 VAStatus ret = VA_STATUS_SUCCESS;
821 if (encode_state->misc_param[VAEncMiscParameterTypeQualityLevel][0] &&
822 encode_state->misc_param[VAEncMiscParameterTypeQualityLevel][0]->buffer) {
823 VAEncMiscParameterBuffer* pMiscParam = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeQualityLevel][0]->buffer;
824 VAEncMiscParameterBufferQualityLevel* param_quality_level = (VAEncMiscParameterBufferQualityLevel*)pMiscParam->data;
825 encoder_context->quality_level = param_quality_level->quality_level;
827 if (encoder_context->quality_level == 0)
828 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
829 else if (encoder_context->quality_level > encoder_context->quality_range) {
830 ret = VA_STATUS_ERROR_INVALID_PARAMETER;
835 ret = intel_encoder_check_temporal_layer_structure(ctx, encode_state, encoder_context);
840 ret = intel_encoder_check_brc_parameter(ctx, encode_state, encoder_context);
847 intel_encoder_check_avc_parameter(VADriverContextP ctx,
848 struct encode_state *encode_state,
849 struct intel_encoder_context *encoder_context)
851 struct i965_driver_data *i965 = i965_driver_data(ctx);
852 struct object_surface *obj_surface;
853 struct object_buffer *obj_buffer;
854 VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
855 VAEncSequenceParameterBufferH264 *seq_param = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
858 assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
860 if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID)
863 obj_surface = SURFACE(pic_param->CurrPic.picture_id);
864 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
869 encode_state->reconstructed_object = obj_surface;
870 obj_buffer = BUFFER(pic_param->coded_buf);
871 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
873 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
876 if (encode_state->num_slice_params_ext > encoder_context->max_slice_or_seg_num)
879 encode_state->coded_buf_object = obj_buffer;
881 for (i = 0; i < 16; i++) {
882 if (pic_param->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID ||
883 pic_param->ReferenceFrames[i].picture_id == VA_INVALID_SURFACE)
886 obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id);
893 encode_state->reference_objects[i] = obj_surface;
895 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
900 encode_state->reference_objects[i] = NULL;
903 * A sequence consists of an IDR unit, followed by zero or more non-IDR unit, but not including any
904 * subsequent IDR unit, so idr_pic_flag can indicate the current frame is the start of a new
907 encoder_context->is_new_sequence = (pic_param->pic_fields.bits.idr_pic_flag && seq_param);
909 if (encoder_context->is_new_sequence) {
910 encoder_context->num_frames_in_sequence = 0;
911 encoder_context->frame_width_in_pixel = seq_param->picture_width_in_mbs * 16;
912 encoder_context->frame_height_in_pixel = seq_param->picture_height_in_mbs * 16;
915 return VA_STATUS_SUCCESS;
918 return VA_STATUS_ERROR_INVALID_PARAMETER;
922 intel_encoder_check_mpeg2_parameter(VADriverContextP ctx,
923 struct encode_state *encode_state,
924 struct intel_encoder_context *encoder_context)
926 struct i965_driver_data *i965 = i965_driver_data(ctx);
927 VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
928 struct object_surface *obj_surface;
929 struct object_buffer *obj_buffer;
932 obj_surface = SURFACE(pic_param->reconstructed_picture);
933 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
938 encode_state->reconstructed_object = obj_surface;
939 obj_buffer = BUFFER(pic_param->coded_buf);
940 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
942 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
945 encode_state->coded_buf_object = obj_buffer;
947 if (pic_param->picture_type == VAEncPictureTypeIntra) {
948 } else if (pic_param->picture_type == VAEncPictureTypePredictive) {
949 assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
950 obj_surface = SURFACE(pic_param->forward_reference_picture);
951 assert(obj_surface && obj_surface->bo);
953 if (!obj_surface || !obj_surface->bo)
956 encode_state->reference_objects[i++] = obj_surface;
957 } else if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
958 assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
959 obj_surface = SURFACE(pic_param->forward_reference_picture);
960 assert(obj_surface && obj_surface->bo);
962 if (!obj_surface || !obj_surface->bo)
965 encode_state->reference_objects[i++] = obj_surface;
967 assert(pic_param->backward_reference_picture != VA_INVALID_SURFACE);
968 obj_surface = SURFACE(pic_param->backward_reference_picture);
969 assert(obj_surface && obj_surface->bo);
971 if (!obj_surface || !obj_surface->bo)
974 encode_state->reference_objects[i++] = obj_surface;
979 encode_state->reference_objects[i] = NULL;
981 return VA_STATUS_SUCCESS;
984 return VA_STATUS_ERROR_INVALID_PARAMETER;
988 intel_encoder_check_jpeg_parameter(VADriverContextP ctx,
989 struct encode_state *encode_state,
990 struct intel_encoder_context *encoder_context)
992 struct i965_driver_data *i965 = i965_driver_data(ctx);
993 struct object_buffer *obj_buffer;
994 VAEncPictureParameterBufferJPEG *pic_param = (VAEncPictureParameterBufferJPEG *)encode_state->pic_param_ext->buffer;
997 assert(!(pic_param->pic_flags.bits.profile)); //Baseline profile is 0.
999 obj_buffer = BUFFER(pic_param->coded_buf);
1000 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
1002 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1005 encode_state->coded_buf_object = obj_buffer;
1007 return VA_STATUS_SUCCESS;
1010 return VA_STATUS_ERROR_INVALID_PARAMETER;
1014 intel_encoder_check_vp8_parameter(VADriverContextP ctx,
1015 struct encode_state *encode_state,
1016 struct intel_encoder_context *encoder_context)
1018 struct i965_driver_data *i965 = i965_driver_data(ctx);
1019 VAEncPictureParameterBufferVP8 *pic_param = (VAEncPictureParameterBufferVP8 *)encode_state->pic_param_ext->buffer;
1020 VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer;
1021 struct object_surface *obj_surface;
1022 struct object_buffer *obj_buffer;
1024 int is_key_frame = !pic_param->pic_flags.bits.frame_type;
1026 obj_surface = SURFACE(pic_param->reconstructed_frame);
1027 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
1032 encode_state->reconstructed_object = obj_surface;
1033 obj_buffer = BUFFER(pic_param->coded_buf);
1034 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
1036 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1039 encode_state->coded_buf_object = obj_buffer;
1041 if (!is_key_frame) {
1042 assert(pic_param->ref_last_frame != VA_INVALID_SURFACE);
1043 obj_surface = SURFACE(pic_param->ref_last_frame);
1044 assert(obj_surface && obj_surface->bo);
1046 if (!obj_surface || !obj_surface->bo)
1049 encode_state->reference_objects[i++] = obj_surface;
1051 assert(pic_param->ref_gf_frame != VA_INVALID_SURFACE);
1052 obj_surface = SURFACE(pic_param->ref_gf_frame);
1053 assert(obj_surface && obj_surface->bo);
1055 if (!obj_surface || !obj_surface->bo)
1058 encode_state->reference_objects[i++] = obj_surface;
1060 assert(pic_param->ref_arf_frame != VA_INVALID_SURFACE);
1061 obj_surface = SURFACE(pic_param->ref_arf_frame);
1062 assert(obj_surface && obj_surface->bo);
1064 if (!obj_surface || !obj_surface->bo)
1067 encode_state->reference_objects[i++] = obj_surface;
1071 encode_state->reference_objects[i] = NULL;
1073 encoder_context->is_new_sequence = (is_key_frame && seq_param);
1075 if (encoder_context->is_new_sequence) {
1076 encoder_context->num_frames_in_sequence = 0;
1077 encoder_context->frame_width_in_pixel = seq_param->frame_width;
1078 encoder_context->frame_height_in_pixel = seq_param->frame_height;
1081 return VA_STATUS_SUCCESS;
1084 return VA_STATUS_ERROR_INVALID_PARAMETER;
1088 intel_encoder_check_hevc_parameter(VADriverContextP ctx,
1089 struct encode_state *encode_state,
1090 struct intel_encoder_context *encoder_context)
1092 struct i965_driver_data *i965 = i965_driver_data(ctx);
1093 struct object_surface *obj_surface;
1094 struct object_buffer *obj_buffer;
1095 VAEncPictureParameterBufferHEVC *pic_param = (VAEncPictureParameterBufferHEVC *)encode_state->pic_param_ext->buffer;
1096 VAEncSliceParameterBufferHEVC *slice_param;
1097 VAEncSequenceParameterBufferHEVC *seq_param;
1102 if (encode_state->seq_param_ext &&
1103 encode_state->seq_param_ext->buffer)
1104 seq_param = (VAEncSequenceParameterBufferHEVC *)(encode_state->seq_param_ext->buffer);
1106 assert(!(pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID));
1108 if (pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID)
1111 obj_surface = SURFACE(pic_param->decoded_curr_pic.picture_id);
1112 assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
1117 encode_state->reconstructed_object = obj_surface;
1118 obj_buffer = BUFFER(pic_param->coded_buf);
1119 assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
1121 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1124 if (encode_state->num_slice_params_ext > encoder_context->max_slice_or_seg_num)
1127 encode_state->coded_buf_object = obj_buffer;
1129 for (i = 0; i < 15; i++) {
1130 if (pic_param->reference_frames[i].flags & VA_PICTURE_HEVC_INVALID ||
1131 pic_param->reference_frames[i].picture_id == VA_INVALID_SURFACE)
1134 obj_surface = SURFACE(pic_param->reference_frames[i].picture_id);
1135 assert(obj_surface);
1140 if (obj_surface->bo)
1141 encode_state->reference_objects[i] = obj_surface;
1143 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
1148 encode_state->reference_objects[i] = NULL;
1150 for (i = 0; i < encode_state->num_slice_params_ext; i++) {
1151 slice_param = (VAEncSliceParameterBufferHEVC *)encode_state->slice_params_ext[i]->buffer;
1153 if (slice_param->slice_type != HEVC_SLICE_I &&
1154 slice_param->slice_type != HEVC_SLICE_P &&
1155 slice_param->slice_type != HEVC_SLICE_B)
1158 /* TODO: add more check here */
1161 encoder_context->is_new_sequence = (pic_param->pic_fields.bits.idr_pic_flag && seq_param);
1163 return VA_STATUS_SUCCESS;
1166 return VA_STATUS_ERROR_INVALID_PARAMETER;
1170 intel_encoder_check_vp9_parameter(VADriverContextP ctx,
1171 struct encode_state *encode_state,
1172 struct intel_encoder_context *encoder_context)
1174 struct i965_driver_data *i965 = i965_driver_data(ctx);
1175 VAEncPictureParameterBufferVP9 *pic_param;
1176 VAEncSequenceParameterBufferVP9 *seq_param;
1177 struct object_surface *obj_surface;
1178 struct object_buffer *obj_buffer;
1180 int is_key_frame = 0;
1183 if (encode_state->pic_param_ext == NULL ||
1184 encode_state->pic_param_ext->buffer == NULL)
1185 return VA_STATUS_ERROR_INVALID_PARAMETER;
1188 if (encode_state->seq_param_ext &&
1189 encode_state->seq_param_ext->buffer)
1190 seq_param = (VAEncSequenceParameterBufferVP9 *)(encode_state->seq_param_ext->buffer);
1192 pic_param = (VAEncPictureParameterBufferVP9 *)encode_state->pic_param_ext->buffer;
1194 obj_surface = SURFACE(pic_param->reconstructed_frame);
1199 encode_state->reconstructed_object = obj_surface;
1200 obj_buffer = BUFFER(pic_param->coded_buf);
1202 if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
1205 encode_state->coded_buf_object = obj_buffer;
1207 is_key_frame = !pic_param->pic_flags.bits.frame_type;
1208 if (!is_key_frame && !pic_param->pic_flags.bits.intra_only) {
1209 /* slot 0 is for last reference frame */
1210 index = pic_param->ref_flags.bits.ref_last_idx;
1211 obj_surface = SURFACE(pic_param->reference_frames[index]);
1212 if (obj_surface && obj_surface->bo)
1213 encode_state->reference_objects[i++] = obj_surface;
1215 encode_state->reference_objects[i++] = NULL;
1217 /* slot 1 is for golden reference frame */
1218 index = pic_param->ref_flags.bits.ref_gf_idx;
1219 obj_surface = SURFACE(pic_param->reference_frames[index]);
1220 if (obj_surface && obj_surface->bo)
1221 encode_state->reference_objects[i++] = obj_surface;
1223 encode_state->reference_objects[i++] = NULL;
1225 /* slot 2 is alt reference frame */
1226 index = pic_param->ref_flags.bits.ref_arf_idx;
1227 obj_surface = SURFACE(pic_param->reference_frames[index]);
1228 if (obj_surface && obj_surface->bo)
1229 encode_state->reference_objects[i++] = obj_surface;
1231 encode_state->reference_objects[i++] = NULL;
1235 encode_state->reference_objects[i] = NULL;
1237 encoder_context->is_new_sequence = (is_key_frame && seq_param);
1239 return VA_STATUS_SUCCESS;
1242 return VA_STATUS_ERROR_INVALID_PARAMETER;
1247 intel_encoder_sanity_check_input(VADriverContextP ctx,
1249 struct encode_state *encode_state,
1250 struct intel_encoder_context *encoder_context)
1255 case VAProfileH264ConstrainedBaseline:
1256 case VAProfileH264Main:
1257 case VAProfileH264High:
1258 case VAProfileH264MultiviewHigh:
1259 case VAProfileH264StereoHigh: {
1260 vaStatus = intel_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
1261 if (vaStatus != VA_STATUS_SUCCESS)
1263 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1267 case VAProfileMPEG2Simple:
1268 case VAProfileMPEG2Main: {
1269 vaStatus = intel_encoder_check_mpeg2_parameter(ctx, encode_state, encoder_context);
1270 if (vaStatus != VA_STATUS_SUCCESS)
1272 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1276 case VAProfileJPEGBaseline: {
1277 vaStatus = intel_encoder_check_jpeg_parameter(ctx, encode_state, encoder_context);
1278 if (vaStatus != VA_STATUS_SUCCESS)
1280 vaStatus = intel_encoder_check_jpeg_yuv_surface(ctx, profile, encode_state, encoder_context);
1284 case VAProfileVP8Version0_3: {
1285 vaStatus = intel_encoder_check_vp8_parameter(ctx, encode_state, encoder_context);
1286 if (vaStatus != VA_STATUS_SUCCESS)
1288 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1292 case VAProfileHEVCMain:
1293 case VAProfileHEVCMain10: {
1294 vaStatus = intel_encoder_check_hevc_parameter(ctx, encode_state, encoder_context);
1295 if (vaStatus != VA_STATUS_SUCCESS)
1297 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1301 case VAProfileVP9Profile0: {
1302 vaStatus = intel_encoder_check_vp9_parameter(ctx, encode_state, encoder_context);
1303 if (vaStatus != VA_STATUS_SUCCESS)
1305 vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
1309 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1313 if (vaStatus == VA_STATUS_SUCCESS)
1314 vaStatus = intel_encoder_check_misc_parameter(ctx, encode_state, encoder_context);
1321 intel_encoder_end_picture(VADriverContextP ctx,
1323 union codec_state *codec_state,
1324 struct hw_context *hw_context)
1326 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
1327 struct encode_state *encode_state = &codec_state->encode;
1330 vaStatus = intel_encoder_sanity_check_input(ctx, profile, encode_state, encoder_context);
1332 if (vaStatus != VA_STATUS_SUCCESS)
1335 encoder_context->mfc_brc_prepare(encode_state, encoder_context);
1337 if ((encoder_context->vme_context && encoder_context->vme_pipeline)) {
1338 vaStatus = encoder_context->vme_pipeline(ctx, profile, encode_state, encoder_context);
1339 if (vaStatus != VA_STATUS_SUCCESS)
1343 encoder_context->mfc_pipeline(ctx, profile, encode_state, encoder_context);
1344 encoder_context->num_frames_in_sequence++;
1345 encoder_context->brc.need_reset = 0;
1347 * ROI is only available for the current frame, see the comment
1348 * for VAEncROI in va.h
1350 encoder_context->brc.num_roi = 0;
1352 return VA_STATUS_SUCCESS;
1356 intel_encoder_context_destroy(void *hw_context)
1358 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
1360 encoder_context->mfc_context_destroy(encoder_context->mfc_context);
1362 if (encoder_context->vme_context_destroy && encoder_context->vme_context)
1363 encoder_context->vme_context_destroy(encoder_context->vme_context);
1365 if (encoder_context->enc_priv_state) {
1366 free(encoder_context->enc_priv_state);
1367 encoder_context->enc_priv_state = NULL;
1370 intel_batchbuffer_free(encoder_context->base.batch);
1371 free(encoder_context);
1376 intel_encoder_get_status(VADriverContextP ctx, struct hw_context *hw_context, void *buffer)
1378 struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
1379 struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer;
1381 if (encoder_context->get_status)
1382 return encoder_context->get_status(ctx, encoder_context, coded_buffer_segment);
1384 return VA_STATUS_ERROR_UNIMPLEMENTED;
1387 typedef Bool(* hw_init_func)(VADriverContextP, struct intel_encoder_context *);
1389 static struct hw_context *
1390 intel_enc_hw_context_init(VADriverContextP ctx,
1391 struct object_config *obj_config,
1392 hw_init_func vme_context_init,
1393 hw_init_func mfc_context_init)
1395 struct i965_driver_data *i965 = i965_driver_data(ctx);
1396 struct intel_driver_data *intel = intel_driver_data(ctx);
1397 struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
1400 assert(encoder_context);
1401 encoder_context->base.destroy = intel_encoder_context_destroy;
1402 encoder_context->base.run = intel_encoder_end_picture;
1403 encoder_context->base.get_status = intel_encoder_get_status;
1404 encoder_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
1405 encoder_context->input_yuv_surface = VA_INVALID_SURFACE;
1406 encoder_context->is_tmp_id = 0;
1407 encoder_context->low_power_mode = 0;
1408 encoder_context->rate_control_mode = VA_RC_NONE;
1409 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
1410 encoder_context->quality_range = 1;
1411 encoder_context->layer.num_layers = 1;
1412 encoder_context->max_slice_or_seg_num = 1;
1414 if (obj_config->entrypoint == VAEntrypointEncSliceLP)
1415 encoder_context->low_power_mode = 1;
1417 switch (obj_config->profile) {
1418 case VAProfileMPEG2Simple:
1419 case VAProfileMPEG2Main:
1420 encoder_context->codec = CODEC_MPEG2;
1423 case VAProfileH264ConstrainedBaseline:
1424 case VAProfileH264Main:
1425 case VAProfileH264High:
1426 encoder_context->codec = CODEC_H264;
1428 if (obj_config->entrypoint == VAEntrypointEncSliceLP)
1429 encoder_context->quality_range = ENCODER_LP_QUALITY_RANGE;
1430 else if (IS_GEN9(i965->intel.device_info)) {
1431 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
1432 encoder_context->quality_range = ENCODER_QUALITY_RANGE_AVC;
1434 encoder_context->quality_range = ENCODER_QUALITY_RANGE;
1437 case VAProfileH264StereoHigh:
1438 case VAProfileH264MultiviewHigh:
1439 if (IS_GEN9(i965->intel.device_info)) {
1440 encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
1441 encoder_context->quality_range = ENCODER_QUALITY_RANGE_AVC;
1443 encoder_context->codec = CODEC_H264_MVC;
1446 case VAProfileJPEGBaseline:
1447 encoder_context->codec = CODEC_JPEG;
1450 case VAProfileVP8Version0_3:
1451 encoder_context->codec = CODEC_VP8;
1452 encoder_context->quality_range = ENCODER_QUALITY_RANGE;
1456 case VAProfileHEVCMain:
1457 case VAProfileHEVCMain10:
1458 encoder_context->codec = CODEC_HEVC;
1461 case VAProfileVP9Profile0:
1462 encoder_context->codec = CODEC_VP9;
1466 /* Never get here */
1471 for (i = 0; i < obj_config->num_attribs; i++) {
1472 if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) {
1473 encoder_context->rate_control_mode = obj_config->attrib_list[i].value;
1475 if (encoder_context->codec == CODEC_MPEG2 &&
1476 encoder_context->rate_control_mode & VA_RC_CBR) {
1477 WARN_ONCE("Don't support CBR for MPEG-2 encoding\n");
1478 encoder_context->rate_control_mode &= ~VA_RC_CBR;
1481 if (obj_config->attrib_list[i].type == VAConfigAttribEncROI) {
1482 if (encoder_context->codec == CODEC_H264)
1483 encoder_context->context_roi = 1;
1485 if (obj_config->attrib_list[i].type == VAConfigAttribEncMaxSlices) {
1486 if (encoder_context->codec == CODEC_H264 ||
1487 encoder_context->codec == CODEC_HEVC)
1488 encoder_context->max_slice_or_seg_num = obj_config->attrib_list[i].value;
1492 if (vme_context_init) {
1493 vme_context_init(ctx, encoder_context);
1494 assert(!encoder_context->vme_context ||
1495 (encoder_context->vme_context_destroy && encoder_context->vme_pipeline));
1498 mfc_context_init(ctx, encoder_context);
1499 assert(encoder_context->mfc_context);
1500 assert(encoder_context->mfc_context_destroy);
1501 assert(encoder_context->mfc_pipeline);
1503 return (struct hw_context *)encoder_context;
1507 gen6_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1509 return intel_enc_hw_context_init(ctx, obj_config, gen6_vme_context_init, gen6_mfc_context_init);
1513 gen7_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1516 return intel_enc_hw_context_init(ctx, obj_config, gen7_vme_context_init, gen7_mfc_context_init);
1520 gen75_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1522 return intel_enc_hw_context_init(ctx, obj_config, gen75_vme_context_init, gen75_mfc_context_init);
1526 gen8_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1528 return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init);
1532 gen9_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1534 return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_mfc_context_init);