xine's output layer
Video output
In order to allow for device-dependant acceleration features, xine
calls upon the video output plugin for more than just displaying
images. The tasks performed by the video plugins are:
Allocation of vo_frame_t structures and their
subsequent destruction.
Allocation of memory for use by one frame (this is to allow
for the ability of some video output plugins to map frames directly
into video-card memory hence removing the need for the frame to
be copied across the PCI/AGP bus at display time).
Most important, the ability to render/copy a given
frame to the output device.
Optionally the copying of the frame from a file dependant
colour-space and depth into the frame structure. This is to allow for
on-the fly colour-space conversion and scaling if required (e.g. the XShm
ouput plugin uses this mechanism).
Although these extra responsibilities add great complexity to your
plugin it should be noted that they allow plugins to take full advantage
of any special hardware-acceleration without sacrificing flexibility.
Writing a xine video out plugin
The video out plugin API is declared in src/xine-engine/video_out.h
The plugin info of video out plugins contains the visual type, priority,
and the init_class function of the plugin.
The visual_type field is used by xine to
determine if the GUI used by the client is supported by the plugin
(e.g. X11 output plugins require the GUI to be running under the
X Windowing system) and also to determine the type of information passed to the
open_plugin() function as its visual parameter.
char *get_description(video_driver_class_t *this_gen);
This function returns a plaintext, one-line string describing the plugin.
char *get_identifier(video_driver_class_t *this_gen);
This function returns a shorter identifier describing the plugin.
void dispose(video_driver_class_t *this_gen);
This function frees the memory used by the video out plugin class object.
vo_driver_t *get_instance(video_driver_class_t *class_gen, const void *visual);
Returns an instance of the plugin.
The visual is a pointer to a visual-dependant
structure/variable. For example, if you had previously claimed your
plugin was of the VISUAL_TYPE_X11 type, this would be a pointer
to a x11_visual_t, which amongst other things hold the
Display variable associated with the
X-server xine should display to. See plugin source-code for other
VISUAL_TYPE_* constants and associated structures. Note that this
field is provided by the client application and so if you wish to add another visual
type you will either need to extend an existing client or write a new
one.
uint32_t get_capabilities(vo_driver_t *this_gen);
Returns a bit mask describing the output plugin's capabilities.
You may logically OR the VO_CAP_* constants together to get
a suitable bit-mask (via the '|' operator).
int get_property(vo_driver_t *self, int property);
int set_property(vo_driver_t *self, int property, int value);
void get_property_min_max(vo_driver_t *self, int property, int *min, int *max);
Handle the getting, setting of properties and define their bounds.
Valid property IDs can be found in the video_out.h
header file.
int gui_data_exchange(vo_driver_t *self, int data_type, void *data);
Accepts various forms of data from the UI (e.g. the mouse has moved or the
window has been hidden). Look at existing plugins for examples of data
exchanges from various UIs.
vo_frame_t *alloc_frame(vo_driver_t *self);
Returns a pointer to a xine video frame.
Typically the video plugin will add private fields to the end of the
vo_frame_t structure which are used for internal purposes by the plugin.
The function pointers within the frame structure provide a mechanism for the
driver to retain full control of how the frames are managed and rendered to. If
the VO_CAP_COPIES_IMAGE flag was set in the plugins capabilities then the
copy field is required and will be called sequentially for each 16-pixel high
strip in the image. The plugin may then decide, based on the frame's format, how
this is copied into the frame.
void update_frame_format(vo_driver_t *self, vo_frame_t *img, uint32_t width, uint32_t height, double ratio, int format, int flags);
This function will be called each time the colour-depth/space or size of a frame changes.
Typically this function would allocate sufficient memory for the frame, assign the pointers
to the individual planes of the frame to the base field of the
frame and perform any driver-specific changes.
void display_frame(vo_driver_t *self, vo_frame_t *vo_img);
Renders a given frame to the output device.
void overlay_begin(vo_driver_t *self, vo_frame_t *vo_img, int changed);
void overlay_blend(vo_driver_t *self, vo_frame_t *vo_img, vo_overlay_t *overlay);
void overlay_end(vo_driver_t *self, vo_frame_t *vo_img);
These are used to blend overlays on frames. overlay_begin() is called,
when the overlay appears for the first time, overlay_blend() is then
called for every subsequent frame and overlay_end() is called, when
the overlay should disappear again.
int redraw_needed(vo_driver_t *self);
Queries the driver, if the current frame needs to be drawn again.
void dispose(vo_driver_t *self);
Releases all resources and frees the plugin.