mirror of
https://github.com/mpv-player/mpv
synced 2024-12-25 08:12:17 +00:00
Merge branch 'vdpau' into build
* vdpau: (22 commits) VO: Prefer vo_vdpau over vo_xv again vo_vdpau: Fix X event handling bugs vo_vdpau: Fix memory corruption bug with MP_IMGTYPE_NUMBERED core/VO: Allow VO drivers to add/modify frames video_out.h: Cosmetics VO interface: Remove obsolete draw_frame() from new interface vo_vdpau: Support recovering from VDPAU display preemption vo_vdpau: Support updating OSD while paused vo_vdpau.c: Reindent control() switch statement vo_vdpau: Allocate one large surface for EOSD content vo_vdpau.c: cosmetics vo_vdpau: reindent after GUI code removal vo_vpdau: Clean up uninit logic vo_vdpau: Make CHECK_ST macro safer vo_vdpau: Move all remaining static/global variables to context vo_vdpau: Move things to context struct vo_vdpau: Make info struct const vo_vdpau: Replace global function table with context variable vo_vdpau: Move VDPAU interface pointers into one struct vo_vdpau: Add template file for VDPAU functions ...
This commit is contained in:
commit
3f215c9f8e
58
TOOLS/vdpau_functions.py
Normal file
58
TOOLS/vdpau_functions.py
Normal file
@ -0,0 +1,58 @@
|
||||
# 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
|
||||
bitmap_surface_query_capabilities
|
||||
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
|
||||
preemption_callback_register
|
||||
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))
|
@ -88,7 +88,6 @@ typedef struct vf_seteq_s
|
||||
#define VFCTRL_SCREENSHOT 14 /* Make a screenshot */
|
||||
#define VFCTRL_INIT_EOSD 15 /* Select EOSD renderer */
|
||||
#define VFCTRL_DRAW_EOSD 16 /* Render EOSD */
|
||||
#define VFCTRL_GET_PTS 17 /* Return last pts value that reached vf_vo*/
|
||||
#define VFCTRL_SET_DEINTERLACE 18 /* Set deinterlacing status */
|
||||
#define VFCTRL_GET_DEINTERLACE 19 /* Get deinterlacing status */
|
||||
/* Hack to make the OSD state object available to vf_expand which accesses
|
||||
|
@ -22,7 +22,6 @@ extern int sub_visibility;
|
||||
extern float sub_delay;
|
||||
|
||||
struct vf_priv_s {
|
||||
double pts;
|
||||
struct vo *vo;
|
||||
#ifdef CONFIG_ASS
|
||||
ASS_Renderer *ass_priv;
|
||||
@ -127,7 +126,7 @@ static int control(struct vf_instance* vf, int request, void* data)
|
||||
case VFCTRL_DRAW_EOSD:
|
||||
{
|
||||
mp_eosd_images_t images = {NULL, 2};
|
||||
double pts = vf->priv->pts;
|
||||
double pts = video_out->next_pts;
|
||||
if (!video_out->config_ok || !vf->priv->ass_priv) return CONTROL_FALSE;
|
||||
if (sub_visibility && vf->priv->ass_priv && ass_track && (pts != MP_NOPTS_VALUE)) {
|
||||
mp_eosd_res_t res;
|
||||
@ -148,11 +147,6 @@ static int control(struct vf_instance* vf, int request, void* data)
|
||||
return vo_control(video_out, VOCTRL_DRAW_EOSD, &images) == VO_TRUE;
|
||||
}
|
||||
#endif
|
||||
case VFCTRL_GET_PTS:
|
||||
{
|
||||
*(double *)data = vf->priv->pts;
|
||||
return CONTROL_TRUE;
|
||||
}
|
||||
}
|
||||
return CONTROL_UNKNOWN;
|
||||
}
|
||||
@ -179,10 +173,9 @@ static void get_image(struct vf_instance* vf,
|
||||
static int put_image(struct vf_instance* vf,
|
||||
mp_image_t *mpi, double pts){
|
||||
if(!video_out->config_ok) return 0; // vo not configured?
|
||||
// record pts (potentially modified by filters) for main loop
|
||||
vf->priv->pts = pts;
|
||||
// first check, maybe the vo/vf plugin implements draw_image using mpi:
|
||||
if (vo_control(video_out, VOCTRL_DRAW_IMAGE,mpi)==VO_TRUE) return 1; // done.
|
||||
if (vo_draw_image(video_out, mpi, pts) >= 0)
|
||||
return 1;
|
||||
// nope, fallback to old draw_frame/draw_slice:
|
||||
if(!(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK))){
|
||||
// blit frame:
|
||||
@ -210,6 +203,9 @@ static void draw_slice(struct vf_instance* vf,
|
||||
static void uninit(struct vf_instance* vf)
|
||||
{
|
||||
if (vf->priv) {
|
||||
/* Allow VO (which may live on to work with another instance of vf_vo)
|
||||
* to get rid of numbered-mpi references that will now be invalid. */
|
||||
vo_control(video_out, VOCTRL_RESET, NULL);
|
||||
#ifdef CONFIG_ASS
|
||||
if (vf->priv->ass_priv)
|
||||
ass_renderer_done(vf->priv->ass_priv);
|
||||
|
39
libvo/vdpau_template.c
Normal file
39
libvo/vdpau_template.c
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
/* 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(VdpBitmapSurfaceQueryCapabilities, VDP_FUNC_ID_BITMAP_SURFACE_QUERY_CAPABILITIES, bitmap_surface_query_capabilities)
|
||||
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(VdpPreemptionCallbackRegister, VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER, preemption_callback_register)
|
||||
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)
|
@ -21,6 +21,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <unistd.h>
|
||||
//#include <sys/mman.h>
|
||||
@ -31,6 +33,7 @@
|
||||
#include "video_out.h"
|
||||
#include "aspect.h"
|
||||
#include "geometry.h"
|
||||
#include "old_vo_wrapper.h"
|
||||
|
||||
#include "mp_msg.h"
|
||||
#include "help_mp.h"
|
||||
@ -162,12 +165,12 @@ const struct vo_driver *video_out_drivers[] =
|
||||
#ifdef CONFIG_3DFX
|
||||
&video_out_3dfx,
|
||||
#endif
|
||||
#ifdef CONFIG_XV
|
||||
&video_out_xv,
|
||||
#endif
|
||||
#if CONFIG_VDPAU
|
||||
&video_out_vdpau,
|
||||
#endif
|
||||
#ifdef CONFIG_XV
|
||||
&video_out_xv,
|
||||
#endif
|
||||
#ifdef CONFIG_X11
|
||||
&video_out_x11,
|
||||
&video_out_xover,
|
||||
@ -276,11 +279,41 @@ int vo_control(struct vo *vo, uint32_t request, void *data)
|
||||
return vo->driver->control(vo, request, data);
|
||||
}
|
||||
|
||||
int vo_draw_frame(struct vo *vo, uint8_t *src[])
|
||||
// Return -1 if driver appears not to support a draw_image interface,
|
||||
// 0 otherwise (whether the driver actually drew something or not).
|
||||
int vo_draw_image(struct vo *vo, struct mp_image *mpi, double pts)
|
||||
{
|
||||
if (!vo->config_ok)
|
||||
return 0;
|
||||
return vo->driver->draw_frame(vo, src);
|
||||
if (vo->driver->buffer_frames) {
|
||||
vo->driver->draw_image(vo, mpi, pts);
|
||||
return 0;
|
||||
}
|
||||
vo->frame_loaded = true;
|
||||
vo->next_pts = pts;
|
||||
if (vo_control(vo, VOCTRL_DRAW_IMAGE, mpi) == VO_NOTIMPL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vo_get_buffered_frame(struct vo *vo, bool eof)
|
||||
{
|
||||
if (!vo->config_ok)
|
||||
return -1;
|
||||
if (vo->frame_loaded)
|
||||
return 0;
|
||||
if (!vo->driver->buffer_frames)
|
||||
return -1;
|
||||
vo->driver->get_buffered_frame(vo, eof);
|
||||
return vo->frame_loaded ? 0 : -1;
|
||||
}
|
||||
|
||||
int vo_draw_frame(struct vo *vo, uint8_t *src[])
|
||||
{
|
||||
assert(!vo->driver->is_new);
|
||||
if (!vo->config_ok)
|
||||
return 0;
|
||||
return old_vo_draw_frame(vo, src);
|
||||
}
|
||||
|
||||
int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y)
|
||||
@ -299,6 +332,8 @@ void vo_flip_page(struct vo *vo)
|
||||
{
|
||||
if (!vo->config_ok)
|
||||
return;
|
||||
vo->frame_loaded = false;
|
||||
vo->next_pts = (-1LL<<63); // MP_NOPTS_VALUE
|
||||
vo->driver->flip_page(vo);
|
||||
}
|
||||
|
||||
@ -309,6 +344,14 @@ void vo_check_events(struct vo *vo)
|
||||
vo->driver->check_events(vo);
|
||||
}
|
||||
|
||||
void vo_seek_reset(struct vo *vo)
|
||||
{
|
||||
if (!vo->config_ok)
|
||||
return;
|
||||
vo_control(vo, VOCTRL_RESET, NULL);
|
||||
vo->frame_loaded = false;
|
||||
}
|
||||
|
||||
void vo_destroy(struct vo *vo)
|
||||
{
|
||||
vo->driver->uninit(vo);
|
||||
|
@ -24,7 +24,7 @@
|
||||
#define MPLAYER_VIDEO_OUT_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
//#include "font_load.h"
|
||||
#include "libmpcodecs/img_format.h"
|
||||
@ -117,91 +117,98 @@ typedef struct {
|
||||
|
||||
typedef struct vo_info_s
|
||||
{
|
||||
/* driver name ("Matrox Millennium G200/G400" */
|
||||
const char *name;
|
||||
/* short name (for config strings) ("mga") */
|
||||
const char *short_name;
|
||||
/* author ("Aaron Holtzman <aholtzma@ess.engr.uvic.ca>") */
|
||||
const char *author;
|
||||
/* any additional comments */
|
||||
const char *comment;
|
||||
/* driver name ("Matrox Millennium G200/G400" */
|
||||
const char *name;
|
||||
/* short name (for config strings) ("mga") */
|
||||
const char *short_name;
|
||||
/* author ("Aaron Holtzman <aholtzma@ess.engr.uvic.ca>") */
|
||||
const char *author;
|
||||
/* any additional comments */
|
||||
const char *comment;
|
||||
} vo_info_t;
|
||||
|
||||
struct vo;
|
||||
struct osd_state;
|
||||
struct mp_image;
|
||||
|
||||
struct vo_driver {
|
||||
// Driver uses new API
|
||||
int is_new;
|
||||
// Driver uses new API
|
||||
bool is_new;
|
||||
// Driver buffers or adds (deinterlace) frames and will keep track
|
||||
// of pts values itself
|
||||
bool buffer_frames;
|
||||
|
||||
// This is set if the driver is not new and contains pointers to
|
||||
// old-API functions to be used instead of the ones below.
|
||||
struct vo_old_functions *old_functions;
|
||||
// This is set if the driver is not new and contains pointers to
|
||||
// old-API functions to be used instead of the ones below.
|
||||
struct vo_old_functions *old_functions;
|
||||
|
||||
const vo_info_t *info;
|
||||
/*
|
||||
* Preinitializes driver (real INITIALIZATION)
|
||||
* arg - currently it's vo_subdevice
|
||||
* returns: zero on successful initialization, non-zero on error.
|
||||
*/
|
||||
int (*preinit)(struct vo *vo, const char *arg);
|
||||
/*
|
||||
* Initialize (means CONFIGURE) the display driver.
|
||||
* params:
|
||||
* width,height: image source size
|
||||
* d_width,d_height: size of the requested window size, just a hint
|
||||
* fullscreen: flag, 0=windowd 1=fullscreen, just a hint
|
||||
* title: window title, if available
|
||||
* format: fourcc of pixel format
|
||||
* returns : zero on successful initialization, non-zero on error.
|
||||
*/
|
||||
int (*config)(struct vo *vo, uint32_t width, uint32_t height,
|
||||
uint32_t d_width, uint32_t d_height, uint32_t fullscreen,
|
||||
char *title, uint32_t format);
|
||||
const vo_info_t *info;
|
||||
/*
|
||||
* Preinitializes driver (real INITIALIZATION)
|
||||
* arg - currently it's vo_subdevice
|
||||
* returns: zero on successful initialization, non-zero on error.
|
||||
*/
|
||||
int (*preinit)(struct vo *vo, const char *arg);
|
||||
/*
|
||||
* Initialize (means CONFIGURE) the display driver.
|
||||
* params:
|
||||
* width,height: image source size
|
||||
* d_width,d_height: size of the requested window size, just a hint
|
||||
* fullscreen: flag, 0=windowd 1=fullscreen, just a hint
|
||||
* title: window title, if available
|
||||
* format: fourcc of pixel format
|
||||
* returns : zero on successful initialization, non-zero on error.
|
||||
*/
|
||||
int (*config)(struct vo *vo, uint32_t width, uint32_t height,
|
||||
uint32_t d_width, uint32_t d_height, uint32_t fullscreen,
|
||||
char *title, uint32_t format);
|
||||
|
||||
/*
|
||||
* Control interface
|
||||
*/
|
||||
int (*control)(struct vo *vo, uint32_t request, void *data);
|
||||
/*
|
||||
* Control interface
|
||||
*/
|
||||
int (*control)(struct vo *vo, uint32_t request, void *data);
|
||||
|
||||
/*
|
||||
* Display a new RGB/BGR frame of the video to the screen.
|
||||
* params:
|
||||
* src[0] - pointer to the image
|
||||
*/
|
||||
int (*draw_frame)(struct vo *vo, uint8_t *src[]);
|
||||
void (*draw_image)(struct vo *vo, struct mp_image *mpi, double pts);
|
||||
|
||||
/*
|
||||
* Draw a planar YUV slice to the buffer:
|
||||
* params:
|
||||
* src[3] = source image planes (Y,U,V)
|
||||
* stride[3] = source image planes line widths (in bytes)
|
||||
* w,h = width*height of area to be copied (in Y pixels)
|
||||
* x,y = position at the destination image (in Y pixels)
|
||||
*/
|
||||
int (*draw_slice)(struct vo *vo, uint8_t *src[], int stride[], int w,
|
||||
int h, int x, int y);
|
||||
/*
|
||||
* Get extra frames from the VO, such as those added by VDPAU
|
||||
* deinterlace. Preparing the next such frame if any could be done
|
||||
* automatically by the VO after a previous flip_page(), but having
|
||||
* it as a separate step seems to allow making code more robust.
|
||||
*/
|
||||
void (*get_buffered_frame)(struct vo *vo, bool eof);
|
||||
|
||||
/*
|
||||
* Draws OSD to the screen buffer
|
||||
*/
|
||||
void (*draw_osd)(struct vo *vo, struct osd_state *osd);
|
||||
/*
|
||||
* Draw a planar YUV slice to the buffer:
|
||||
* params:
|
||||
* src[3] = source image planes (Y,U,V)
|
||||
* stride[3] = source image planes line widths (in bytes)
|
||||
* w,h = width*height of area to be copied (in Y pixels)
|
||||
* x,y = position at the destination image (in Y pixels)
|
||||
*/
|
||||
int (*draw_slice)(struct vo *vo, uint8_t *src[], int stride[], int w,
|
||||
int h, int x, int y);
|
||||
|
||||
/*
|
||||
* Blit/Flip buffer to the screen. Must be called after each frame!
|
||||
*/
|
||||
void (*flip_page)(struct vo *vo);
|
||||
/*
|
||||
* Draws OSD to the screen buffer
|
||||
*/
|
||||
void (*draw_osd)(struct vo *vo, struct osd_state *osd);
|
||||
|
||||
/*
|
||||
* This func is called after every frames to handle keyboard and
|
||||
* other events. It's called in PAUSE mode too!
|
||||
*/
|
||||
void (*check_events)(struct vo *vo);
|
||||
/*
|
||||
* Blit/Flip buffer to the screen. Must be called after each frame!
|
||||
*/
|
||||
void (*flip_page)(struct vo *vo);
|
||||
|
||||
/*
|
||||
* Closes driver. Should restore the original state of the system.
|
||||
*/
|
||||
void (*uninit)(struct vo *vo);
|
||||
/*
|
||||
* This func is called after every frames to handle keyboard and
|
||||
* other events. It's called in PAUSE mode too!
|
||||
*/
|
||||
void (*check_events)(struct vo *vo);
|
||||
|
||||
/*
|
||||
* Closes driver. Should restore the original state of the system.
|
||||
*/
|
||||
void (*uninit)(struct vo *vo);
|
||||
};
|
||||
|
||||
struct vo_old_functions {
|
||||
@ -221,6 +228,10 @@ struct vo_old_functions {
|
||||
struct vo {
|
||||
int config_ok; // Last config call was successful?
|
||||
int config_count; // Total number of successful config calls
|
||||
|
||||
bool frame_loaded; // Is there a next frame the VO could flip to?
|
||||
double next_pts; // pts value of the next frame if any
|
||||
|
||||
const struct vo_driver *driver;
|
||||
void *priv;
|
||||
struct MPOpts *opts;
|
||||
@ -258,11 +269,14 @@ int vo_config(struct vo *vo, uint32_t width, uint32_t height,
|
||||
void list_video_out(void);
|
||||
|
||||
int vo_control(struct vo *vo, uint32_t request, void *data);
|
||||
int vo_draw_image(struct vo *vo, struct mp_image *mpi, double pts);
|
||||
int vo_get_buffered_frame(struct vo *vo, bool eof);
|
||||
int vo_draw_frame(struct vo *vo, uint8_t *src[]);
|
||||
int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y);
|
||||
void vo_draw_osd(struct vo *vo, struct osd_state *osd);
|
||||
void vo_flip_page(struct vo *vo);
|
||||
void vo_check_events(struct vo *vo);
|
||||
void vo_seek_reset(struct vo *vo);
|
||||
void vo_destroy(struct vo *vo);
|
||||
|
||||
|
||||
|
@ -50,7 +50,6 @@ static int preinit(const char *);
|
||||
.preinit = old_vo_preinit,\
|
||||
.config = old_vo_config,\
|
||||
.control = old_vo_control,\
|
||||
.draw_frame = old_vo_draw_frame,\
|
||||
.draw_slice = old_vo_draw_slice,\
|
||||
.draw_osd = old_vo_draw_osd,\
|
||||
.flip_page = old_vo_flip_page,\
|
||||
|
1836
libvo/vo_vdpau.c
1836
libvo/vo_vdpau.c
File diff suppressed because it is too large
Load Diff
@ -518,11 +518,6 @@ static int draw_slice(struct vo *vo, uint8_t *image[], int stride[], int w,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int draw_frame(struct vo *vo, uint8_t *src[])
|
||||
{
|
||||
return VO_ERROR;
|
||||
}
|
||||
|
||||
static uint32_t draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
{
|
||||
struct xvctx *ctx = vo->priv;
|
||||
@ -840,7 +835,6 @@ const struct vo_driver video_out_xv = {
|
||||
.preinit = preinit,
|
||||
.config = config,
|
||||
.control = control,
|
||||
.draw_frame = draw_frame,
|
||||
.draw_slice = draw_slice,
|
||||
.draw_osd = draw_osd,
|
||||
.flip_page = flip_page,
|
||||
|
@ -204,6 +204,7 @@ int vo_config(struct vo *vo, uint32_t width, uint32_t height,
|
||||
uint32_t d_width, uint32_t d_height, uint32_t flags,
|
||||
char *title, uint32_t format) { abort(); }
|
||||
int vo_control(struct vo *vo, uint32_t request, void *data) { abort(); }
|
||||
int vo_draw_image(struct vo *vo, struct mp_image *mpi, double pts) { abort(); }
|
||||
int vo_draw_frame(struct vo *vo, uint8_t *src[]) { abort(); }
|
||||
int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y) { abort(); }
|
||||
void vo_draw_osd(struct vo *vo, struct osd_state *osd) { abort(); }
|
||||
|
@ -103,10 +103,6 @@ typedef struct MPContext {
|
||||
struct demux_stream *d_sub;
|
||||
mixer_t mixer;
|
||||
struct vo *video_out;
|
||||
// Frames buffered in the vo ready to flip. Currently always 0 or 1.
|
||||
// This is really a vo variable but currently there's no suitable vo
|
||||
// struct.
|
||||
int num_buffered_frames;
|
||||
|
||||
// Show a video frame as quickly as possible without trying to adjust
|
||||
// for AV sync. Used when starting a file or after seeking.
|
||||
|
27
mplayer.c
27
mplayer.c
@ -2266,6 +2266,7 @@ static double update_video_nocorrect_pts(struct MPContext *mpctx,
|
||||
static double update_video(struct MPContext *mpctx, int *blit_frame)
|
||||
{
|
||||
struct sh_video *sh_video = mpctx->sh_video;
|
||||
struct vo *video_out = mpctx->video_out;
|
||||
*blit_frame = 0;
|
||||
sh_video->vfilter->control(sh_video->vfilter, VFCTRL_SET_OSD_OBJ,
|
||||
mpctx->osd); // hack for vf_expand
|
||||
@ -2274,14 +2275,18 @@ static double update_video(struct MPContext *mpctx, int *blit_frame)
|
||||
|
||||
double pts;
|
||||
|
||||
while (1) {
|
||||
bool hit_eof = false;
|
||||
while (!video_out->frame_loaded) {
|
||||
current_module = "filter_video";
|
||||
if (vo_get_buffered_frame(video_out, hit_eof) >= 0)
|
||||
break;
|
||||
if (hit_eof)
|
||||
return -1;
|
||||
// XXX Time used in this call is not counted in any performance
|
||||
// timer now, OSD time is not updated correctly for filter-added frames
|
||||
if (vf_output_queued_frame(sh_video->vfilter))
|
||||
break;
|
||||
unsigned char *packet = NULL;
|
||||
bool hit_eof = false;
|
||||
int in_size = ds_get_packet_pts(mpctx->d_video, &packet, &pts);
|
||||
if (pts != MP_NOPTS_VALUE)
|
||||
pts += mpctx->video_offset;
|
||||
@ -2304,12 +2309,12 @@ static double update_video(struct MPContext *mpctx, int *blit_frame)
|
||||
update_osd_msg(mpctx);
|
||||
current_module = "filter video";
|
||||
if (filter_video(sh_video, decoded_frame, sh_video->pts))
|
||||
break;
|
||||
} else if (hit_eof)
|
||||
return -1;
|
||||
if (!video_out->config_ok)
|
||||
break; // We'd likely hang in this loop otherwise
|
||||
}
|
||||
}
|
||||
|
||||
sh_video->vfilter->control(sh_video->vfilter, VFCTRL_GET_PTS, &pts);
|
||||
pts = video_out->next_pts;
|
||||
if (pts == MP_NOPTS_VALUE) {
|
||||
mp_msg(MSGT_CPLAYER, MSGL_ERR, "Video pts after filters MISSING\n");
|
||||
// Try to use decoder pts from before filters
|
||||
@ -2565,11 +2570,9 @@ static int seek(MPContext *mpctx, double amount, int style)
|
||||
if (mpctx->sh_video) {
|
||||
current_module = "seek_video_reset";
|
||||
resync_video_stream(mpctx->sh_video);
|
||||
if (mpctx->video_out->config_ok)
|
||||
vo_control(mpctx->video_out, VOCTRL_RESET, NULL);
|
||||
vo_seek_reset(mpctx->video_out);
|
||||
mpctx->sh_video->num_buffered_pts = 0;
|
||||
mpctx->sh_video->last_pts = MP_NOPTS_VALUE;
|
||||
mpctx->num_buffered_frames = 0;
|
||||
mpctx->delay = 0;
|
||||
mpctx->time_frame = 0;
|
||||
mpctx->update_video_immediately = true;
|
||||
@ -3799,7 +3802,6 @@ if(verbose) term_osd = 0;
|
||||
|
||||
int frame_time_remaining=0; // flag
|
||||
int blit_frame=0;
|
||||
mpctx->num_buffered_frames=0;
|
||||
|
||||
// Make sure old OSD does not stay around,
|
||||
// e.g. with -fixed-vo and same-resolution files
|
||||
@ -3948,7 +3950,7 @@ if(!mpctx->sh_video) {
|
||||
vo_pts=mpctx->sh_video->timer*90000.0;
|
||||
vo_fps=mpctx->sh_video->fps;
|
||||
|
||||
if (!mpctx->num_buffered_frames) {
|
||||
if (!mpctx->video_out->frame_loaded) {
|
||||
double frame_time = update_video(mpctx, &blit_frame);
|
||||
mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"*** ftime=%5.3f ***\n",frame_time);
|
||||
if (mpctx->sh_video->vf_initialized < 0) {
|
||||
@ -3965,8 +3967,6 @@ if(!mpctx->sh_video) {
|
||||
if (frame_time < 0)
|
||||
mpctx->stop_play = AT_END_OF_FILE;
|
||||
else {
|
||||
// might return with !eof && !blit_frame if !correct_pts
|
||||
mpctx->num_buffered_frames += blit_frame;
|
||||
if (mpctx->update_video_immediately) {
|
||||
// Show this frame immediately, rest normally
|
||||
mpctx->update_video_immediately = false;
|
||||
@ -4018,7 +4018,6 @@ if(!mpctx->sh_video) {
|
||||
unsigned int t2=GetTimer();
|
||||
|
||||
vo_flip_page(mpctx->video_out);
|
||||
mpctx->num_buffered_frames--;
|
||||
|
||||
mpctx->last_vo_flip_duration = (GetTimer() - t2) * 0.000001;
|
||||
vout_time_usage += mpctx->last_vo_flip_duration;
|
||||
|
Loading…
Reference in New Issue
Block a user