diff options
author | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2009-08-29 21:21:16 +0300 |
---|---|---|
committer | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2009-08-31 22:18:51 +0300 |
commit | 575331d73cf3a992c779cca7f90ae4810d17dcfc (patch) | |
tree | 91c39a51189b090bb8279a881d2d5fd9485231fc | |
parent | a9618c1c6fe9424dfaeb1677348e0382d7252554 (diff) | |
parent | 84964c0dec03b4d7ba6e0b78a49273f7ca8a56ea (diff) | |
download | mpv-575331d73cf3a992c779cca7f90ae4810d17dcfc.tar.bz2 mpv-575331d73cf3a992c779cca7f90ae4810d17dcfc.tar.xz |
Merge branch 'vdpau_old' into vdpau
-rw-r--r-- | TOOLS/vdpau_functions.py | 56 | ||||
-rw-r--r-- | libvo/vdpau_template.c | 37 | ||||
-rw-r--r-- | libvo/vo_vdpau.c | 1441 |
3 files changed, 850 insertions, 684 deletions
diff --git a/TOOLS/vdpau_functions.py b/TOOLS/vdpau_functions.py new file mode 100644 index 0000000000..386d70ab33 --- /dev/null +++ b/TOOLS/vdpau_functions.py @@ -0,0 +1,56 @@ +# Generate vdpau_template.c + +functions = """ +# get_error_string should be first, because the function lookup loop should +# have it available to print errors for other functions +get_error_string + +bitmap_surface_create +bitmap_surface_destroy +bitmap_surface_put_bits_native +decoder_create +decoder_destroy +decoder_render +device_destroy +generate_csc_matrix GenerateCSCMatrix # CSC completely capitalized +output_surface_create +output_surface_destroy +output_surface_put_bits_indexed +output_surface_put_bits_native +output_surface_render_bitmap_surface +output_surface_render_output_surface +presentation_queue_block_until_surface_idle +presentation_queue_create +presentation_queue_destroy +presentation_queue_display +presentation_queue_target_create_x11 +presentation_queue_target_destroy +video_mixer_create +video_mixer_destroy +video_mixer_render +video_mixer_set_attribute_values +video_mixer_set_feature_enables +video_surface_create +video_surface_destroy +video_surface_put_bits_y_cb_cr +""" + +print(""" +/* List the VDPAU functions used by MPlayer. + * Generated by vdpau_functions.py. + * First argument on each line is the VDPAU function type name, + * second macro name needed to get function address, + * third name MPlayer uses for the function. + */ +""") +for line in functions.splitlines(): + parts = line.split('#')[0].strip().split() + if not parts: + continue # empty/comment line + if len(parts) > 1: + mp_name, vdpau_name = parts + else: + mp_name = parts[0] + vdpau_name = ''.join(part.capitalize() for part in mp_name.split('_')) + macro_name = mp_name.upper() + print('VDP_FUNCTION(Vdp%s, VDP_FUNC_ID_%s, %s)' % (vdpau_name, macro_name, mp_name)) diff --git a/libvo/vdpau_template.c b/libvo/vdpau_template.c new file mode 100644 index 0000000000..82660b9bb5 --- /dev/null +++ b/libvo/vdpau_template.c @@ -0,0 +1,37 @@ + +/* List the VDPAU functions used by MPlayer. + * Generated by vdpau_functions.py. + * First argument on each line is the VDPAU function type name, + * second macro name needed to get function address, + * third name MPlayer uses for the function. + */ + +VDP_FUNCTION(VdpGetErrorString, VDP_FUNC_ID_GET_ERROR_STRING, get_error_string) +VDP_FUNCTION(VdpBitmapSurfaceCreate, VDP_FUNC_ID_BITMAP_SURFACE_CREATE, bitmap_surface_create) +VDP_FUNCTION(VdpBitmapSurfaceDestroy, VDP_FUNC_ID_BITMAP_SURFACE_DESTROY, bitmap_surface_destroy) +VDP_FUNCTION(VdpBitmapSurfacePutBitsNative, VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE, bitmap_surface_put_bits_native) +VDP_FUNCTION(VdpDecoderCreate, VDP_FUNC_ID_DECODER_CREATE, decoder_create) +VDP_FUNCTION(VdpDecoderDestroy, VDP_FUNC_ID_DECODER_DESTROY, decoder_destroy) +VDP_FUNCTION(VdpDecoderRender, VDP_FUNC_ID_DECODER_RENDER, decoder_render) +VDP_FUNCTION(VdpDeviceDestroy, VDP_FUNC_ID_DEVICE_DESTROY, device_destroy) +VDP_FUNCTION(VdpGenerateCSCMatrix, VDP_FUNC_ID_GENERATE_CSC_MATRIX, generate_csc_matrix) +VDP_FUNCTION(VdpOutputSurfaceCreate, VDP_FUNC_ID_OUTPUT_SURFACE_CREATE, output_surface_create) +VDP_FUNCTION(VdpOutputSurfaceDestroy, VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY, output_surface_destroy) +VDP_FUNCTION(VdpOutputSurfacePutBitsIndexed, VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED, output_surface_put_bits_indexed) +VDP_FUNCTION(VdpOutputSurfacePutBitsNative, VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE, output_surface_put_bits_native) +VDP_FUNCTION(VdpOutputSurfaceRenderBitmapSurface, VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE, output_surface_render_bitmap_surface) +VDP_FUNCTION(VdpOutputSurfaceRenderOutputSurface, VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE, output_surface_render_output_surface) +VDP_FUNCTION(VdpPresentationQueueBlockUntilSurfaceIdle, VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE, presentation_queue_block_until_surface_idle) +VDP_FUNCTION(VdpPresentationQueueCreate, VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE, presentation_queue_create) +VDP_FUNCTION(VdpPresentationQueueDestroy, VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY, presentation_queue_destroy) +VDP_FUNCTION(VdpPresentationQueueDisplay, VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY, presentation_queue_display) +VDP_FUNCTION(VdpPresentationQueueTargetCreateX11, VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11, presentation_queue_target_create_x11) +VDP_FUNCTION(VdpPresentationQueueTargetDestroy, VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY, presentation_queue_target_destroy) +VDP_FUNCTION(VdpVideoMixerCreate, VDP_FUNC_ID_VIDEO_MIXER_CREATE, video_mixer_create) +VDP_FUNCTION(VdpVideoMixerDestroy, VDP_FUNC_ID_VIDEO_MIXER_DESTROY, video_mixer_destroy) +VDP_FUNCTION(VdpVideoMixerRender, VDP_FUNC_ID_VIDEO_MIXER_RENDER, video_mixer_render) +VDP_FUNCTION(VdpVideoMixerSetAttributeValues, VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES, video_mixer_set_attribute_values) +VDP_FUNCTION(VdpVideoMixerSetFeatureEnables, VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES, video_mixer_set_feature_enables) +VDP_FUNCTION(VdpVideoSurfaceCreate, VDP_FUNC_ID_VIDEO_SURFACE_CREATE, video_surface_create) +VDP_FUNCTION(VdpVideoSurfaceDestroy, VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, video_surface_destroy) +VDP_FUNCTION(VdpVideoSurfacePutBitsYCbCr, VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, video_surface_put_bits_y_cb_cr) diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c index 486a6e699f..a8bd13d6dc 100644 --- a/libvo/vo_vdpau.c +++ b/libvo/vo_vdpau.c @@ -20,58 +20,54 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/** - * \defgroup VDPAU_Presentation VDPAU Presentation - * \ingroup Decoder - * +/* * Actual decoding and presentation are implemented here. * All necessary frame information is collected through * the "vdpau_render_state" structure after parsing all headers * etc. in libavcodec for different codecs. - * - * @{ */ #include <stdio.h> #include <dlfcn.h> +#include <stdint.h> +#include <stdbool.h> #include "config.h" #include "mp_msg.h" +#include "options.h" +#include "talloc.h" #include "video_out.h" -#include "video_out_internal.h" #include "x11_common.h" #include "aspect.h" #include "sub.h" #include "subopt-helper.h" -#include "font_load.h" +#include "libmpcodecs/vfcap.h" +#include "libmpcodecs/mp_image.h" #include "libavcodec/vdpau.h" +#include "font_load.h" + #include "libavutil/common.h" #include "libavutil/mathematics.h" #include "ass_mp.h" -static vo_info_t info = { - "VDPAU with X11", - "vdpau", - "Rajib Mahapatra <rmahapatra@nvidia.com> and others", - "" -}; - -LIBVO_EXTERN(vdpau) - #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)); \ - return -1; \ - } + do { \ + if (vdp_st != VDP_STATUS_OK) { \ + mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] %s: %s\n", \ + message, vdp->get_error_string(vdp_st)); \ + return -1; \ + } \ + } while (0) #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)); + do { \ + if (vdp_st != VDP_STATUS_OK) \ + mp_msg(MSGT_VO, MSGL_WARN, "[ vdpau] %s: %s\n", \ + message, vdp->get_error_string(vdp_st)); \ + } while (0) /* number of video and output surfaces */ #define NUM_OUTPUT_SURFACES 2 @@ -87,320 +83,273 @@ LIBVO_EXTERN(vdpau) * Global variable declaration - VDPAU specific */ -/* Declaration for all variables of win_x11_init_vdpau_procs() and - * win_x11_init_vdpau_flip_queue() functions - */ -static VdpDevice vdp_device; -static VdpDeviceCreateX11 *vdp_device_create; -static VdpGetProcAddress *vdp_get_proc_address; - -static VdpPresentationQueueTarget vdp_flip_target; -static VdpPresentationQueue vdp_flip_queue; - -static VdpDeviceDestroy *vdp_device_destroy; -static VdpVideoSurfaceCreate *vdp_video_surface_create; -static VdpVideoSurfaceDestroy *vdp_video_surface_destroy; - -static VdpGetErrorString *vdp_get_error_string; - -/* May be used in software filtering/postprocessing options - * in MPlayer (./mplayer -vf ..) if we copy video_surface data to - * system memory. - */ -static VdpVideoSurfacePutBitsYCbCr *vdp_video_surface_put_bits_y_cb_cr; -static VdpOutputSurfacePutBitsNative *vdp_output_surface_put_bits_native; - -static VdpOutputSurfaceCreate *vdp_output_surface_create; -static VdpOutputSurfaceDestroy *vdp_output_surface_destroy; - -/* VideoMixer puts video_surface data on displayable output_surface. */ -static VdpVideoMixerCreate *vdp_video_mixer_create; -static VdpVideoMixerDestroy *vdp_video_mixer_destroy; -static VdpVideoMixerRender *vdp_video_mixer_render; -static VdpVideoMixerSetFeatureEnables *vdp_video_mixer_set_feature_enables; -static VdpVideoMixerSetAttributeValues *vdp_video_mixer_set_attribute_values; - -static VdpPresentationQueueTargetDestroy *vdp_presentation_queue_target_destroy; -static VdpPresentationQueueCreate *vdp_presentation_queue_create; -static VdpPresentationQueueDestroy *vdp_presentation_queue_destroy; -static VdpPresentationQueueDisplay *vdp_presentation_queue_display; -static VdpPresentationQueueBlockUntilSurfaceIdle *vdp_presentation_queue_block_until_surface_idle; -static VdpPresentationQueueTargetCreateX11 *vdp_presentation_queue_target_create_x11; - -static VdpOutputSurfaceRenderOutputSurface *vdp_output_surface_render_output_surface; -static VdpOutputSurfacePutBitsIndexed *vdp_output_surface_put_bits_indexed; -static VdpOutputSurfaceRenderBitmapSurface *vdp_output_surface_render_bitmap_surface; - -static VdpBitmapSurfaceCreate *vdp_bitmap_surface_create; -static VdpBitmapSurfaceDestroy *vdp_bitmap_surface_destroy; -static VdpBitmapSurfacePutBitsNative *vdp_bitmap_surface_putbits_native; - -static VdpDecoderCreate *vdp_decoder_create; -static VdpDecoderDestroy *vdp_decoder_destroy; -static VdpDecoderRender *vdp_decoder_render; - -static VdpGenerateCSCMatrix *vdp_generate_csc_matrix; - -static void *vdpau_lib_handle; -/* output_surfaces[NUM_OUTPUT_SURFACES] is misused for OSD. */ -#define osd_surface output_surfaces[NUM_OUTPUT_SURFACES] -static VdpOutputSurface output_surfaces[NUM_OUTPUT_SURFACES + 1]; -static VdpVideoSurface deint_surfaces[3]; -static mp_image_t *deint_mpi[2]; -static int output_surface_width, output_surface_height; - -static VdpVideoMixer video_mixer; -static int deint; -static int deint_type; -static int deint_counter; -static int deint_buffer_past_frames; -static int pullup; -static float denoise; -static float sharpen; -static int chroma_deint; -static int top_field_first; - -static VdpDecoder decoder; -static int decoder_max_refs; - -static VdpRect src_rect_vid; -static VdpRect out_rect_vid; -static int border_x, border_y; - -static struct vdpau_render_state surface_render[MAX_VIDEO_SURFACES]; -static int surface_num; -static int vid_surface_num; -static uint32_t vid_width, vid_height; -static uint32_t image_format; -static VdpChromaType vdp_chroma_type; -static VdpYCbCrFormat vdp_pixel_format; - -/* draw_osd */ -static unsigned char *index_data; -static int index_data_size; -static uint32_t palette[PALETTE_SIZE]; - -// EOSD -// Pool of surfaces -struct { - VdpBitmapSurface surface; - int w; - int h; - char in_use; -} *eosd_surfaces; - -// List of surfaces to be rendered -struct { - VdpBitmapSurface surface; - VdpRect source; - VdpRect dest; - VdpColor color; -} *eosd_targets; - -static int eosd_render_count; -static int eosd_surface_count; - -// Video equalizer -static VdpProcamp procamp; +struct vdp_functions { +#define VDP_FUNCTION(vdp_type, _, mp_name) vdp_type *mp_name; +#include "vdpau_template.c" +#undef VDP_FUNCTION +}; -/* - * X11 specific - */ -static int visible_buf; -static int int_pause; +struct vdpctx { + struct vdp_functions *vdp; + + VdpDevice vdp_device; + VdpDeviceCreateX11 *vdp_device_create; + VdpGetProcAddress *vdp_get_proc_address; + + VdpPresentationQueueTarget flip_target; + VdpPresentationQueue flip_queue; + + void *vdpau_lib_handle; + + /* output_surfaces[NUM_OUTPUT_SURFACES] is misused for OSD. */ +#define osd_surface vc->output_surfaces[NUM_OUTPUT_SURFACES] + VdpOutputSurface output_surfaces[NUM_OUTPUT_SURFACES + 1]; + VdpVideoSurface deint_surfaces[3]; + mp_image_t *deint_mpi[2]; + int output_surface_width, output_surface_height; + + VdpVideoMixer video_mixer; + int deint; + int deint_type; + int deint_counter; + int deint_buffer_past_frames; + int pullup; + float denoise; + float sharpen; + int chroma_deint; + int top_field_first; + + VdpDecoder decoder; + int decoder_max_refs; + + VdpRect src_rect_vid; + VdpRect out_rect_vid; + int border_x, border_y; + + struct vdpau_render_state surface_render[MAX_VIDEO_SURFACES]; + int surface_num; + int vid_surface_num; + uint32_t vid_width, vid_height; + uint32_t image_format; + VdpChromaType vdp_chroma_type; + VdpYCbCrFormat vdp_pixel_format; + + /* draw_osd */ + unsigned char *index_data; + int index_data_size; + uint32_t palette[PALETTE_SIZE]; + + // EOSD + // Pool of surfaces + struct { + VdpBitmapSurface surface; + int w; + int h; + bool in_use; + } *eosd_surfaces; + + // List of surfaces to be rendered + struct eosd_target { + VdpBitmapSurface surface; + VdpRect source; + VdpRect dest; + VdpColor color; + } *eosd_targets; + + int eosd_render_count; + int eosd_surface_count; + + // Video equalizer + VdpProcamp procamp; + + bool visible_buf; + bool paused; + + // These tell what's been initialized and uninit() should free/uninitialize + bool mode_switched; +}; -static void draw_eosd(void); -static void push_deint_surface(VdpVideoSurface surface) +static void push_deint_surface(struct vo *vo, VdpVideoSurface surface) { - deint_surfaces[2] = deint_surfaces[1]; - deint_surfaces[1] = deint_surfaces[0]; - deint_surfaces[0] = surface; + struct vdpctx *vc = vo->priv; + vc->deint_surfaces[2] = vc->deint_surfaces[1]; + vc->deint_surfaces[1] = vc->deint_surfaces[0]; + vc->deint_surfaces[0] = surface; } -static void video_to_output_surface(void) +static void flip_page(struct vo *vo); +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; - if (vid_surface_num < 0) + if (vc->vid_surface_num < 0) return; - if (deint < 2 || deint_surfaces[0] == VDP_INVALID_HANDLE) - push_deint_surface(surface_render[vid_surface_num].surface); + if (vc->deint < 2 || vc->deint_surfaces[0] == VDP_INVALID_HANDLE) + push_deint_surface(vo, vc->surface_render[vc->vid_surface_num].surface); - for (i = 0; i <= !!(deint > 1); i++) { + for (i = 0; i <= (vc->deint > 1); i++) { int field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; VdpOutputSurface output_surface; if (i) { - draw_eosd(); - draw_osd(); - flip_page(); + // draw_eosd() + // draw_osd() + flip_page(vo); } - if (deint) - field = (top_field_first == i) ^ (deint > 1) ? - 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, - output_surface, - &dummy); - 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, - field, 2, deint_surfaces + 1, - deint_surfaces[0], - 1, &surface_render[vid_surface_num].surface, - &src_rect_vid, - output_surface, - NULL, &out_rect_vid, 0, NULL); - CHECK_ST_WARNING("Error when calling vdp_video_mixer_render") - push_deint_surface(surface_render[vid_surface_num].surface); + if (vc->deint) + field = (vc->top_field_first == i) ^ (vc->deint > 1) ? + VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD: + VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; + output_surface = vc->output_surfaces[vc->surface_num]; + vdp_st = vdp-> + presentation_queue_block_until_surface_idle(vc->flip_queue, + output_surface, + &dummy); + CHECK_ST_WARNING("Error when calling " + "vdp_presentation_queue_block_until_surface_idle"); + + vdp_st = vdp->video_mixer_render(vc->video_mixer, VDP_INVALID_HANDLE, + 0, field, 2, vc->deint_surfaces + 1, + vc->deint_surfaces[0], 1, + &vc->surface_render[vc->vid_surface_num].surface, + &vc->src_rect_vid, output_surface, + NULL, &vc->out_rect_vid, 0, NULL); + CHECK_ST_WARNING("Error when calling vdp_video_mixer_render"); + push_deint_surface(vo, vc->surface_render[vc->vid_surface_num].surface); } } -static void resize(void) +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; struct vo_rect dst_rect; struct vo_rect borders; - calc_src_dst_rects(vid_width, vid_height, &src_rect, &dst_rect, &borders, NULL); - out_rect_vid.x0 = dst_rect.left; - out_rect_vid.x1 = dst_rect.right; - out_rect_vid.y0 = dst_rect.top; - out_rect_vid.y1 = dst_rect.bottom; - src_rect_vid.x0 = src_rect.left; - src_rect_vid.x1 = src_rect.right; - src_rect_vid.y0 = src_rect.top; - src_rect_vid.y1 = src_rect.bottom; - border_x = borders.left; - border_y = borders.top; + calc_src_dst_rects(vo, vc->vid_width, vc->vid_height, &src_rect, &dst_rect, + &borders, NULL); + vc->out_rect_vid.x0 = dst_rect.left; + vc->out_rect_vid.x1 = dst_rect.right; + vc->out_rect_vid.y0 = dst_rect.top; + vc->out_rect_vid.y1 = dst_rect.bottom; + vc->src_rect_vid.x0 = src_rect.left; + vc->src_rect_vid.x1 = src_rect.right; + vc->src_rect_vid.y0 = src_rect.top; + vc->src_rect_vid.y1 = src_rect.bottom; + vc->border_x = borders.left; + vc->border_y = borders.top; #ifdef CONFIG_FREETYPE // adjust font size to display size force_load_font = 1; #endif vo_osd_changed(OSDTYPE_OSD); - if (output_surface_width < vo_dwidth || output_surface_height < vo_dheight) { - if (output_surface_width < vo_dwidth) { - output_surface_width += output_surface_width >> 1; - output_surface_width = FFMAX(output_surface_width, vo_dwidth); + if (vc->output_surface_width < vo->dwidth + || vc->output_surface_height < vo->dheight) { + if (vc->output_surface_width < vo->dwidth) { + vc->output_surface_width += vc->output_surface_width >> 1; + vc->output_surface_width = FFMAX(vc->output_surface_width, + vo->dwidth); } - if (output_surface_height < vo_dheight) { - output_surface_height += output_surface_height >> 1; - output_surface_height = FFMAX(output_surface_height, vo_dheight); + if (vc->output_surface_height < vo->dheight) { + vc->output_surface_height += vc->output_surface_height >> 1; + vc->output_surface_height = FFMAX(vc->output_surface_height, + vo->dheight); } // 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, - output_surface_width, output_surface_height, - &output_surfaces[i]); - CHECK_ST_WARNING("Error when calling vdp_output_surface_create") - mp_msg(MSGT_VO, MSGL_DBG2, "OUT CREATE: %u\n", output_surfaces[i]); + if (vc->output_surfaces[i] != VDP_INVALID_HANDLE) + vdp->output_surface_destroy(vc->output_surfaces[i]); + vdp_st = vdp->output_surface_create(vc->vdp_device, + VDP_RGBA_FORMAT_B8G8R8A8, + vc->output_surface_width, + vc->output_surface_height, + &vc->output_surfaces[i]); + CHECK_ST_WARNING("Error when calling vdp_output_surface_create"); + mp_msg(MSGT_VO, MSGL_DBG2, "OUT CREATE: %u\n", + vc->output_surfaces[i]); } } - video_to_output_surface(); - if (visible_buf) - flip_page(); + video_to_output_surface(vo); + if (vc->visible_buf) + flip_page(vo); } /* Initialize vdp_get_proc_address, called from preinit() */ -static int win_x11_init_vdpau_procs(void) +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[] = { - {VDP_FUNC_ID_GET_ERROR_STRING, &vdp_get_error_string}, - {VDP_FUNC_ID_DEVICE_DESTROY, &vdp_device_destroy}, - {VDP_FUNC_ID_VIDEO_SURFACE_CREATE, &vdp_video_surface_create}, - {VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, &vdp_video_surface_destroy}, - {VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, - &vdp_video_surface_put_bits_y_cb_cr}, - {VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE, - &vdp_output_surface_put_bits_native}, - {VDP_FUNC_ID_OUTPUT_SURFACE_CREATE, &vdp_output_surface_create}, - {VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY, &vdp_output_surface_destroy}, - {VDP_FUNC_ID_VIDEO_MIXER_CREATE, &vdp_video_mixer_create}, - {VDP_FUNC_ID_VIDEO_MIXER_DESTROY, &vdp_video_mixer_destroy}, - {VDP_FUNC_ID_VIDEO_MIXER_RENDER, &vdp_video_mixer_render}, - {VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES, - &vdp_video_mixer_set_feature_enables}, - {VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES, - &vdp_video_mixer_set_attribute_values}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY, - &vdp_presentation_queue_target_destroy}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE, &vdp_presentation_queue_create}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY, - &vdp_presentation_queue_destroy}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY, - &vdp_presentation_queue_display}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE, - &vdp_presentation_queue_block_until_surface_idle}, - {VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11, - &vdp_presentation_queue_target_create_x11}, - {VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE, - &vdp_output_surface_render_output_surface}, - {VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED, - &vdp_output_surface_put_bits_indexed}, - {VDP_FUNC_ID_DECODER_CREATE, &vdp_decoder_create}, - {VDP_FUNC_ID_DECODER_RENDER, &vdp_decoder_render}, - {VDP_FUNC_ID_DECODER_DESTROY, &vdp_decoder_destroy}, - {VDP_FUNC_ID_BITMAP_SURFACE_CREATE, &vdp_bitmap_surface_create}, - {VDP_FUNC_ID_BITMAP_SURFACE_DESTROY, &vdp_bitmap_surface_destroy}, - {VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE, - &vdp_bitmap_surface_putbits_native}, - {VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE, - &vdp_output_surface_render_bitmap_surface}, - {VDP_FUNC_ID_GENERATE_CSC_MATRIX, &vdp_generate_csc_matrix}, - {0, NULL} +#define VDP_FUNCTION(_, macro_name, mp_name) {macro_name, offsetof(struct vdp_functions, mp_name)}, +#include "vdpau_template.c" +#undef VDP_FUNCTION + {0, -1} }; - vdp_st = vdp_device_create(mDisplay, mScreen, - &vdp_device, &vdp_get_proc_address); + vdp_st = vc->vdp_device_create(x11->display, x11->screen,&vc->vdp_device, + &vc->vdp_get_proc_address); if (vdp_st != VDP_STATUS_OK) { - mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Error when calling vdp_device_create_x11: %i\n", vdp_st); + mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Error when calling " + "vdp_device_create_x11: %i\n", vdp_st); 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 = vc->vdp_get_proc_address(vc->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; } } return 0; } -/* Initialize vdpau_flip_queue, called from config() */ -static int win_x11_init_vdpau_flip_queue(void) +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, vo_window, - &vdp_flip_target); - CHECK_ST_ERROR("Error when calling vdp_presentation_queue_target_create_x11") + vdp_st = vdp->presentation_queue_target_create_x11(vc->vdp_device, + x11->window, + &vc->flip_target); + CHECK_ST_ERROR("Error when calling " + "vdp_presentation_queue_target_create_x11"); - vdp_st = vdp_presentation_queue_create(vdp_device, vdp_flip_target, - &vdp_flip_queue); - CHECK_ST_ERROR("Error when calling vdp_presentation_queue_create") + vdp_st = vdp->presentation_queue_create(vc->vdp_device, vc->flip_target, + &vc->flip_queue); + 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; @@ -408,95 +357,110 @@ static int create_vdp_mixer(VdpChromaType vdp_chroma_type) { int feature_count = 0; VdpVideoMixerFeature features[MAX_NUM_FEATURES]; VdpBool feature_enables[MAX_NUM_FEATURES]; - static const VdpVideoMixerAttribute denoise_attrib[] = {VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL}; - const void * const denoise_value[] = {&denoise}; - static const VdpVideoMixerAttribute sharpen_attrib[] = {VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL}; - const void * const sharpen_value[] = {&sharpen}; - static const VdpVideoMixerAttribute skip_chroma_attrib[] = {VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE}; + static const VdpVideoMixerAttribute denoise_attrib[] = + {VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL}; + const void * const denoise_value[] = {&vc->denoise}; + static const VdpVideoMixerAttribute sharpen_attrib[] = + {VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL}; + const void * const sharpen_value[] = {&vc->sharpen}; + static const VdpVideoMixerAttribute skip_chroma_attrib[] = + {VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE}; const uint8_t skip_chroma_value = 1; const void * const skip_chroma_value_ptr[] = {&skip_chroma_value}; static const VdpVideoMixerParameter parameters[VDP_NUM_MIXER_PARAMETER] = { VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT, - VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE + VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE, }; const void *const parameter_values[VDP_NUM_MIXER_PARAMETER] = { - &vid_width, - &vid_height, - &vdp_chroma_type + &vc->vid_width, + &vc->vid_height, + &vdp_chroma_type, }; features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL; - if (deint == 4) - features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL; - if (pullup) + if (vc->deint == 4) + features[feature_count++] = + VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL; + if (vc->pullup) features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE; - if (denoise) + if (vc->denoise) features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION; - if (sharpen) + if (vc->sharpen) features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_SHARPNESS; - vdp_st = vdp_video_mixer_create(vdp_device, feature_count, features, - VDP_NUM_MIXER_PARAMETER, - parameters, parameter_values, - &video_mixer); - CHECK_ST_ERROR("Error when calling vdp_video_mixer_create") + vdp_st = vdp->video_mixer_create(vc->vdp_device, feature_count, features, + VDP_NUM_MIXER_PARAMETER, + parameters, parameter_values, + &vc->video_mixer); + CHECK_ST_ERROR("Error when calling vdp_video_mixer_create"); - for (i = 0; i < feature_count; i++) feature_enables[i] = VDP_TRUE; - if (deint < 3) + for (i = 0; i < feature_count; i++) + feature_enables[i] = VDP_TRUE; + if (vc->deint < 3) feature_enables[0] = VDP_FALSE; if (feature_count) - 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); - if (sharpen) - 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_feature_enables(vc->video_mixer, feature_count, + features, feature_enables); + if (vc->denoise) + vdp->video_mixer_set_attribute_values(vc->video_mixer, 1, + denoise_attrib, denoise_value); + if (vc->sharpen) + vdp->video_mixer_set_attribute_values(vc->video_mixer, 1, + sharpen_attrib, sharpen_value); + if (!vc->chroma_deint) + vdp->video_mixer_set_attribute_values(vc->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); - decoder = VDP_INVALID_HANDLE; - decoder_max_refs = -1; + if (vc->decoder != VDP_INVALID_HANDLE) + vdp->decoder_destroy(vc->decoder); + vc->decoder = VDP_INVALID_HANDLE; + vc->decoder_max_refs = -1; for (i = 0; i < 3; i++) - deint_surfaces[i] = VDP_INVALID_HANDLE; + vc->deint_surfaces[i] = VDP_INVALID_HANDLE; for (i = 0; i < 2; i++) - if (deint_mpi[i]) { - deint_mpi[i]->usage_count--; - deint_mpi[i] = NULL; + if (vc->deint_mpi[i]) { + vc->deint_mpi[i]->usage_count--; + vc->deint_mpi[i] = NULL; } 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); - CHECK_ST_WARNING("Error when calling vdp_video_surface_destroy") + if (vc->surface_render[i].surface != VDP_INVALID_HANDLE) { + vdp_st = vdp->video_surface_destroy(vc->surface_render[i].surface); + CHECK_ST_WARNING("Error when calling vdp_video_surface_destroy"); } - surface_render[i].surface = VDP_INVALID_HANDLE; + vc->surface_render[i].surface = VDP_INVALID |