📄 vdpau_video.c
字号:
pinfo->syncmarker = pic_param->sequence_fields.bits.syncmarker; pinfo->rangered = pic_param->sequence_fields.bits.rangered; if (!vdpau_is_nvidia(driver_data, &major_version, &minor_version) || (major_version > 180 || minor_version >= 35)) pinfo->rangered |= pic_param->range_reduction_frame << 1; pinfo->maxbframes = pic_param->sequence_fields.bits.max_b_frames; pinfo->deblockEnable = 0; /* XXX: fill */ pinfo->pquant = 0; /* XXX: fill */ return 1;}static intvdpau_translate_VASliceParameterBufferVC1(vdpau_driver_data_t *driver_data, object_context_p obj_context, object_buffer_p obj_buffer){ VdpPictureInfoVC1 * const pinfo = &obj_context->vdp_picture_info.vc1; VASliceParameterBufferVC1 * const slice_params = obj_buffer->buffer_data; VASliceParameterBufferVC1 * const slice_param = &slice_params[obj_buffer->num_elements - 1]; pinfo->slice_count = obj_buffer->num_elements; return 1;}typedef int (*vdpau_translate_buffer_func_t)(vdpau_driver_data_t *driver_data, object_context_p obj_context, object_buffer_p obj_buffer);typedef struct vdpau_translate_buffer_info vdpau_translate_buffer_info_t;struct vdpau_translate_buffer_info { VdpCodec codec; VABufferType type; vdpau_translate_buffer_func_t func;};static intvdpau_translate_buffer(vdpau_driver_data_t *driver_data, object_context_p obj_context, object_buffer_p obj_buffer){ static const vdpau_translate_buffer_info_t translate_info[] = {#define _(CODEC, TYPE) \ { VDP_CODEC_##CODEC, VA##TYPE##BufferType, \ vdpau_translate_VA##TYPE##Buffer##CODEC } _(MPEG2, PictureParameter), _(MPEG2, IQMatrix), _(MPEG2, SliceParameter), _(H264, PictureParameter), _(H264, IQMatrix), _(H264, SliceParameter), _(VC1, PictureParameter), _(VC1, SliceParameter),#undef _ { VDP_CODEC_VC1, VABitPlaneBufferType, vdpau_translate_nothing }, { 0, VASliceDataBufferType, vdpau_translate_VASliceDataBuffer }, { 0, 0, NULL } }; const vdpau_translate_buffer_info_t *tbip; for (tbip = translate_info; tbip->func != NULL; tbip++) { if (tbip->codec && tbip->codec != obj_context->vdp_codec) continue; if (tbip->type != obj_buffer->type) continue; return tbip->func(driver_data, obj_context, obj_buffer); } D(bug("ERROR: no translate function found for %s%s\n", string_of_VABufferType(obj_buffer->type), obj_context->vdp_codec ? string_of_VdpCodec(obj_context->vdp_codec) : NULL)); return 0;}/* ====================================================================== *//* === VA API Implementation with VDPAU === *//* ====================================================================== */static inline int get_num_ref_frames(object_context_p obj_context){ if (obj_context->vdp_codec == VDP_CODEC_H264) return obj_context->vdp_picture_info.h264.num_ref_frames; return 2;}static VdpStatus ensure_decoder_with_max_refs(vdpau_driver_data_t *driver_data, object_context_p obj_context, int max_ref_frames){ if (max_ref_frames < 0) max_ref_frames = get_VdpDecoder_max_references(obj_context->vdp_profile, obj_context->picture_width, obj_context->picture_height); if (obj_context->vdp_decoder == VDP_INVALID_HANDLE || obj_context->max_ref_frames < max_ref_frames) { obj_context->max_ref_frames = max_ref_frames; if (obj_context->vdp_decoder != VDP_INVALID_HANDLE) { vdpau_decoder_destroy(driver_data, obj_context->vdp_decoder); obj_context->vdp_decoder = VDP_INVALID_HANDLE; } return vdpau_decoder_create(driver_data, driver_data->vdp_device, obj_context->vdp_profile, obj_context->picture_width, obj_context->picture_height, max_ref_frames, &obj_context->vdp_decoder); } return VDP_STATUS_OK;}static void destroy_output_surface(vdpau_driver_data_t *driver_data, VASurfaceID surface){ if (surface == 0) return; object_output_p obj_output = OUTPUT(surface); ASSERT(obj_output); if (obj_output == NULL) return; if (obj_output->vdp_flip_queue != VDP_INVALID_HANDLE) { vdpau_presentation_queue_destroy(driver_data, obj_output->vdp_flip_queue); obj_output->vdp_flip_queue = VDP_INVALID_HANDLE; } if (obj_output->vdp_flip_target != VDP_INVALID_HANDLE) { vdpau_presentation_queue_target_destroy(driver_data, obj_output->vdp_flip_target); obj_output->vdp_flip_target = VDP_INVALID_HANDLE; } int i; for (i = 0; i < 2; i++) { VdpOutputSurface vdp_output_surface = obj_output->vdp_output_surfaces[i]; if (vdp_output_surface) { vdpau_output_surface_destroy(driver_data, vdp_output_surface); obj_output->vdp_output_surfaces[i] = VDP_INVALID_HANDLE; } } object_heap_free(&driver_data->output_heap, (object_base_p)obj_output);}static VASurfaceID create_output_surface(vdpau_driver_data_t *driver_data, uint32_t width, uint32_t height){ int surface = object_heap_allocate(&driver_data->output_heap); if (surface < 0) return 0; object_output_p obj_output = OUTPUT(surface); ASSERT(obj_output); if (obj_output == NULL) return 0; obj_output->drawable = None; obj_output->width = 0; obj_output->height = 0; obj_output->vdp_flip_queue = VDP_INVALID_HANDLE; obj_output->vdp_flip_target = VDP_INVALID_HANDLE; obj_output->output_surface_width = width; obj_output->output_surface_height = height; obj_output->vdp_output_surfaces[0] = VDP_INVALID_HANDLE; obj_output->vdp_output_surfaces[1] = VDP_INVALID_HANDLE; obj_output->current_output_surface = 0; VADriverContextP const ctx = driver_data->va_context; uint32_t display_width, display_height; display_width = DisplayWidth(ctx->x11_dpy, ctx->x11_screen); display_height = DisplayHeight(ctx->x11_dpy, ctx->x11_screen); if (obj_output->output_surface_width < display_width) obj_output->output_surface_width = display_width; if (obj_output->output_surface_height < display_height) obj_output->output_surface_height = display_height; int i; for (i = 0; i < 3; i++) { VdpStatus vdp_status; VdpOutputSurface vdp_output_surface; vdp_status = vdpau_output_surface_create(driver_data, driver_data->vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, obj_output->output_surface_width, obj_output->output_surface_height, &vdp_output_surface); if (vdp_status != VDP_STATUS_OK) { destroy_output_surface(driver_data, surface); return 0; } obj_output->vdp_output_surfaces[i] = vdp_output_surface; } return surface;}// vaQueryConfigProfilesstatic VAStatusvdpau_QueryConfigProfiles(VADriverContextP ctx, VAProfile *profile_list, /* out */ int *num_profiles /* out */){ INIT_DRIVER_DATA; static const VAProfile va_profiles[] = { VAProfileMPEG2Simple, VAProfileMPEG2Main, VAProfileH264Baseline, VAProfileH264Main, VAProfileH264High, VAProfileVC1Simple, VAProfileVC1Main, VAProfileVC1Advanced }; int i, n = 0; for (i = 0; i < ARRAY_ELEMS(va_profiles); i++) { VAProfile profile = va_profiles[i]; VdpDecoderProfile vdp_profile = get_VdpDecoderProfile(profile); if (vdpau_is_supported_profile(driver_data, profile)) profile_list[n++] = profile; } /* If the assert fails then VDPAU_MAX_PROFILES needs to be bigger */ ASSERT(n <= VDPAU_MAX_PROFILES); if (num_profiles) *num_profiles = n; return VA_STATUS_SUCCESS;}// vaQueryConfigEntrypointsstatic VAStatusvdpau_QueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, VAEntrypoint *entrypoint_list, /* out */ int *num_entrypoints /* out */){ INIT_DRIVER_DATA; VAEntrypoint entrypoint; switch (profile) { case VAProfileMPEG2Simple: case VAProfileMPEG2Main: entrypoint = VAEntrypointVLD; break; case VAProfileH264Baseline: case VAProfileH264Main: case VAProfileH264High: entrypoint = VAEntrypointVLD; break; case VAProfileVC1Simple: case VAProfileVC1Main: case VAProfileVC1Advanced: entrypoint = VAEntrypointVLD; break; default: entrypoint = 0; break; } if (entrypoint_list) *entrypoint_list = entrypoint; if (num_entrypoints) *num_entrypoints = entrypoint != 0; return VA_STATUS_SUCCESS;}// vaGetConfigAttributesstatic VAStatusvdpau_GetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, /* in/out */ int num_attribs){ INIT_DRIVER_DATA; int i; for (i = 0; i < num_attribs; i++) { switch (attrib_list[i].type) { case VAConfigAttribRTFormat: attrib_list[i].value = VA_RT_FORMAT_YUV420; break; default: attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED; break; } } return VA_STATUS_SUCCESS;}static VAStatusvdpau_update_attribute(object_config_p obj_config, VAConfigAttrib *attrib){ int i; /* Check existing attrbiutes */ for (i = 0; obj_config->attrib_count < i; i++) { if (obj_config->attrib_list[i].type == attrib->type) { /* Update existing attribute */ obj_config->attrib_list[i].value = attrib->value; return VA_STATUS_SUCCESS; } } if (obj_config->attrib_count < VDPAU_MAX_CONFIG_ATTRIBUTES) { i = obj_config->attrib_count; obj_config->attrib_list[i].type = attrib->type; obj_config->attrib_list[i].value = attrib->value; obj_config->attrib_count++; return VA_STATUS_SUCCESS; } return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;}// vaDestroyConfigstatic VAStatusvdpau_DestroyConfig(VADriverContextP ctx, VAConfigID config_id){ INIT_DRIVER_DATA; VAStatus va_status; object_config_p obj_config; if ((obj_config = CONFIG(config_id)) == NULL) return VA_STATUS_ERROR_INVALID_CONFIG; object_heap_free(&driver_data->config_heap, (object_base_p)obj_config); return VA_STATUS_SUCCESS;}// vaCreateConfigstatic VAStatusvdpau_CreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) /* out */{ INIT_DRIVER_DATA; VAStatus va_status; int configID; object_config_p obj_config; int i; /* Validate profile and entrypoint */ switch (profile) { case VAProfileMPEG2Simple: case VAProfileMPEG2Main: if (entrypoint == VAEntrypointVLD) va_status = VA_STATUS_SUCCESS; else va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; break; case VAProfileH264Baseline: case VAProfileH264Main: case VAProfileH264High: if (entrypoint == VAEntrypointVLD) va_status = VA_STATUS_SUCCESS; else va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; break; case VAProfileVC1Simple: case VAProfileVC1Main: case VAProfileVC1Advanced: if (entrypoint == VAEntrypointVLD) va_status = VA_STATUS_SUCCESS; else va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; break; default: va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; break; } if (va_status != VA_STATUS_SUCCESS) return va_status; configID = object_heap_allocate(&driver_data->config_heap); if ((obj_config = CONFIG(configID)) == NULL) return VA_STATUS_ERROR_ALLOCATION_FAILED; obj_config->profile = profile; obj_config->entrypoint = entrypoint; obj_config->attrib_list[0].type = VAConfigAttribRTFormat; obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420; obj_config->attrib_count = 1; for(i = 0; i < num_attribs; i++) { va_status = vdpau_update_attribute(obj_config, &attrib_list[i]); if (va_status != VA_STATUS_SUCCESS) { vdpau_DestroyConfig(ctx, configID); return va_status; } } if (config_id) *config_id = configID; return va_status;}// vaQueryConfigAttributesstatic VAStatusvdpau_QueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, /* out */ VAEntrypoint *entrypoint, /* out */ VAConfigAttrib *attrib_list,/* out */ int *num_attribs) /* out */{ INIT_DRIVER_DATA; VAStatus va_status = VA_STATUS_SUCCESS; object_config_p obj_config;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -