[Libva] [PATCH V2 3/6] HEVC ENC:Added HEVC support in API function

Zhao, Yakui yakui.zhao at intel.com
Tue Jan 6 17:21:25 PST 2015


On Tue, 2015-01-06 at 01:57 -0700, Qu,Pengfei wrote:

Not sure whether the HEVC encoding profile is exported earlier than the
low-level implementation?

If the subsequent patches are not applied, maybe user-space app queries
the entrypoint for HEVC encoding and then try to use it. In such case it
doesn't work at all. 

How about exporting the HEVC encoding profile/entrypoint after the
low-level implementations are already added?

> Signed-off-by: Qu,Pengfei <Pengfei.Qu at intel.com>
> ---
>  src/i965_device_info.c |   1 +
>  src/i965_drv_video.c   | 121 +++++++++++++++++++++++++++++++++++++++++--------
>  2 files changed, 103 insertions(+), 19 deletions(-)
> 
> diff --git a/src/i965_device_info.c b/src/i965_device_info.c
> index d03aceb..9ccc85e 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 = {
> diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
> index 74895da..ca9703b 100644
> --- a/src/i965_drv_video.c
> +++ b/src/i965_drv_video.c
> @@ -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,7 +740,8 @@ 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);
>                  }
> @@ -1894,6 +1906,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)
> @@ -1980,6 +1994,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) {
> @@ -2053,7 +2081,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;
> @@ -2131,9 +2163,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);
> @@ -2157,21 +2202,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;
> @@ -2179,26 +2231,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) &&
> @@ -2207,7 +2268,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;
> @@ -2383,6 +2444,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);
> @@ -2586,11 +2648,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++) {  
> @@ -2664,6 +2729,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,
> @@ -2751,10 +2822,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;       




More information about the Libva mailing list