Copyright © 2001-2003 the xine project team
You are currently looking at a piece of documentation for xine. xine is a free video player. It lives on http://xinehq.de/. Specifically this document goes under the moniker of the "xine Hackers' Guide".
This document should help xine hackers to find their way through xine's architecture and source code. It's a pretty free-form document containing a loose collection of articles describing various aspects of xine's internals. It has been written by a number of people who work on xine themselves and is intended to provide the important concepts and methods used within xine. Readers should not consider this document to be an exhausative description of the internals of xine. As with all projects which provide access, the source-code should be considered the definitive source of information.
This document is being developed in the xine-lib cvs repository within the directory doc/hackersguide/. If you are unsure what to do with the stuff in that directory, please read the README file located there.
New versions of this document can also be obtained from the xine web site: http://xinehq.de/.
All comments, error reports, additional information and criticism
concerning this document should be directed to the xine documentations
mailing list <xine-docs@lists.sourceforge.net>.
Questions about xine hacking in general should be sent to the
developer mailing list <xine-devel@lists.sourceforge.net>.
The following drawing shows the components of xine as outside applications see them. For every component, the functions for creating and destroying it are given. Every other function works in the context it is enclosed in. Functions that facilitate the connection of the individual components are also given.

outside view on xine components
The function are named just to give you an overview of what is actually there. It is all thoroughly documented in the plublic header xine.h, which is the main and preferably the only xine header, clients should include. (xine/xineutils.h and the XML parser might make an exception.)
Details on the OSD feature can be found in the OSD section.
The best way to explain this seems to be actual code. Below you will find a very easy and hopefully self-explaining xine frontend to give you a start.
One important thing to note is that any X11 based xine-lib frontend
must call XInitThreads() before calling the
first Xlib function, because xine will access the display from
within a different thread than the frontend.
/*
** Copyright (C) 2003 Daniel Caujolle-Bert <segfault@club-internet.fr>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
*/
/*
* compile-command: "gcc -Wall -O2 `xine-config --cflags` `xine-config --libs` -L/usr/X11R6/lib -lX11 -lm -o xinimin xinimin.c"
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/extensions/XShm.h>
#include <xine.h>
#include <xine/xineutils.h>
#define MWM_HINTS_DECORATIONS (1L << 1)
#define PROP_MWM_HINTS_ELEMENTS 5
typedef struct {
uint32_t flags;
uint32_t functions;
uint32_t decorations;
int32_t input_mode;
uint32_t status;
} MWMHints;
static xine_t *xine;
static xine_stream_t *stream;
static xine_video_port_t *vo_port;
static xine_audio_port_t *ao_port;
static xine_event_queue_t *event_queue;
static Display *display;
static int screen;
static Window window[2];
static int xpos, ypos, width, height, fullscreen;
static double pixel_aspect;
static int running = 1;
#define INPUT_MOTION (ExposureMask | ButtonPressMask | KeyPressMask | \
ButtonMotionMask | StructureNotifyMask | \
PropertyChangeMask | PointerMotionMask)
/* this will be called by xine, if it wants to know the target size of a frame */
static void dest_size_cb(void *data, int video_width, int video_height, double video_pixel_aspect,
int *dest_width, int *dest_height, double *dest_pixel_aspect) {
*dest_width = width;
*dest_height = height;
*dest_pixel_aspect = pixel_aspect;
}
/* this will be called by xine when it's about to draw the frame */
static void frame_output_cb(void *data, int video_width, int video_height,
double video_pixel_aspect, int *dest_x, int *dest_y,
int *dest_width, int *dest_height,
double *dest_pixel_aspect, int *win_x, int *win_y) {
*dest_x = 0;
*dest_y = 0;
*win_x = xpos;
*win_y = ypos;
*dest_width = width;
*dest_height = height;
*dest_pixel_aspect = pixel_aspect;
}
static void event_listener(void *user_data, const xine_event_t *event) {
switch(event->type) {
case XINE_EVENT_UI_PLAYBACK_FINISHED:
running = 0;
break;
case XINE_EVENT_PROGRESS:
{
xine_progress_data_t *pevent = (xine_progress_data_t *) event->data;
printf("%s [%d%%]\n", pevent->description, pevent->percent);
}
break;
/* you can handle a lot of other interesting events here */
}
}
int main(int argc, char **argv) {
char configfile[2048];
x11_visual_t vis;
double res_h, res_v;
char *vo_driver = "auto";
char *ao_driver = "auto";
char *mrl = NULL;
int i;
Atom XA_NO_BORDER;
MWMHints mwmhints;
/* parsing command line */
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-vo") == 0) {
vo_driver = argv[++i];
}
else if (strcmp(argv[i], "-ao") == 0) {
ao_driver = argv[++i];
}
else
mrl = argv[i];
}
if (!mrl) {
printf("specify an mrl\n");
return 1;
}
printf("mrl: '%s'\n", mrl);
if (!XInitThreads()) {
printf("XInitThreads() failed\n");
return 1;
}
/* load xine config file and init xine */
xine = xine_new();
snprintf(configfile, sizeof(configfile), "%s%s", xine_get_homedir(), "/.xine/config");
xine_config_load(xine, configfile);
xine_init(xine);
display = XOpenDisplay(NULL);
screen = XDefaultScreen(display);
xpos = 0;
ypos = 0;
width = 320;
height = 200;
/* some initalization for the X11 Window we will be showing video in */
XLockDisplay(display);
fullscreen = 0;
window[0] = XCreateSimpleWindow(display, XDefaultRootWindow(display),
xpos, ypos, width, height, 1, 0, 0);
window[1] = XCreateSimpleWindow(display, XDefaultRootWindow(display),
0, 0, (DisplayWidth(display, screen)),
(DisplayHeight(display, screen)), 0, 0, 0);
XSelectInput(display, window[0], INPUT_MOTION);
XSelectInput(display, window[1], INPUT_MOTION);
XA_NO_BORDER = XInternAtom(display, "_MOTIF_WM_HINTS", False);
mwmhints.flags = MWM_HINTS_DECORATIONS;
mwmhints.decorations = 0;
XChangeProperty(display, window[1],
XA_NO_BORDER, XA_NO_BORDER, 32, PropModeReplace, (unsigned char *) &mwmhints,
PROP_MWM_HINTS_ELEMENTS);
XMapRaised(display, window[fullscreen]);
res_h = (DisplayWidth(display, screen) * 1000 / DisplayWidthMM(display, screen));
res_v = (DisplayHeight(display, screen) * 1000 / DisplayHeightMM(display, screen));
XSync(display, False);
XUnlockDisplay(display);
/* filling in the xine visual struct */
vis.display = display;
vis.screen = screen;
vis.d = window[fullscreen];
vis.dest_size_cb = dest_size_cb;
vis.frame_output_cb = frame_output_cb;
vis.user_data = NULL;
pixel_aspect = res_v / res_h;
/* opening xine output ports */
vo_port = xine_open_video_driver(xine, vo_driver, XINE_VISUAL_TYPE_X11, (void *)&vis);
ao_port = xine_open_audio_driver(xine , ao_driver, NULL);
/* open a xine stream connected to these ports */
stream = xine_stream_new(xine, ao_port, vo_port);
/* hook our event handler into the streams events */
event_queue = xine_event_new_queue(stream);
xine_event_create_listener_thread(event_queue, event_listener, NULL);
/* make the video window visible to xine */
xine_port_send_gui_data(vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED, (void *) window[fullscreen]);
xine_port_send_gui_data(vo_port, XINE_GUI_SEND_VIDEOWIN_VISIBLE, (void *) 1);
/* start playback */
if (!xine_open(stream, mrl) || !xine_play(stream, 0, 0)) {
printf("Unable to open mrl '%s'\n", mrl);
return 1;
}
while (running) {
XEvent xevent;
int got_event;
XLockDisplay(display);
got_event = XPending(display);
if( got_event )
XNextEvent(display, &xevent);
XUnlockDisplay(display);
if( !got_event ) {
xine_usec_sleep(20000);
continue;
}
switch(xevent.type) {
case KeyPress:
{
XKeyEvent kevent;
KeySym ksym;
char kbuf[256];
int len;
kevent = xevent.xkey;
XLockDisplay(display);
len = XLookupString(&kevent, kbuf, sizeof(kbuf), &ksym, NULL);
XUnlockDisplay(display);
switch (ksym) {
case XK_q:
case XK_Q:
/* user pressed q => quit */
running = 0;
break;
case XK_f:
case XK_F:
{
/* user pressed f => toggle fullscreen */
Window tmp_win;
XLockDisplay(display);
XUnmapWindow(display, window[fullscreen]);
fullscreen = !fullscreen;
XMapRaised(display, window[fullscreen]);
XSync(display, False);
XTranslateCoordinates(display, window[fullscreen],
DefaultRootWindow(display),
0, 0, &xpos, &ypos, &tmp_win);
XUnlockDisplay(display);
xine_port_send_gui_data(vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED,
(void*) window[fullscreen]);
}
break;
case XK_Up:
/* cursor up => increase volume */
xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME,
(xine_get_param(stream, XINE_PARAM_AUDIO_VOLUME) + 1));
break;
case XK_Down:
/* cursor down => decrease volume */
xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME,
(xine_get_param(stream, XINE_PARAM_AUDIO_VOLUME) - 1));
break;
case XK_plus:
/* plus => next audio channel */
xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL,
(xine_get_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL) + 1));
break;
case XK_minus:
/* minus => previous audio channel */
xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL,
(xine_get_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL) - 1));
break;
case XK_space:
/* space => toggle pause mode */
if (xine_get_param(stream, XINE_PARAM_SPEED) != XINE_SPEED_PAUSE)
xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
else
xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
break;
}
}
break;
case Expose:
/* this handles (partial) occlusion of our video window */
if (xevent.xexpose.count != 0)
break;
xine_port_send_gui_data(vo_port, XINE_GUI_SEND_EXPOSE_EVENT, &xevent);
break;
case ConfigureNotify:
{
XConfigureEvent *cev = (XConfigureEvent *) &xevent;
Window tmp_win;
width = cev->width;
height = cev->height;
if ((cev->x == 0) && (cev->y == 0)) {
XLockDisplay(display);
XTranslateCoordinates(display, cev->window,
DefaultRootWindow(cev->display),
0, 0, &xpos, &ypos, &tmp_win);
XUnlockDisplay(display);
} else {
xpos = cev->x;
ypos = cev->y;
}
}
break;
}
}
/* cleanup */
xine_close(stream);
xine_event_dispose_queue(event_queue);
xine_dispose(stream);
xine_close_audio_driver(xine, ao_port);
xine_close_video_driver(xine, vo_port);
xine_exit(xine);
XLockDisplay(display);
XUnmapWindow(display, window[fullscreen]);
XDestroyWindow(display, window[0]);
XDestroyWindow(display, window[1]);
XUnlockDisplay(display);
XCloseDisplay (display);
return 0;
} |
The src/ directory in xine-lib contains several modules, this should give you a quick overview on where to find what sources.
Directories marked with "(imported)" contain code that is copied from an external project into xine-lib. Everything below such a directory is up to this project. When modifying code there, be sure to send the patches on. If some xine specific adaptation of the code is absolutely necessary, a patch containing the changes should be stored in CVS to not loose the changes the next time we sync with the external project.
Audio output plugins. These provide a thin abstraction layer around different types of audio output architectures or platforms. Basically an audio output plugin provides functions to query and setup the audio hardware and output audio data (e.g. PCM samples).
Demuxer plugins that handle various system layer file formats like avi, asf or mpeg. The ideal demuxer know nothing about where the data comes from and who decodes it. It should basically just unpack it into chunks the rest of the engine can eat.
Code to support the DXR3 / hollywood+ hardware mpeg decoder.
Input plugins encapsulate the origin of the data. Data sources like ordinary files, DVDs, CDA or streaming media are handled here.
Some headers for Digital Video Broadcast.
The libdvdnav library for DVD navigation is used by xine's DVD input plugin.
Support for RealMedia streaming as used by the RTSP input plugin.
The enhanced VCD input plugin which also handles VCD navigation.
Libraries used by the enhanced VCD plugin.
A52 (aka AC3, aka Dolby Digital) audio decoder library and xine plugin.
We maintain some small integration improving differences between the original liba52 and our copy in the file diff_against_release.patch.
AC5 (aka DTS) audio decoder library and xine plugin, which is capable of software decoding as well as digital passthrough.
The Free AAC Decoder library and xine plugin.
A xine decoder plugin using various audio and video decoders from the ffmpeg decoder pack libavcodec. Their MPEG encoder is also for the DXR3.
To optimize the integration of libavcodec and the xine engine, we maintain some differences between the original ffmpeg and our copy in the file diff_to_ffmpeg_cvs.txt.
The libavcodec decoder pack as used by xine's ffmpeg plugin.
A xine demuxer and decoder plugin for the Free Lossless Audio Codec library, which has to be installed separately.
Audio decoder plugin that "decodes" raw PCM data; most notably endianess-conversions are done here.
Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). ISO/IEC compliant decoder using fixed point math.
Most important MPEG video decoder plugin, provides fast and high-precision MPEG-1/2 video decoding.
Although this is an imported library, we have heavily modified our internal copy to blend it as seamlessly as possible into the xine engine in order to get the maximum MPEG decoding performance.
James started an effort to bring a recent and unmodified version of libmpeg2 into xine to one day replace our current internal modified libmpeg2 with one closer to the original. But since the full feature catalog has not yet been achieved with the new one, it is still disabled.
The code of the imported new libmpeg2.
A thin wrapper around Real's binary codecs from the Linux RealPlayer to use them as a xine plugin.
A xine decoder plugin for the speex library, which has to be installed separately.
Closed caption subtitle decoder plugin.
DVD SPU subtitle decoder plugin.
Plain text subtitle decoder plugins.
A xine decoder plugin for the theora library, which has to be installed separately.
A xine decoder plugin for the ogg/vorbis library, which has to be installed separately.
Video and audio decoder plugins that exploit some wine code to use win32 (media player and Quicktime) codecs in xine. Works on x86 platforms only.
Stripped down version of wine to support Video for Windows DLLs and additional code to use DirectShow, DMO and QuickTime DLLs.
xine's decoder pack of additional audio decoders.
The gsm610 audio decoder library as used by the related xine plugin.
The nosefart audio decoder library as used by the related xine plugin.
xine's decoder pack of additional video decoders.
Video and audio post effect plugins live here. Post plugins modify streams of video frames or audio buffers as they leave the decoder to provide conversion or effects.
Some audio effects as xine audio filter posts.
The tvtime deinterlacer as a xine video filter post.
The goom audio visualizer as a xine visualizer post.
Some post plugins merging multiple frames into one. For example picture in picture can be done with this.
Some simple 2D video effects as xine video filter posts.
Audio visualization post plugins.
Contains various video output driver plugins. Video output drivers are thin abstraction layers over various video output platforms (e.g. X11, directfb, directX,...). Video output driver plugins provide functions like frame allocation and drawing and handle stuff like hardware acceleration, scaling and colorspace conversion if necessary. They do not handle a/v sync since this is done in the xine-engine already.
A library for direct hardware access to the graphics card as used by the vidix video out plugin.
The vidix system for high performance video output as used by the vidix video out plugin.
The heart of xine - it's engine. Contains code to load and handle all the plugins, the configuration repository as well as the generic decoding loops and code for synchronized output. A lot of helper functions for plugins to use live here as well. What's in the individual files should be guessable by the files' names. This document is not going to explain the source, because it simply changes too often. A look at the architectural drawing in the internals section should give you a pretty good idea, what to expect in this directory. Basically, everything in this picture that is not called "plugin" lives here.
Collection of utility functions and platform abstractions. Also contains a simple XML parser for frontend playlist handling.
xine uses a lot of design principles normally found in object oriented designs. As xine is written in C, a few basic principles shall be explained here on how xine is object oriented anyway.
Classes are structs containing function pointers and public member data. Example:
typedef struct my_stack_s my_class_t;
struct my_stack_s {
/* method "push" with one parameter and no return value */
void (*push)(my_stack_t *this, int i);
/* method "add" with no parameters and no return value */
void (*add)(my_stack_t *this);
/* method "pop" with no parameters (except "this") and a return value */
int (*pop) (my_stack_t *this);
};
/* constructor */
my_class_t *new_my_stack(void); |
To derive from such a class, private member variables can be added:
typedef struct {
my_stack_t stack; /* public part */
/* private part follows here */
int values[MAX_STACK_SIZE];
int stack_size;
} intstack_t; |
Implementation of the "push" method follows:
static void push (my_stack_t *this_gen, int i) {
intstack_t *this = (intstack_t *)this_gen;
this->values[MAX_STACK_SIZE - ++this->stack_size] = i;
} |
The part added to the derived class is private, because when defining the new structure directly in the .c file, where it will be used, outside modules have no way of seeing the definition of the derived class. A public derivation is possible by defining the above structure in a .h file for others to include.
Something similar to a protected, package or friend visibility is also possible:
struct my_stack_s {
void (*push)(my_stack_t *this, int i);
void (*add)(my_stack_t *this);
int (*pop)(my_stack_t *this);
#ifdef STACK_INTERNAL
void (*flush)(my_stack_t *this);
#endif
}; |
#define STACK_INTERNAL |
Finally the contructor malloc()s the data struct (private variant) and fills in function pointers and default values. Usually the constructor is the only public (i.e. non-static) function in the module:
my_stack_t *new_my_stack(void) {
intstack_t *this;
/* alloc memory */
this = malloc(sizeof(intstack_t));
/* fill in methods */
this->push = push;
this->add = add;
this->pop = pop;
/* init data fields */
this->stack_size = 0;
/* return public part */
return &this->stack;
} |
After all these considerations about object oriented C, you might ask, why we do not use C++ after all? The easy answer would be: xine wants to be as fast as possible and C++ is simply too slow. But this is only the easy answer and it is not entirely true any more. Thoughtfully applied, you can write very fast C++ code with today's compilers, but these compilers might not be available on all platforms in the necessary quality. Even with a sophisticated compiler, C++ is much harder to optimize than plain C and thus C compiles much faster. Another big problem is that the C++ ABI is not as well-defined as the C ABI. With C, you can easily mix libraries and applications built by different compilers. With C++, this is unlikely to work. But the final argument is that xine does not really need C++. xine's inheritance hierarchy is very flat, mostly one level only and does not need things like multiple or virtual inheritance. Most of the external projects that are used by xine are plain C as well and using more than one language complicates the build system. As we saw above, we can emulate object orientation reduced to our real needs in plain C.
This section contains some guidelines for writing xine-code. These are really just guidelines, no strict rules. Contributions will not be rejected if they do not meet these rules but they will be even more appreciated if they do.
Comment your interfaces directly in the header files. No doxygen comments, ordinary C comments will do.
Use C-style comments (/* */), not C++-style (//).
When in doubt, use lower case. BTW: This thing is called xine, never Xine.
Use expressive variable and function identifiers on all public interfaces. Use underscores to seperate words in identifiers, not uppercase letters (my_function_name is ok, myFunctionName is not ok).
Avoid macros unless they are really useful. Avoid gotos.
use something like
printf("module: ..."[,...]); |
Refer to emac's C-mode for all questions of proper indentiation. That first of all means: indent with two spaces.
xine offers a wide range of possibilities to display strings. This section should describe when to use which way and how to do it right.
Output which is done thru this function will be
displayed for the end user by the frontend.
If xine->verbosity is not 0 the messages will also
be displayed I_SEND_ibffmpeg
A xine decoder plugin using various audio and video decoders from the ffmpeg decoder pack libavcodec. Their MPEG encoder is also for the DXR3.
To optimize the integration of libavcodec and the xine engine, we maintain some differences between the original ffmpeg and our copy in the file diff_to_ffmpeg_cvs.txt.
The libavcodec decoder pack as used by xine's ffmpeg plugin.
A xine demuxer and decoder plugin for the Free Lossless Audio Codec library, which has to be installed separately.
Audio decoder plugin that "decodes" raw PCM data; most notably endianess-conversions are done here.
Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). ISO/IEC compliant decoder using fixed point math.
Most important MPEG video decoder plugin, provides fast and high-precision MPEG-1/2 video decoding.
Although this is an imported library, we have heavily modified our internal copy to blend it as seamlessly as possible into the xine engine in order to get the maximum MPEG decoding performance.
James started an effort to bring a recent and unmodified version of libmpeg2 into xine to one day replace our current internal modified libmpeg2 with one closer to the original. But since the full feature catalog has not yet been achieved with the new one, it is still disabled.
The code of the imported new libmpeg2.
A thin wrapper around Real's binary codecs from the Linux RealPlayer to use them as a xine plugin.
A xine decoder plugin for the speex library, which has to be installed separately.
Closed caption subtitle decoder plugin.
DVD SPU subtitle decoder plugin.
Plain text subtitle decoder plugins.
A xine decoder plugin for the theora library, which has to be installed separately.
A xine decoder plugin for the ogg/vorbis library, which has to be installed separately.
Video and audio decoder plugins that exploit some wine code to use win32 (media player and Quicktime) codecs in xine. Works on x86 platforms only.
Stripped down version of wine to support Video for Windows DLLs and additional code to use DirectShow, DMO and QuickTime DLLs.
xine's decoder pack of additional audio decoders.
The gsm610 audio decoder library as used by the related xine plugin.
The nosefart audio decoder library as used by the related xine plugin.
xine's decoder pack of additional video decoders.
Video and audio post effect plugins live here. Post plugins modify streams of video frames or audio buffers as they leave the decoder to provide conversion or effects.
Some audio effects as xine audio filter posts.
The tvtime deinterlacer as a xine video filter post.
The goom audio visualizer as a xine visualizer post.
Some post plugins merging multiple frames into one. For example picture in picture can be done with this.
Some simple 2D video effects as xine video filter posts.
Audio visualization post plugins.
Contains various video output driver plugins. Video output drivers are thin abstraction layers over various video output platforms (e.g. X11, directfb, directX,...). Video output driver plugins provide functions like frame allocation and drawing and handle stuff like hardware acceleration, scaling and colorspace conversion if necessary. They do not handle a/v sync since this is done in the xine-engine already.
A library for direct hardware access to the graphics card as used by the vidix video out plugin.
The vidix system for high performance video output as used by the vidix video out plugin.
The heart of xine - it's engine. Contains code to load and handle all the plugins, the configuration repository as well as the generic decoding loops and code for synchronized output. A lot of helper functions for plugins to use live here as well. What's in the individual files should be guessable by the files' names. This document is not going to explain the source, because it simply changes too often. A look at the architectural drawing in the internals section should give you a pretty good idea, what to expect in this directory. Basically, everything in this picture that is not called "plugin" lives here.
Collection of utility functions and platform abstractions. Also contains a simple XML parser for frontend playlist handling.
xine uses a lot of design principles normally found in object oriented designs. As xine is written in C, a few basic principles shall be explained here on how xine is object oriented anyway.
Classes are structs containing function pointers and public member data. Example:
typedef struct my_stack_s my_class_t;
struct my_stack_s {
/* method "push" with one parameter and no return value */
void (*push)(my_stack_t *this, int i);
/* method "add" with no parameters and no return value */
void (*add)(my_stack_t *this);
/* method "pop" with no parameters (except "this") and a return value */
int (*pop) (my_stack_t *this);
};
/* constructor */
my_class_t *new_my_stack(void); |
To derive from such a class, private member variables can be added:
typedef struct {
my_stack_t stack; /* public part */
/* private part follows here */
int values[MAX_STACK_SIZE];
int stack_size;
} intstack_t; |
Implementation of the "push" method follows:
static void push (my_stack_t *this_gen, int i) {
intstack_t *this = (intstack_t *)this_gen;
this->values[MAX_STACK_SIZE - ++this->stack_size] = i;
} |
The part added to the derived class is private, because when defining the new structure directly in the .c file, where it will be used, outside modules have no way of seeing the definition of the derived class. A public derivation is possible by defining the above structure in a .h file for others to include.
Something similar to a protected, package or friend visibility is also possible:
struct my_stack_s {
void (*push)(my_stack_t *this, int i);
void (*add)(my_stack_t *this);
int (*pop)(my_stack_t *this);
#ifdef STACK_INTERNAL
void (*flush)(my_stack_t *this);
#endif
}; |
#define STACK_INTERNAL |
Finally the contructor malloc()s the data struct (private variant) and fills in function pointers and default values. Usually the constructor is the only public (i.e. non-static) function in the module:
my_stack_t *new_my_stack(void) {
intstack_t *this;
/* alloc memory */
this = malloc(sizeof(intstack_t));
/* fill in methods */
this->push = push;
this->add = add;
this->pop = pop;
/* init data fields */
this->stack_size = 0;
/* return public part */
return &this->stack;
} |
After all these considerations about object oriented C, you might ask, why we do not use C++ after all? The easy answer would be: xine wants to be as fast as possible and C++ is simply too slow. But this is only the easy answer and it is not entirely true any more. Thoughtfully applied, you can write very fast C++ code with today's compilers, but these compilers might not be available on all platforms in the necessary quality. Even with a sophisticated compiler, C++ is much harder to optimize than plain C and thus C compiles much faster. Another big problem is that the C++ ABI is not as well-defined as the C ABI. With C, you can easily mix libraries and applications built by different compilers. With C++, this is unlikely to work. But the final argument is that xine does not really need C++. xine's inheritance hierarchy is very flat, mostly one level only and does not need things like multiple or virtual inheritance. Most of the external projects that are used by xine are plain C as well and using more than one language complicates the build system. As we saw above, we can emulate object orientation reduced to our real needs in plain C.
This section contains some guidelines for writing xine-code. These are really just guidelines, no strict rules. Contributions will not be rejected if they do not meet these rules but they will be even more appreciated if they do.
Comment your interfaces directly in the header files. No doxygen comments, ordinary C comments will do.
Use C-style comments (/* */), not C++-style (//).
When in doubt, use lower case. BTW: This thing is called xine, never Xine.
Use expressive variable and function identifiers on all public interfaces. Use underscores to seperate words in identifiers, not uppercase letters (my_function_name is ok, myFunctionName is not ok).
Avoid macros unless they are really useful. Avoid gotos.
use something like
printf("module: ..."[,...]); |
Refer to emac's C-mode for all questions of proper indentiation. That first of all means: indent with two spaces.
xine offers a wide range of possibilities to display strings. This section should describe when to use which way and how to do it right.
Output which is done thru this function will be
displayed for the end user by the frontend.
If xine->verbosity is not 0 the messages will also
be displayed I_SEND_ibffmpeg
A xine decoder plugin using various audio and video decoders from the ffmpeg decoder pack libavcodec. Their MPEG encoder is also for the DXR3.
To optimize the integration of libavcodec and the xine engine, we maintain some differences between the original ffmpeg and our copy in the file diff_to_ffmpeg_cvs.txt.
The libavcodec decoder pack as used by xine's ffmpeg plugin.
A xine demuxer and decoder plugin for the Free Lossless Audio Codec library, which has to be installed separately.
Audio decoder plugin that "decodes" raw PCM data; most notably endianess-conversions are done here.
Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). ISO/IEC compliant decoder using fixed point math.
Most important MPEG video decoder plugin, provides fast and high-precision MPEG-1/2 video decoding.
Although this is an imported library, we have heavily modified our internal copy to blend it as seamlessly as possible into the xine engine in order to get the maximum MPEG decoding performance.
James started an effort to bring a recent and unmodified version of libmpeg2 into xine to one day replace our current internal modified libmpeg2 with one closer to the original. But since the full feature catalog has not yet been achieved with the new one, it is still disabled.
The code of the imported new libmpeg2.
A thin wrapper around Real's binary codecs from the Linux RealPlayer to use them as a xine plugin.
A xine decoder plugin for the speex library, which has to be installed separately.
Closed caption subtitle decoder plugin.
DVD SPU subtitle decoder plugin.
Plain text subtitle decoder plugins.
A xine decoder plugin for the theora library, which has to be installed separately.
A xine decoder plugin for the ogg/vorbis library, which has to be installed separately.
Video and audio decoder plugins that exploit some wine code to use win32 (media player and Quicktime) codecs in xine. Works on x86 platforms only.
Stripped down version of wine to support Video for Windows DLLs and additional code to use DirectShow, DMO and QuickTime DLLs.
xine's decoder pack of additional audio decoders.
The gsm610 audio decoder library as used by the related xine plugin.
The nosefart audio decoder library as used by the related xine plugin.
xine's decoder pack of additional video decoders.
Video and audio post effect plugins live here. Post plugins modify streams of video frames or audio buffers as they leave the decoder to provide conversion or effects.
Some audio effects as xine audio filter posts.
The tvtime deinterlacer as a xine video filter post.
The goom audio visualizer as a xine visualizer post.
Some post plugins merging multiple frames into one. For example picture in picture can be done with this.
Some simple 2D video effects as xine video filter posts.
Audio visualization post plugins.
Contains various video output driver plugins. Video output drivers are thin abstraction layers over various video output platforms (e.g. X11, directfb, directX,...). Video output driver plugins provide functions like frame allocation and drawing and handle stuff like hardware acceleration, scaling and colorspace conversion if necessary. They do not handle a/v sync since this is done in the xine-engine already.
A library for direct hardware access to the graphics card as used by the vidix video out plugin.
The vidix system for high performance video output as used by the vidix video out plugin.
The heart of xine - it's engine. Contains code to load and handle all the plugins, the configuration repository as well as the generic decoding loops and code for synchronized output. A lot of helper functions for plugins to use live here as well. What's in the individual files should be guessable by the files' names. This document is not going to explain the source, because it simply changes too often. A look at the architectural drawing in the internals section should give you a pretty good idea, what to expect in this directory. Basically, everything in this picture that is not called "plugin" lives here.
Collection of utility functions and platform abstractions. Also contains a simple XML parser for frontend playlist handling.
xine uses a lot of design principles normally found in object oriented designs. As xine is written in C, a few basic principles shall be explained here on how xine is object oriented anyway.
Classes are structs containing function pointers and public member data. Example:
typedef struct my_stack_s my_class_t;
struct my_stack_s {
/* method "push" with one parameter and no return value */
void (*push)(my_stack_t *this, int i);
/* method "add" with no parameters and no return value */
void (*add)(my_stack_t *this);
/* method "pop" with no parameters (except "this") and a return value */
int (*pop) (my_stack_t *this);
};
/* constructor */
my_class_t *new_my_stack(void); |
To derive from such a class, private member variables can be added:
typedef struct {
my_stack_t stack; /* public part */
/* private part follows here */
int values[MAX_STACK_SIZE];
int stack_size;
} intstack_t; |
Implementation of the "push" method follows:
static void push (my_stack_t *this_gen, int i) {
intstack_t *this = (intstack_t *)this_gen;
this->values[MAX_STACK_SIZE - ++this->stack_size] = i;
} |
The part added to the derived class is private, because when defining the new structure directly in the .c file, where it will be used, outside modules have no way of seeing the definition of the derived class. A public derivation is possible by defining the above structure in a .h file for others to include.
Something similar to a protected, package or friend visibility is also possible:
struct my_stack_s {
void (*push)(my_stack_t *this, int i);
void (*add)(my_stack_t *this);
int (*pop)(my_stack_t *this);
#ifdef STACK_INTERNAL
void (*flush)(my_stack_t *this);
#endif
}; |
#define STACK_INTERNAL |
Finally the contructor malloc()s the data struct (private variant) and fills in function pointers and default values. Usually the constructor is the only public (i.e. non-static) function in the module:
my_stack_t *new_my_stack(void) {
intstack_t *this;
/* alloc memory */
this = malloc(sizeof(intstack_t));
/* fill in methods */
this->push = push;
this->add = add;
this->pop = pop;
/* init data fields */
this->stack_size = 0;
/* return public part */
return &this->stack;
} |
After all these considerations about object oriented C, you might ask, why we do not use C++ after all? The easy answer would be: xine wants to be as fast as possible and C++ is simply too slow. But this is only the easy answer and it is not entirely true any more. Thoughtfully applied, you can write very fast C++ code with today's compilers, but these compilers might not be available on all platforms in the necessary quality. Even with a sophisticated compiler, C++ is much harder to optimize than plain C and thus C compiles much faster. Another big problem is that the C++ ABI is not as well-defined as the C ABI. With C, you can easily mix libraries and applications built by different compilers. With C++, this is unlikely to work. But the final argument is that xine does not really need C++. xine's inheritance hierarchy is very flat, mostly one level only and does not need things like multiple or virtual inheritance. Most of the external projects that are used by xine are plain C as well and using more than one language complicates the build system. As we saw above, we can emulate object orientation reduced to our real needs in plain C.
This section contains some guidelines for writing xine-code. These are really just guidelines, no strict rules. Contributions will not be rejected if they do not meet these rules but they will be even more appreciated if they do.
Comment your interfaces directly in the header files. No doxygen comments, ordinary C comments will do.
Use C-style comments (/* */), not C++-style (//).
When in doubt, use lower case. BTW: This thing is called xine, never Xine.
Use expressive variable and function identifiers on all public interfaces. Use underscores to seperate words in identifiers, not uppercase letters (my_function_name is ok, myFunctionName is not ok).
Avoid macros unless they are really useful. Avoid gotos.
use something like
printf("module: ..."[,...]); |
Refer to emac's C-mode for all questions of proper indentiation. That first of all means: indent with two spaces.
xine offers a wide range of possibilities to display strings. This section should describe when to use which way and how to do it right.
Output which is done thru this function will be
displayed for the end user by the frontend.
If xine->verbosity is not 0 the messages will also
be displayed I_SEND_ibffmpeg
A xine decoder plugin using various audio and video decoders from the ffmpeg decoder pack libavcodec. Their MPEG encoder is also for the DXR3.
To optimize the integration of libavcodec and the xine engine, we maintain some differences between the original ffmpeg and our copy in the file diff_to_ffmpeg_cvs.txt.
The libavcodec decoder pack as used by xine's ffmpeg plugin.
A xine demuxer and decoder plugin for the Free Lossless Audio Codec library, which has to be installed separately.
Audio decoder plugin that "decodes" raw PCM data; most notably endianess-conversions are done here.
Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). ISO/IEC compliant decoder using fixed point math.
Most important MPEG video decoder plugin, provides fast and high-precision MPEG-1/2 video decoding.
Although this is an imported library, we have heavily modified our internal copy to blend it as seamlessly as possible into the xine engine in order to get the maximum MPEG decoding performance.
James started an effort to bring a recent and unmodified version of libmpeg2 into xine to one day replace our current internal modified libmpeg2 with one closer to the original. But since the full feature catalog has not yet been achieved with the new one, it is still disabled.
The code of the imported new libmpeg2.
A thin wrapper around Real's binary codecs from the Linux RealPlayer to use them as a xine plugin.
A xine decoder plugin for the speex library, which has to be installed separately.
Closed caption subtitle decoder plugin.
DVD SPU subtitle decoder plugin.
Plain text subtitle decoder plugins.
A xine decoder plugin for the theora library, which has to be installed separately.
A xine decoder plugin for the ogg/vorbis library, which has to be installed separately.
Video and audio decoder plugins that exploit some wine code to use win32 (media player and Quicktime) codecs in xine. Works on x86 platforms only.
Stripped down version of wine to support Video for Windows DLLs and additional code to use DirectShow, DMO and QuickTime DLLs.
xine's decoder pack of additional audio decoders.
The gsm610 audio decoder library as used by the related xine plugin.
The nosefart audio decoder library as used by the related xine plugin.
xine's decoder pack of additional video decoders.
Video and audio post effect plugins live here. Post plugins modify streams of video frames or audio buffers as they leave the decoder to provide conversion or effects.
Some audio effects as xine audio filter posts.
The tvtime deinterlacer as a xine video filter post.
The goom audio visualizer as a xine visualizer post.
Some post plugins merging multiple frames into one. For example picture in picture can be done with this.
Some simple 2D video effects as xine video filter posts.
Audio visualization post plugins.
Contains various video output driver plugins. Video output drivers are thin abstraction layers over various video output platforms (e.g. X11, directfb, directX,...). Video output driver plugins provide functions like frame allocation and drawing and handle stuff like hardware acceleration, scaling and colorspace conversion if necessary. They do not handle a/v sync since this is done in the xine-engine already.
A library for direct hardware access to the graphics card as used by the vidix video out plugin.
The vidix system for high performance video output as used by the vidix video out plugin.
The heart of xine - it's engine. Contains code to load and handle all the plugins, the configuration repository as well as the generic decoding loops and code for synchronized output. A lot of helper functions for plugins to use live here as well. What's in the individual files should be guessable by the files' names. This document is not going to explain the source, because it simply changes too often. A look at the architectural drawing in the internals section should give you a pretty good idea, what to expect in this directory. Basically, everything in this picture that is not called "plugin" lives here.
Collection of utility functions and platform abstractions. Also contains a simple XML parser for frontend playlist handling.
xine uses a lot of design principles normally found in object oriented designs. As xine is written in C, a few basic principles shall be explained here on how xine is object oriented anyway.
Classes are structs containing function pointers and public member data. Example:
typedef struct my_stack_s my_class_t;
struct my_stack_s {
/* method "push" with one parameter and no return value */
void (*push)(my_stack_t *this, int i);
/* method "add" with no parameters and no return value */
void (*add)(my_stack_t *this);
/* method "pop" with no parameters (except "this") and a return value */
int (*pop) (my_stack_t *this);
};
/* constructor */
my_class_t *new_my_stack(void); |
To derive from such a class, private member variables can be added:
typedef struct {
my_stack_t stack; /* public part */
/* private part follows here */
int values[MAX_STACK_SIZE];
int stack_size;
} intstack_t; |
Implementation of the "push" method follows:
static void push (my_stack_t *this_gen, int i) {
intstack_t *this = (intstack_t *)this_gen;
this->values[MAX_STACK_SIZE - ++this->stack_size] = i;
} |
The part added to the derived class is private, because when defining the new structure directly in the .c file, where it will be used, outside modules have no way of seeing the definition of the derived class. A public derivation is possible by defining the above structure in a .h file for others to include.
Something similar to a protected, package or friend visibility is also possible:
struct my_stack_s {
void (*push)(my_stack_t *this, int i);
void (*add)(my_stack_t *this);
int (*pop)(my_stack_t *this);
#ifdef STACK_INTERNAL
void (*flush)(my_stack_t *this);
#endif
}; |
#define STACK_INTERNAL |
Finally the contructor malloc()s the data struct (private variant) and fills in function pointers and default values. Usually the constructor is the only public (i.e. non-static) function in the module:
my_stack_t *new_my_stack(void) {
intstack_t *this;
/* alloc memory */
this = malloc(sizeof(intstack_t));
/* fill in methods */
this->push = push;
this->add = add;
this->pop = pop;
/* init data fields */
this->stack_size = 0;
/* return public part */
return &this->stack;
} |
After all these considerations about object oriented C, you might ask, why we do not use C++ after all? The easy answer would be: xine wants to be as fast as possible and C++ is simply too slow. But this is only the easy answer and it is not entirely true any more. Thoughtfully applied, you can write very fast C++ code with today's compilers, but these compilers might not be available on all platforms in the necessary quality. Even with a sophisticated compiler, C++ is much harder to optimize than plain C and thus C compiles much faster. Another big problem is that the C++ ABI is not as well-defined as the C ABI. With C, you can easily mix libraries and applications built by different compilers. With C++, this is unlikely to work. But the final argument is that xine does not really need C++. xine's inheritance hierarchy is very flat, mostly one level only and does not need things like multiple or virtual inheritance. Most of the external projects that are used by xine are plain C as well and using more than one language complicates the build system. As we saw above, we can emulate object orientation reduced to our real needs in plain C.
This section contains some guidelines for writing xine-code. These are really just guidelines, no strict rules. Contributions will not be rejected if they do not meet these rules but they will be even more appreciated if they do.
Comment your interfaces directly in the header files. No doxygen comments, ordinary C comments will do.
Use C-style comments (/* */), not C++-style (//).
When in doubt, use lower case. BTW: This thing is called xine, never Xine.
Use expressive variable and function identifiers on all public interfaces. Use underscores to seperate words in identifiers, not uppercase letters (my_function_name is ok, myFunctionName is not ok).
Avoid macros unless they are really useful. Avoid gotos.
use something like
printf("module: ..."[,...]); |
Refer to emac's C-mode for all questions of proper indentiation. That first of all means: indent with two spaces.
xine offers a wide range of possibilities to display strings. This section should describe when to use which way and how to do it right.
Output which is done thru this function will be
displayed for the end user by the frontend.
If xine->verbosity is not 0 the messages will also
be displayed I_SEND_ibffmpeg
A xine decoder plugin using various audio and video decoders from the ffmpeg decoder pack libavcodec. Their MPEG encoder is also for the DXR3.
To optimize the integration of libavcodec and the xine engine, we maintain some differences between the original ffmpeg and our copy in the file diff_to_ffmpeg_cvs.txt.
The libavcodec decoder pack as used by xine's ffmpeg plugin.
A xine demuxer and decoder plugin for the Free Lossless Audio Codec library, which has to be installed separately.
Audio decoder plugin that "decodes" raw PCM data; most notably endianess-conversions are done here.
Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). ISO/IEC compliant decoder using fixed point math.
Most important MPEG video decoder plugin, provides fast and high-precision MPEG-1/2 video decoding.
Although this is an imported library, we have heavily modified our internal copy to blend it as seamlessly as possible into the xine engine in order to get the maximum MPEG decoding performance.
James started an effort to bring a recent and unmodified version of libmpeg2 into xine to one day replace our current internal modified libmpeg2 with one closer to the original. But since the full feature catalog has not yet been achieved with the new one, it is still disabled.
The code of the imported new libmpeg2.
A thin wrapper around Real's binary codecs from the Linux RealPlayer to use them as a xine plugin.
A xine decoder plugin for the speex library, which has to be installed separately.
Closed caption subtitle decoder plugin.
DVD SPU subtitle decoder plugin.
Plain text subtitle decoder plugins.
A xine decoder plugin for the theora library, which has to be installed separately.
A xine decoder plugin for the ogg/vorbis library, which has to be installed separately.
Video and audio decoder plugins that exploit some wine code to use win32 (media player and Quicktime) codecs in xine. Works on x86 platforms only.
Stripped down version of wine to support Video for Windows DLLs and additional code to use DirectShow, DMO and QuickTime DLLs.
xine's decoder pack of additional audio decoders.
The gsm610 audio decoder library as used by the related xine plugin.
The nosefart audio decoder library as used by the related xine plugin.
xine's decoder pack of additional video decoders.
Video and audio post effect plugins live here. Post plugins modify streams of video frames or audio buffers as they leave the decoder to provide conversion or effects.
Some audio effects as xine audio filter posts.
The tvtime deinterlacer as a xine video filter post.
The goom audio visualizer as a xine visualizer post.
Some post plugins merging multiple frames into one. For example picture in picture can be done with this.
Some simple 2D video effects as xine video filter posts.
Audio visualization post plugins.
Contains various video output driver plugins. Video output drivers are thin abstraction layers over various video output platforms (e.g. X11, directfb, directX,...). Video output driver plugins provide functions like frame allocation and drawing and handle stuff like hardware acceleration, scaling and colorspace conversion if necessary. They do not handle a/v sync since this is done in the xine-engine already.
A library for direct hardware access to the graphics card as used by the vidix video out plugin.
The vidix system for high performance video output as used by the vidix video out plugin.
The heart of xine - it's engine. Contains code to load and handle all the plugins, the configuration repository as well as the generic decoding loops and code for synchronized output. A lot of helper functions for plugins to use live here as well. What's in the individual files should be guessable by the files' names. This document is not going to explain the source, because it simply changes too often. A look at the architectural drawing in the internals section should give you a pretty good idea, what to expect in this directory. Basically, everything in this picture that is not called "plugin" lives here.
Collection of utility functions and platform abstractions. Also contains a simple XML parser for frontend playlist handling.
xine uses a lot of design principles normally found in object oriented designs. As xine is written in C, a few basic principles shall be explained here on how xine is object oriented anyway.
Classes are structs containing function pointers and public member data. Example:
typedef struct my_stack_s my_class_t;
struct my_stack_s {
/* method "push" with one parameter and no return value */
void (*push)(my_stack_t *this, int i);
/* method "add" with no parameters and no return value */
void (*add)(my_stack_t *this);
/* method "pop" with no parameters (except "this") and a return value */
int (*pop) (my_stack_t *this);
};
/* constructor */
my_class_t *new_my_stack(void); |
To derive from such a class, private member variables can be added:
typedef struct {
my_stack_t stack; /* public part */
/* private part follows here */
int values[MAX_STACK_SIZE];
int stack_size;
} intstack_t; |
Implementation of the "push" method follows:
static void push (my_stack_t *this_gen, int i) {
intstack_t *this = (intstack_t *)this_gen;
this->values[MAX_STACK_SIZE - ++this->stack_size] = i;
} |
The part added to the derived class is private, because when defining the new structure directly in the .c file, where it will be used, outside modules have no way of seeing the definition of the derived class. A public derivation is possible by defining the above structure in a .h file for others to include.
Something similar to a protected, package or friend visibility is also possible:
struct my_stack_s {
void (*push)(my_stack_t *this, int i);
void (*add)(my_stack_t *this);
int (*pop)(my_stack_t *this);
#ifdef STACK_INTERNAL
void (*flush)(my_stack_t *this);
#endif
}; |
#define STACK_INTERNAL |
Finally the contructor malloc()s the data struct (private variant) and fills in function pointers and default values. Usually the constructor is the only public (i.e. non-static) function in the module:
my_stack_t *new_my_stack(void) {
intstack_t *this;
/* alloc memory */
this = malloc(sizeof(intstack_t));
/* fill in methods */
this->push = push;
this->add = add;
this->pop = pop;
/* init data fields */
this->stack_size = 0;
/* return public part */
return &this->stack;
} |
After all these considerations about object oriented C, you might ask, why we do not use C++ after all? The easy answer would be: xine wants to be as fast as possible and C++ is simply too slow. But this is only the easy answer and it is not entirely true any more. Thoughtfully applied, you can write very fast C++ code with today's compilers, but these compilers might not be available on all platforms in the necessary quality. Even with a sophisticated compiler, C++ is much harder to optimize than plain C and thus C compiles much faster. Another big problem is that the C++ ABI is not as well-defined as the C ABI. With C, you can easily mix libraries and applications built by different compilers. With C++, this is unlikely to work. But the final argument is that xine does not really need C++. xine's inheritance hierarchy is very flat, mostly one level only and does not need things like multiple or virtual inheritance. Most of the external projects that are used by xine are plain C as well and using more than one language complicates the build system. As we saw above, we can emulate object orientation reduced to our real needs in plain C.
This section contains some guidelines for writing xine-code. These are really just guidelines, no strict rules. Contributions will not be rejected if they do not meet these rules but they will be even more appreciated if they do.
Comment your interfaces directly in the header files. No doxygen comments, ordinary C comments will do.
Use C-style comments (/* */), not C++-style (//).
When in doubt, use lower case. BTW: This thing is called xine, never Xine.
Use expressive variable and function identifiers on all public interfaces. Use underscores to seperate words in identifiers, not uppercase letters (my_function_name is ok, myFunctionName is not ok).
Avoid macros unless they are really useful. Avoid gotos.
use something like
printf("module: ..."[,...]); |
Refer to emac's C-mode for all questions of proper indentiation. That first of all means: indent with two spaces.
xine offers a wide range of possibilities to display strings. This section should describe when to use which way and how to do it right.
Output which is done thru this function will be
displayed for the end user by the frontend.
If xine->verbosity is not 0 the messages will also
be displayed I_SEND_ibffmpeg
A xine decoder plugin using various audio and video decoders from the ffmpeg decoder pack libavcodec. Their MPEG encoder is also for the DXR3.
To optimize the integration of libavcodec and the xine engine, we maintain some differences between the original ffmpeg and our copy in the file diff_to_ffmpeg_cvs.txt.
The libavcodec decoder pack as used by xine's ffmpeg plugin.
A xine demuxer and decoder plugin for the Free Lossless Audio Codec library, which has to be installed separately.
Audio decoder plugin that "decodes" raw PCM data; most notably endianess-conversions are done here.
Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). ISO/IEC compliant decoder using fixed point math.
Most important MPEG video decoder plugin, provides fast and high-precision MPEG-1/2 video decoding.
Although this is an imported library, we have heavily modified our internal copy to blend it as seamlessly as possible into the xine engine in order to get the maximum MPEG decoding performance.
James started an effort to bring a recent and unmodified version of libmpeg2 into xine to one day replace our current internal modified libmpeg2 with one closer to the original. But since the full feature catalog has not yet been achieved with the new one, it is still disabled.
The code of the imported new libmpeg2.
A thin wrapper around Real's binary codecs from the Linux RealPlayer to use them as a xine plugin.
A xine decoder plugin for the speex library, which has to be installed separately.
Closed caption subtitle decoder plugin.
DVD SPU subtitle decoder plugin.
Plain text subtitle decoder plugins.
A xine decoder plugin for the theora library, which has to be installed separately.
A xine decoder plugin for the ogg/vorbis library, which has to be installed separately.
Video and audio decoder plugins that exploit some wine code to use win32 (media player and Quicktime) codecs in xine. Works on x86 platforms only.
Stripped down version of wine to support Video for Windows DLLs and additional code to use DirectShow, DMO and QuickTime DLLs.
xine's decoder pack of additional audio decoders.
The gsm610 audio decoder library as used by the related xine plugin.
The nosefart audio decoder library as used by the related xine plugin.
xine's decoder pack of additional video decoders.
Video and audio post effect plugins live here. Post plugins modify streams of video frames or audio buffers as they leave the decoder to provide conversion or effects.
Some audio effects as xine audio filter posts.
The tvtime deinterlacer as a xine video filter post.
The goom audio visualizer as a xine visualizer post.
Some post plugins merging multiple frames into one. For example picture in picture can be done with this.
Some simple 2D video effects as xine video filter posts.
Audio visualization post plugins.
Contains various video output driver plugins. Video output drivers are thin abstraction layers over various video output platforms (e.g. X11, directfb, directX,...). Video output driver plugins provide functions like frame allocation and drawing and handle stuff like hardware acceleration, scaling and colorspace conversion if necessary. They do not handle a/v sync since this is done in the xine-engine already.
A library for direct hardware access to the graphics card as used by the vidix video out plugin.
The vidix system for high performance video output as used by the vidix video out plugin.
The heart of xine - it's engine. Contains code to load and handle all the plugins, the configuration repository as well as the generic decoding loops and code for synchronized output. A lot of helper functions for plugins to use live here as well. What's in the individual files should be guessable by the files' names. This document is not going to explain the source, because it simply changes too often. A look at the architectural drawing in the internals section should give you a pretty good idea, what to expect in this directory. Basically, everything in this picture that is not called "plugin" lives here.
Collection of utility functions and platform abstractions. Also contains a simple XML parser for frontend playlist handling.
xine uses a lot of design principles normally found in object oriented designs. As xine is written in C, a few basic principles shall be explained here on how xine is object oriented anyway.
Classes are structs containing function pointers and public member data. Example:
typedef struct my_stack_s my_class_t;
struct my_stack_s {
/* method "push" with one parameter and no return value */
void (*push)(my_stack_t *this, int i);
/* method "add" with no parameters and no return value */
void (*add)(my_stack_t *this);
/* method "pop" with no parameters (except "this") and a return value */
int (*pop) (my_stack_t *this);
};
/* constructor */
my_class_t *new_my_stack(void); |
To derive from such a class, private member variables can be added:
typedef struct {
my_stack_t stack; /* public part */
/* private part follows here */
int values[MAX_STACK_SIZE];
int stack_size;
} intstack_t; |
Implementation of the "push" method follows:
static void push (my_stack_t *this_gen, int i) {
intstack_t *this = (intstack_t *)this_gen;
this->values[MAX_STACK_SIZE - ++this->stack_size] = i;
} |
The part added to the derived class is private, because when defining the new structure directly in the .c file, where it will be used, outside modules have no way of seeing the definition of the derived class. A public derivation is possible by defining the above structure in a .h file for others to include.
Something similar to a protected, package or friend visibility is also possible:
struct my_stack_s {
void (*push)(my_stack_t *this, int i);
void (*add)(my_stack_t *this);
int (*pop)(my_stack_t *this);
#ifdef STACK_INTERNAL
void (*flush)(my_stack_t *this);
#endif
}; |
#define STACK_INTERNAL |
Finally the contructor malloc()s the data struct (private variant) and fills in function pointers and default values. Usually the constructor is the only public (i.e. non-static) function in the module:
my_stack_t *new_my_stack(void) {
intstack_t *this;
/* alloc memory */
this = malloc(sizeof(intstack_t));
/* fill in methods */
this->push = push;
this->add = add;
this->pop = pop;
/* init data fields */
this->stack_size = 0;
/* return public part */
return &this->stack;
} |
After all these considerations about object oriented C, you might ask, why we do not use C++ after all? The easy answer would be: xine wants to be as fast as possible and C++ is simply too slow. But this is only the easy answer and it is not entirely true any more. Thoughtfully applied, you can write very fast C++ code with today's compilers, but these compilers might not be available on all platforms in the necessary quality. Even with a sophisticated compiler, C++ is much harder to optimize than plain C and thus C compiles much faster. Another big problem is that the C++ ABI is not as well-defined as the C ABI. With C, you can easily mix libraries and applications built by different compilers. With C++, this is unlikely to work. But the final argument is that xine does not really need C++. xine's inheritance hierarchy is very flat, mostly one level only and does not need things like multiple or virtual inheritance. Most of the external projects that are used by xine are plain C as well and using more than one language complicates the build system. As we saw above, we can emulate object orientation reduced to our real needs in plain C.
This section contains some guidelines for writing xine-code. These are really just guidelines, no strict rules. Contributions will not be rejected if they do not meet these rules but they will be even more appreciated if they do.
Comment your interfaces directly in the header files. No doxygen comments, ordinary C comments will do.
Use C-style comments (/* */), not C++-style (//).
When in doubt, use lower case. BTW: This thing is called xine, never Xine.
Use expressive variable and function identifiers on all public interfaces. Use underscores to seperate words in identifiers, not uppercase letters (my_function_name is ok, myFunctionName is not ok).
Avoid macros unless they are really useful. Avoid gotos.
use something like
printf("module: ..."[,...]); |
Refer to emac's C-mode for all questions of proper indentiation. That first of all means: indent with two spaces.
xine offers a wide range of possibilities to display strings. This section should describe when to use which way and how to do it right.
Output which is done thru this function will be
displayed for the end user by the frontend.
If xine->verbosity is not 0 the messages will also
be displayed I_SEND_ibffmpeg
A xine decoder plugin using various audio and video decoders from the ffmpeg decoder pack libavcodec. Their MPEG encoder is also for the DXR3.
To optimize the integration of libavcodec and the xine engine, we maintain some differences between the original ffmpeg and our copy in the file diff_to_ffmpeg_cvs.txt.
The libavcodec decoder pack as used by xine's ffmpeg plugin.
A xine demuxer and decoder plugin for the Free Lossless Audio Codec library, which has to be installed separately.
Audio decoder plugin that "decodes" raw PCM data; most notably endianess-conversions are done here.
Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). ISO/IEC compliant decoder using fixed point math.
Most important MPEG video decoder plugin, provides fast and high-precision MPEG-1/2 video decoding.
Although this is an imported library, we have heavily modified our internal copy to blend it as seamlessly as possible into the xine engine in order to get the maximum MPEG decoding performance.
James started an effort to bring a recent and unmodified version of libmpeg2 into xine to one day replace our current internal modified libmpeg2 with one closer to the original. But since the full feature catalog has not yet been achieved with the new one, it is still disabled.
The code of the imported new libmpeg2.
A thin wrapper around Real's binary codecs from the Linux RealPlayer to use them as a xine plugin.
A xine decoder plugin for the speex library, which has to be installed separately.
Closed caption subtitle decoder plugin.
DVD SPU subtitle decoder plugin.
Plain text subtitle decoder plugins.
A xine decoder plugin for the theora library, which has to be installed separately.
A xine decoder plugin for the ogg/vorbis library, which has to be installed separately.
Video and audio decoder plugins that exploit some wine code to use win32 (media player and Quicktime) codecs in xine. Works on x86 platforms only.
Stripped down version of wine to support Video for Windows DLLs and additional code to use DirectShow, DMO and QuickTime DLLs.
xine's decoder pack of additional audio decoders.
The gsm610 audio decoder library as used by the related xine plugin.
The nosefart audio decoder library as used by the related xine plugin.
xine's decoder pack of additional video decoders.
Video and audio post effect plugins live here. Post plugins modify streams of video frames or audio buffers as they leave the decoder to provide conversion or effects.
Some audio effects as xine audio filter posts.
The tvtime deinterlacer as a xine video filter post.
The goom audio visualizer as a xine visualizer post.
Some post plugins merging multiple frames into one. For example picture in picture can be done with this.
Some simple 2D video effects as xine video filter posts.
Audio visualization post plugins.
Contains various video output driver plugins. Video output drivers are thin abstraction layers over various video output platforms (e.g. X11, directfb, directX,...). Video output driver plugins provide functions like frame allocation and drawing and handle stuff like hardware acceleration, scaling and colorspace conversion if necessary. They do not handle a/v sync since this is done in the xine-engine already.
A library for direct hardware access to the graphics card as used by the vidix video out plugin.
The vidix system for high performance video output as used by the vidix video out plugin.
The heart of xine - it's engine. Contains code to load and handle all the plugins, the configuration repository as well as the generic decoding loops and code for synchronized output. A lot of helper functions for plugins to use live here as well. What's in the individual files should be guessable by the files' names. This document is not going to explain the source, because it simply changes too often. A look at the architectural drawing in the internals section should give you a pretty good idea, what to expect in this directory. Basically, everything in this picture that is not called "plugin" lives here.
Collection of utility functions and platform abstractions. Also contains a simple XML parser for frontend playlist handling.
xine uses a lot of design principles normally found in object oriented designs. As xine is written in C, a few basic principles shall be explained here on how xine is object oriented anyway.
Classes are structs containing function pointers and public member data. Example:
typedef struct my_stack_s my_class_t;
struct my_stack_s {
/* method "push" with one parameter and no return value */
void (*push)(my_stack_t *this, int i);
/* method "add" with no parameters and no return value */
void (*add)(my_stack_t *this);
/* method "pop" with no parameters (except "this") and a return value */
int (*pop) (my_stack_t *this);
};
/* constructor */
my_class_t *new_my_stack(void); |
To derive from such a class, private member variables can be added:
typedef struct {
my_stack_t stack; /* public part */
/* private part follows here */
int values[MAX_STACK_SIZE];
int stack_size;
} intstack_t; |
Implementation of the "push" method follows:
static void push (my_stack_t *this_gen, int i) {
intstack_t *this = (intstack_t *)this_gen;
this->values[MAX_STACK_SIZE - ++this->stack_size] = i;
} |
The part added to the derived class is private, because when defining the new structure directly in the .c file, where it will be used, outside modules have no way of seeing the definition of the derived class. A public derivation is possible by defining the above structure in a .h file for others to include.
Something similar to a protected, package or friend visibility is also possible:
struct my_stack_s {
void (*push)(my_stack_t *this, int i);
void (*add)(my_stack_t *this);
int (*pop)(my_stack_t *this);
#ifdef STACK_INTERNAL
void (*flush)(my_stack_t *this);
#endif
}; |
#define STACK_INTERNAL |
Finally the contructor malloc()s the data struct (private variant) and fills in function pointers and default values. Usually the constructor is the only public (i.e. non-static) function in the module:
my_stack_t *new_my_stack(void) {
intstack_t *this;
/* alloc memory */
this = malloc(sizeof(intstack_t));
/* fill in methods */
this->push = push;
this->add = add;
this->pop = pop;
/* init data fields */
this->stack_size = 0;
/* return public part */
return &this->stack;
} |
After all these considerations about object oriented C, you might ask, why we do not use C++ after all? The easy answer would be: xine wants to be as fast as possible and C++ is simply too slow. But this is only the easy answer and it is not entirely true any more. Thoughtfully applied, you can write very fast C++ code with today's compilers, but these compilers might not be available on all platforms in the necessary quality. Even with a sophisticated compiler, C++ is much harder to optimize than plain C and thus C compiles much faster. Another big problem is that the C++ ABI is not as well-defined as the C ABI. With C, you can easily mix libraries and applications built by different compilers. With C++, this is unlikely to work. But the final argument is that xine does not really need C++. xine's inheritance hierarchy is very flat, mostly one level only and does not need things like multiple or virtual inheritance. Most of the external projects that are used by xine are plain C as well and using more than one language complicates the build system. As we saw above, we can emulate object orientation reduced to our real needs in plain C.
This section contains some guidelines for writing xine-code. These are really just guidelines, no strict rules. Contributions will not be rejected if they do not meet these rules but they will be even more appreciated if they do.
Comment your interfaces directly in the header files. No doxygen comments, ordinary C comments will do.
Use C-style comments (/* */), not C++-style (//).
When in doubt, use lower case. BTW: This thing is called xine, never Xine.
Use expressive variable and function identifiers on all public interfaces. Use underscores to seperate words in identifiers, not uppercase letters (my_function_name is ok, myFunctionName is not ok).
Avoid macros unless they are really useful. Avoid gotos.
use something like
printf("module: ..."[,...]); |
Refer to emac's C-mode for all questions of proper indentiation. That first of all means: indent with two spaces.
xine offers a wide range of possibilities to display strings. This section should describe when to use which way and how to do it right.
Output which is done thru this function will be
displayed for the end user by the frontend.
If xine->verbosity is not 0 the messages will also
be displayed I_SEND_ibffmpeg
A xine decoder plugin using various audio and video decoders from the ffmpeg decoder pack libavcodec. Their MPEG encoder is also for the DXR3.
To optimize the integration of libavcodec and the xine engine, we maintain some differences between the original ffmpeg and our copy in the file diff_to_ffmpeg_cvs.txt.
The libavcodec decoder pack as used by xine's ffmpeg plugin.
A xine demuxer and decoder plugin for the Free Lossless Audio Codec library, which has to be installed separately.
Audio decoder plugin that "decodes" raw PCM data; most notably endianess-conversions are done here.
Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). ISO/IEC compliant decoder using fixed point math.
Most important MPEG video decoder plugin, provides fast and high-precision MPEG-1/2 video decoding.
Although this is an imported library, we have heavily modified our internal copy to blend it as seamlessly as possible into the xine engine in order to get the maximum MPEG decoding performance.
James started an effort to bring a recent and unmodified version of libmpeg2 into xine to one day replace our current internal modified libmpeg2 with one closer to the original. But since the full feature catalog has not yet been achieved with the new one, it is still disabled.
The code of the imported new libmpeg2.
A thin wrapper around Real's binary codecs from the Linux RealPlayer to use them as a xine plugin.
A xine decoder plugin for the speex library, which has to be installed separately.
Closed caption subtitle decoder plugin.
DVD SPU subtitle decoder plugin.
Plain text subtitle decoder plugins.
A xine decoder plugin for the theora library, which has to be installed separately.
A xine decoder plugin for the ogg/vorbis library, which has to be installed separately.
Video and audio decoder plugins that exploit some wine code to use win32 (media player and Quicktime) codecs in xine. Works on x86 platforms only.
Stripped down version of wine to support Video for Windows DLLs and additional code to use DirectShow, DMO and QuickTime DLLs.
xine's decoder pack of additional audio decoders.
The gsm610 audio decoder library as used by the related xine plugin.
The nosefart audio decoder library as used by the related xine plugin.
xine's decoder pack of additional video decoders.
Video and audio post effect plugins live here. Post plugins modify streams of video frames or audio buffers as they leave the decoder to provide conversion or effects.
Some audio effects as xine audio filter posts.
The tvtime deinterlacer as a xine video filter post.
The goom audio visualizer as a xine visualizer post.
Some post plugins merging multiple frames into one. For example picture in picture can be done with this.
Some simple 2D video effects as xine video filter posts.
Audio visualization post plugins.
Contains various video output driver plugins. Video output drivers are thin abstraction layers over various video output platforms (e.g. X11, directfb, directX,...). Video output driver plugins provide functions like frame allocation and drawing and handle stuff like hardware acceleration, scaling and colorspace conversion if necessary. They do not handle a/v sync since this is done in the xine-engine already.
A library for direct hardware access to the graphics card as used by the vidix video out plugin.
The vidix system for high performance video output as used by the vidix video out plugin.
The heart of xine - it's engine. Contains code to load and handle all the plugins, the configuration repository as well as the generic decoding loops and code for synchronized output. A lot of helper functions for plugins to use live here as well. What's in the individual files should be guessable by the files' names. This document is not going to explain the source, because it simply changes too often. A look at the architectural drawing in the internals section should give you a pretty good idea, what to expect in this directory. Basically, everything in this picture that is not called "plugin" lives here.
Collection of utility functions and platform abstractions. Also contains a simple XML parser for frontend playlist handling.
xine uses a lot of design principles normally found in object oriented designs. As xine is written in C, a few basic principles shall be explained here on how xine is object oriented anyway.
Classes are structs containing function pointers and public member data. Example:
typedef struct my_stack_s my_class_t;
struct my_stack_s {
/* method "push" with one parameter and no return value */
void (*push)(my_stack_t *this, int i);
/* method "add" with no parameters and no return value */
void (*add)(my_stack_t *this);
/* method "pop" with no parameters (except "this") and a return value */
int (*pop) (my_stack_t *this);
};
/* constructor */
my_class_t *new_my_stack(void); |
To derive from such a class, private member variables can be added:
typedef struct {
my_stack_t stack; /* public part */
/* private part follows here */
int values[MAX_STACK_SIZE];
int stack_size;
} intstack_t; |
Implementation of the "push" method follows:
static void push (my_stack_t *this_gen, int i) {
intstack_t *this = (intstack_t *)this_gen;
this->values[MAX_STACK_SIZE - ++this->stack_size] = i;
} |
The part added to the derived class is private, because when defining the new structure directly in the .c file, where it will be used, outside modules have no way of seeing the definition of the derived class. A public derivation is possible by defining the above structure in a .h file for others to include.
Something similar to a protected, package or friend visibility is also possible:
struct my_stack_s {
void (*push)(my_stack_t *this, int i);
void (*add)(my_stack_t *this);
int (*pop)(my_stack_t *this);
#ifdef STACK_INTERNAL
void (*flush)(my_stack_t *this);
#endif
}; |
#define STACK_INTERNAL |
Finally the contructor malloc()s the data struct (private variant) and fills in function pointers and default values. Usually the constructor is the only public (i.e. non-static) function in the module:
my_stack_t *new_my_stack(void) {
intstack_t *this;
/* alloc memory */
this = malloc(sizeof(intstack_t));
/* fill in methods */
this->push = push;
this->add = add;
this->pop = pop;
/* init data fields */
this->stack_size = 0;
/* return public part */
return &this->stack;
} |
After all these considerations about object oriented C, you might ask, why we do not use C++ after all? The easy answer would be: xine wants to be as fast as possible and C++ is simply too slow. But this is only the easy answer and it is not entirely true any more. Thoughtfully applied, you can write very fast C++ code with today's compilers, but these compilers might not be available on all platforms in the necessary quality. Even with a sophisticated compiler, C++ is much harder to optimize than plain C and thus C compiles much faster. Another big problem is that the C++ ABI is not as well-defined as the C ABI. With C, you can easily mix libraries and applications built by different compilers. With C++, this is unlikely to work. But the final argument is that xine does not really need C++. xine's inheritance hierarchy is very flat, mostly one level only and does not need things like multiple or virtual inheritance. Most of the external projects that are used by xine are plain C as well and using more than one language complicates the build system. As we saw above, we can emulate object orientation reduced to our real needs in plain C.
This section contains some guidelines for writing xine-code. These are really just guidelines, no strict rules. Contributions will not be rejected if they do not meet these rules but they will be even more appreciated if they do.
Comment your interfaces directly in the header files. No doxygen comments, ordinary C comments will do.
Use C-style comments (/* */), not C++-style (//).
When in doubt, use lower case. BTW: This thing is called xine, never Xine.
Use expressive variable and function identifiers on all public interfaces. Use underscores to seperate words in identifiers, not uppercase letters (my_function_name is ok, myFunctionName is not ok).
Avoid macros unless they are really useful. Avoid gotos.
use something like
printf("module: ..."[,...]); |
Refer to emac's C-mode for all questions of proper indentiation. That first of all means: indent with two spaces.
xine offers a wide range of possibilities to display strings. This section should describe when to use which way and how to do it right.
Output which is done thru this function will be
displayed for the end user by the frontend.
If xine->verbosity is not 0 the messages will also
be displayed I_SEND_ibffmpeg
A xine decoder plugin using various audio and video decoders from the ffmpeg decoder pack libavcodec. Their MPEG encoder is also for the DXR3.
To optimize the integration of libavcodec and the xine engine, we maintain some differences between the original ffmpeg and our copy in the file diff_to_ffmpeg_cvs.txt.
The libavcodec decoder pack as used by xine's ffmpeg plugin.
A xine demuxer and decoder plugin for the Free Lossless Audio Codec library, which has to be installed separately.
Audio decoder plugin that "decodes" raw PCM data; most notably endianess-conversions are done here.
Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). ISO/IEC compliant decoder using fixed point math.
Most important MPEG video decoder plugin, provides fast and high-precision MPEG-1/2 video decoding.
Although this is an imported library, we have heavily modified our internal copy to blend it as seamlessly as possible into the xine engine in order to get the maximum MPEG decoding performance.
James started an effort to bring a recent and unmodified version of libmpeg2 into xine to one day replace our current internal modified libmpeg2 with one closer to the original. But since the full feature catalog has not yet been achieved with the new one, it is still disabled.
The code of the imported new libmpeg2.