{
struct i965_driver_data *i965 = i965_driver_data(ctx);
VAStatus ret = VA_STATUS_SUCCESS;
+ int min_width_height = I965_MIN_CODEC_ENC_RESOLUTION_WIDTH_HEIGHT;
+
+ if (encoder_context->frame_width_in_pixel > 0 &&
+ encoder_context->frame_height_in_pixel > 0) {
+ if (profile == VAProfileJPEGBaseline)
+ min_width_height = 1;
+ if (encoder_context->frame_width_in_pixel < min_width_height ||
+ encoder_context->frame_height_in_pixel < min_width_height)
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+ }
if (encode_state->misc_param[VAEncMiscParameterTypeQualityLevel][0] &&
encode_state->misc_param[VAEncMiscParameterTypeQualityLevel][0]->buffer) {
case VAProfileH264High:
case VAProfileH264MultiviewHigh:
case VAProfileH264StereoHigh:
- if (IS_SKL(i965->intel.device_info) ||
- IS_BXT(i965->intel.device_info))
+ if (IS_GEN9(i965->intel.device_info) ||
+ IS_GEN10(i965->intel.device_info))
encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
break;
}
static VAStatus
+intel_pre_encoder_check_avc_parameter(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context)
+{
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+ struct object_surface *obj_surface = NULL;
+ VAStatsStatisticsParameterH264 *stat_param_h264 = NULL;
+ VAStatsStatisticsParameter*stat_param = NULL;
+
+ if (!encode_state->stat_param_ext)
+ goto error;
+ stat_param_h264 =
+ (VAStatsStatisticsParameterH264 *) encode_state->stat_param_ext->buffer;
+ stat_param = (VAStatsStatisticsParameter *)(&stat_param_h264->stats_params);
+
+ if (stat_param->input.flags == VA_PICTURE_STATS_INVALID)
+ goto error;
+
+ obj_surface = SURFACE(encoder_context->input_yuv_surface);
+ if (!obj_surface)
+ goto error;
+
+#if 0
+ /* FeiPreEncFixme: Since the driver is doing internal CSC for non NV12
+ input surfaces, this check may fail here */
+ /* Make sure the same input yuv has been provided in vaBeginPicture()
+ * and VAStatsStatisticsParameter */
+ if (obj_surface != SURFACE(stat_param->input.picture_id))
+ goto error;
+#endif
+
+ /* There is no reconstructed object in preenc. Here we just assigning
+ * the input yuv object to reconstructed object pointer inorder
+ * to use the same encode code path later on */
+ encode_state->reconstructed_object = obj_surface;
+
+ encoder_context->frame_width_in_pixel = obj_surface->orig_width;
+ encoder_context->frame_height_in_pixel = obj_surface->orig_height;
+
+ /* PreEnc only supports maxium of 1 past and 1 future reference */
+ if (stat_param->num_past_references > 1 || stat_param->num_future_references > 1)
+ goto error;
+
+ return VA_STATUS_SUCCESS;
+error:
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+}
+
+static VAStatus
intel_encoder_check_mpeg2_parameter(VADriverContextP ctx,
struct encode_state *encode_state,
struct intel_encoder_context *encoder_context)
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
+ VAEncSequenceParameterBufferMPEG2 *seq_param = NULL;
struct object_surface *obj_surface;
struct object_buffer *obj_buffer;
int i = 0;
+ if (encode_state->seq_param_ext &&
+ encode_state->seq_param_ext->buffer)
+ seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
+
obj_surface = SURFACE(pic_param->reconstructed_picture);
assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
for (; i < 16; i++)
encode_state->reference_objects[i] = NULL;
+ if (seq_param) {
+ encoder_context->frame_width_in_pixel = seq_param->picture_width;
+ encoder_context->frame_height_in_pixel = seq_param->picture_height;
+ }
+
return VA_STATUS_SUCCESS;
error:
encode_state->coded_buf_object = obj_buffer;
+ encoder_context->frame_width_in_pixel = pic_param->picture_width;
+ encoder_context->frame_height_in_pixel = pic_param->picture_height;
+
return VA_STATUS_SUCCESS;
error:
encoder_context->is_new_sequence = (pic_param->pic_fields.bits.idr_pic_flag && seq_param);
+ if (encoder_context->is_new_sequence) {
+ encoder_context->num_frames_in_sequence = 0;
+ encoder_context->frame_width_in_pixel = seq_param->pic_width_in_luma_samples;
+ encoder_context->frame_height_in_pixel = seq_param->pic_height_in_luma_samples;
+ }
+
return VA_STATUS_SUCCESS;
error:
encoder_context->is_new_sequence = (is_key_frame && seq_param);
+ encoder_context->frame_width_in_pixel = pic_param->frame_width_src;
+ encoder_context->frame_height_in_pixel = pic_param->frame_height_src;
+
return VA_STATUS_SUCCESS;
error:
case VAProfileH264High:
case VAProfileH264MultiviewHigh:
case VAProfileH264StereoHigh: {
- vaStatus = intel_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
- if (vaStatus != VA_STATUS_SUCCESS)
+ if (!encoder_context->preenc_enabled) {
+ vaStatus = intel_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
+ if (vaStatus != VA_STATUS_SUCCESS)
+ goto out;
+ vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
+ break;
+ } else {
+ vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
+ if (vaStatus != VA_STATUS_SUCCESS)
+ goto out;
+
+ vaStatus = intel_pre_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
goto out;
- vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
- break;
+ }
}
case VAProfileMPEG2Simple:
/* VME or PAK stages are separately invoked if middleware configured the corresponding
* FEI modes through confgiruation attributes. On the other hand, ENC_PAK mode
- * will invoke both VME and PAK similar to the non fei use case */
- if (encoder_context->fei_enabled) {
- if (encoder_context->fei_function_mode == VA_FEI_FUNCTION_ENC) {
+ * will invoke both VME and PAK similar to the non fei use case.
+ * PreEnc always invoke the VME */
+ if (encoder_context->fei_enabled || encoder_context->preenc_enabled) {
+ if ((encoder_context->fei_function_mode == VA_FEI_FUNCTION_ENC) ||
+ (encoder_context->preenc_enabled)) {
if ((encoder_context->vme_context && encoder_context->vme_pipeline))
return encoder_context->vme_pipeline(ctx, profile, encode_state, encoder_context);
} else if (encoder_context->fei_function_mode == VA_FEI_FUNCTION_PAK) {
if (obj_config->entrypoint == VAEntrypointEncSliceLP)
encoder_context->quality_range = ENCODER_LP_QUALITY_RANGE;
- else if (IS_GEN9(i965->intel.device_info)) {
+ else if (IS_GEN9(i965->intel.device_info) ||
+ IS_GEN10(i965->intel.device_info)) {
encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
encoder_context->quality_range = ENCODER_QUALITY_RANGE_AVC;
} else
encoder_context->fei_function_mode = obj_config->attrib_list[i].value;
}
}
+
+ if (obj_config->entrypoint == VAEntrypointStats)
+ encoder_context->preenc_enabled = 1;
+
break;
case VAProfileH264StereoHigh:
case VAProfileH264MultiviewHigh:
- if (IS_GEN9(i965->intel.device_info)) {
+ if (IS_GEN9(i965->intel.device_info) ||
+ IS_GEN10(i965->intel.device_info)) {
encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
encoder_context->quality_range = ENCODER_QUALITY_RANGE_AVC;
}
case VAProfileVP9Profile0:
encoder_context->codec = CODEC_VP9;
+
+ if (obj_config->entrypoint == VAEntrypointEncSliceLP) {
+ encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_VP9;
+ encoder_context->quality_range = ENCODER_QUALITY_RANGE_VP9;
+ }
+
break;
default: