OSDN Git Service

Fix a typo
[android-x86/hardware-intel-common-vaapi.git] / src / i965_encoder.c
index 8ad1c41..3e28fcb 100644 (file)
@@ -824,6 +824,16 @@ intel_encoder_check_misc_parameter(VADriverContextP ctx,
 {
     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) {
@@ -838,8 +848,8 @@ intel_encoder_check_misc_parameter(VADriverContextP ctx,
             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;
 
@@ -959,16 +969,70 @@ error:
 }
 
 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 */
 
@@ -1018,6 +1082,11 @@ intel_encoder_check_mpeg2_parameter(VADriverContextP ctx,
     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:
@@ -1044,6 +1113,9 @@ intel_encoder_check_jpeg_parameter(VADriverContextP ctx,
 
     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:
@@ -1203,6 +1275,12 @@ intel_encoder_check_hevc_parameter(VADriverContextP ctx,
 
     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:
@@ -1279,6 +1357,9 @@ intel_encoder_check_vp9_parameter(VADriverContextP ctx,
 
     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:
@@ -1300,11 +1381,20 @@ intel_encoder_sanity_check_input(VADriverContextP ctx,
     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:
@@ -1379,9 +1469,11 @@ intel_encoder_end_picture(VADriverContextP ctx,
 
     /* 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) {
@@ -1493,7 +1585,8 @@ intel_enc_hw_context_init(VADriverContextP ctx,
 
         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
@@ -1508,11 +1601,16 @@ intel_enc_hw_context_init(VADriverContextP ctx,
                     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;
         }
@@ -1541,6 +1639,12 @@ intel_enc_hw_context_init(VADriverContextP ctx,
 
     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: