OSDN Git Service

ENC: Add the attribute of VAConfigAttribEncMaxSlices for AVC/HEVC encoder
[android-x86/hardware-intel-common-vaapi.git] / src / i965_encoder.c
index ae31f01..9839f06 100644 (file)
@@ -41,6 +41,7 @@
 #include "gen6_mfc.h"
 
 #include "i965_post_processing.h"
+#include "i965_encoder_api.h"
 
 static struct intel_fraction
 reduce_fraction(struct intel_fraction f)
@@ -116,6 +117,8 @@ intel_encoder_check_yuv_surface(VADriverContextP ctx,
     struct object_surface *obj_surface;
     VAStatus status;
     VARectangle rect;
+    int format = VA_RT_FORMAT_YUV420;
+    unsigned int fourcc = VA_FOURCC_NV12;
 
     /* releae the temporary surface */
     if (encoder_context->is_tmp_id) {
@@ -148,6 +151,11 @@ intel_encoder_check_yuv_surface(VADriverContextP ctx,
         }
     }
 
+    if (VAProfileHEVCMain10 == profile) {
+        format = VA_RT_FORMAT_YUV420_10BPP;
+        fourcc = VA_FOURCC_P010;
+    }
+
     rect.x = 0;
     rect.y = 0;
     rect.width = obj_surface->orig_width;
@@ -160,7 +168,7 @@ intel_encoder_check_yuv_surface(VADriverContextP ctx,
     status = i965_CreateSurfaces(ctx,
                                  obj_surface->orig_width,
                                  obj_surface->orig_height,
-                                 VA_RT_FORMAT_YUV420,
+                                 format,
                                  1,
                                  &encoder_context->input_yuv_surface);
     ASSERT_RET(status == VA_STATUS_SUCCESS, status);
@@ -168,7 +176,7 @@ intel_encoder_check_yuv_surface(VADriverContextP ctx,
     obj_surface = SURFACE(encoder_context->input_yuv_surface);
     encode_state->input_yuv_object = obj_surface;
     assert(obj_surface);
-    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
+    i965_check_alloc_surface_bo(ctx, obj_surface, 1, fourcc, SUBSAMPLE_YUV420);
     
     dst_surface.base = (struct object_base *)obj_surface;
     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
@@ -575,8 +583,12 @@ intel_encoder_check_rate_control_parameter(VADriverContextP ctx,
         encoder_context->brc.need_reset = 1;
     }
 
-    if (encoder_context->brc.window_size != misc->window_size) {
+    if (encoder_context->brc.window_size != misc->window_size ||
+        encoder_context->brc.initial_qp  != misc->initial_qp ||
+        encoder_context->brc.min_qp      != misc->min_qp) {
         encoder_context->brc.window_size = misc->window_size;
+        encoder_context->brc.initial_qp  = misc->initial_qp;
+        encoder_context->brc.min_qp      = misc->min_qp;
         encoder_context->brc.need_reset = 1;
     }
 
@@ -845,6 +857,9 @@ intel_encoder_check_avc_parameter(VADriverContextP ctx,
     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
         goto error;
 
+    if (encode_state->num_slice_params_ext > encoder_context->max_slice_or_seg_num )
+        goto error;
+
     encode_state->coded_buf_object = obj_buffer;
 
     for (i = 0; i < 16; i++) {
@@ -1090,6 +1105,9 @@ intel_encoder_check_hevc_parameter(VADriverContextP ctx,
     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
         goto error;
 
+    if (encode_state->num_slice_params_ext > encoder_context->max_slice_or_seg_num )
+        goto error;
+
     encode_state->coded_buf_object = obj_buffer;
 
     for (i = 0; i < 15; i++) {
@@ -1358,6 +1376,7 @@ intel_enc_hw_context_init(VADriverContextP ctx,
                           hw_init_func vme_context_init,
                           hw_init_func mfc_context_init)
 {
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct intel_driver_data *intel = intel_driver_data(ctx);
     struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
     int i;
@@ -1374,6 +1393,7 @@ intel_enc_hw_context_init(VADriverContextP ctx,
     encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
     encoder_context->quality_range = 1;
     encoder_context->layer.num_layers = 1;
+    encoder_context->max_slice_or_seg_num = 1;
 
     if (obj_config->entrypoint == VAEntrypointEncSliceLP)
         encoder_context->low_power_mode = 1;
@@ -1391,12 +1411,20 @@ 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)){
+            encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
+            encoder_context->quality_range = ENCODER_QUALITY_RANGE_AVC;
+        }
         else
             encoder_context->quality_range = ENCODER_QUALITY_RANGE;
         break;
 
     case VAProfileH264StereoHigh:
     case VAProfileH264MultiviewHigh:
+        if(IS_GEN9(i965->intel.device_info)){
+            encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_AVC;
+            encoder_context->quality_range = ENCODER_QUALITY_RANGE_AVC;
+        }
         encoder_context->codec = CODEC_H264_MVC;
         break;
         
@@ -1406,6 +1434,8 @@ intel_enc_hw_context_init(VADriverContextP ctx,
 
     case VAProfileVP8Version0_3:
         encoder_context->codec = CODEC_VP8;
+        encoder_context->quality_range = ENCODER_QUALITY_RANGE;
+
         break;
 
     case VAProfileHEVCMain:
@@ -1437,6 +1467,11 @@ intel_enc_hw_context_init(VADriverContextP ctx,
             if (encoder_context->codec == CODEC_H264)
                 encoder_context->context_roi = 1;
         }
+        if (obj_config->attrib_list[i].type == VAConfigAttribEncMaxSlices) {
+            if (encoder_context->codec == CODEC_H264 ||
+                encoder_context->codec == CODEC_HEVC)
+                encoder_context->max_slice_or_seg_num = obj_config->attrib_list[i].value;
+        }
     }
 
     if (vme_context_init) {