OSDN Git Service

Add the support of multi-slices for the HEVC encoder
authorpeng.chen <peng.c.chen@intel.com>
Wed, 19 Apr 2017 02:36:34 +0000 (10:36 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Thu, 27 Apr 2017 11:56:30 +0000 (19:56 +0800)
Signed-off-by: peng.chen <peng.c.chen@intel.com>
src/gen9_hevc_encoder.c
src/gen9_hevc_encoder.h
src/i965_drv_video.c
src/i965_encoder.c

index 7ff0d9e..20f05a9 100644 (file)
@@ -5783,12 +5783,44 @@ gen9_hevc_vme_gpe_init(VADriverContextP ctx,
 {
     struct encoder_vme_mfc_context *vme_context = NULL;
     struct gen9_hevc_encoder_context *priv_ctx = NULL;
+    struct gen9_hevc_encoder_state *priv_state = NULL;
+    VAEncSliceParameterBufferHEVC *slice_param = NULL;
+    int i = 0, j = 0;
 
     vme_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context;
     priv_ctx = (struct gen9_hevc_encoder_context *)vme_context->private_enc_ctx;
+    priv_state = (struct gen9_hevc_encoder_state *)vme_context->private_enc_state;
 
     i965_zero_gpe_resource(&priv_ctx->res_mb_code_surface);
+
     i965_zero_gpe_resource(&priv_ctx->res_slice_map_buffer);
+    if (encode_state->num_slice_params_ext > 1) {
+        struct gen9_hevc_slice_map *pslice_map = NULL;
+        int width = priv_state->width_in_lcu;
+        int pitch = ALIGN(priv_state->frame_width_in_max_lcu >> 3, 64);
+        void *ptr_start = NULL;
+        int lcu_count = 0;
+
+        ptr_start = (void *)i965_map_gpe_resource(&priv_ctx->res_slice_map_buffer);
+
+        pslice_map = (struct gen9_hevc_slice_map *)ptr_start;
+        for (i = 0; i < encode_state->num_slice_params_ext; i++) {
+            slice_param = (VAEncSliceParameterBufferHEVC *)encode_state->slice_params_ext[i]->buffer;
+
+            for (j = 0; j < slice_param->num_ctu_in_slice; j++) {
+                pslice_map[lcu_count++].slice_id = i;
+
+                if (lcu_count >= width) {
+                    lcu_count = 0;
+                    ptr_start += pitch;
+
+                    pslice_map = (struct gen9_hevc_slice_map *)ptr_start;
+                }
+            }
+        }
+
+        i965_unmap_gpe_resource(&priv_ctx->res_slice_map_buffer);
+    }
 
     return VA_STATUS_SUCCESS;
 }
index c8c568d..4604b7b 100644 (file)
@@ -317,6 +317,11 @@ struct gen9_hevc_brc_context {
     struct i965_gpe_context gpe_contexts[GEN9_HEVC_ENC_BRC_NUM];
 };
 
+struct gen9_hevc_slice_map {
+    unsigned char slice_id;
+    unsigned char reserved[3];
+};
+
 // PAK paramerters
 #define GEN9_HEVC_ENC_BRC_PIC_STATE_SIZE      (128)
 #define GEN9_HEVC_ENC_BRC_PAK_STATISTCS_SIZE  (32)
index 9d22792..993a82c 100644 (file)
@@ -1136,7 +1136,7 @@ i965_GetConfigAttributes(VADriverContextP ctx,
                         attrib_list[i].value = I965_MAX_NUM_SLICE;
                 } else if (profile == VAProfileHEVCMain ||
                            profile == VAProfileHEVCMain10) {
-                    attrib_list[i].value = 1;
+                    attrib_list[i].value = I965_MAX_NUM_SLICE;
                 }
             } else if (entrypoint == VAEntrypointEncSliceLP) {
                 if ((profile == VAProfileH264ConstrainedBaseline ||
@@ -1150,6 +1150,15 @@ i965_GetConfigAttributes(VADriverContextP ctx,
 
             break;
 
+        case VAConfigAttribEncSliceStructure:
+            if (entrypoint == VAEntrypointEncSlice) {
+                if (profile == VAProfileHEVCMain ||
+                    profile == VAProfileHEVCMain10)
+                    attrib_list[i].value = VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS;
+            }
+
+            break;
+
         default:
             /* Do nothing */
             attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
@@ -1279,9 +1288,8 @@ i965_CreateConfig(VADriverContextP ctx,
                 else
                     attrib.value = I965_MAX_NUM_SLICE;
             } else if (profile == VAProfileHEVCMain ||
-                       profile == VAProfileHEVCMain10) {
-                attrib.value = 1;
-            }
+                       profile == VAProfileHEVCMain10)
+                attrib.value = I965_MAX_NUM_SLICE;
         } else if (entrypoint == VAEntrypointEncSliceLP) {
             if ((profile == VAProfileH264ConstrainedBaseline ||
                  profile == VAProfileH264Main ||
index bd6cc8a..5f1a425 100644 (file)
@@ -1480,6 +1480,8 @@ intel_enc_hw_context_init(VADriverContextP ctx,
 
         encoder_context->quality_level = ENCODER_DEFAULT_QUALITY_HEVC;
         encoder_context->quality_range = ENCODER_QUALITY_RANGE_HEVC;
+
+        encoder_context->max_slice_or_seg_num = I965_MAX_NUM_SLICE;
         break;
 
     case VAProfileVP9Profile0: