[Libva] [PATCH 3/5] Added to support HEVC related to intel driver API

Qu,Pengfei Pengfei.Qu at intel.com
Mon Jan 5 19:33:28 PST 2015


Signed-off-by: Qu,Pengfei <Pengfei.Qu at intel.com>
---
 src/i965_device_info.c |  17 +++---
 src/i965_drv_video.c   | 153 ++++++++++++++++++++++++++++++++++++++-----------
 src/i965_drv_video.h   |  15 ++++-
 src/i965_encoder.c     |  74 +++++++++++++++++++++++-
 4 files changed, 213 insertions(+), 46 deletions(-)

diff --git a/src/i965_device_info.c b/src/i965_device_info.c
index ac5031a..e400b3f 100755
--- a/src/i965_device_info.c
+++ b/src/i965_device_info.c
@@ -347,6 +347,7 @@ static struct hw_codec_info skl_hw_codec_info = {
     .has_blending = 1,
     .has_h264_mvc_encoding = 1,
     .has_hevc_decoding = 1,
+    .has_hevc_encoding = 1,
 
     .num_filters = 5,
     .filters = {
@@ -502,7 +503,7 @@ static void cpuid(unsigned int op,
                          uint32_t *eax, uint32_t *ebx,
                          uint32_t *ecx, uint32_t *edx)
 {
-	__cpuid_count(op, 0, *eax, *ebx, *ecx, *edx);
+    __cpuid_count(op, 0, *eax, *ebx, *ecx, *edx);
 }
 
 /*
@@ -523,7 +524,7 @@ static int intel_driver_detect_cpustring(char *model_id)
 
     /* If the max extended CPUID info is less than 0x80000004, fail */
     if (rdata[0] < 0x80000004)
-	return -EINVAL;
+        return -EINVAL;
 
     /* obtain the CPUID string */
     cpuid(0x80000002, &rdata[0], &rdata[1], &rdata[2], &rdata[3]);
@@ -585,18 +586,18 @@ static void hsw_hw_codec_preinit(VADriverContextP ctx, struct hw_codec_info *cod
         model_ptr = (char *)hsw_cpu_hook_list[i];
 
         if (strlen(model_ptr) != model_len)
-	    continue;
+            continue;
 
         if (strncasecmp(model_string, model_ptr, model_len) == 0) {
             found = true;
             break;
-	}
+        }
     }
 
     if (found) {
-	codec_info->has_h264_encoding = 0;
-	codec_info->has_h264_mvc_encoding = 0;
-	codec_info->has_mpeg2_encoding = 0;
+        codec_info->has_h264_encoding = 0;
+        codec_info->has_h264_mvc_encoding = 0;
+        codec_info->has_mpeg2_encoding = 0;
     }
     return;
 }
@@ -713,7 +714,7 @@ static void gen7_hw_codec_preinit(VADriverContextP ctx, struct hw_codec_info *co
         if (strncasecmp(model_string, model_ptr, model_len) == 0) {
             found = true;
             break;
-	}
+        }
     }
 
     if (found) {
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index 034ff20..ccae568 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2009 Intel Corporation
+ * Copyright ?2009 Intel Corporation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -104,6 +104,9 @@
 #define HAS_HEVC_DECODING(ctx)          ((ctx)->codec_info->has_hevc_decoding && \
                                          (ctx)->intel.has_bsd)
 
+#define HAS_HEVC_ENCODING(ctx)          ((ctx)->codec_info->has_hevc_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) */
@@ -376,7 +379,10 @@ is_image_busy(struct i965_driver_data *i965, struct object_image *obj_image)
 }
 
 #define I965_PACKED_HEADER_BASE         0
-#define I965_PACKED_MISC_HEADER_BASE    3
+#define I965_SEQ_PACKED_HEADER_BASE     0
+#define I965_SEQ_PACKED_HEADER_END      2
+#define I965_PIC_PACKED_HEADER_BASE     2
+#define I965_PACKED_MISC_HEADER_BASE    4
 
 int
 va_enc_packed_type_to_idx(int packed_type)
@@ -393,15 +399,15 @@ va_enc_packed_type_to_idx(int packed_type)
 
         switch (packed_type) {
         case VAEncPackedHeaderSequence:
-            idx = I965_PACKED_HEADER_BASE + 0;
+            idx = I965_SEQ_PACKED_HEADER_BASE + 0;
             break;
 
         case VAEncPackedHeaderPicture:
-            idx = I965_PACKED_HEADER_BASE + 1;
+            idx = I965_PIC_PACKED_HEADER_BASE + 0;
             break;
 
         case VAEncPackedHeaderSlice:
-            idx = I965_PACKED_HEADER_BASE + 2;
+            idx = I965_PIC_PACKED_HEADER_BASE + 1;
             break;
 
         default:
@@ -411,7 +417,7 @@ va_enc_packed_type_to_idx(int packed_type)
         }
     }
 
-    ASSERT_RET(idx < 4, 0);
+    ASSERT_RET(idx < 5, 0);
     return idx;
 }
 
@@ -465,7 +471,8 @@ i965_QueryConfigProfiles(VADriverContextP ctx,
         profile_list[i++] = VAProfileH264StereoHigh;
     }
 
-    if (HAS_HEVC_DECODING(i965)) {
+    if (HAS_HEVC_DECODING(i965)||
+        HAS_HEVC_ENCODING(i965)) {
         profile_list[i++] = VAProfileHEVCMain;
     }
 
@@ -548,6 +555,9 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx,
         if (HAS_HEVC_DECODING(i965))
             entrypoint_list[n++] = VAEntrypointVLD;
 
+        if (HAS_HEVC_ENCODING(i965))
+            entrypoint_list[n++] = VAEntrypointEncSlice;
+
         break;
 
     default:
@@ -639,7 +649,8 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
         break;
 
     case VAProfileHEVCMain:
-        if (HAS_HEVC_DECODING(i965) && (entrypoint == VAEntrypointVLD))
+        if ((HAS_HEVC_DECODING(i965) && (entrypoint == VAEntrypointVLD))||
+            (HAS_HEVC_ENCODING(i965) && (entrypoint == VAEntrypointEncSlice)))
             va_status = VA_STATUS_SUCCESS;
         else
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
@@ -729,28 +740,29 @@ i965_GetConfigAttributes(VADriverContextP ctx,
                     profile == VAProfileH264Main ||
                     profile == VAProfileH264High ||
                     profile == VAProfileH264StereoHigh ||
-                    profile == VAProfileH264MultiviewHigh) {
+                    profile == VAProfileH264MultiviewHigh ||
+                    profile == VAProfileHEVCMain) {
                     attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA |
                                              VA_ENC_PACKED_HEADER_SLICE);
                 }
                 break;
             }
 
-	case VAConfigAttribEncMaxRefFrames:
-	    if (entrypoint == VAEntrypointEncSlice) {
-		attrib_list[i].value = (1 << 16) | (1 << 0);
-		break;
-	    }
+        case VAConfigAttribEncMaxRefFrames:
+            if (entrypoint == VAEntrypointEncSlice) {
+                attrib_list[i].value = (1 << 16) | (1 << 0);
+                break;
+            }
 
-	case VAConfigAttribEncQualityRange:
-	    if (entrypoint == VAEntrypointEncSlice) {
-		attrib_list[i].value = 1;
+        case VAConfigAttribEncQualityRange:
+            if (entrypoint == VAEntrypointEncSlice) {
+                attrib_list[i].value = 1;
                 if (profile == VAProfileH264ConstrainedBaseline ||
                     profile == VAProfileH264Main ||
                     profile == VAProfileH264High )
                     attrib_list[i].value = ENCODER_QUALITY_RANGE;
-		break;
-	    }
+                break;
+            }
     
     case VAConfigAttribEncJPEG: 
         if( entrypoint == VAEntrypointEncPicture) {
@@ -983,7 +995,7 @@ i965_surface_native_memory(VADriverContextP ctx,
         expected_fourcc == VA_FOURCC_YV12 ||
         expected_fourcc == VA_FOURCC_YV16)
         tiling = 0;
-		
+
     i965_check_alloc_surface_bo(ctx, obj_surface, tiling, expected_fourcc, get_sampling_from_fourcc(expected_fourcc));
 
     return VA_STATUS_SUCCESS;
@@ -1922,6 +1934,8 @@ i965_CreateContext(VADriverContextP ctx,
             obj_context->codec_state.encode.slice_header_index =
                 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
 
+            obj_context->codec_state.encode.vps_sps_seq_index = 0;
+
             obj_context->codec_state.encode.slice_index = 0;
             packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders);
             if (packed_attrib)
@@ -2008,6 +2022,20 @@ i965_create_buffer_internal(VADriverContextP ctx,
     struct object_buffer *obj_buffer = NULL;
     struct buffer_store *buffer_store = NULL;
     int bufferID;
+    struct object_context *obj_context = NULL;
+    struct object_config *obj_config = NULL;
+    VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
+
+    if (i965->current_context_id == VA_INVALID_ID)
+        return vaStatus;
+
+    obj_context = CONTEXT(i965->current_context_id);
+
+    if (!obj_context)
+        return vaStatus;
+
+    obj_config = obj_context->obj_config;
+    assert(obj_config);
 
     /* Validate type */
     switch (type) {
@@ -2081,7 +2109,11 @@ i965_create_buffer_internal(VADriverContextP ctx,
             struct i965_coded_buffer_segment *coded_buffer_segment;
 
             dri_bo_map(buffer_store->bo, 1);
-            coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual;
+            if(obj_config->profile == VAProfileHEVCMain){
+                coded_buffer_segment = (struct i965_coded_buffer_segment *)(buffer_store->bo->virtual + ALIGN(size - 0x1000, 0x1000));
+            }else {
+                coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual;
+            }
             coded_buffer_segment->base.size = size - I965_CODEDBUFFER_HEADER_SIZE;
             coded_buffer_segment->base.bit_offset = 0;
             coded_buffer_segment->base.status = 0;
@@ -2159,9 +2191,22 @@ i965_MapBuffer(VADriverContextP ctx,
                void **pbuf)             /* out */
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
+    struct object_context *obj_context = NULL;
+    struct object_config *obj_config = NULL;
     struct object_buffer *obj_buffer = BUFFER(buf_id);
     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
 
+    if (i965->current_context_id == VA_INVALID_ID)
+        return vaStatus;
+
+    obj_context = CONTEXT(i965->current_context_id);
+
+    if (!obj_context)
+        return vaStatus;
+
+    obj_config = obj_context->obj_config;
+    assert(obj_config);
+
     ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
     ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
     ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_INVALID_BUFFER);
@@ -2185,21 +2230,28 @@ i965_MapBuffer(VADriverContextP ctx,
         if (obj_buffer->type == VAEncCodedBufferType) {
             int i;
             unsigned char *buffer = NULL;
+            unsigned int  header_offset = I965_CODEDBUFFER_HEADER_SIZE;
             struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual);
 
+            if(obj_config->profile == VAProfileHEVCMain){
+                coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual + ALIGN(obj_buffer->size_element - 0x1000, 0x1000));
+                *pbuf = (unsigned char *)(obj_buffer->buffer_store->bo->virtual + ALIGN(obj_buffer->size_element - 0x1000, 0x1000));
+            }
+
             if (!coded_buffer_segment->mapped) {
                 unsigned char delimiter0, delimiter1, delimiter2, delimiter3, delimiter4;
 
-                coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
 
                 if (coded_buffer_segment->codec == CODEC_H264 ||
                     coded_buffer_segment->codec == CODEC_H264_MVC) {
+                    coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
                     delimiter0 = H264_DELIMITER0;
                     delimiter1 = H264_DELIMITER1;
                     delimiter2 = H264_DELIMITER2;
                     delimiter3 = H264_DELIMITER3;
                     delimiter4 = H264_DELIMITER4;
                 } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
+                    coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
                     delimiter0 = MPEG2_DELIMITER0;
                     delimiter1 = MPEG2_DELIMITER1;
                     delimiter2 = MPEG2_DELIMITER2;
@@ -2207,26 +2259,35 @@ i965_MapBuffer(VADriverContextP ctx,
                     delimiter4 = MPEG2_DELIMITER4;
                 } else if(coded_buffer_segment->codec == CODEC_JPEG) {
                     //In JPEG End of Image (EOI = 0xDDF9) marker can be used for delimiter.
+                    coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual);
                     delimiter0 = 0xFF;
                     delimiter1 = 0xD9;
-                }  else {
+                } else if (coded_buffer_segment->codec == CODEC_HEVC) {
+                    coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual);
+                    header_offset = 0 ;
+                    delimiter0 = HEVC_DELIMITER0;
+                    delimiter1 = HEVC_DELIMITER1;
+                    delimiter2 = HEVC_DELIMITER2;
+                    delimiter3 = HEVC_DELIMITER3;
+                    delimiter4 = HEVC_DELIMITER4;
+                } else {
                     ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
                 }
 
                 if(coded_buffer_segment->codec == CODEC_JPEG) {
-                    for(i = 0; i <  obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 1 - 0x1000; i++) {
+                    for(i = 0; i <  obj_buffer->size_element - header_offset - 1 - 0x1000; i++) {
                         if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) {
                             break;
                         }
                    }
 
-                   if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 1 - 0x1000) {
+                   if (i == obj_buffer->size_element - header_offset - 1 - 0x1000) {
                        coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
                    }
  
                    coded_buffer_segment->base.size = i + 2;
                 } else {
-                    for (i = 0; i < obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000; i++) {
+                    for (i = 0; i < obj_buffer->size_element - header_offset - 3 - 0x1000; i++) {
                         if ((buffer[i] == delimiter0) &&
                             (buffer[i + 1] == delimiter1) &&
                             (buffer[i + 2] == delimiter2) &&
@@ -2235,7 +2296,7 @@ i965_MapBuffer(VADriverContextP ctx,
                             break;
                         }
 
-                        if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000) {
+                        if (i == obj_buffer->size_element - header_offset - 3 - 0x1000) {
                             coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
                         }
                     coded_buffer_segment->base.size = i;
@@ -2411,6 +2472,7 @@ i965_BeginPicture(VADriverContextP ctx,
         obj_context->codec_state.encode.num_packed_header_params_ext = 0;
         obj_context->codec_state.encode.num_packed_header_data_ext = 0;
         obj_context->codec_state.encode.slice_index = 0;
+        obj_context->codec_state.encode.vps_sps_seq_index = 0;
     } else {
         obj_context->codec_state.decode.current_render_target = render_target;
         i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
@@ -2614,11 +2676,14 @@ i965_encoder_render_picture(VADriverContextP ctx,
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx); 
     struct object_context *obj_context = CONTEXT(context);
+    struct object_config *obj_config;
     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
     struct encode_state *encode;
     int i;
 
     ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
+    obj_config = obj_context->obj_config;
+    ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
 
     encode = &obj_context->codec_state.encode;
     for (i = 0; i < num_buffers; i++) {  
@@ -2692,6 +2757,12 @@ i965_encoder_render_picture(VADriverContextP ctx,
             if ((param->type == VAEncPackedHeaderRawData) ||
                 (param->type == VAEncPackedHeaderSlice)) {
                 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext);
+            } else if((obj_config->profile == VAProfileHEVCMain)&&
+                (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
+                vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
+                                                                          obj_context,
+                                                                          obj_buffer,
+                                                                          va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index);
             } else {
                 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
                                                                           obj_context,
@@ -2779,10 +2850,22 @@ i965_encoder_render_picture(VADriverContextP ctx,
                    (((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) &&
                     ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)),
                     VA_STATUS_ERROR_ENCODING_ERROR);
-                vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
-                                                                     obj_context,
-                                                                     obj_buffer,
-                                                                     va_enc_packed_type_to_idx(encode->last_packed_header_type));
+
+                if((obj_config->profile == VAProfileHEVCMain)&&
+                    (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
+
+                        vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
+                            obj_context,
+                            obj_buffer,
+                            va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index);
+                        encode->vps_sps_seq_index = (encode->vps_sps_seq_index + 1) % I965_SEQ_PACKED_HEADER_END;
+                }else{
+                    vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
+                        obj_context,
+                        obj_buffer,
+                        va_enc_packed_type_to_idx(encode->last_packed_header_type));
+
+                }
             }
             encode->last_packed_header_type = 0;
             break;       
@@ -3196,10 +3279,10 @@ i965_CreateImage(VADriverContextP ctx,
     awidth = ALIGN(width, i965->codec_info->min_linear_wpitch);
 
     if ((format->fourcc == VA_FOURCC_YV12) ||
-    		(format->fourcc == VA_FOURCC_I420)) {
-	if (awidth % 128 != 0) {
-		awidth = ALIGN(width, 128);	
-	}
+        (format->fourcc == VA_FOURCC_I420)) {
+            if (awidth % 128 != 0) {
+                awidth = ALIGN(width, 128);	
+            }
     }
 
     aheight = ALIGN(height, i965->codec_info->min_linear_hpitch);
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index cb4e8e8..90a7100 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -33,6 +33,7 @@
 #include <va/va.h>
 #include <va/va_enc_h264.h>
 #include <va/va_enc_mpeg2.h>
+#include <va/va_enc_hevc.h>
 #include <va/va_enc_jpeg.h>
 #include <va/va_vpp.h>
 #include <va/va_backend.h>
@@ -150,8 +151,8 @@ struct encode_state
     /* for ext */
     struct buffer_store *seq_param_ext;
     struct buffer_store *pic_param_ext;
-    struct buffer_store *packed_header_param[4];
-    struct buffer_store *packed_header_data[4];
+    struct buffer_store *packed_header_param[5];
+    struct buffer_store *packed_header_data[5];
     struct buffer_store **slice_params_ext;
     int max_slice_params_ext;
     int num_slice_params_ext;
@@ -171,6 +172,8 @@ struct encode_state
     int max_packed_header_data_ext;
     int num_packed_header_data_ext;
 
+    /* the index of current vps and sps ,special for HEVC*/
+    int vps_sps_seq_index;
     /* the index of current slice */
     int slice_index;
     /* the array is determined by max_slice_params_ext */
@@ -370,6 +373,7 @@ struct hw_codec_info
     unsigned int has_vp8_encoding:1;
     unsigned int has_h264_mvc_encoding:1;
     unsigned int has_hevc_decoding:1;
+    unsigned int has_hevc_encoding:1;
 
     unsigned int num_filters;
     struct i965_filter filters[VAProcFilterCount];
@@ -454,6 +458,7 @@ va_enc_packed_type_to_idx(int packed_type);
 #define CODEC_MPEG2     1
 #define CODEC_H264_MVC  2
 #define CODEC_JPEG      3
+#define CODEC_HEVC      4
 
 #define H264_DELIMITER0 0x00
 #define H264_DELIMITER1 0x00
@@ -467,6 +472,12 @@ va_enc_packed_type_to_idx(int packed_type);
 #define MPEG2_DELIMITER3        0x00
 #define MPEG2_DELIMITER4        0xb0
 
+#define HEVC_DELIMITER0 0x00
+#define HEVC_DELIMITER1 0x00
+#define HEVC_DELIMITER2 0x00
+#define HEVC_DELIMITER3 0x00
+#define HEVC_DELIMITER4 0x00
+
 struct i965_coded_buffer_segment
 {
     VACodedBufferSegment base;
diff --git a/src/i965_encoder.c b/src/i965_encoder.c
index d924f5a..c9ff2ec 100644
--- a/src/i965_encoder.c
+++ b/src/i965_encoder.c
@@ -39,10 +39,12 @@
 #include "i965_encoder.h"
 #include "gen6_vme.h"
 #include "gen6_mfc.h"
+#include "gen9_mfc.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);
+extern Bool gen9_hcpe_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
 
 static VAStatus
 intel_encoder_check_yuv_surface(VADriverContextP ctx,
@@ -422,6 +424,63 @@ error:
 }
 
 static VAStatus
+intel_encoder_check_hevc_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;	
+    struct object_buffer *obj_buffer;
+    VAEncPictureParameterBufferHEVC *pic_param = (VAEncPictureParameterBufferHEVC *)encode_state->pic_param_ext->buffer;
+    int i;
+
+    assert(!(pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID));
+
+    if (pic_param->decoded_curr_pic.flags & VA_PICTURE_HEVC_INVALID)
+        goto error;
+
+    obj_surface = SURFACE(pic_param->decoded_curr_pic.picture_id);
+    assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
+    
+    if (!obj_surface)
+        goto error;
+
+    encode_state->reconstructed_object = obj_surface;
+    obj_buffer = BUFFER(pic_param->coded_buf);
+    assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
+
+    if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
+        goto error;
+
+    encode_state->coded_buf_object = obj_buffer;
+
+    for (i = 0; i < 15; i++) {
+        if (pic_param->reference_frames[i].flags & VA_PICTURE_HEVC_INVALID ||
+            pic_param->reference_frames[i].picture_id == VA_INVALID_SURFACE)
+            break;
+        else {
+            obj_surface = SURFACE(pic_param->reference_frames[i].picture_id);
+            assert(obj_surface);
+
+            if (!obj_surface)
+                goto error;
+
+            if (obj_surface->bo)
+                encode_state->reference_objects[i] = obj_surface;
+            else
+                encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
+        }
+    }
+
+    for ( ; i < 15; 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,
                                  struct encode_state *encode_state,
@@ -459,6 +518,13 @@ intel_encoder_sanity_check_input(VADriverContextP ctx,
         break;
     }
 
+    case VAProfileHEVCMain:  {
+        vaStatus = intel_encoder_check_hevc_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;
+    }
     default:
         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
         break;
@@ -554,6 +620,10 @@ intel_enc_hw_context_init(VADriverContextP ctx,
         encoder_context->codec = CODEC_JPEG;
         break;
 
+    case VAProfileHEVCMain:
+        encoder_context->codec = CODEC_HEVC;
+        break;
+
     default:
         /* Never get here */
         assert(0);
@@ -617,7 +687,9 @@ gen8_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
 struct hw_context *
 gen9_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
 {
-    if (obj_config->profile == VAProfileJPEGBaseline)
+    if (obj_config->profile == VAProfileHEVCMain) {
+        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
         return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_mfc_context_init);
-- 
1.9.1



More information about the Libva mailing list