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

Qu, Pengfei pengfei.qu at intel.com
Tue Jan 6 18:09:28 PST 2015


Sure, I will try to adjust the patch order again.

-----Original Message-----
From: Zhao, Yakui 
Sent: Wednesday, January 7, 2015 9:21 AM
To: Qu, Pengfei
Cc: libva at lists.freedesktop.org
Subject: Re: [Libva] [PATCH V2 3/6] HEVC ENC:Added HEVC support in API function

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