[Libva] [LIBVA-INTEL-DRIVER][PATCH 09/12] Export the Vp9 encoding profile/entrypoint for KBL

Zhao Yakui yakui.zhao at intel.com
Tue May 24 12:00:35 UTC 2016


Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
Reviewed-by: Sean V Kelley <sean.v.kelley at intel.com>
---
 src/i965_device_info.c |  1 +
 src/i965_drv_video.c   | 51 +++++++++++++++++++++++++----
 src/i965_drv_video.h   |  2 ++
 src/i965_encoder.c     | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 135 insertions(+), 6 deletions(-)

diff --git a/src/i965_device_info.c b/src/i965_device_info.c
index 0d9f2cd..96ea43c 100644
--- a/src/i965_device_info.c
+++ b/src/i965_device_info.c
@@ -468,6 +468,7 @@ static struct hw_codec_info kbl_hw_codec_info = {
     .has_hevc10_decoding = 1,
     .has_vp9_decoding = 1,
     .has_vpp_p010 = 1,
+    .has_vp9_encoding = 1,
 
     .num_filters = 5,
     .filters = {
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index 932e5be..186443b 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -48,6 +48,8 @@
 #include "i965_decoder.h"
 #include "i965_encoder.h"
 
+#include "gen9_vp9_encapi.h"
+
 #define CONFIG_ID_OFFSET                0x01000000
 #define CONTEXT_ID_OFFSET               0x02000000
 #define SURFACE_ID_OFFSET               0x04000000
@@ -122,6 +124,9 @@
 #define HAS_VPP_P010(ctx)        ((ctx)->codec_info->has_vpp_p010 && \
                                          (ctx)->intel.has_bsd)
 
+#define HAS_VP9_ENCODING(ctx)          ((ctx)->codec_info->has_vp9_encoding && \
+                                         (ctx)->intel.has_bsd)
+
 static int get_sampling_from_fourcc(unsigned int fourcc);
 
 /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */
@@ -604,7 +609,8 @@ i965_QueryConfigProfiles(VADriverContextP ctx,
         profile_list[i++] = VAProfileHEVCMain10;
     }
 
-    if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile0)) {
+    if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile0) ||
+        HAS_VP9_ENCODING(i965)) {
         profile_list[i++] = VAProfileVP9Profile0;
     }
 
@@ -729,6 +735,9 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx,
         if(HAS_VP9_DECODING_PROFILE(i965, profile))
             entrypoint_list[n++] = VAEntrypointVLD;
 
+        if (HAS_VP9_ENCODING(i965))
+            entrypoint_list[n++] = VAEntrypointEncSlice;
+
         if(profile == VAProfileVP9Profile0) {
           if (i965->wrapper_pdrvctx) {
               VAStatus va_status = VA_STATUS_SUCCESS;
@@ -854,6 +863,8 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
     case VAProfileVP9Profile2:
         if ((HAS_VP9_DECODING_PROFILE(i965, profile)) && (entrypoint == VAEntrypointVLD))
             va_status = VA_STATUS_SUCCESS;
+       else if ((HAS_VP9_ENCODING(i965)) && (entrypoint == VAEntrypointEncSlice))
+            va_status = VA_STATUS_SUCCESS;
         else if ((profile == VAProfileVP9Profile0) && i965->wrapper_pdrvctx)
             va_status = VA_STATUS_SUCCESS;
         else
@@ -977,6 +988,8 @@ i965_GetConfigAttributes(VADriverContextP ctx,
                     attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA |
                                              VA_ENC_PACKED_HEADER_SLICE);
                 }
+                else if (profile == VAProfileVP9Profile0)
+                    attrib_list[i].value = VA_ENC_PACKED_HEADER_RAW_DATA;
                 break;
             }
             else if (entrypoint == VAEntrypointEncPicture) {
@@ -2216,9 +2229,12 @@ i965_CreateContext(VADriverContextP ctx,
 
             obj_context->codec_state.encode.slice_index = 0;
             packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders);
-            if (packed_attrib)
+            if (packed_attrib) {
                 obj_context->codec_state.encode.packed_header_flag = packed_attrib->value;
-            else {
+                if (obj_config->profile == VAProfileVP9Profile0)
+                    obj_context->codec_state.encode.packed_header_flag =
+                            packed_attrib->value & VA_ENC_PACKED_HEADER_RAW_DATA;
+            } else {
                 /* use the default value. SPS/PPS/RAWDATA is passed from user
                  * while Slice_header data is generated by driver.
                  */
@@ -2226,6 +2242,10 @@ i965_CreateContext(VADriverContextP ctx,
                                VA_ENC_PACKED_HEADER_SEQUENCE |
                                VA_ENC_PACKED_HEADER_PICTURE |
                                VA_ENC_PACKED_HEADER_RAW_DATA;
+
+                /* it is not used for VP9 */
+                if (obj_config->profile == VAProfileVP9Profile0)
+                    obj_context->codec_state.encode.packed_header_flag = 0;
             }
             assert(i965->codec_info->enc_hw_context_init);
             obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
@@ -2599,7 +2619,16 @@ i965_MapBuffer(VADriverContextP ctx,
                     coded_buffer_segment->status_support) {
                     vaStatus = obj_context->hw_context->get_status(ctx, obj_context->hw_context, coded_buffer_segment);
                 } else {
-                    if (coded_buffer_segment->codec == CODEC_H264 ||
+
+                    if (coded_buffer_segment->codec == CODEC_VP9) {
+
+                        if (obj_context == NULL)
+                            return VA_STATUS_ERROR_ENCODING_ERROR;
+
+                        gen9_vp9_get_coded_status(ctx, (char *)coded_buffer_segment,
+                                                  obj_context->hw_context);
+                    }
+                    else if (coded_buffer_segment->codec == CODEC_H264 ||
                         coded_buffer_segment->codec == CODEC_H264_MVC) {
                         delimiter0 = H264_DELIMITER0;
                         delimiter1 = H264_DELIMITER1;
@@ -2626,6 +2655,9 @@ i965_MapBuffer(VADriverContextP ctx,
                         ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
                     }
 
+                    if(coded_buffer_segment->codec == CODEC_VP9) {
+                        /* it is already handled */
+                    } else
                     if(coded_buffer_segment->codec == CODEC_JPEG) {
                         for(i = 0; i <  obj_buffer->size_element - header_offset - 1 - 0x1000; i++) {
                             if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) {
@@ -3240,10 +3272,14 @@ i965_encoder_render_picture(VADriverContextP ctx,
                 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
                 return vaStatus;
             }
+
             if (encode->last_packed_header_type == VAEncPackedHeaderRawData ||
                 encode->last_packed_header_type == VAEncPackedHeaderSlice) {
                 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext);
 
+                if (obj_config->profile == VAProfileVP9Profile0)
+                    break;
+
                 /* When the PACKED_SLICE_HEADER flag is passed, it will use
                  * the packed_slice_header as the delimeter to decide how
                  * the packed rawdata is inserted for the given slice.
@@ -3453,11 +3489,14 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context)
         if (!(obj_context->codec_state.encode.seq_param ||
                 obj_context->codec_state.encode.seq_param_ext) &&
                 (VAEntrypointEncPicture != obj_config->entrypoint)) {
-            return VA_STATUS_ERROR_INVALID_PARAMETER;
+            /* The seq_param is not mandatory for VP9 encoding */
+            if (obj_config->profile != VAProfileVP9Profile0)
+                return VA_STATUS_ERROR_INVALID_PARAMETER;
         }
         if ((obj_context->codec_state.encode.num_slice_params <=0) &&
                 (obj_context->codec_state.encode.num_slice_params_ext <=0) &&
-                (obj_config->profile != VAProfileVP8Version0_3)) {
+                ((obj_config->profile != VAProfileVP8Version0_3) &&
+                 (obj_config->profile != VAProfileVP9Profile0))) {
             return VA_STATUS_ERROR_INVALID_PARAMETER;
         }
 
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index 93f9921..b8d61a1 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -400,6 +400,7 @@ struct hw_codec_info
     unsigned int has_vp9_decoding:1;
     unsigned int has_vpp_p010:1;
     unsigned int has_lp_h264_encoding:1;
+    unsigned int has_vp9_encoding:1;
 
     unsigned int lp_h264_brc_mode;
 
@@ -490,6 +491,7 @@ va_enc_packed_type_to_idx(int packed_type);
 #define CODEC_JPEG      3
 #define CODEC_VP8       4
 #define CODEC_HEVC      5
+#define CODEC_VP9       6
 
 #define H264_DELIMITER0 0x00
 #define H264_DELIMITER1 0x00
diff --git a/src/i965_encoder.c b/src/i965_encoder.c
index cee27fa..1088f08 100644
--- a/src/i965_encoder.c
+++ b/src/i965_encoder.c
@@ -42,6 +42,8 @@
 #include "gen9_mfc.h"
 #include "gen9_vdenc.h"
 
+#include "gen9_vp9_encapi.h"
+
 extern Bool gen6_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
 extern Bool gen6_vme_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
 extern Bool gen7_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
@@ -558,6 +560,76 @@ intel_encoder_check_hevc_parameter(VADriverContextP ctx,
 error:
     return VA_STATUS_ERROR_INVALID_PARAMETER;
 }
+
+static VAStatus
+intel_encoder_check_vp9_parameter(VADriverContextP ctx,
+                                  struct encode_state *encode_state,
+                                  struct intel_encoder_context *encoder_context)
+{
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+    VAEncPictureParameterBufferVP9 *pic_param;
+    struct object_surface *obj_surface;
+    struct object_buffer *obj_buffer;
+    int i = 0;
+    int is_key_frame = 0;
+    int index;
+
+    if (encode_state->pic_param_ext == NULL ||
+        encode_state->pic_param_ext->buffer == NULL)
+        return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+    pic_param = (VAEncPictureParameterBufferVP9 *)encode_state->pic_param_ext->buffer;
+
+    obj_surface = SURFACE(pic_param->reconstructed_frame);
+
+    if (!obj_surface)
+        goto error;
+
+    encode_state->reconstructed_object = obj_surface;
+    obj_buffer = BUFFER(pic_param->coded_buf);
+
+    if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
+        goto error;
+
+    encode_state->coded_buf_object = obj_buffer;
+
+    is_key_frame = !pic_param->pic_flags.bits.frame_type;
+    if (!is_key_frame && !pic_param->pic_flags.bits.intra_only) {
+        /* slot 0 is for last reference frame */
+        index = pic_param->ref_flags.bits.ref_last_idx;
+        obj_surface = SURFACE(pic_param->reference_frames[index]);
+        if (obj_surface && obj_surface->bo)
+            encode_state->reference_objects[i++] = obj_surface;
+        else
+            encode_state->reference_objects[i++] = NULL;
+
+        /* slot 1 is for golden reference frame */
+        index = pic_param->ref_flags.bits.ref_gf_idx;
+        obj_surface = SURFACE(pic_param->reference_frames[index]);
+        if (obj_surface && obj_surface->bo)
+            encode_state->reference_objects[i++] = obj_surface;
+        else
+            encode_state->reference_objects[i++] = NULL;
+
+        /* slot 2 is alt reference frame */
+        index = pic_param->ref_flags.bits.ref_arf_idx;
+        obj_surface = SURFACE(pic_param->reference_frames[index]);
+        if (obj_surface && obj_surface->bo)
+            encode_state->reference_objects[i++] = obj_surface;
+        else
+            encode_state->reference_objects[i++] = NULL;
+    }
+
+    for ( ; i < 16; i++)
+        encode_state->reference_objects[i] = NULL;
+
+    return VA_STATUS_SUCCESS;
+
+error:
+    return VA_STATUS_ERROR_INVALID_PARAMETER;
+}
+
+
 static VAStatus
 intel_encoder_sanity_check_input(VADriverContextP ctx,
                                  VAProfile profile,
@@ -611,6 +683,13 @@ intel_encoder_sanity_check_input(VADriverContextP ctx,
         vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
         break;
     }
+
+    case VAProfileVP9Profile0: {
+        vaStatus = intel_encoder_check_vp9_parameter(ctx, encode_state, encoder_context);
+        if (vaStatus != VA_STATUS_SUCCESS)
+            goto out;
+        break;
+    }
     default:
         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
         break;
@@ -739,6 +818,10 @@ intel_enc_hw_context_init(VADriverContextP ctx,
         encoder_context->codec = CODEC_HEVC;
         break;
 
+    case VAProfileVP9Profile0:
+        encoder_context->codec = CODEC_VP9;
+        break;
+
     default:
         /* Never get here */
         assert(0);
@@ -814,6 +897,10 @@ gen9_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
             return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_hcpe_context_init);
         } else if (obj_config->profile == VAProfileJPEGBaseline)
             return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init);
+        else if (obj_config->profile == VAProfileVP9Profile0)
+            return intel_enc_hw_context_init(ctx, obj_config,
+                                             gen9_vp9_vme_context_init,
+                                             gen9_vp9_pak_context_init);
         else
             return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_mfc_context_init);
     }
-- 
1.8.2.1



More information about the Libva mailing list