X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fi965_drv_video.c;h=ba7c7be547c4ef64b713bec71215ff6a69a913c4;hb=54a1067672991bc7004d3496a486ede0feef61bf;hp=d8b50dcdf81fb82eca098b5579824937e801773b;hpb=89507c06c7ed03d829cf2526e621d844e174c90c;p=platform%2Fupstream%2Flibva-intel-driver.git diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c old mode 100755 new mode 100644 index d8b50dc..ba7c7be --- a/src/i965_drv_video.c +++ b/src/i965_drv_video.c @@ -28,6 +28,7 @@ */ #include "sysdeps.h" +#include #ifdef HAVE_VA_X11 # include "i965_output_dri.h" @@ -627,6 +628,7 @@ i965_GetConfigAttributes(VADriverContextP ctx, int num_attribs) { VAStatus va_status; + struct i965_driver_data *i965 = i965_driver_data(ctx); int i; va_status = i965_validate_config(ctx, profile, entrypoint); @@ -658,8 +660,10 @@ i965_GetConfigAttributes(VADriverContextP ctx, if (profile == VAProfileH264ConstrainedBaseline || profile == VAProfileH264Main || profile == VAProfileH264High || + profile == VAProfileH264StereoHigh || profile == VAProfileH264MultiviewHigh) { - attrib_list[i].value |= VA_ENC_PACKED_HEADER_RAW_DATA; + attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA | + VA_ENC_PACKED_HEADER_SLICE); } break; } @@ -670,6 +674,16 @@ i965_GetConfigAttributes(VADriverContextP ctx, break; } + 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; + } + default: /* Do nothing */ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED; @@ -1650,6 +1664,12 @@ i965_destroy_context(struct object_heap *heap, struct object_base *obj) free(obj_context->codec_state.encode.slice_rawdata_count); obj_context->codec_state.encode.slice_rawdata_count = NULL; } + + if (obj_context->codec_state.encode.slice_header_index) { + free(obj_context->codec_state.encode.slice_header_index); + obj_context->codec_state.encode.slice_header_index = NULL; + } + for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++) i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]); free(obj_context->codec_state.encode.packed_header_params_ext); @@ -1770,6 +1790,7 @@ i965_CreateContext(VADriverContextP ctx, assert(i965->codec_info->proc_hw_context_init); obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config); } else if (VAEntrypointEncSlice == obj_config->entrypoint) { /*encode routin only*/ + VAConfigAttrib *packed_attrib; obj_context->codec_type = CODEC_ENC; memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode)); obj_context->codec_state.encode.current_render_target = VA_INVALID_ID; @@ -1786,12 +1807,28 @@ i965_CreateContext(VADriverContextP ctx, calloc(obj_context->codec_state.encode.max_packed_header_data_ext, sizeof(struct buffer_store *)); - obj_context->codec_state.encode.slice_num = NUM_SLICES; + obj_context->codec_state.encode.max_slice_num = NUM_SLICES; obj_context->codec_state.encode.slice_rawdata_index = - calloc(obj_context->codec_state.encode.slice_num, sizeof(int)); + calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int)); obj_context->codec_state.encode.slice_rawdata_count = - calloc(obj_context->codec_state.encode.slice_num, sizeof(int)); - + calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int)); + + obj_context->codec_state.encode.slice_header_index = + calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int)); + + obj_context->codec_state.encode.slice_index = 0; + packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders); + if (packed_attrib) + obj_context->codec_state.encode.packed_header_flag = packed_attrib->value; + else { + /* use the default value. SPS/PPS/RAWDATA is passed from user + * while Slice_header data is generated by driver. + */ + obj_context->codec_state.encode.packed_header_flag = + VA_ENC_PACKED_HEADER_SEQUENCE | + VA_ENC_PACKED_HEADER_PICTURE | + VA_ENC_PACKED_HEADER_RAW_DATA; + } assert(i965->codec_info->enc_hw_context_init); obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config); } else { @@ -1913,6 +1950,7 @@ i965_create_buffer_internal(VADriverContextP ctx, obj_buffer->num_elements = num_elements; obj_buffer->size_element = size; obj_buffer->type = type; + obj_buffer->export_refcount = 0; obj_buffer->buffer_store = NULL; buffer_store = calloc(1, sizeof(struct buffer_store)); assert(buffer_store); @@ -2226,9 +2264,11 @@ i965_BeginPicture(VADriverContextP ctx, obj_context->codec_state.encode.current_render_target = render_target; /*This is input new frame*/ obj_context->codec_state.encode.last_packed_header_type = 0; memset(obj_context->codec_state.encode.slice_rawdata_index, 0, - sizeof(int) * obj_context->codec_state.encode.slice_num); + sizeof(int) * obj_context->codec_state.encode.max_slice_num); memset(obj_context->codec_state.encode.slice_rawdata_count, 0, - sizeof(int) * obj_context->codec_state.encode.slice_num); + sizeof(int) * obj_context->codec_state.encode.max_slice_num); + memset(obj_context->codec_state.encode.slice_header_index, 0, + sizeof(int) * obj_context->codec_state.encode.max_slice_num); for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++) i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]); @@ -2236,6 +2276,7 @@ i965_BeginPicture(VADriverContextP ctx, i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]); 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; } else { obj_context->codec_state.decode.current_render_target = render_target; i965_release_buffer_store(&obj_context->codec_state.decode.pic_param); @@ -2475,13 +2516,27 @@ i965_encoder_render_picture(VADriverContextP ctx, * to reallocate the arrays that is used to store * the packed data index/count for the slice */ - if (encode->max_slice_params_ext > encode->slice_num) { - encode->slice_num = encode->max_slice_params_ext; + if (!(encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE)) { + encode->slice_index++; + } + if (encode->slice_index == encode->max_slice_num) { + int slice_num = encode->max_slice_num; encode->slice_rawdata_index = realloc(encode->slice_rawdata_index, - encode->slice_num * sizeof(int)); + (slice_num + NUM_SLICES) * sizeof(int)); encode->slice_rawdata_count = realloc(encode->slice_rawdata_count, - encode->slice_num * sizeof(int)); + (slice_num + NUM_SLICES) * sizeof(int)); + encode->slice_header_index = realloc(encode->slice_header_index, + (slice_num + NUM_SLICES) * sizeof(int)); + memset(encode->slice_rawdata_index + slice_num, 0, + sizeof(int) * NUM_SLICES); + memset(encode->slice_rawdata_count + slice_num, 0, + sizeof(int) * NUM_SLICES); + memset(encode->slice_header_index + slice_num, 0, + sizeof(int) * NUM_SLICES); + + encode->max_slice_num += NUM_SLICES; if ((encode->slice_rawdata_index == NULL) || + (encode->slice_header_index == NULL) || (encode->slice_rawdata_count == NULL)) { vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; return vaStatus; @@ -2495,7 +2550,8 @@ i965_encoder_render_picture(VADriverContextP ctx, VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer; encode->last_packed_header_type = param->type; - if (param->type == VAEncPackedHeaderRawData) { + if ((param->type == VAEncPackedHeaderRawData) || + (param->type == VAEncPackedHeaderSlice)) { vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext); } else { vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx, @@ -2508,16 +2564,74 @@ i965_encoder_render_picture(VADriverContextP ctx, case VAEncPackedHeaderDataBufferType: { - - if (encode->last_packed_header_type == VAEncPackedHeaderRawData) { + if (encode->last_packed_header_type == 0) { + WARN_ONCE("the packed header data is passed without type!\n"); + 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 (vaStatus == VA_STATUS_SUCCESS) { + + /* 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. + * Otherwise it will use the VAEncSequenceParameterBuffer + * as the delimeter + */ + if (encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) { /* store the first index of the packed header data for current slice */ - if (encode->slice_rawdata_index[encode->num_slice_params_ext] == 0) { - encode->slice_rawdata_index[encode->num_slice_params_ext] = - SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1); + if (encode->slice_rawdata_index[encode->slice_index] == 0) { + encode->slice_rawdata_index[encode->slice_index] = + SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1); + } + encode->slice_rawdata_count[encode->slice_index]++; + if (encode->last_packed_header_type == VAEncPackedHeaderSlice) { + /* find one packed slice_header delimeter. And the following + * packed data is for the next slice + */ + encode->slice_header_index[encode->slice_index] = + SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1); + encode->slice_index++; + /* Reallocate the buffer to record the index/count of + * packed_data for one slice. + */ + if (encode->slice_index == encode->max_slice_num) { + int slice_num = encode->max_slice_num; + + encode->slice_rawdata_index = realloc(encode->slice_rawdata_index, + (slice_num + NUM_SLICES) * sizeof(int)); + encode->slice_rawdata_count = realloc(encode->slice_rawdata_count, + (slice_num + NUM_SLICES) * sizeof(int)); + encode->slice_header_index = realloc(encode->slice_header_index, + (slice_num + NUM_SLICES) * sizeof(int)); + memset(encode->slice_rawdata_index + slice_num, 0, + sizeof(int) * NUM_SLICES); + memset(encode->slice_rawdata_count + slice_num, 0, + sizeof(int) * NUM_SLICES); + memset(encode->slice_header_index + slice_num, 0, + sizeof(int) * NUM_SLICES); + encode->max_slice_num += NUM_SLICES; + } + } + } else { + if (vaStatus == VA_STATUS_SUCCESS) { + /* store the first index of the packed header data for current slice */ + if (encode->slice_rawdata_index[encode->slice_index] == 0) { + encode->slice_rawdata_index[encode->slice_index] = + SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1); + } + encode->slice_rawdata_count[encode->slice_index]++; + if (encode->last_packed_header_type == VAEncPackedHeaderSlice) { + if (encode->slice_header_index[encode->slice_index] == 0) { + encode->slice_header_index[encode->slice_index] = + SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1); + } else { + WARN_ONCE("Multi slice header data is passed for" + " slice %d!\n", encode->slice_index); + } + } } - encode->slice_rawdata_count[encode->num_slice_params_ext]++; } } else { ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence || @@ -2531,6 +2645,7 @@ i965_encoder_render_picture(VADriverContextP ctx, obj_buffer, va_enc_packed_type_to_idx(encode->last_packed_header_type)); } + encode->last_packed_header_type = 0; break; } @@ -2651,6 +2766,14 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context) (obj_context->codec_state.encode.num_slice_params_ext <=0)) { return VA_STATUS_ERROR_INVALID_PARAMETER; } + + if ((obj_context->codec_state.encode.packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) && + (obj_context->codec_state.encode.num_slice_params_ext != + obj_context->codec_state.encode.slice_index)) { + WARN_ONCE("packed slice_header data is missing for some slice" + " under packed SLICE_HEADER mode\n"); + return VA_STATUS_ERROR_INVALID_PARAMETER; + } } else { if (obj_context->codec_state.decode.pic_param == NULL) { return VA_STATUS_ERROR_INVALID_PARAMETER; @@ -5024,6 +5147,130 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx, return vaStatus; } +/* Acquires buffer handle for external API usage (internal implementation) */ +static VAStatus +i965_acquire_buffer_handle(struct object_buffer *obj_buffer, + uint32_t mem_type, VABufferInfo *out_buf_info) +{ + struct buffer_store *buffer_store; + + buffer_store = obj_buffer->buffer_store; + if (!buffer_store || !buffer_store->bo) + return VA_STATUS_ERROR_INVALID_BUFFER; + + /* Synchronization point */ + drm_intel_bo_wait_rendering(buffer_store->bo); + + if (obj_buffer->export_refcount > 0) { + if (obj_buffer->export_state.mem_type != mem_type) + return VA_STATUS_ERROR_INVALID_PARAMETER; + } + else { + VABufferInfo * const buf_info = &obj_buffer->export_state; + + switch (mem_type) { + case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: { + uint32_t name; + if (drm_intel_bo_flink(buffer_store->bo, &name) != 0) + return VA_STATUS_ERROR_INVALID_BUFFER; + buf_info->handle = name; + break; + } + case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: { + int fd; + if (drm_intel_bo_gem_export_to_prime(buffer_store->bo, &fd) != 0) + return VA_STATUS_ERROR_INVALID_BUFFER; + buf_info->handle = (intptr_t)fd; + break; + } + } + + buf_info->type = obj_buffer->type; + buf_info->mem_type = mem_type; + buf_info->mem_size = + obj_buffer->num_elements * obj_buffer->size_element; + } + + obj_buffer->export_refcount++; + *out_buf_info = obj_buffer->export_state; + return VA_STATUS_SUCCESS; +} + +/* Releases buffer handle after usage (internal implementation) */ +static VAStatus +i965_release_buffer_handle(struct object_buffer *obj_buffer) +{ + if (obj_buffer->export_refcount == 0) + return VA_STATUS_ERROR_INVALID_BUFFER; + + if (--obj_buffer->export_refcount == 0) { + VABufferInfo * const buf_info = &obj_buffer->export_state; + + switch (buf_info->mem_type) { + case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: { + close((intptr_t)buf_info->handle); + break; + } + } + buf_info->mem_type = 0; + } + return VA_STATUS_SUCCESS; +} + +/** Acquires buffer handle for external API usage */ +static VAStatus +i965_AcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, + VABufferInfo *buf_info) +{ + struct i965_driver_data * const i965 = i965_driver_data(ctx); + struct object_buffer * const obj_buffer = BUFFER(buf_id); + uint32_t i, mem_type; + + /* List of supported memory types, in preferred order */ + static const uint32_t mem_types[] = { + VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME, + VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM, + 0 + }; + + if (!obj_buffer) + return VA_STATUS_ERROR_INVALID_BUFFER; + /* XXX: only VA surface|image like buffers are supported for now */ + if (obj_buffer->type != VAImageBufferType) + return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE; + + if (!buf_info) + return VA_STATUS_ERROR_INVALID_PARAMETER; + + if (!buf_info->mem_type) + mem_type = mem_types[0]; + else { + mem_type = 0; + for (i = 0; mem_types[i] != 0; i++) { + if (buf_info->mem_type & mem_types[i]) { + mem_type = buf_info->mem_type; + break; + } + } + if (!mem_type) + return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE; + } + return i965_acquire_buffer_handle(obj_buffer, mem_type, buf_info); +} + +/** Releases buffer handle after usage from external API */ +static VAStatus +i965_ReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id) +{ + struct i965_driver_data * const i965 = i965_driver_data(ctx); + struct object_buffer * const obj_buffer = BUFFER(buf_id); + + if (!obj_buffer) + return VA_STATUS_ERROR_INVALID_BUFFER; + + return i965_release_buffer_handle(obj_buffer); +} + static int i965_os_has_ring_support(VADriverContextP ctx, int ring) @@ -5274,7 +5521,7 @@ VAStatus i965_QueryVideoProcPipelineCaps( return VA_STATUS_SUCCESS; } -extern const struct hw_codec_info *i965_get_codec_info(int devid); +extern struct hw_codec_info *i965_get_codec_info(int devid); static bool i965_driver_data_init(VADriverContextP ctx) @@ -5422,6 +5669,9 @@ i965_Init(VADriverContextP ctx) break; } + if (i965->codec_info->preinit_hw_codec) + i965->codec_info->preinit_hw_codec(ctx, i965->codec_info); + if (i == ARRAY_ELEMS(i965_sub_ops)) { switch (i965->intel.device_id) { #undef CHIPSET @@ -5550,6 +5800,10 @@ VA_DRIVER_INIT_FUNC( VADriverContextP ctx ) vtable->vaQuerySurfaceAttributes = i965_QuerySurfaceAttributes; vtable->vaCreateSurfaces2 = i965_CreateSurfaces2; + /* 0.36.0 */ + vtable->vaAcquireBufferHandle = i965_AcquireBufferHandle; + vtable->vaReleaseBufferHandle = i965_ReleaseBufferHandle; + vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters; vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps; vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;