From 3512f985e0b93d20806bd8b6b67c25863a5e3153 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Wed, 6 May 2009 21:04:37 +0300 Subject: [PATCH] vo_vdpau: Replace global function table with context variable --- libvo/vo_vdpau.c | 239 +++++++++++++++++++++++++++++------------------ 1 file changed, 148 insertions(+), 91 deletions(-) diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c index c924389509..c6e2973ddd 100644 --- a/libvo/vo_vdpau.c +++ b/libvo/vo_vdpau.c @@ -38,6 +38,7 @@ #include "config.h" #include "mp_msg.h" #include "options.h" +#include "talloc.h" #include "video_out.h" #include "x11_common.h" #include "aspect.h" @@ -59,14 +60,14 @@ #define CHECK_ST_ERROR(message) \ if (vdp_st != VDP_STATUS_OK) { \ mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] %s: %s\n", \ - message, vdp.get_error_string(vdp_st)); \ + message, vdp->get_error_string(vdp_st)); \ return -1; \ } #define CHECK_ST_WARNING(message) \ if (vdp_st != VDP_STATUS_OK) \ mp_msg(MSGT_VO, MSGL_WARN, "[vdpau] %s: %s\n", \ - message, vdp.get_error_string(vdp_st)); + message, vdp->get_error_string(vdp_st)); /* number of video and output surfaces */ #define NUM_OUTPUT_SURFACES 2 @@ -82,6 +83,16 @@ * Global variable declaration - VDPAU specific */ +struct vdp_functions { +#define VDP_FUNCTION(vdp_type, _, mp_name) vdp_type *mp_name; +#include "vdpau_template.c" +#undef VDP_FUNCTION +}; + +struct vdpctx { + struct vdp_functions *vdp; +}; + /* Declaration for all variables of win_x11_init_vdpau_procs() and * win_x11_init_vdpau_flip_queue() functions */ @@ -92,12 +103,6 @@ static VdpGetProcAddress *vdp_get_proc_address; static VdpPresentationQueueTarget vdp_flip_target; static VdpPresentationQueue vdp_flip_queue; -struct vdp_functions { -#define VDP_FUNCTION(vdp_type, _, mp_name) vdp_type *mp_name; -#include "vdpau_template.c" -#undef VDP_FUNCTION -} vdp; - static void *vdpau_lib_handle; /* output_surfaces[NUM_OUTPUT_SURFACES] is misused for OSD. */ #define osd_surface output_surfaces[NUM_OUTPUT_SURFACES] @@ -166,8 +171,6 @@ static VdpProcamp procamp; static int visible_buf; static int int_pause; -static void draw_eosd(void); - static void push_deint_surface(VdpVideoSurface surface) { deint_surfaces[2] = deint_surfaces[1]; @@ -176,9 +179,10 @@ static void push_deint_surface(VdpVideoSurface surface) } static void flip_page(struct vo *vo); -static void draw_osd(struct vo *vo, struct osd_state *osd); static void video_to_output_surface(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpTime dummy; VdpStatus vdp_st; int i; @@ -192,7 +196,7 @@ static void video_to_output_surface(struct vo *vo) int field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; VdpOutputSurface output_surface; if (i) { - draw_eosd(); + // draw_eosd(vo); //draw_osd(vo, NULL); flip_page(vo); } @@ -201,12 +205,12 @@ static void video_to_output_surface(struct vo *vo) VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD: VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; output_surface = output_surfaces[surface_num]; - vdp_st = vdp.presentation_queue_block_until_surface_idle(vdp_flip_queue, + vdp_st = vdp->presentation_queue_block_until_surface_idle(vdp_flip_queue, output_surface, &dummy); - CHECK_ST_WARNING("Error when calling vdp.presentation_queue_block_until_surface_idle") + CHECK_ST_WARNING("Error when calling vdp->presentation_queue_block_until_surface_idle") - vdp_st = vdp.video_mixer_render(video_mixer, VDP_INVALID_HANDLE, 0, + vdp_st = vdp->video_mixer_render(video_mixer, VDP_INVALID_HANDLE, 0, field, 2, deint_surfaces + 1, deint_surfaces[0], 1, &surface_render[vid_surface_num].surface, @@ -220,6 +224,8 @@ static void video_to_output_surface(struct vo *vo) static void resize(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; int i; struct vo_rect src_rect; @@ -255,11 +261,11 @@ static void resize(struct vo *vo) // Creation of output_surfaces for (i = 0; i <= NUM_OUTPUT_SURFACES; i++) { if (output_surfaces[i] != VDP_INVALID_HANDLE) - vdp.output_surface_destroy(output_surfaces[i]); - vdp_st = vdp.output_surface_create(vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, + vdp->output_surface_destroy(output_surfaces[i]); + vdp_st = vdp->output_surface_create(vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, output_surface_width, output_surface_height, &output_surfaces[i]); - CHECK_ST_WARNING("Error when calling vdp.output_surface_create") + CHECK_ST_WARNING("Error when calling vdp->output_surface_create") mp_msg(MSGT_VO, MSGL_DBG2, "OUT CREATE: %u\n", output_surfaces[i]); } } @@ -272,20 +278,23 @@ static void resize(struct vo *vo) static int win_x11_init_vdpau_procs(struct vo *vo) { struct vo_x11_state *x11 = vo->x11; + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = talloc_zero(vc, struct vdp_functions); + vc->vdp = vdp; VdpStatus vdp_st; struct vdp_function { const int id; - void *pointer; + int offset; }; const struct vdp_function *dsc; static const struct vdp_function vdp_func[] = { -#define VDP_FUNCTION(_, macro_name, mp_name) {macro_name, &vdp.mp_name}, +#define VDP_FUNCTION(_, macro_name, mp_name) {macro_name, offsetof(struct vdp_functions, mp_name)}, #include "vdpau_template.c" #undef VDP_FUNCTION - {0, NULL} + {0, -1} }; vdp_st = vdp_device_create(x11->display, x11->screen, @@ -295,11 +304,12 @@ static int win_x11_init_vdpau_procs(struct vo *vo) return -1; } - vdp.get_error_string = NULL; - for (dsc = vdp_func; dsc->pointer; dsc++) { - vdp_st = vdp_get_proc_address(vdp_device, dsc->id, dsc->pointer); + vdp->get_error_string = NULL; + for (dsc = vdp_func; dsc->offset >= 0; dsc++) { + vdp_st = vdp_get_proc_address(vdp_device, dsc->id, + (void **)((char *)vdp + dsc->offset)); if (vdp_st != VDP_STATUS_OK) { - mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Error when calling vdp_get_proc_address(function id %d): %s\n", dsc->id, vdp.get_error_string ? vdp.get_error_string(vdp_st) : "?"); + mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Error when calling vdp_get_proc_address(function id %d): %s\n", dsc->id, vdp->get_error_string ? vdp->get_error_string(vdp_st) : "?"); return -1; } } @@ -309,21 +319,26 @@ static int win_x11_init_vdpau_procs(struct vo *vo) /* Initialize vdpau_flip_queue, called from config() */ static int win_x11_init_vdpau_flip_queue(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; struct vo_x11_state *x11 = vo->x11; VdpStatus vdp_st; - vdp_st = vdp.presentation_queue_target_create_x11(vdp_device, x11->window, + vdp_st = vdp->presentation_queue_target_create_x11(vdp_device, x11->window, &vdp_flip_target); - CHECK_ST_ERROR("Error when calling vdp.presentation_queue_target_create_x11") + CHECK_ST_ERROR("Error when calling vdp->presentation_queue_target_create_x11") - vdp_st = vdp.presentation_queue_create(vdp_device, vdp_flip_target, + vdp_st = vdp->presentation_queue_create(vdp_device, vdp_flip_target, &vdp_flip_queue); - CHECK_ST_ERROR("Error when calling vdp.presentation_queue_create") + CHECK_ST_ERROR("Error when calling vdp->presentation_queue_create") return 0; } -static int create_vdp_mixer(VdpChromaType vdp_chroma_type) { +static int create_vdp_mixer(struct vo *vo, VdpChromaType vdp_chroma_type) +{ + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; #define VDP_NUM_MIXER_PARAMETER 3 #define MAX_NUM_FEATURES 5 int i; @@ -358,7 +373,7 @@ static int create_vdp_mixer(VdpChromaType vdp_chroma_type) { if (sharpen) features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_SHARPNESS; - vdp_st = vdp.video_mixer_create(vdp_device, feature_count, features, + vdp_st = vdp->video_mixer_create(vdp_device, feature_count, features, VDP_NUM_MIXER_PARAMETER, parameters, parameter_values, &video_mixer); @@ -368,24 +383,27 @@ static int create_vdp_mixer(VdpChromaType vdp_chroma_type) { if (deint < 3) feature_enables[0] = VDP_FALSE; if (feature_count) - vdp.video_mixer_set_feature_enables(video_mixer, feature_count, features, feature_enables); + vdp->video_mixer_set_feature_enables(video_mixer, feature_count, features, feature_enables); if (denoise) - vdp.video_mixer_set_attribute_values(video_mixer, 1, denoise_attrib, denoise_value); + vdp->video_mixer_set_attribute_values(video_mixer, 1, denoise_attrib, denoise_value); if (sharpen) - vdp.video_mixer_set_attribute_values(video_mixer, 1, sharpen_attrib, sharpen_value); + vdp->video_mixer_set_attribute_values(video_mixer, 1, sharpen_attrib, sharpen_value); if (!chroma_deint) - vdp.video_mixer_set_attribute_values(video_mixer, 1, skip_chroma_attrib, skip_chroma_value_ptr); + vdp->video_mixer_set_attribute_values(video_mixer, 1, skip_chroma_attrib, skip_chroma_value_ptr); return 0; } // Free everything specific to a certain video file -static void free_video_specific(void) { +static void free_video_specific(struct vo *vo) +{ + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; int i; VdpStatus vdp_st; if (decoder != VDP_INVALID_HANDLE) - vdp.decoder_destroy(decoder); + vdp->decoder_destroy(decoder); decoder = VDP_INVALID_HANDLE; decoder_max_refs = -1; @@ -400,25 +418,27 @@ static void free_video_specific(void) { for (i = 0; i < MAX_VIDEO_SURFACES; i++) { if (surface_render[i].surface != VDP_INVALID_HANDLE) { - vdp_st = vdp.video_surface_destroy(surface_render[i].surface); + vdp_st = vdp->video_surface_destroy(surface_render[i].surface); CHECK_ST_WARNING("Error when calling vdp_video_surface_destroy") } surface_render[i].surface = VDP_INVALID_HANDLE; } if (video_mixer != VDP_INVALID_HANDLE) { - vdp_st = vdp.video_mixer_destroy(video_mixer); + vdp_st = vdp->video_mixer_destroy(video_mixer); CHECK_ST_WARNING("Error when calling vdp_video_mixer_destroy") } video_mixer = VDP_INVALID_HANDLE; } -static int create_vdp_decoder(int max_refs) +static int create_vdp_decoder(struct vo *vo, int max_refs) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; VdpDecoderProfile vdp_decoder_profile; if (decoder != VDP_INVALID_HANDLE) - vdp.decoder_destroy(decoder); + vdp->decoder_destroy(decoder); switch (image_format) { case IMGFMT_VDPAU_MPEG1: vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG1; @@ -437,7 +457,7 @@ static int create_vdp_decoder(int max_refs) vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_ADVANCED; break; } - vdp_st = vdp.decoder_create(vdp_device, vdp_decoder_profile, + vdp_st = vdp->decoder_create(vdp_device, vdp_decoder_profile, vid_width, vid_height, max_refs, &decoder); CHECK_ST_WARNING("Failed creating VDPAU decoder"); if (vdp_st != VDP_STATUS_OK) { @@ -471,8 +491,8 @@ static int config(struct vo *vo, uint32_t width, uint32_t height, image_format = format; vid_width = width; vid_height = height; - free_video_specific(); - if (IMGFMT_IS_VDPAU(image_format) && !create_vdp_decoder(2)) + free_video_specific(vo); + if (IMGFMT_IS_VDPAU(image_format) && !create_vdp_decoder(vo, 2)) return -1; visible_buf = 0; @@ -538,7 +558,7 @@ static int config(struct vo *vo, uint32_t width, uint32_t height, vdp_pixel_format = VDP_YCBCR_FORMAT_UYVY; vdp_chroma_type = VDP_CHROMA_TYPE_422; } - if (create_vdp_mixer(vdp_chroma_type)) + if (create_vdp_mixer(vo, vdp_chroma_type)) return -1; surface_num = 0; @@ -550,6 +570,9 @@ static int config(struct vo *vo, uint32_t width, uint32_t height, static void check_events(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + int e = vo_x11_check_events(vo); if (e & VO_EVENT_RESIZE) @@ -560,11 +583,11 @@ static void check_events(struct vo *vo) if (visible_buf) { /* redraw the last visible buffer */ VdpStatus vdp_st; - vdp_st = vdp.presentation_queue_display(vdp_flip_queue, + vdp_st = vdp->presentation_queue_display(vdp_flip_queue, output_surfaces[surface_num], vo->dwidth, vo->dheight, 0); - CHECK_ST_WARNING("Error when calling vdp.presentation_queue_display") + CHECK_ST_WARNING("Error when calling vdp->presentation_queue_display") } } } @@ -572,6 +595,9 @@ static void check_events(struct vo *vo) static void draw_osd_I8A8(void *ctx, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { + struct vo *vo = ctx; + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpOutputSurface output_surface = output_surfaces[surface_num]; VdpStatus vdp_st; int i, j; @@ -604,14 +630,14 @@ static void draw_osd_I8A8(void *ctx, int x0, int y0, int w, int h, pitch = w*2; // write source_data to osd_surface. - vdp_st = vdp.output_surface_put_bits_indexed(osd_surface, + vdp_st = vdp->output_surface_put_bits_indexed(osd_surface, VDP_INDEXED_FORMAT_I8A8, (const void *const*)&index_data, &pitch, &output_indexed_rect_vid, VDP_COLOR_TABLE_FORMAT_B8G8R8X8, (void *)palette); - CHECK_ST_WARNING("Error when calling vdp.output_surface_put_bits_indexed") + CHECK_ST_WARNING("Error when calling vdp->output_surface_put_bits_indexed") blend_state.struct_version = VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION; blend_state.blend_factor_source_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE; @@ -621,17 +647,20 @@ static void draw_osd_I8A8(void *ctx, int x0, int y0, int w, int h, blend_state.blend_equation_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD; blend_state.blend_equation_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD; - vdp_st = vdp.output_surface_render_output_surface(output_surface, + vdp_st = vdp->output_surface_render_output_surface(output_surface, &output_indexed_rect_vid, osd_surface, &output_indexed_rect_vid, NULL, &blend_state, VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); - CHECK_ST_WARNING("Error when calling vdp.output_surface_render_output_surface") + CHECK_ST_WARNING("Error when calling vdp->output_surface_render_output_surface") } -static void draw_eosd(void) { +static void draw_eosd(struct vo *vo) +{ + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; VdpOutputSurface output_surface = output_surfaces[surface_num]; VdpOutputSurfaceRenderBlendState blend_state; @@ -646,7 +675,7 @@ static void draw_eosd(void) { blend_state.blend_equation_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD; for (i=0; ioutput_surface_render_bitmap_surface( output_surface, &eosd_targets[i].dest, eosd_targets[i].surface, &eosd_targets[i].source, &eosd_targets[i].color, &blend_state, @@ -655,7 +684,10 @@ static void draw_eosd(void) { } } -static void generate_eosd(mp_eosd_images_t *imgs) { +static void generate_eosd(struct vo *vo, mp_eosd_images_t *imgs) +{ + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; VdpRect destRect; int j, found; @@ -691,7 +723,7 @@ static void generate_eosd(mp_eosd_images_t *imgs) { for (j=0; jbitmap_surface_destroy(eosd_surfaces[j].surface); found = j; break; } @@ -707,7 +739,7 @@ static void generate_eosd(mp_eosd_images_t *imgs) { eosd_surfaces[j].in_use = 0; } } - vdp_st = vdp.bitmap_surface_create(vdp_device, VDP_RGBA_FORMAT_A8, + vdp_st = vdp->bitmap_surface_create(vdp_device, VDP_RGBA_FORMAT_A8, i->w, i->h, VDP_TRUE, &eosd_surfaces[found].surface); CHECK_ST_WARNING("EOSD: error when creating surface") eosd_surfaces[found].w = i->w; @@ -719,7 +751,7 @@ static void generate_eosd(mp_eosd_images_t *imgs) { destRect.y0 = 0; destRect.x1 = i->w; destRect.y1 = i->h; - vdp_st = vdp.bitmap_surface_put_bits_native(eosd_targets[eosd_render_count].surface, + vdp_st = vdp->bitmap_surface_put_bits_native(eosd_targets[eosd_render_count].surface, (const void *) &i->bitmap, &i->stride, &destRect); CHECK_ST_WARNING("EOSD: putbits failed") eosd_render_count++; @@ -756,14 +788,16 @@ static void draw_osd(struct vo *vo, struct osd_state *osd) static void flip_page(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; mp_msg(MSGT_VO, MSGL_DBG2, "\nFLIP_PAGE VID:%u -> OUT:%u\n", surface_render[vid_surface_num].surface, output_surfaces[surface_num]); - vdp_st = vdp.presentation_queue_display(vdp_flip_queue, output_surfaces[surface_num], + vdp_st = vdp->presentation_queue_display(vdp_flip_queue, output_surfaces[surface_num], vo->dwidth, vo->dheight, 0); - CHECK_ST_WARNING("Error when calling vdp.presentation_queue_display") + CHECK_ST_WARNING("Error when calling vdp->presentation_queue_display") surface_num = (surface_num + 1) % NUM_OUTPUT_SURFACES; visible_buf = 1; @@ -772,16 +806,18 @@ static void flip_page(struct vo *vo) static int draw_slice(struct vo *vo, uint8_t *image[], int stride[], int w, int h, int x, int y) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; struct vdpau_render_state *rndr = (struct vdpau_render_state *)image[0]; int max_refs = image_format == IMGFMT_VDPAU_H264 ? rndr->info.h264.num_ref_frames : 2; if (!IMGFMT_IS_VDPAU(image_format)) return VO_FALSE; if ((decoder == VDP_INVALID_HANDLE || decoder_max_refs < max_refs) - && !create_vdp_decoder(max_refs)) + && !create_vdp_decoder(vo, max_refs)) return VO_FALSE; - vdp_st = vdp.decoder_render(decoder, rndr->surface, (void *)&rndr->info, rndr->bitstream_buffers_used, rndr->bitstream_buffers); + vdp_st = vdp->decoder_render(decoder, rndr->surface, (void *)&rndr->info, rndr->bitstream_buffers_used, rndr->bitstream_buffers); CHECK_ST_WARNING("Failed VDPAU decoder rendering"); return VO_TRUE; } @@ -792,13 +828,16 @@ static int draw_frame(struct vo *vo, uint8_t *src[]) return VO_ERROR; } -static struct vdpau_render_state *get_surface(int number) +static struct vdpau_render_state *get_surface(struct vo *vo, int number) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + if (number > MAX_VIDEO_SURFACES) return NULL; if (surface_render[number].surface == VDP_INVALID_HANDLE) { VdpStatus vdp_st; - vdp_st = vdp.video_surface_create(vdp_device, vdp_chroma_type, + vdp_st = vdp->video_surface_create(vdp_device, vdp_chroma_type, vid_width, vid_height, &surface_render[number].surface); CHECK_ST_WARNING("Error when calling vdp_video_surface_create") @@ -811,6 +850,9 @@ static struct vdpau_render_state *get_surface(int number) static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + if (IMGFMT_IS_VDPAU(image_format)) { struct vdpau_render_state *rndr = mpi->priv; vid_surface_num = rndr - surface_render; @@ -824,12 +866,12 @@ static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) } else if (!(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)) { VdpStatus vdp_st; void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]}; - struct vdpau_render_state *rndr = get_surface(deint_counter); + struct vdpau_render_state *rndr = get_surface(vo, deint_counter); deint_counter = (deint_counter + 1) % 3; vid_surface_num = rndr - surface_render; if (image_format == IMGFMT_NV12) destdata[1] = destdata[2]; - vdp_st = vdp.video_surface_put_bits_y_cb_cr(rndr->surface, + vdp_st = vdp->video_surface_put_bits_y_cb_cr(rndr->surface, vdp_pixel_format, (const void *const*)destdata, mpi->stride); // pitch @@ -844,7 +886,7 @@ static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) return VO_TRUE; } -static uint32_t get_image(mp_image_t *mpi) +static uint32_t get_image(struct vo *vo, mp_image_t *mpi) { struct vdpau_render_state *rndr; @@ -852,7 +894,7 @@ static uint32_t get_image(mp_image_t *mpi) if (!IMGFMT_IS_VDPAU(image_format)) return VO_FALSE; if (mpi->type != MP_IMGTYPE_NUMBERED) return VO_FALSE; - rndr = get_surface(mpi->number); + rndr = get_surface(vo, mpi->number); if (!rndr) { mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] no surfaces available in get_image\n"); // TODO: this probably breaks things forever, provide a dummy buffer? @@ -889,34 +931,37 @@ static int query_format(uint32_t format) return 0; } -static void DestroyVdpauObjects(void) +static void destroy_vdpau_objects(struct vo *vo) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + int i; VdpStatus vdp_st; - free_video_specific(); + free_video_specific(vo); - vdp_st = vdp.presentation_queue_destroy(vdp_flip_queue); - CHECK_ST_WARNING("Error when calling vdp.presentation_queue_destroy") + vdp_st = vdp->presentation_queue_destroy(vdp_flip_queue); + CHECK_ST_WARNING("Error when calling vdp->presentation_queue_destroy") - vdp_st = vdp.presentation_queue_target_destroy(vdp_flip_target); - CHECK_ST_WARNING("Error when calling vdp.presentation_queue_target_destroy") + vdp_st = vdp->presentation_queue_target_destroy(vdp_flip_target); + CHECK_ST_WARNING("Error when calling vdp->presentation_queue_target_destroy") for (i = 0; i <= NUM_OUTPUT_SURFACES; i++) { - vdp_st = vdp.output_surface_destroy(output_surfaces[i]); + vdp_st = vdp->output_surface_destroy(output_surfaces[i]); output_surfaces[i] = VDP_INVALID_HANDLE; - CHECK_ST_WARNING("Error when calling vdp.output_surface_destroy") + CHECK_ST_WARNING("Error when calling vdp->output_surface_destroy") } for (i = 0; ibitmap_surface_destroy(eosd_surfaces[i].surface); + CHECK_ST_WARNING("Error when calling vdp->bitmap_surface_destroy") } eosd_surfaces[i].surface = VDP_INVALID_HANDLE; } - vdp_st = vdp.device_destroy(vdp_device); + vdp_st = vdp->device_destroy(vdp_device); CHECK_ST_WARNING("Error when calling vdp_device_destroy") } @@ -927,7 +972,7 @@ static void uninit(struct vo *vo) visible_buf = 0; /* Destroy all vdpau objects */ - DestroyVdpauObjects(); + destroy_vdpau_objects(vo); free(index_data); index_data = NULL; @@ -978,8 +1023,9 @@ static const char help_msg[] = static int preinit(struct vo *vo, const char *arg) { int i; - static const char *vdpaulibrary = "libvdpau.so.1"; - static const char *vdpau_device_create = "vdp_device_create_x11"; + + struct vdpctx *vc = talloc_zero(vo, struct vdpctx); + vo->priv = vc; deint = 0; deint_type = 3; @@ -999,6 +1045,8 @@ static int preinit(struct vo *vo, const char *arg) if (deint > 1) deint_buffer_past_frames = 1; + char *vdpaulibrary = "libvdpau.so.1"; + char *vdpau_device_create = "vdp_device_create_x11"; vdpau_lib_handle = dlopen(vdpaulibrary, RTLD_LAZY); if (!vdpau_lib_handle) { mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Could not open dynamic library %s\n", @@ -1042,7 +1090,10 @@ static int preinit(struct vo *vo, const char *arg) return 0; } -static int get_equalizer(const char *name, int *value) { +static int get_equalizer(struct vo *vo, const char *name, int *value) +{ + struct vdpctx *vc = vo->priv; + if (!strcasecmp(name, "brightness")) *value = procamp.brightness * 100; else if (!strcasecmp(name, "contrast")) @@ -1056,7 +1107,10 @@ static int get_equalizer(const char *name, int *value) { return VO_TRUE; } -static int set_equalizer(const char *name, int value) { +static int set_equalizer(struct vo *vo, const char *name, int value) +{ + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; VdpStatus vdp_st; VdpCSCMatrix matrix; static const VdpVideoMixerAttribute attributes[] = {VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX}; @@ -1073,10 +1127,10 @@ static int set_equalizer(const char *name, int value) { else return VO_NOTIMPL; - vdp_st = vdp.generate_csc_matrix(&procamp, VDP_COLOR_STANDARD_ITUR_BT_601, + vdp_st = vdp->generate_csc_matrix(&procamp, VDP_COLOR_STANDARD_ITUR_BT_601, &matrix); CHECK_ST_WARNING("Error when generating CSC matrix") - vdp_st = vdp.video_mixer_set_attribute_values(video_mixer, 1, attributes, + vdp_st = vdp->video_mixer_set_attribute_values(video_mixer, 1, attributes, attribute_values); CHECK_ST_WARNING("Error when setting CSC matrix") return VO_TRUE; @@ -1084,6 +1138,9 @@ static int set_equalizer(const char *name, int value) { static int control(struct vo *vo, uint32_t request, void *data) { + struct vdpctx *vc = vo->priv; + struct vdp_functions *vdp = vc->vdp; + switch (request) { case VOCTRL_GET_DEINTERLACE: *(int*)data = deint; @@ -1099,7 +1156,7 @@ static int control(struct vo *vo, uint32_t request, void *data) VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL : VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL}; VdpBool feature_enables[1] = {deint ? VDP_TRUE : VDP_FALSE}; - vdp_st = vdp.video_mixer_set_feature_enables(video_mixer, 1, + vdp_st = vdp->video_mixer_set_feature_enables(video_mixer, 1, features, feature_enables); CHECK_ST_WARNING("Error changing deinterlacing settings") @@ -1113,7 +1170,7 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_QUERY_FORMAT: return query_format(*(uint32_t *)data); case VOCTRL_GET_IMAGE: - return get_image(data); + return get_image(vo, data); case VOCTRL_DRAW_IMAGE: return draw_image(vo, data); case VOCTRL_BORDER: @@ -1131,12 +1188,12 @@ static int control(struct vo *vo, uint32_t request, void *data) return VO_TRUE; case VOCTRL_SET_EQUALIZER: { struct voctrl_set_equalizer_args *args = data; - return set_equalizer(args->name, args->value); + return set_equalizer(vo, args->name, args->value); } case VOCTRL_GET_EQUALIZER: { struct voctrl_get_equalizer_args *args = data; - return get_equalizer(args->name, args->valueptr); + return get_equalizer(vo, args->name, args->valueptr); } case VOCTRL_ONTOP: vo_x11_ontop(vo); @@ -1147,8 +1204,8 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_DRAW_EOSD: if (!data) return VO_FALSE; - generate_eosd(data); - draw_eosd(); + generate_eosd(vo, data); + draw_eosd(vo); return VO_TRUE; case VOCTRL_GET_EOSD_RES: { mp_eosd_res_t *r = data;