/*
- * 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
*/
#include "sysdeps.h"
+#include <unistd.h>
+#include <dlfcn.h>
#ifdef HAVE_VA_X11
# include "i965_output_dri.h"
# include "i965_output_wayland.h"
#endif
+#include "intel_version.h"
#include "intel_driver.h"
#include "intel_memman.h"
#include "intel_batchbuffer.h"
#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
#define HAS_H264_ENCODING(ctx) ((ctx)->codec_info->has_h264_encoding && \
(ctx)->intel.has_bsd)
+#define HAS_LP_H264_ENCODING(ctx) ((ctx)->codec_info->has_lp_h264_encoding && \
+ (ctx)->intel.has_bsd)
+
#define HAS_VC1_DECODING(ctx) ((ctx)->codec_info->has_vc1_decoding && \
(ctx)->intel.has_bsd)
#define HAS_JPEG_DECODING(ctx) ((ctx)->codec_info->has_jpeg_decoding && \
(ctx)->intel.has_bsd)
+
+#define HAS_JPEG_ENCODING(ctx) ((ctx)->codec_info->has_jpeg_encoding && \
+ (ctx)->intel.has_bsd)
#define HAS_VPP(ctx) ((ctx)->codec_info->has_vpp)
#define HAS_H264_MVC_ENCODING(ctx) ((ctx)->codec_info->has_h264_mvc_encoding && \
(ctx)->intel.has_bsd)
+#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)
+
+#define HAS_VP9_DECODING(ctx) ((ctx)->codec_info->has_vp9_decoding && \
+ (ctx)->intel.has_bsd)
+
+#define HAS_VP9_DECODING_PROFILE(ctx, profile) \
+ (HAS_VP9_DECODING(ctx) && \
+ ((ctx)->codec_info->vp9_dec_profiles & (1U << (profile - VAProfileVP9Profile0))))
+
+#define HAS_HEVC10_DECODING(ctx) ((ctx)->codec_info->has_hevc10_decoding && \
+ (ctx)->intel.has_bsd)
+
+#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) */
#define I_YV12 2, 2, 3, {I965_8BITS, I965_2BITS, I965_2BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_2, OFFSET_0}, {PLANE_1, OFFSET_0} }
#define I_IMC1 I_YV12
+#define I_P010 2, 2, 2, {I965_16BITS, I965_8BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_16} }
+
#define I_422H 2, 1, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
#define I_422V 1, 2, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
#define I_YV16 2, 1, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_2, OFFSET_0}, {PLANE_1, OFFSET_0} }
-#define I_YUY2 2, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_24} }
-#define I_UYVY 2, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16} }
+#define I_YUY2 2, 1, 1, {I965_16BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_24} }
+#define I_UYVY 2, 1, 1, {I965_16BITS}, 3, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_16} }
#define I_444P 1, 1, 3, {I965_8BITS, I965_8BITS, I965_8BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
DEF_YUV(YV12, YUV420, I_SI),
DEF_YUV(IMC1, YUV420, I_S),
+ DEF_YUV(P010, YUV420, I_SI),
+
DEF_YUV(422H, YUV422H, I_SI),
DEF_YUV(422V, YUV422V, I_S),
DEF_YUV(YV16, YUV422H, I_S),
{
unsigned int i;
- for (i = 0; ARRAY_ELEMS(i965_fourcc_infos); i++) {
+ for (i = 0; i < ARRAY_ELEMS(i965_fourcc_infos); i++) {
const i965_fourcc_info * const info = &i965_fourcc_infos[i];
if (info->fourcc == fourcc)
return NULL;
}
+static int
+get_bpp_from_fourcc(unsigned int fourcc)
+{
+ const i965_fourcc_info *info = get_fourcc_info(fourcc);
+ unsigned int i = 0;
+ unsigned int bpp = 0;
+
+ if (!info)
+ return 0;
+
+ for (i = 0; i < info->num_planes; i++)
+ bpp += info->bpp[i];
+
+ return bpp;
+}
+
enum {
I965_SURFACETYPE_RGBA = 1,
I965_SURFACETYPE_YUV,
{ VA_FOURCC_RGBX, VA_LSB_FIRST, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000 } },
{ I965_SURFACETYPE_RGBA,
{ VA_FOURCC_BGRX, VA_LSB_FIRST, 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff } },
+ { I965_SURFACETYPE_YUV,
+ { VA_FOURCC_P010, VA_LSB_FIRST, 24, } },
};
/* List of supported subpicture formats */
return NULL;
}
+/* Checks whether the surface is in busy state */
+static bool
+is_surface_busy(struct i965_driver_data *i965,
+ struct object_surface *obj_surface)
+{
+ assert(obj_surface != NULL);
+
+ if (obj_surface->locked_image_id != VA_INVALID_ID)
+ return true;
+ if (obj_surface->derived_image_id != VA_INVALID_ID)
+ return true;
+ return false;
+}
+
+/* Checks whether the image is in busy state */
+static bool
+is_image_busy(struct i965_driver_data *i965, struct object_image *obj_image, VASurfaceID surface)
+{
+ struct object_buffer *obj_buffer;
+
+ assert(obj_image != NULL);
+
+ if (obj_image->derived_surface != VA_INVALID_ID &&
+ obj_image->derived_surface == surface)
+ return true;
+
+ obj_buffer = BUFFER(obj_image->image.buf);
+ if (obj_buffer && obj_buffer->export_refcount > 0)
+ return true;
+ return false;
+}
+
#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)
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:
}
}
- ASSERT_RET(idx < 4, 0);
+ ASSERT_RET(idx < 5, 0);
return idx;
}
+#define CALL_VTABLE(vawr, status, param) status = (vawr->vtable->param)
+
+static VAStatus
+i965_surface_wrapper(VADriverContextP ctx, VASurfaceID surface)
+{
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+ struct object_surface *obj_surface = SURFACE(surface);
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ if (!obj_surface) {
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+ }
+
+ if (obj_surface->wrapper_surface != VA_INVALID_ID) {
+ /* the wrapped surface already exists. just return it */
+ return va_status;
+ }
+
+ if (obj_surface->fourcc == 0)
+ i965_check_alloc_surface_bo(ctx, obj_surface,
+ 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
+
+ /*
+ * TBD: Support more surface formats.
+ * Currently only NV12 is support as NV12 is used by decoding.
+ */
+ if (obj_surface->fourcc != VA_FOURCC_NV12 )
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+ if ((i965->wrapper_pdrvctx == NULL) ||
+ (obj_surface->bo == NULL))
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+ {
+ int fd_handle;
+ VASurfaceAttrib attrib_list[2];
+ VASurfaceAttribExternalBuffers buffer_descriptor;
+ VAGenericID wrapper_surface;
+
+ if (drm_intel_bo_gem_export_to_prime(obj_surface->bo, &fd_handle) != 0)
+ return VA_STATUS_ERROR_OPERATION_FAILED;
+
+ obj_surface->exported_primefd = fd_handle;
+
+ memset(&attrib_list, 0, sizeof(attrib_list));
+ memset(&buffer_descriptor, 0, sizeof(buffer_descriptor));
+
+ attrib_list[0].type = VASurfaceAttribExternalBufferDescriptor;
+ attrib_list[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
+ attrib_list[0].value.value.p = &buffer_descriptor;
+ attrib_list[0].value.type = VAGenericValueTypePointer;
+
+ attrib_list[1].type = VASurfaceAttribMemoryType;
+ attrib_list[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
+ attrib_list[1].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
+ attrib_list[1].value.type = VAGenericValueTypeInteger;
+
+ buffer_descriptor.num_buffers = 1;
+ buffer_descriptor.num_planes = 2;
+ buffer_descriptor.width = obj_surface->orig_width;
+ buffer_descriptor.height = obj_surface->orig_height;
+ buffer_descriptor.pixel_format = obj_surface->fourcc;
+ buffer_descriptor.data_size = obj_surface->size;
+ buffer_descriptor.pitches[0] = obj_surface->width;
+ buffer_descriptor.pitches[1] = obj_surface->cb_cr_pitch;
+ buffer_descriptor.offsets[0] = 0;
+ buffer_descriptor.offsets[1] = obj_surface->width * obj_surface->height;
+ buffer_descriptor.buffers = (void *)&fd_handle;
+
+ CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
+ vaCreateSurfaces2(i965->wrapper_pdrvctx,
+ VA_RT_FORMAT_YUV420,
+ obj_surface->orig_width,
+ obj_surface->orig_height,
+ &wrapper_surface, 1,
+ attrib_list, 2));
+
+ if (va_status == VA_STATUS_SUCCESS) {
+ obj_surface->wrapper_surface = wrapper_surface;
+ } else {
+ /* This needs to be checked */
+ va_status = VA_STATUS_ERROR_OPERATION_FAILED;
+ }
+ return va_status;
+ }
+
+}
+
VAStatus
i965_QueryConfigProfiles(VADriverContextP ctx,
VAProfile *profile_list, /* out */
}
if (HAS_H264_DECODING(i965) ||
- HAS_H264_ENCODING(i965)) {
+ HAS_H264_ENCODING(i965) ||
+ HAS_LP_H264_ENCODING(i965)) {
profile_list[i++] = VAProfileH264ConstrainedBaseline;
profile_list[i++] = VAProfileH264Main;
profile_list[i++] = VAProfileH264High;
}
- if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264MultiviewHigh))
+ if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264MultiviewHigh) ||
+ HAS_H264_MVC_ENCODING(i965))
profile_list[i++] = VAProfileH264MultiviewHigh;
- if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264StereoHigh))
+ if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264StereoHigh) ||
+ HAS_H264_MVC_ENCODING(i965))
profile_list[i++] = VAProfileH264StereoHigh;
if (HAS_VC1_DECODING(i965)) {
profile_list[i++] = VAProfileNone;
}
- if (HAS_JPEG_DECODING(i965)) {
+ if (HAS_JPEG_DECODING(i965) ||
+ HAS_JPEG_ENCODING(i965)) {
profile_list[i++] = VAProfileJPEGBaseline;
}
profile_list[i++] = VAProfileVP8Version0_3;
}
- if (HAS_H264_MVC_ENCODING(i965)) {
- profile_list[i++] = VAProfileH264MultiviewHigh;
- profile_list[i++] = VAProfileH264StereoHigh;
+ if (HAS_HEVC_DECODING(i965)||
+ HAS_HEVC_ENCODING(i965)) {
+ profile_list[i++] = VAProfileHEVCMain;
+ }
+
+ if (HAS_HEVC10_DECODING(i965)) {
+ profile_list[i++] = VAProfileHEVCMain10;
+ }
+
+ if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile0) ||
+ HAS_VP9_ENCODING(i965)) {
+ profile_list[i++] = VAProfileVP9Profile0;
+ }
+
+ if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile2)) {
+ profile_list[i++] = VAProfileVP9Profile2;
+ }
+
+ if (i965->wrapper_pdrvctx) {
+ VAProfile wrapper_list[4];
+ int wrapper_num;
+ VADriverContextP pdrvctx;
+ VAStatus va_status;
+
+ pdrvctx = i965->wrapper_pdrvctx;
+ CALL_VTABLE(pdrvctx, va_status,
+ vaQueryConfigProfiles(pdrvctx,
+ wrapper_list, &wrapper_num));
+
+ if (va_status == VA_STATUS_SUCCESS) {
+ int j;
+ for (j = 0; j < wrapper_num; j++)
+ if (wrapper_list[j] != VAProfileNone)
+ profile_list[i++] = wrapper_list[j];
+ }
}
/* If the assert fails then I965_MAX_PROFILES needs to be bigger */
if (HAS_H264_ENCODING(i965))
entrypoint_list[n++] = VAEntrypointEncSlice;
+ if (HAS_LP_H264_ENCODING(i965))
+ entrypoint_list[n++] = VAEntrypointEncSliceLP;
+
break;
case VAProfileH264MultiviewHigh:
case VAProfileH264StereoHigh:
case VAProfileJPEGBaseline:
if (HAS_JPEG_DECODING(i965))
entrypoint_list[n++] = VAEntrypointVLD;
+
+ if (HAS_JPEG_ENCODING(i965))
+ entrypoint_list[n++] = VAEntrypointEncPicture;
break;
case VAProfileVP8Version0_3:
if (HAS_VP8_ENCODING(i965))
entrypoint_list[n++] = VAEntrypointEncSlice;
+ break;
+
+ case VAProfileHEVCMain:
+ if (HAS_HEVC_DECODING(i965))
+ entrypoint_list[n++] = VAEntrypointVLD;
+
+ if (HAS_HEVC_ENCODING(i965))
+ entrypoint_list[n++] = VAEntrypointEncSlice;
+
+ break;
+
+ case VAProfileHEVCMain10:
+ if (HAS_HEVC10_DECODING(i965))
+ entrypoint_list[n++] = VAEntrypointVLD;
+
+ break;
+
+ case VAProfileVP9Profile0:
+ case VAProfileVP9Profile2:
+ if(HAS_VP9_DECODING_PROFILE(i965, profile))
+ entrypoint_list[n++] = VAEntrypointVLD;
+
+ if (HAS_VP9_ENCODING(i965) && (profile == VAProfileVP9Profile0))
+ entrypoint_list[n++] = VAEntrypointEncSlice;
+
+ if(profile == VAProfileVP9Profile0) {
+ if (i965->wrapper_pdrvctx) {
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+
+ CALL_VTABLE(pdrvctx, va_status,
+ vaQueryConfigEntrypoints(pdrvctx, profile,
+ entrypoint_list,
+ num_entrypoints));
+ return va_status;
+ }
+ }
+
+ break;
+
default:
break;
}
case VAProfileH264Main:
case VAProfileH264High:
if ((HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
- (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
+ (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice) ||
+ (HAS_LP_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSliceLP)) {
va_status = VA_STATUS_SUCCESS;
} else {
va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
break;
case VAProfileJPEGBaseline:
- if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) {
+ if ((HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
+ (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)) {
va_status = VA_STATUS_SUCCESS;
} else {
va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
break;
+ case VAProfileHEVCMain:
+ 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;
+
+ break;
+
+ case VAProfileHEVCMain10:
+ if (HAS_HEVC10_DECODING(i965) && (entrypoint == VAEntrypointVLD))
+ va_status = VA_STATUS_SUCCESS;
+ else
+ va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
+
+ break;
+
+ case VAProfileVP9Profile0:
+ 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
+ va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
+ break;
+
default:
va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
break;
case VAProfileJPEGBaseline:
if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD)
chroma_formats |= i965->codec_info->jpeg_dec_chroma_formats;
+ if (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)
+ chroma_formats |= i965->codec_info->jpeg_enc_chroma_formats;
+ break;
+
+ case VAProfileHEVCMain10:
+ if (HAS_HEVC10_DECODING(i965) && entrypoint == VAEntrypointVLD)
+ chroma_formats |= i965->codec_info->hevc_dec_chroma_formats;
+ break;
+
+ case VAProfileNone:
+ if(HAS_VPP_P010(i965))
+ chroma_formats |= VA_RT_FORMAT_YUV420_10BPP;
+ break;
+
+ case VAProfileVP9Profile0:
+ case VAProfileVP9Profile2:
+ if (HAS_VP9_DECODING_PROFILE(i965, profile) && entrypoint == VAEntrypointVLD)
+ chroma_formats |= i965->codec_info->vp9_dec_chroma_formats;
break;
default:
/* Other attributes don't seem to be defined */
/* What to do if we don't know the attribute? */
for (i = 0; i < num_attribs; i++) {
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
switch (attrib_list[i].type) {
case VAConfigAttribRTFormat:
attrib_list[i].value = i965_get_default_chroma_formats(ctx,
if (profile != VAProfileMPEG2Main &&
profile != VAProfileMPEG2Simple)
attrib_list[i].value |= VA_RC_CBR;
+
+ if (profile == VAProfileVP9Profile0)
+ attrib_list[i].value |= VA_RC_VBR;
+
break;
- }
+ } else if (entrypoint == VAEntrypointEncSliceLP) {
+ struct i965_driver_data * const i965 = i965_driver_data(ctx);
+
+ /* Support low power encoding for H.264 only by now */
+ if (profile == VAProfileH264ConstrainedBaseline ||
+ profile == VAProfileH264Main ||
+ profile == VAProfileH264High)
+ attrib_list[i].value = i965->codec_info->lp_h264_brc_mode;
+ else
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+ } else
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+
+ break;
case VAConfigAttribEncPackedHeaders:
- if (entrypoint == VAEntrypointEncSlice) {
+ if (entrypoint == VAEntrypointEncSlice ||
+ entrypoint == VAEntrypointEncSliceLP) {
attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
if (profile == VAProfileH264ConstrainedBaseline ||
profile == VAProfileH264Main ||
profile == VAProfileH264High ||
- profile == VAProfileH264MultiviewHigh) {
+ profile == VAProfileH264StereoHigh ||
+ profile == VAProfileH264MultiviewHigh ||
+ profile == VAProfileHEVCMain) {
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) {
+ if (profile == VAProfileJPEGBaseline)
+ attrib_list[i].value = VA_ENC_PACKED_HEADER_RAW_DATA;
+ }
+ break;
+
+ case VAConfigAttribEncMaxRefFrames:
+ if (entrypoint == VAEntrypointEncSlice)
+ attrib_list[i].value = (1 << 16) | (1 << 0);
+ else if (entrypoint == VAEntrypointEncSliceLP) {
+ /* Don't support B frame for low power mode */
+ if (profile == VAProfileH264ConstrainedBaseline ||
+ profile == VAProfileH264Main ||
+ profile == VAProfileH264High)
+ attrib_list[i].value = (1 << 0);
+ else
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+ }
+
+ break;
+
+ case VAConfigAttribEncQualityRange:
+ if (entrypoint == VAEntrypointEncSlice ||
+ entrypoint == VAEntrypointEncSliceLP) {
+ 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) {
+ VAConfigAttribValEncJPEG *configVal = (VAConfigAttribValEncJPEG*)&(attrib_list[i].value);
+ (configVal->bits).arithmatic_coding_mode = 0; // Huffman coding is used
+ (configVal->bits).progressive_dct_mode = 0; // Only Sequential DCT is supported
+ (configVal->bits).non_interleaved_mode = 1; // Support both interleaved and non-interleaved
+ (configVal->bits).differential_mode = 0; // Baseline DCT is non-differential
+ (configVal->bits).max_num_components = 3; // Only 3 components supported
+ (configVal->bits).max_num_scans = 1; // Only 1 scan per frame
+ (configVal->bits).max_num_huffman_tables = 3; // Max 3 huffman tables
+ (configVal->bits).max_num_quantization_tables = 3; // Max 3 quantization tables
+ }
+ break;
+
+ case VAConfigAttribDecSliceMode:
+ attrib_list[i].value = VA_DEC_SLICE_MODE_NORMAL;
+ break;
- case VAConfigAttribEncMaxRefFrames:
- if (entrypoint == VAEntrypointEncSlice) {
- attrib_list[i].value = (1 << 16) | (1 << 0);
- break;
- }
+ case VAConfigAttribEncROI:
+ if ((entrypoint == VAEntrypointEncSliceLP) &&
+ (profile == VAProfileH264ConstrainedBaseline ||
+ profile == VAProfileH264Main ||
+ profile == VAProfileH264High))
+ attrib_list[i].value = 3;
+ else
+ attrib_list[i].value = 0;
+
+ break;
default:
/* Do nothing */
obj_config->profile = profile;
obj_config->entrypoint = entrypoint;
obj_config->num_attribs = 0;
+ obj_config->wrapper_config = VA_INVALID_ID;
for (i = 0; i < num_attribs; i++) {
vaStatus = i965_ensure_config_attribute(obj_config, &attrib_list[i]);
vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
}
+ if ((vaStatus == VA_STATUS_SUCCESS) &&
+ (profile == VAProfileVP9Profile0) &&
+ (entrypoint == VAEntrypointVLD) &&
+ !HAS_VP9_DECODING(i965)) {
+
+ if (i965->wrapper_pdrvctx) {
+ VAGenericID wrapper_config;
+
+ CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
+ vaCreateConfig(i965->wrapper_pdrvctx, profile,
+ entrypoint, attrib_list,
+ num_attribs, &wrapper_config));
+
+ if (vaStatus == VA_STATUS_SUCCESS)
+ obj_config->wrapper_config = wrapper_config;
+ }
+ }
+
/* Error recovery */
if (VA_STATUS_SUCCESS != vaStatus) {
i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
return vaStatus;
}
+ if ((obj_config->wrapper_config != VA_INVALID_ID) &&
+ i965->wrapper_pdrvctx) {
+ CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
+ vaDestroyConfig(i965->wrapper_pdrvctx,
+ obj_config->wrapper_config));
+ obj_config->wrapper_config = VA_INVALID_ID;
+ }
+
i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
return VA_STATUS_SUCCESS;
}
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;
+ return i965_check_alloc_surface_bo(ctx, obj_surface, tiling, expected_fourcc, get_sampling_from_fourcc(expected_fourcc));
}
static VAStatus
switch (obj_surface->fourcc) {
case VA_FOURCC_NV12:
+ case VA_FOURCC_P010:
ASSERT_RET(memory_attibute->num_planes == 2, VA_STATUS_ERROR_INVALID_PARAMETER);
ASSERT_RET(memory_attibute->pitches[0] == memory_attibute->pitches[1], VA_STATUS_ERROR_INVALID_PARAMETER);
/* support 420 & 422 & RGB32 format, 422 and RGB32 are only used
* for post-processing (including color conversion) */
if (VA_RT_FORMAT_YUV420 != format &&
+ VA_RT_FORMAT_YUV420_10BPP != format &&
VA_RT_FORMAT_YUV422 != format &&
VA_RT_FORMAT_YUV444 != format &&
VA_RT_FORMAT_YUV411 != format &&
obj_surface->height = ALIGN(height, i965->codec_info->min_linear_hpitch);
obj_surface->flags = SURFACE_REFERENCED;
obj_surface->fourcc = 0;
+ obj_surface->expected_format = format;
obj_surface->bo = NULL;
obj_surface->locked_image_id = VA_INVALID_ID;
+ obj_surface->derived_image_id = VA_INVALID_ID;
obj_surface->private_data = NULL;
obj_surface->free_private_data = NULL;
obj_surface->subsampling = SUBSAMPLE_YUV420;
+ obj_surface->wrapper_surface = VA_INVALID_ID;
+ obj_surface->exported_primefd = -1;
+
switch (memory_type) {
case I965_SURFACE_MEM_NATIVE:
if (memory_attibute) {
if (memory_attibute->pitches[0]) {
int bpp_1stplane = bpp_1stplane_by_fourcc(expected_fourcc);
ASSERT_RET(bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
- obj_surface->width = memory_attibute->pitches[0]/bpp_1stplane;
+ obj_surface->width = memory_attibute->pitches[0];
obj_surface->user_h_stride_set = true;
ASSERT_RET(IS_ALIGNED(obj_surface->width, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
- ASSERT_RET(obj_surface->width >= width, VA_STATUS_ERROR_INVALID_PARAMETER);
+ ASSERT_RET(obj_surface->width >= width * bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
if (memory_attibute->offsets[1]) {
ASSERT_RET(!memory_attibute->offsets[0], VA_STATUS_ERROR_INVALID_PARAMETER);
}
}
}
- i965_surface_native_memory(ctx,
- obj_surface,
- format,
- expected_fourcc);
+ vaStatus = i965_surface_native_memory(ctx,
+ obj_surface,
+ format,
+ expected_fourcc);
break;
case I965_SURFACE_MEM_GEM_FLINK:
case I965_SURFACE_MEM_DRM_PRIME:
- i965_suface_external_memory(ctx,
- obj_surface,
- memory_type,
- memory_attibute,
- i);
+ vaStatus = i965_suface_external_memory(ctx,
+ obj_surface,
+ memory_type,
+ memory_attibute,
+ i);
+ break;
+ }
+ if (VA_STATUS_SUCCESS != vaStatus) {
+ i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
break;
}
}
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
int i;
+ VAStatus va_status = VA_STATUS_SUCCESS;
for (i = num_surfaces; i--; ) {
struct object_surface *obj_surface = SURFACE(surface_list[i]);
ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
+
+ if ((obj_surface->wrapper_surface != VA_INVALID_ID) &&
+ i965->wrapper_pdrvctx) {
+ CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
+ vaDestroySurfaces(i965->wrapper_pdrvctx,
+ &(obj_surface->wrapper_surface),
+ 1));
+ obj_surface->wrapper_surface = VA_INVALID_ID;
+ }
+ if (obj_surface->exported_primefd >= 0) {
+ close(obj_surface->exported_primefd);
+ obj_surface->exported_primefd = -1;
+ }
+
i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
}
- return VA_STATUS_SUCCESS;
+ return va_status;
}
VAStatus
if (IS_GEN6(i965->intel.device_info) ||
IS_GEN7(i965->intel.device_info) ||
- IS_GEN8(i965->intel.device_info)) {
+ IS_GEN8(i965->intel.device_info) ||
+ IS_GEN9(i965->intel.device_info)) {
*fourcc = VA_FOURCC_NV12;
*is_tiled = 1;
return;
i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
i965_release_buffer_store(&obj_context->codec_state.encode.seq_param);
+ i965_release_buffer_store(&obj_context->codec_state.encode.q_matrix);
+ i965_release_buffer_store(&obj_context->codec_state.encode.huffman_table);
+
for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++)
i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
free(obj_context->codec_state.encode.packed_header_data_ext);
+ i965_release_buffer_store(&obj_context->codec_state.encode.encmb_map);
} else {
assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
object_heap_free(heap, obj);
}
+static inline void
+max_resolution(struct i965_driver_data *i965,
+ struct object_config *obj_config,
+ int *w, /* out */
+ int *h) /* out */
+{
+ if (i965->codec_info->max_resolution) {
+ i965->codec_info->max_resolution(i965, obj_config, w, h);
+ } else {
+ *w = i965->codec_info->max_width;
+ *h = i965->codec_info->max_height;
+ }
+}
+
VAStatus
i965_CreateContext(VADriverContextP ctx,
VAConfigID config_id,
VAContextID *context) /* out */
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
- struct i965_render_state *render_state = &i965->render_state;
struct object_config *obj_config = CONFIG(config_id);
struct object_context *obj_context = NULL;
VAConfigAttrib *attrib;
VAStatus vaStatus = VA_STATUS_SUCCESS;
int contextID;
int i;
+ int max_width;
+ int max_height;
if (NULL == obj_config) {
vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
return vaStatus;
}
- if (picture_width > i965->codec_info->max_width ||
- picture_height > i965->codec_info->max_height) {
+ max_resolution(i965, obj_config, &max_width, &max_height);
+
+ if (picture_width > max_width ||
+ picture_height > max_height) {
vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
return vaStatus;
}
return vaStatus;
}
- render_state->inited = 1;
-
- switch (obj_config->profile) {
- case VAProfileH264ConstrainedBaseline:
- case VAProfileH264Main:
- case VAProfileH264High:
- if (!HAS_H264_DECODING(i965) &&
- !HAS_H264_ENCODING(i965))
- return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
- render_state->interleaved_uv = 1;
- break;
- case VAProfileH264MultiviewHigh:
- case VAProfileH264StereoHigh:
- if (!HAS_H264_MVC_DECODING(i965))
- return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
- render_state->interleaved_uv = 1;
- break;
- default:
- render_state->interleaved_uv = !!(IS_GEN6(i965->intel.device_info) || IS_GEN7(i965->intel.device_info) || IS_GEN8(i965->intel.device_info));
- break;
- }
-
*context = contextID;
obj_context->flags = flag;
obj_context->context_id = contextID;
obj_context->render_targets =
(VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
obj_context->hw_context = NULL;
+ obj_context->wrapper_context = VA_INVALID_ID;
+
+ if (!obj_context->render_targets)
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
for(i = 0; i < num_render_targets; i++) {
if (NULL == SURFACE(render_targets[i])) {
obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
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*/
+ } else if ((VAEntrypointEncSlice == obj_config->entrypoint) ||
+ (VAEntrypointEncPicture == obj_config->entrypoint) ||
+ (VAEntrypointEncSliceLP == obj_config->entrypoint)) {
+ 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;
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.slice_num, sizeof(int));
+ 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) {
+ obj_context->codec_state.encode.packed_header_flag = packed_attrib->value;
+ 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.
+ */
+ obj_context->codec_state.encode.packed_header_flag =
+ 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);
} else {
return VA_STATUS_ERROR_INVALID_CONFIG;
obj_context->codec_state.base.chroma_formats = attrib->value;
+ if (obj_config->wrapper_config != VA_INVALID_ID) {
+ /* The wrapper_pdrvctx should exist when wrapper_config is valid.
+ * So it won't check i965->wrapper_pdrvctx again.
+ * Fixme if it is incorrect.
+ */
+ VAGenericID wrapper_context;
+
+ /*
+ * The render_surface is not passed when calling
+ * vaCreateContext.
+ * If it is needed, we must get the wrapped surface
+ * for the corresponding Surface_list.
+ * So the wrapped surface conversion is deferred.
+ */
+ CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
+ vaCreateContext(i965->wrapper_pdrvctx,
+ obj_config->wrapper_config,
+ picture_width, picture_height,
+ flag, NULL, 0,
+ &wrapper_context));
+
+ if (vaStatus == VA_STATUS_SUCCESS)
+ obj_context->wrapper_context = wrapper_context;
+ }
/* Error recovery */
if (VA_STATUS_SUCCESS != vaStatus) {
i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct object_context *obj_context = CONTEXT(context);
+ VAStatus va_status = VA_STATUS_SUCCESS;
ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
if (i965->current_context_id == context)
i965->current_context_id = VA_INVALID_ID;
+ if ((obj_context->wrapper_context != VA_INVALID_ID) &&
+ i965->wrapper_pdrvctx) {
+ CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
+ vaDestroyContext(i965->wrapper_pdrvctx,
+ obj_context->wrapper_context));
+
+ obj_context->wrapper_context = VA_INVALID_ID;
+ }
+
i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
- return VA_STATUS_SUCCESS;
+ return va_status;
}
static void
struct object_buffer *obj_buffer = NULL;
struct buffer_store *buffer_store = NULL;
int bufferID;
+ VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
+ struct object_context *obj_context = CONTEXT(context);
+ int wrapper_flag = 0;
/* Validate type */
switch (type) {
case VAProcFilterParameterBufferType:
case VAHuffmanTableBufferType:
case VAProbabilityBufferType:
+ case VAEncMacroblockMapBufferType:
/* Ok */
break;
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;
+ obj_buffer->wrapper_buffer = VA_INVALID_ID;
+ obj_buffer->context_id = context;
+
buffer_store = calloc(1, sizeof(struct buffer_store));
assert(buffer_store);
buffer_store->ref_count = 1;
+ if (obj_context &&
+ (obj_context->wrapper_context != VA_INVALID_ID) &&
+ i965->wrapper_pdrvctx) {
+ VAGenericID wrapper_buffer;
+ VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+
+ CALL_VTABLE(pdrvctx, vaStatus,
+ vaCreateBuffer(pdrvctx, obj_context->wrapper_context, type, size, num_elements,
+ data, &wrapper_buffer));
+ if (vaStatus == VA_STATUS_SUCCESS) {
+ obj_buffer->wrapper_buffer = wrapper_buffer;
+ } else {
+ free(buffer_store);
+ return vaStatus;
+ }
+ wrapper_flag = 1;
+ }
+
if (store_bo != NULL) {
buffer_store->bo = store_bo;
dri_bo_reference(buffer_store->bo);
-
- if (data)
+
+ /* If the buffer is wrapped, the buffer_store is bogus. Unnecessary to copy it */
+ if (data && !wrapper_flag)
dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
} else if (type == VASliceDataBufferType ||
type == VAImageBufferType ||
type == VAEncCodedBufferType ||
+ type == VAEncMacroblockMapBufferType ||
type == VAProbabilityBufferType) {
- buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
- "Buffer",
- size * num_elements, 64);
+
+ /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
+ * So it is enough to allocate one 64 byte bo
+ */
+ if (wrapper_flag)
+ buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr, "Bogus buffer",
+ 64, 64);
+ else
+ buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
+ "Buffer",
+ size * num_elements, 64);
assert(buffer_store->bo);
- if (type == VAEncCodedBufferType) {
+ /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
+ * In fact it can be skipped. But it is still allocated and it is
+ * only to follow the normal flowchart of buffer_allocation/release.
+ */
+ if (!wrapper_flag) {
+ if (type == VAEncCodedBufferType) {
struct i965_coded_buffer_segment *coded_buffer_segment;
dri_bo_map(buffer_store->bo, 1);
coded_buffer_segment->base.next = NULL;
coded_buffer_segment->mapped = 0;
coded_buffer_segment->codec = 0;
+ coded_buffer_segment->status_support = 0;
dri_bo_unmap(buffer_store->bo);
- } else if (data) {
- dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
- }
+ } else if (data) {
+ dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
+ }
+ }
} else {
int msize = size;
msize = ALIGN(size, 4);
}
- buffer_store->buffer = malloc(msize * num_elements);
+ /* If the buffer is wrapped, it is enough to allocate 4 bytes */
+ if (wrapper_flag)
+ buffer_store->buffer = malloc(4);
+ else
+ buffer_store->buffer = malloc(msize * num_elements);
assert(buffer_store->buffer);
- if (data)
+ if (data && (!wrapper_flag))
memcpy(buffer_store->buffer, data, size * num_elements);
}
ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
+ /* When the wrapper_buffer exists, it will wrapper to the
+ * buffer allocated from backend driver.
+ */
+ if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
+ i965->wrapper_pdrvctx) {
+ VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+
+ CALL_VTABLE(pdrvctx, vaStatus,
+ vaBufferSetNumElements(pdrvctx, obj_buffer->wrapper_buffer,
+ num_elements));
+ return vaStatus;
+ }
+
if ((num_elements < 0) ||
(num_elements > obj_buffer->max_num_elements)) {
vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct object_buffer *obj_buffer = BUFFER(buf_id);
VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
+ struct object_context *obj_context;
ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
+
+ obj_context = CONTEXT(obj_buffer->context_id);
+
+ /* When the wrapper_buffer exists, it will wrapper to the
+ * buffer allocated from backend driver.
+ */
+ if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
+ i965->wrapper_pdrvctx) {
+ VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+
+ CALL_VTABLE(pdrvctx, vaStatus,
+ vaMapBuffer(pdrvctx, obj_buffer->wrapper_buffer, pbuf));
+ return vaStatus;
+ }
+
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);
+ if (obj_buffer->export_refcount > 0)
+ return VA_STATUS_ERROR_INVALID_BUFFER;
+
if (NULL != obj_buffer->buffer_store->bo) {
unsigned int tiling, swizzle;
ASSERT_RET(obj_buffer->buffer_store->bo->virtual, VA_STATUS_ERROR_OPERATION_FAILED);
*pbuf = obj_buffer->buffer_store->bo->virtual;
+ vaStatus = VA_STATUS_SUCCESS;
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 (!coded_buffer_segment->mapped) {
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) {
- delimiter0 = H264_DELIMITER0;
- delimiter1 = H264_DELIMITER1;
- delimiter2 = H264_DELIMITER2;
- delimiter3 = H264_DELIMITER3;
- delimiter4 = H264_DELIMITER4;
- } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
- delimiter0 = MPEG2_DELIMITER0;
- delimiter1 = MPEG2_DELIMITER1;
- delimiter2 = MPEG2_DELIMITER2;
- delimiter3 = MPEG2_DELIMITER3;
- delimiter4 = MPEG2_DELIMITER4;
+ if (obj_context &&
+ obj_context->hw_context &&
+ obj_context->hw_context->get_status &&
+ coded_buffer_segment->status_support) {
+ vaStatus = obj_context->hw_context->get_status(ctx, obj_context->hw_context, coded_buffer_segment);
} else {
- ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
- }
- for (i = 0; i < obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000; i++) {
- if ((buffer[i] == delimiter0) &&
- (buffer[i + 1] == delimiter1) &&
- (buffer[i + 2] == delimiter2) &&
- (buffer[i + 3] == delimiter3) &&
- (buffer[i + 4] == delimiter4))
- break;
- }
+ 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;
+ delimiter2 = H264_DELIMITER2;
+ delimiter3 = H264_DELIMITER3;
+ delimiter4 = H264_DELIMITER4;
+ } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
+ delimiter0 = MPEG2_DELIMITER0;
+ delimiter1 = MPEG2_DELIMITER1;
+ delimiter2 = MPEG2_DELIMITER2;
+ delimiter3 = MPEG2_DELIMITER3;
+ delimiter4 = MPEG2_DELIMITER4;
+ } else if(coded_buffer_segment->codec == CODEC_JPEG) {
+ //In JPEG End of Image (EOI = 0xDDF9) marker can be used for delimiter.
+ delimiter0 = 0xFF;
+ delimiter1 = 0xD9;
+ } else if (coded_buffer_segment->codec == CODEC_HEVC) {
+ delimiter0 = HEVC_DELIMITER0;
+ delimiter1 = HEVC_DELIMITER1;
+ delimiter2 = HEVC_DELIMITER2;
+ delimiter3 = HEVC_DELIMITER3;
+ delimiter4 = HEVC_DELIMITER4;
+ } else if (coded_buffer_segment->codec != CODEC_VP8) {
+ 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)) {
+ break;
+ }
+ }
+ coded_buffer_segment->base.size = i + 2;
+ } else if (coded_buffer_segment->codec != CODEC_VP8) {
+ /* vp8 coded buffer size can be told by vp8 internal statistics buffer,
+ so it don't need to traversal the coded buffer */
+ 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) &&
+ (buffer[i + 3] == delimiter3) &&
+ (buffer[i + 4] == delimiter4))
+ break;
+ }
+
+ 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;
+ }
+
+ if (coded_buffer_segment->base.size >= obj_buffer->size_element - header_offset - 0x1000) {
+ coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
+ }
- if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000) {
- coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
+ vaStatus = VA_STATUS_SUCCESS;
}
- coded_buffer_segment->base.size = i;
coded_buffer_segment->mapped = 1;
} else {
assert(coded_buffer_segment->base.buf);
+ vaStatus = VA_STATUS_SUCCESS;
}
}
-
- vaStatus = VA_STATUS_SUCCESS;
} else if (NULL != obj_buffer->buffer_store->buffer) {
*pbuf = obj_buffer->buffer_store->buffer;
vaStatus = VA_STATUS_SUCCESS;
return VA_STATUS_ERROR_INVALID_BUFFER;
ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
+ /* When the wrapper_buffer exists, it will wrapper to the
+ * buffer allocated from backend driver.
+ */
+ if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
+ i965->wrapper_pdrvctx) {
+ VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+
+ CALL_VTABLE(pdrvctx, vaStatus,
+ vaUnmapBuffer(pdrvctx, obj_buffer->wrapper_buffer));
+ return vaStatus;
+ }
+
ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_OPERATION_FAILED);
ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_OPERATION_FAILED);
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct object_buffer *obj_buffer = BUFFER(buffer_id);
+ VAStatus va_status = VA_STATUS_SUCCESS;
ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
+ if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
+ i965->wrapper_pdrvctx) {
+ CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
+ vaDestroyBuffer(i965->wrapper_pdrvctx,
+ obj_buffer->wrapper_buffer));
+ obj_buffer->wrapper_buffer = VA_INVALID_ID;
+ }
+
i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
- return VA_STATUS_SUCCESS;
+ return va_status;
}
VAStatus
struct object_context *obj_context = CONTEXT(context);
struct object_surface *obj_surface = SURFACE(render_target);
struct object_config *obj_config;
- VAStatus vaStatus;
+ VAStatus vaStatus = VA_STATUS_SUCCESS;
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);
- switch (obj_config->profile) {
- case VAProfileMPEG2Simple:
- case VAProfileMPEG2Main:
- vaStatus = VA_STATUS_SUCCESS;
- break;
-
- case VAProfileH264ConstrainedBaseline:
- case VAProfileH264Main:
- case VAProfileH264High:
- vaStatus = VA_STATUS_SUCCESS;
- break;
-
- case VAProfileH264MultiviewHigh:
- case VAProfileH264StereoHigh:
- if (HAS_H264_MVC_DECODING_PROFILE(i965, obj_config->profile) ||
- HAS_H264_MVC_ENCODING(i965)) {
- vaStatus = VA_STATUS_SUCCESS;
- } else {
- ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
- }
- break;
-
- case VAProfileVC1Simple:
- case VAProfileVC1Main:
- case VAProfileVC1Advanced:
- vaStatus = VA_STATUS_SUCCESS;
- break;
-
- case VAProfileJPEGBaseline:
- vaStatus = VA_STATUS_SUCCESS;
- break;
-
- case VAProfileNone:
- vaStatus = VA_STATUS_SUCCESS;
- break;
-
- case VAProfileVP8Version0_3:
- vaStatus = VA_STATUS_SUCCESS;
- break;
-
- default:
- ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
- break;
- }
+ if (is_surface_busy(i965, obj_surface))
+ return VA_STATUS_ERROR_SURFACE_BUSY;
if (obj_context->codec_type == CODEC_PROC) {
obj_context->codec_state.proc.current_render_target = render_target;
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.slice_num);
+ 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]);
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;
+ obj_context->codec_state.encode.vps_sps_seq_index = 0;
+ i965_release_buffer_store(&obj_context->codec_state.encode.encmb_map);
+
+ if (obj_config->profile == VAProfileVP9Profile0) {
+ for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
+ i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i]);
+
+ i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
+ }
} else {
obj_context->codec_state.decode.current_render_target = render_target;
i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
obj_context->codec_state.decode.num_slice_params = 0;
obj_context->codec_state.decode.num_slice_datas = 0;
+
+ if ((obj_context->wrapper_context != VA_INVALID_ID) &&
+ i965->wrapper_pdrvctx) {
+ if (obj_surface->wrapper_surface == VA_INVALID_ID)
+ vaStatus = i965_surface_wrapper(ctx, render_target);
+
+ if (vaStatus != VA_STATUS_SUCCESS)
+ return vaStatus;
+
+ CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
+ vaBeginPicture(i965->wrapper_pdrvctx,
+ obj_context->wrapper_context,
+ obj_surface->wrapper_surface));
+ }
}
return vaStatus;
DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_data, slice_datas)
+
+static VAStatus
+i965_decoder_vp9_wrapper_picture(VADriverContextP ctx,
+ VABufferID *buffers,
+ int num_buffers)
+{
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+ VAStatus vaStatus = VA_STATUS_SUCCESS;
+ int i;
+ VADecPictureParameterBufferVP9 *pVp9PicParams;
+ VADriverContextP pdrvctx;
+ struct object_buffer *obj_buffer;
+
+ pdrvctx = i965->wrapper_pdrvctx;
+ /* do the conversion of VADecPictureParameterBufferVP9 */
+ for (i = 0; i < num_buffers; i++) {
+ obj_buffer = BUFFER(buffers[i]);
+
+ if (!obj_buffer)
+ continue;
+
+ if (obj_buffer->wrapper_buffer == VA_INVALID_ID)
+ continue;
+
+ if (obj_buffer->type == VAPictureParameterBufferType) {
+ int j;
+ VASurfaceID surface_id;
+ struct object_surface *obj_surface;
+
+ pdrvctx = i965->wrapper_pdrvctx;
+
+ CALL_VTABLE(pdrvctx, vaStatus,
+ vaMapBuffer(pdrvctx, obj_buffer->wrapper_buffer,
+ (void **)(&pVp9PicParams)));
+
+ if (vaStatus != VA_STATUS_SUCCESS)
+ return vaStatus;
+
+ for (j = 0; j < 8; j++) {
+ surface_id = pVp9PicParams->reference_frames[j];
+ obj_surface = SURFACE(surface_id);
+
+ if (!obj_surface)
+ continue;
+
+ if (obj_surface->wrapper_surface == VA_INVALID_ID) {
+ vaStatus = i965_surface_wrapper(ctx, surface_id);
+ if (vaStatus != VA_STATUS_SUCCESS) {
+ pdrvctx->vtable->vaUnmapBuffer(pdrvctx,
+ obj_buffer->wrapper_buffer);
+ goto fail_out;
+ }
+ }
+
+ pVp9PicParams->reference_frames[j] = obj_surface->wrapper_surface;
+ }
+ CALL_VTABLE(pdrvctx, vaStatus,
+ vaUnmapBuffer(pdrvctx, obj_buffer->wrapper_buffer));
+ break;
+ }
+ }
+
+ return VA_STATUS_SUCCESS;
+
+fail_out:
+ return vaStatus;
+}
+
+static VAStatus
+i965_decoder_wrapper_picture(VADriverContextP ctx,
+ VAContextID context,
+ VABufferID *buffers,
+ int num_buffers)
+{
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+ struct object_context *obj_context = CONTEXT(context);
+ VAStatus vaStatus = VA_STATUS_SUCCESS;
+ int i;
+ VADriverContextP pdrvctx;
+ struct object_buffer *obj_buffer;
+
+ if (obj_context == NULL)
+ return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+ /* When it is not wrapped context, continue the normal flowchart */
+ if (obj_context->wrapper_context == VA_INVALID_ID)
+ return vaStatus;
+
+ if (obj_context->obj_config &&
+ (obj_context->obj_config->profile == VAProfileVP9Profile0)) {
+ vaStatus = i965_decoder_vp9_wrapper_picture(ctx, buffers, num_buffers);
+ } else
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+ pdrvctx = i965->wrapper_pdrvctx;
+
+ for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
+ obj_buffer = BUFFER(buffers[i]);
+
+ if (!obj_buffer)
+ continue;
+
+ if (obj_buffer->wrapper_buffer == VA_INVALID_ID) {
+ vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
+ break;
+ }
+
+ CALL_VTABLE(pdrvctx, vaStatus,
+ vaRenderPicture(pdrvctx, obj_context->wrapper_context,
+ &(obj_buffer->wrapper_buffer), 1));
+ }
+ return vaStatus;
+}
+
static VAStatus
i965_decoder_render_picture(VADriverContextP ctx,
VAContextID context,
}
}
+ if ((vaStatus == VA_STATUS_SUCCESS) &&
+ (obj_context->wrapper_context != VA_INVALID_ID))
+ vaStatus = i965_decoder_wrapper_picture(ctx, context, buffers, num_buffers);
+
return vaStatus;
}
// DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_control, pic_control)
DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(qmatrix, q_matrix)
DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(iqmatrix, iq_matrix)
+DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
/* extended buffer */
DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
+DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(encmb_map, encmb_map)
#define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
// DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
{
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++) {
vaStatus = I965_RENDER_ENCODE_BUFFER(picture_parameter_ext);
break;
+ case VAHuffmanTableBufferType:
+ vaStatus = I965_RENDER_ENCODE_BUFFER(huffman_table);
+ break;
+
case VAEncSliceParameterBufferType:
vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
if (vaStatus == VA_STATUS_SUCCESS) {
* 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,
- encode->slice_num * sizeof(int));
+ (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)) {
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,
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) {
+
+ 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.
+ * 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->num_slice_params_ext]++;
+ encode->slice_rawdata_count[encode->slice_index]++;
if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
- if (encode->slice_header_index[encode->num_slice_params_ext] == 0) {
- encode->slice_header_index[encode->num_slice_params_ext] =
+ /* 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);
- } else {
- WARN_ONCE("Multi slice header data is passed for"
- " slice %d!\n", encode->num_slice_params_ext);
+ }
+ 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->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;
obj_buffer);
break;
+ case VAEncMacroblockMapBufferType:
+ vaStatus = I965_RENDER_ENCODE_BUFFER(encmb_map);
+ break;
+
default:
vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
break;
if (VAEntrypointVideoProc == obj_config->entrypoint) {
vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
- } else if (VAEntrypointEncSlice == obj_config->entrypoint ) {
+ } else if ((VAEntrypointEncSlice == obj_config->entrypoint ) ||
+ (VAEntrypointEncPicture == obj_config->entrypoint) ||
+ (VAEntrypointEncSliceLP == obj_config->entrypoint)) {
vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
} else {
vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
if (obj_context->codec_type == CODEC_PROC) {
ASSERT_RET(VAEntrypointVideoProc == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
} else if (obj_context->codec_type == CODEC_ENC) {
- ASSERT_RET(VAEntrypointEncSlice == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
+ ASSERT_RET(((VAEntrypointEncSlice == obj_config->entrypoint) ||
+ (VAEntrypointEncPicture == obj_config->entrypoint) ||
+ (VAEntrypointEncSliceLP == obj_config->entrypoint)),
+ VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
if (obj_context->codec_state.encode.num_packed_header_params_ext !=
obj_context->codec_state.encode.num_packed_header_data_ext) {
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
if (!(obj_context->codec_state.encode.seq_param ||
- obj_context->codec_state.encode.seq_param_ext)) {
- return VA_STATUS_ERROR_INVALID_PARAMETER;
+ obj_context->codec_state.encode.seq_param_ext) &&
+ (VAEntrypointEncPicture != obj_config->entrypoint)) {
+ /* 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_context->codec_state.encode.num_slice_params_ext <=0) &&
+ ((obj_config->profile != VAProfileVP8Version0_3) &&
+ (obj_config->profile != VAProfileVP9Profile0))) {
+ 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 {
obj_context->codec_state.decode.num_slice_datas) {
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
+
+ if (obj_context->wrapper_context != VA_INVALID_ID) {
+ /* call the vaEndPicture of wrapped driver */
+ VADriverContextP pdrvctx;
+ VAStatus va_status;
+
+ pdrvctx = i965->wrapper_pdrvctx;
+ CALL_VTABLE(pdrvctx, va_status,
+ vaEndPicture(pdrvctx, obj_context->wrapper_context));
+
+ return va_status;
+ }
}
ASSERT_RET(obj_context->hw_context->run, VA_STATUS_ERROR_OPERATION_FAILED);
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);
image->offsets[0] = 0;
image->data_size = size * 2;
break;
+ case VA_FOURCC_P010:
+ image->num_planes = 2;
+ image->pitches[0] = awidth * 2;
+ image->offsets[0] = 0;
+ image->pitches[1] = awidth * 2;
+ image->offsets[1] = size * 2;
+ image->data_size = size * 2 + 2 * size2 * 2;
+ break;
default:
goto error;
}
obj_surface->x_cb_offset = 0; /* X offset is always 0 */
obj_surface->x_cr_offset = 0;
+ int bpp_1stplane = bpp_1stplane_by_fourcc(fourcc);
+
if ((tiled && !obj_surface->user_disable_tiling)) {
ASSERT_RET(fourcc != VA_FOURCC_I420 &&
fourcc != VA_FOURCC_IYUV &&
fourcc != VA_FOURCC_YV12,
VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
+
if (obj_surface->user_h_stride_set) {
- ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
+ ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
} else
- obj_surface->width = ALIGN(obj_surface->orig_width, 128);
+ obj_surface->width = ALIGN(obj_surface->orig_width * bpp_1stplane, 128);
if (obj_surface->user_v_stride_set) {
- ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
- } else
- obj_surface->height = ALIGN(obj_surface->orig_height, 32);
+ ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
+ }else
+ obj_surface->height = ALIGN(obj_surface->orig_height, 32);
region_height = obj_surface->height;
switch (fourcc) {
case VA_FOURCC_NV12:
+ case VA_FOURCC_P010:
assert(subsampling == SUBSAMPLE_YUV420);
obj_surface->cb_cr_pitch = obj_surface->width;
obj_surface->cb_cr_width = obj_surface->orig_width / 2;
switch (fourcc) {
case VA_FOURCC_NV12:
+ case VA_FOURCC_P010:
obj_surface->y_cb_offset = obj_surface->height;
obj_surface->y_cr_offset = obj_surface->height;
obj_surface->cb_cr_width = obj_surface->orig_width / 2;
image->format.fourcc = obj_surface->fourcc;
image->format.byte_order = VA_LSB_FIRST;
- image->format.bits_per_pixel = 12;
+ image->format.bits_per_pixel = get_bpp_from_fourcc(obj_surface->fourcc);
+
+ if (!image->format.bits_per_pixel)
+ goto error;
switch (image->format.fourcc) {
case VA_FOURCC_YV12:
break;
case VA_FOURCC_NV12:
+ case VA_FOURCC_P010:
image->num_planes = 2;
image->pitches[0] = w_pitch; /* Y */
image->offsets[0] = 0;
case VA_FOURCC_BGRX:
image->num_planes = 1;
image->pitches[0] = obj_surface->width;
+
+ switch (image->format.fourcc) {
+ case VA_FOURCC_RGBA:
+ case VA_FOURCC_RGBX:
+ image->format.red_mask = 0x000000ff;
+ image->format.green_mask = 0x0000ff00;
+ image->format.blue_mask = 0x00ff0000;
+ break;
+ case VA_FOURCC_BGRA:
+ case VA_FOURCC_BGRX:
+ image->format.red_mask = 0x00ff0000;
+ image->format.green_mask = 0x0000ff00;
+ image->format.blue_mask = 0x000000ff;
+ break;
+ default:
+ goto error;
+ }
+
+ switch (image->format.fourcc) {
+ case VA_FOURCC_RGBA:
+ case VA_FOURCC_BGRA:
+ image->format.alpha_mask = 0xff000000;
+ image->format.depth = 32;
+ break;
+ case VA_FOURCC_RGBX:
+ case VA_FOURCC_BGRX:
+ image->format.alpha_mask = 0x00000000;
+ image->format.depth = 24;
+ break;
+ default:
+ goto error;
+ }
+
break;
default:
goto error;
*out_image = *image;
obj_surface->flags |= SURFACE_DERIVED;
+ obj_surface->derived_image_id = image_id;
obj_image->derived_surface = surface;
return VA_STATUS_SUCCESS;
if (obj_surface) {
obj_surface->flags &= ~SURFACE_DERIVED;
+ obj_surface->derived_image_id = VA_INVALID_ID;
}
i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
static VAStatus
i965_sw_getimage(VADriverContextP ctx,
- VASurfaceID surface,
- int x, /* coordinates of the upper left source pixel */
- int y,
- unsigned int width, /* width and height of the region */
- unsigned int height,
- VAImageID image)
+ struct object_surface *obj_surface, struct object_image *obj_image,
+ const VARectangle *rect)
{
- struct i965_driver_data *i965 = i965_driver_data(ctx);
- struct i965_render_state *render_state = &i965->render_state;
- VAStatus va_status = VA_STATUS_SUCCESS;
-
- struct object_surface *obj_surface = SURFACE(surface);
- if (!obj_surface)
- return VA_STATUS_ERROR_INVALID_SURFACE;
-
- struct object_image *obj_image = IMAGE(image);
- if (!obj_image)
- return VA_STATUS_ERROR_INVALID_IMAGE;
-
- if (x < 0 || y < 0)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
- if (x + width > obj_surface->orig_width ||
- y + height > obj_surface->orig_height)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
- if (x + width > obj_image->image.width ||
- y + height > obj_image->image.height)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
+ void *image_data = NULL;
+ VAStatus va_status;
if (obj_surface->fourcc != obj_image->image.format.fourcc)
return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
- void *image_data = NULL;
-
va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
if (va_status != VA_STATUS_SUCCESS)
return va_status;
- VARectangle rect;
- rect.x = x;
- rect.y = y;
- rect.width = width;
- rect.height = height;
-
switch (obj_image->image.format.fourcc) {
case VA_FOURCC_YV12:
case VA_FOURCC_I420:
- /* I420 is native format for MPEG-2 decoded surfaces */
- if (render_state->interleaved_uv)
- goto operation_failed;
- get_image_i420(obj_image, image_data, obj_surface, &rect);
+ get_image_i420(obj_image, image_data, obj_surface, rect);
break;
case VA_FOURCC_NV12:
- /* NV12 is native format for H.264 decoded surfaces */
- if (!render_state->interleaved_uv)
- goto operation_failed;
- get_image_nv12(obj_image, image_data, obj_surface, &rect);
+ get_image_nv12(obj_image, image_data, obj_surface, rect);
break;
case VA_FOURCC_YUY2:
/* YUY2 is the format supported by overlay plane */
- get_image_yuy2(obj_image, image_data, obj_surface, &rect);
+ get_image_yuy2(obj_image, image_data, obj_surface, rect);
break;
default:
- operation_failed:
va_status = VA_STATUS_ERROR_OPERATION_FAILED;
break;
}
-
if (va_status != VA_STATUS_SUCCESS)
return va_status;
static VAStatus
i965_hw_getimage(VADriverContextP ctx,
- VASurfaceID surface,
- int x, /* coordinates of the upper left source pixel */
- int y,
- unsigned int width, /* width and height of the region */
- unsigned int height,
- VAImageID image)
+ struct object_surface *obj_surface, struct object_image *obj_image,
+ const VARectangle *rect)
{
- struct i965_driver_data *i965 = i965_driver_data(ctx);
struct i965_surface src_surface;
struct i965_surface dst_surface;
- VAStatus va_status = VA_STATUS_SUCCESS;
- VARectangle rect;
- struct object_surface *obj_surface = SURFACE(surface);
- struct object_image *obj_image = IMAGE(image);
-
- if (!obj_surface)
- return VA_STATUS_ERROR_INVALID_SURFACE;
-
- if (!obj_image)
- return VA_STATUS_ERROR_INVALID_IMAGE;
-
- if (x < 0 || y < 0)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
- if (x + width > obj_surface->orig_width ||
- y + height > obj_surface->orig_height)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
- if (x + width > obj_image->image.width ||
- y + height > obj_image->image.height)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
-
- if (!obj_surface->bo)
- return VA_STATUS_SUCCESS;
- assert(obj_image->bo); // image bo is always created, see i965_CreateImage()
-
- rect.x = x;
- rect.y = y;
- rect.width = width;
- rect.height = height;
src_surface.base = (struct object_base *)obj_surface;
src_surface.type = I965_SURFACE_TYPE_SURFACE;
dst_surface.type = I965_SURFACE_TYPE_IMAGE;
dst_surface.flags = I965_SURFACE_FLAG_FRAME;
- va_status = i965_image_processing(ctx,
- &src_surface,
- &rect,
- &dst_surface,
- &rect);
-
-
- return va_status;
+ return i965_image_processing(ctx, &src_surface, rect, &dst_surface, rect);
}
VAStatus
VAImageID image)
{
struct i965_driver_data * const i965 = i965_driver_data(ctx);
- VAStatus va_status = VA_STATUS_SUCCESS;
+ struct object_surface * const obj_surface = SURFACE(surface);
+ struct object_image * const obj_image = IMAGE(image);
+ VARectangle rect;
+ VAStatus va_status;
+
+ if (!obj_surface)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+ if (!obj_surface->bo) /* don't get anything, keep previous data */
+ return VA_STATUS_SUCCESS;
+ if (is_surface_busy(i965, obj_surface))
+ return VA_STATUS_ERROR_SURFACE_BUSY;
+
+ if (!obj_image || !obj_image->bo)
+ return VA_STATUS_ERROR_INVALID_IMAGE;
+ if (is_image_busy(i965, obj_image, surface))
+ return VA_STATUS_ERROR_SURFACE_BUSY;
+
+ if (x < 0 || y < 0)
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+ if (x + width > obj_surface->orig_width ||
+ y + height > obj_surface->orig_height)
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+ if (x + width > obj_image->image.width ||
+ y + height > obj_image->image.height)
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = width;
+ rect.height = height;
if (HAS_ACCELERATED_GETIMAGE(i965))
- va_status = i965_hw_getimage(ctx,
- surface,
- x, y,
- width, height,
- image);
+ va_status = i965_hw_getimage(ctx, obj_surface, obj_image, &rect);
else
- va_status = i965_sw_getimage(ctx,
- surface,
- x, y,
- width, height,
- image);
+ va_status = i965_sw_getimage(ctx, obj_surface, obj_image, &rect);
return va_status;
}
return va_status;
}
-
static VAStatus
i965_sw_putimage(VADriverContextP ctx,
- VASurfaceID surface,
- VAImageID image,
- int src_x,
- int src_y,
- unsigned int src_width,
- unsigned int src_height,
- int dest_x,
- int dest_y,
- unsigned int dest_width,
- unsigned int dest_height)
+ struct object_surface *obj_surface, struct object_image *obj_image,
+ const VARectangle *src_rect, const VARectangle *dst_rect)
{
- struct i965_driver_data *i965 = i965_driver_data(ctx);
- struct object_surface *obj_surface = SURFACE(surface);
- struct object_image *obj_image = IMAGE(image);
VAStatus va_status = VA_STATUS_SUCCESS;
void *image_data = NULL;
- ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
- ASSERT_RET(obj_image, VA_STATUS_ERROR_INVALID_IMAGE);
-
- if (src_x < 0 || src_y < 0)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
- if (src_x + src_width > obj_image->image.width ||
- src_y + src_height > obj_image->image.height)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
- if (dest_x < 0 || dest_y < 0)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
- if (dest_x + dest_width > obj_surface->orig_width ||
- dest_y + dest_height > obj_surface->orig_height)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
-
/* XXX: don't allow scaling */
- if (src_width != dest_width || src_height != dest_height)
+ if (src_rect->width != dst_rect->width ||
+ src_rect->height != dst_rect->height)
return VA_STATUS_ERROR_INVALID_PARAMETER;
if (obj_surface->fourcc) {
va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
if (va_status != VA_STATUS_SUCCESS)
return va_status;
-
- VARectangle src_rect, dest_rect;
- src_rect.x = src_x;
- src_rect.y = src_y;
- src_rect.width = src_width;
- src_rect.height = src_height;
- dest_rect.x = dest_x;
- dest_rect.y = dest_y;
- dest_rect.width = dest_width;
- dest_rect.height = dest_height;
switch (obj_image->image.format.fourcc) {
case VA_FOURCC_YV12:
case VA_FOURCC_I420:
- va_status = put_image_i420(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
+ va_status = put_image_i420(obj_surface, dst_rect, obj_image, image_data, src_rect);
break;
case VA_FOURCC_NV12:
- va_status = put_image_nv12(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
+ va_status = put_image_nv12(obj_surface, dst_rect, obj_image, image_data, src_rect);
break;
case VA_FOURCC_YUY2:
- va_status = put_image_yuy2(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
+ va_status = put_image_yuy2(obj_surface, dst_rect, obj_image, image_data, src_rect);
break;
default:
va_status = VA_STATUS_ERROR_OPERATION_FAILED;
static VAStatus
i965_hw_putimage(VADriverContextP ctx,
- VASurfaceID surface,
- VAImageID image,
- int src_x,
- int src_y,
- unsigned int src_width,
- unsigned int src_height,
- int dest_x,
- int dest_y,
- unsigned int dest_width,
- unsigned int dest_height)
+ struct object_surface *obj_surface, struct object_image *obj_image,
+ const VARectangle *src_rect, const VARectangle *dst_rect)
{
- struct i965_driver_data *i965 = i965_driver_data(ctx);
- struct object_surface *obj_surface = SURFACE(surface);
- struct object_image *obj_image = IMAGE(image);
struct i965_surface src_surface, dst_surface;
VAStatus va_status = VA_STATUS_SUCCESS;
- VARectangle src_rect, dst_rect;
-
- ASSERT_RET(obj_surface,VA_STATUS_ERROR_INVALID_SURFACE);
- ASSERT_RET(obj_image && obj_image->bo, VA_STATUS_ERROR_INVALID_IMAGE);
-
- if (src_x < 0 ||
- src_y < 0 ||
- src_x + src_width > obj_image->image.width ||
- src_y + src_height > obj_image->image.height)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
-
- if (dest_x < 0 ||
- dest_y < 0 ||
- dest_x + dest_width > obj_surface->orig_width ||
- dest_y + dest_height > obj_surface->orig_height)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
if (!obj_surface->bo) {
unsigned int tiling, swizzle;
src_surface.base = (struct object_base *)obj_image;
src_surface.type = I965_SURFACE_TYPE_IMAGE;
src_surface.flags = I965_SURFACE_FLAG_FRAME;
- src_rect.x = src_x;
- src_rect.y = src_y;
- src_rect.width = src_width;
- src_rect.height = src_height;
dst_surface.base = (struct object_base *)obj_surface;
dst_surface.type = I965_SURFACE_TYPE_SURFACE;
dst_surface.flags = I965_SURFACE_FLAG_FRAME;
- dst_rect.x = dest_x;
- dst_rect.y = dest_y;
- dst_rect.width = dest_width;
- dst_rect.height = dest_height;
va_status = i965_image_processing(ctx,
&src_surface,
- &src_rect,
+ src_rect,
&dst_surface,
- &dst_rect);
+ dst_rect);
return va_status;
}
unsigned int dest_width,
unsigned int dest_height)
{
- struct i965_driver_data *i965 = i965_driver_data(ctx);
- VAStatus va_status = VA_STATUS_SUCCESS;
+ struct i965_driver_data * const i965 = i965_driver_data(ctx);
+ struct object_surface * const obj_surface = SURFACE(surface);
+ struct object_image * const obj_image = IMAGE(image);
+ VARectangle src_rect, dst_rect;
+ VAStatus va_status;
+
+ if (!obj_surface)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+ if (is_surface_busy(i965, obj_surface))
+ return VA_STATUS_ERROR_SURFACE_BUSY;
+
+ if (!obj_image || !obj_image->bo)
+ return VA_STATUS_ERROR_INVALID_IMAGE;
+ if (is_image_busy(i965, obj_image, surface))
+ return VA_STATUS_ERROR_SURFACE_BUSY;
+
+ if (src_x < 0 ||
+ src_y < 0 ||
+ src_x + src_width > obj_image->image.width ||
+ src_y + src_height > obj_image->image.height)
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+ src_rect.x = src_x;
+ src_rect.y = src_y;
+ src_rect.width = src_width;
+ src_rect.height = src_height;
+
+ if (dest_x < 0 ||
+ dest_y < 0 ||
+ dest_x + dest_width > obj_surface->orig_width ||
+ dest_y + dest_height > obj_surface->orig_height)
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+ dst_rect.x = dest_x;
+ dst_rect.y = dest_y;
+ dst_rect.width = dest_width;
+ dst_rect.height = dest_height;
if (HAS_ACCELERATED_PUTIMAGE(i965))
- va_status = i965_hw_putimage(ctx,
- surface,
- image,
- src_x,
- src_y,
- src_width,
- src_height,
- dest_x,
- dest_y,
- dest_width,
- dest_height);
+ va_status = i965_hw_putimage(ctx, obj_surface, obj_image,
+ &src_rect, &dst_rect);
else
- va_status = i965_sw_putimage(ctx,
- surface,
- image,
- src_x,
- src_y,
- src_width,
- src_height,
- dest_x,
- dest_y,
- dest_width,
- dest_height);
+ va_status = i965_sw_putimage(ctx, obj_surface, obj_image,
+ &src_rect, &dst_rect);
return va_status;
}
} else if (IS_GEN6(i965->intel.device_info)) {
attrib_list[i].value.value.i = VA_FOURCC_NV12;
} else if (IS_GEN7(i965->intel.device_info) ||
- IS_GEN8(i965->intel.device_info)) {
+ IS_GEN8(i965->intel.device_info) ||
+ IS_GEN9(i965->intel.device_info)) {
if (obj_config->profile == VAProfileJPEGBaseline)
attrib_list[i].value.value.i = 0; /* internal format */
else
}
}
} else if (IS_GEN7(i965->intel.device_info) ||
- IS_GEN8(i965->intel.device_info)) {
+ IS_GEN8(i965->intel.device_info) ||
+ IS_GEN9(i965->intel.device_info)) {
if (obj_config->entrypoint == VAEntrypointEncSlice ||
- obj_config->entrypoint == VAEntrypointVideoProc) {
+ obj_config->entrypoint == VAEntrypointVideoProc ||
+ obj_config->entrypoint == VAEntrypointEncSliceLP) {
switch (attrib_list[i].value.value.i) {
case VA_FOURCC_NV12:
case VA_FOURCC_I420:
struct object_config *obj_config;
int i = 0;
VASurfaceAttrib *attribs = NULL;
-
+ int max_width;
+ int max_height;
+
if (config == VA_INVALID_ID)
return VA_STATUS_ERROR_INVALID_CONFIG;
attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
attribs[i].value.value.i = VA_FOURCC_444P;
i++;
- } else {
+ } else if (obj_config->profile == VAProfileHEVCMain10) {
+ attribs[i].type = VASurfaceAttribPixelFormat;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+ attribs[i].value.value.i = VA_FOURCC_P010;
+ i++;
+ } else {
attribs[i].type = VASurfaceAttribPixelFormat;
attribs[i].value.type = VAGenericValueTypeInteger;
attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
attribs[i].type = VASurfaceAttribPixelFormat;
attribs[i].value.type = VAGenericValueTypeInteger;
attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+ attribs[i].value.value.i = VA_FOURCC_BGRA;
+ i++;
+
+ attribs[i].type = VASurfaceAttribPixelFormat;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+ attribs[i].value.value.i = VA_FOURCC_BGRX;
+ i++;
+
+ attribs[i].type = VASurfaceAttribPixelFormat;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
attribs[i].value.value.i = VA_FOURCC_YV16;
i++;
}
}
- } else if (IS_GEN8(i965->intel.device_info)) {
+ } else if (IS_GEN8(i965->intel.device_info) ||
+ IS_GEN9(i965->intel.device_info)) {
if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
if (obj_config->profile == VAProfileJPEGBaseline) {
attribs[i].type = VASurfaceAttribPixelFormat;
i++;
}
} else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
- obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
-
- attribs[i].type = VASurfaceAttribPixelFormat;
- attribs[i].value.type = VAGenericValueTypeInteger;
- attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
- attribs[i].value.value.i = VA_FOURCC_NV12;
- i++;
-
- attribs[i].type = VASurfaceAttribPixelFormat;
- attribs[i].value.type = VAGenericValueTypeInteger;
- attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
- attribs[i].value.value.i = VA_FOURCC_I420;
- i++;
+ obj_config->entrypoint == VAEntrypointVideoProc ||
+ obj_config->entrypoint == VAEntrypointEncSliceLP) {
- attribs[i].type = VASurfaceAttribPixelFormat;
- attribs[i].value.type = VAGenericValueTypeInteger;
- attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
- attribs[i].value.value.i = VA_FOURCC_YV12;
- i++;
-
- attribs[i].type = VASurfaceAttribPixelFormat;
- attribs[i].value.type = VAGenericValueTypeInteger;
- attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
- attribs[i].value.value.i = VA_FOURCC_IMC3;
- i++;
+ if (obj_config->profile == VAProfileHEVCMain10) {
+ attribs[i].type = VASurfaceAttribPixelFormat;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+ attribs[i].value.value.i = VA_FOURCC_P010;
+ i++;
+ } else {
+ attribs[i].type = VASurfaceAttribPixelFormat;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+ attribs[i].value.value.i = VA_FOURCC_NV12;
+ i++;
+
+ attribs[i].type = VASurfaceAttribPixelFormat;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+ attribs[i].value.value.i = VA_FOURCC_I420;
+ i++;
+
+ attribs[i].type = VASurfaceAttribPixelFormat;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+ attribs[i].value.value.i = VA_FOURCC_YV12;
+ i++;
+
+ attribs[i].type = VASurfaceAttribPixelFormat;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+ attribs[i].value.value.i = VA_FOURCC_IMC3;
+ i++;
+ }
if (obj_config->entrypoint == VAEntrypointVideoProc) {
attribs[i].type = VASurfaceAttribPixelFormat;
attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
attribs[i].value.value.i = VA_FOURCC_YV16;
i++;
+
+ if(HAS_VPP_P010(i965)) {
+ attribs[i].type = VASurfaceAttribPixelFormat;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+ attribs[i].value.value.i = VA_FOURCC_P010;
+ i++;
+ }
}
}
}
attribs[i].value.value.p = NULL; /* ignore */
i++;
+ max_resolution(i965, obj_config, &max_width, &max_height);
+
+ attribs[i].type = VASurfaceAttribMaxWidth;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
+ attribs[i].value.value.i = max_width;
+ i++;
+
+ attribs[i].type = VASurfaceAttribMaxHeight;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
+ attribs[i].value.value.i = max_height;
+ i++;
+
if (i > *num_attribs) {
*num_attribs = i;
free(attribs);
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;
+
+ /*
+ * As the allocated buffer by calling vaCreateBuffer is related with
+ * the specific context, it is unnecessary to export it.
+ * So it is not supported when the buffer is allocated from wrapped
+ * backend dirver.
+ */
+ if (obj_buffer->wrapper_buffer != VA_INVALID_ID) {
+ 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;
+
+ if (obj_buffer->wrapper_buffer != VA_INVALID_ID) {
+ return VA_STATUS_ERROR_INVALID_BUFFER;
+ }
+
+ return i965_release_buffer_handle(obj_buffer);
+}
+
static int
i965_os_has_ring_support(VADriverContextP ctx,
int ring)
VA_STATUS_ERROR_INVALID_PARAMETER);
if (deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
- deint->algorithm == VAProcDeinterlacingMotionCompensated);
+ deint->algorithm == VAProcDeinterlacingMotionCompensated)
pipeline_cap->num_forward_references++;
} else if (base->type == VAProcFilterSkinToneEnhancement) {
VAProcFilterParameterBuffer *stde = (VAProcFilterParameterBuffer *)base;
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)
#endif
};
+static bool
+ensure_vendor_string(struct i965_driver_data *i965, const char *chipset)
+{
+ int ret, len;
+
+ if (i965->va_vendor[0] != '\0')
+ return true;
+
+ len = 0;
+ ret = snprintf(i965->va_vendor, sizeof(i965->va_vendor),
+ "%s %s driver for %s - %d.%d.%d",
+ INTEL_STR_DRIVER_VENDOR, INTEL_STR_DRIVER_NAME, chipset,
+ INTEL_DRIVER_MAJOR_VERSION, INTEL_DRIVER_MINOR_VERSION,
+ INTEL_DRIVER_MICRO_VERSION);
+ if (ret < 0 || ret >= sizeof(i965->va_vendor))
+ goto error;
+ len = ret;
+
+ if (INTEL_DRIVER_PRE_VERSION > 0) {
+ ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
+ ".pre%d", INTEL_DRIVER_PRE_VERSION);
+ if (ret < 0 || ret >= sizeof(i965->va_vendor))
+ goto error;
+ len += ret;
+
+ ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
+ " (%s)", INTEL_DRIVER_GIT_VERSION);
+ if (ret < 0 || ret >= sizeof(i965->va_vendor))
+ goto error;
+ len += ret;
+ }
+ return true;
+
+error:
+ i965->va_vendor[0] = '\0';
+ ASSERT_RET(ret > 0 && len < sizeof(i965->va_vendor), false);
+ return false;
+}
+
+/* Only when the option of "enable-wrapper" is passed, it is possible
+ * to initialize/load the wrapper context of backend driver.
+ * Otherwise it is not loaded.
+ */
+#if HAVE_HYBRID_CODEC
+
+static VAStatus
+i965_initialize_wrapper(VADriverContextP ctx, const char *driver_name)
+{
+#define DRIVER_EXTENSION "_drv_video.so"
+
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+
+ VADriverContextP wrapper_pdrvctx;
+ struct VADriverVTable *vtable;
+ char *search_path, *driver_dir;
+ char *saveptr;
+ char driver_path[256];
+ void *handle = NULL;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ bool driver_loaded = false;
+
+ if (HAS_VP9_DECODING(i965)) {
+ i965->wrapper_pdrvctx = NULL;
+ return va_status;
+ }
+
+ wrapper_pdrvctx = calloc(1, sizeof(*wrapper_pdrvctx));
+ vtable = calloc(1, sizeof(*vtable));
+
+ if (!wrapper_pdrvctx || !vtable) {
+ fprintf(stderr, "Failed to allocate memory for wrapper \n");
+ free(wrapper_pdrvctx);
+ free(vtable);
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+
+ /* use the same drm_state with CTX */
+ wrapper_pdrvctx->drm_state = ctx->drm_state;
+ wrapper_pdrvctx->display_type = ctx->display_type;
+ wrapper_pdrvctx->vtable = vtable;
+
+ search_path = VA_DRIVERS_PATH;
+ search_path = strdup((const char *)search_path);
+
+ driver_dir = strtok_r(search_path, ":", &saveptr);
+ while (driver_dir && !driver_loaded) {
+ memset(driver_path, 0, sizeof(driver_path));
+ sprintf(driver_path, "%s/%s%s", driver_dir, driver_name, DRIVER_EXTENSION);
+
+ handle = dlopen(driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
+ if (!handle) {
+ fprintf(stderr, "failed to open %s\n", driver_path);
+ driver_dir = strtok_r(NULL, ":", &saveptr);
+ continue;
+ }
+ {
+ VADriverInit init_func = NULL;
+ char init_func_s[256];
+ int i;
+
+ static const struct {
+ int major;
+ int minor;
+ } compatible_versions[] = {
+ { VA_MAJOR_VERSION, VA_MINOR_VERSION },
+ { 0, 37 },
+ { 0, 36 },
+ { 0, 35 },
+ { 0, 34 },
+ { 0, 33 },
+ { 0, 32 },
+ { -1, }
+ };
+ for (i = 0; compatible_versions[i].major >= 0; i++) {
+ snprintf(init_func_s, sizeof(init_func_s),
+ "__vaDriverInit_%d_%d",
+ compatible_versions[i].major,
+ compatible_versions[i].minor);
+ init_func = (VADriverInit)dlsym(handle, init_func_s);
+ if (init_func) {
+ break;
+ }
+ }
+ if (compatible_versions[i].major < 0) {
+ dlclose(handle);
+ fprintf(stderr, "%s has no function %s\n",
+ driver_path, init_func_s);
+ driver_dir = strtok_r(NULL, ":", &saveptr);
+ continue;
+ }
+
+ if (init_func)
+ va_status = (*init_func)(wrapper_pdrvctx);
+
+ if (va_status != VA_STATUS_SUCCESS) {
+ dlclose(handle);
+ fprintf(stderr, "%s init failed\n", driver_path);
+ driver_dir = strtok_r(NULL, ":", &saveptr);
+ continue;
+ }
+
+ wrapper_pdrvctx->handle = handle;
+ driver_loaded = true;
+ }
+ }
+
+ free(search_path);
+
+ if (driver_loaded) {
+ i965->wrapper_pdrvctx = wrapper_pdrvctx;
+ return VA_STATUS_SUCCESS;
+ } else {
+ fprintf(stderr, "Failed to wrapper %s%s\n", driver_name, DRIVER_EXTENSION);
+ free(vtable);
+ free(wrapper_pdrvctx);
+ return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
+}
+#endif
+
static VAStatus
i965_Init(VADriverContextP ctx)
{
break;
}
- sprintf(i965->va_vendor, "%s %s driver for %s - %d.%d.%d",
- INTEL_STR_DRIVER_VENDOR,
- INTEL_STR_DRIVER_NAME,
- chipset,
- INTEL_DRIVER_MAJOR_VERSION,
- INTEL_DRIVER_MINOR_VERSION,
- INTEL_DRIVER_MICRO_VERSION);
-
- if (INTEL_DRIVER_PRE_VERSION > 0) {
- const int len = strlen(i965->va_vendor);
- sprintf(&i965->va_vendor[len], ".pre%d", INTEL_DRIVER_PRE_VERSION);
- }
+ if (!ensure_vendor_string(i965, chipset))
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
i965->current_context_id = VA_INVALID_ID;
+ if (i965->codec_info && i965->codec_info->preinit_hw_codec)
+ i965->codec_info->preinit_hw_codec(ctx, i965->codec_info);
+
+#if HAVE_HYBRID_CODEC
+ i965_initialize_wrapper(ctx, "hybrid");
+#endif
+
return VA_STATUS_SUCCESS;
} else {
i--;
int i;
if (i965) {
+ if (i965->wrapper_pdrvctx) {
+ VADriverContextP pdrvctx;
+ pdrvctx = i965->wrapper_pdrvctx;
+ if (pdrvctx->handle) {
+ pdrvctx->vtable->vaTerminate(pdrvctx);
+ dlclose(pdrvctx->handle);
+ pdrvctx->handle = NULL;
+ }
+ free(pdrvctx->vtable);
+ free(pdrvctx);
+ i965->wrapper_pdrvctx = NULL;
+ }
+
for (i = ARRAY_ELEMS(i965_sub_ops); i > 0; i--)
if (i965_sub_ops[i - 1].display_type == 0 ||
i965_sub_ops[i - 1].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
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;
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
+ i965->wrapper_pdrvctx = NULL;
ctx->pDriverData = (void *)i965;
ret = i965_Init(ctx);