diff options
Diffstat (limited to 'doc/hackersguide')
-rw-r--r-- | doc/hackersguide/README | 2 | ||||
-rw-r--r-- | doc/hackersguide/architecture.fig | 2 | ||||
-rw-r--r-- | doc/hackersguide/internals.sgml | 138 | ||||
-rw-r--r-- | doc/hackersguide/intro.sgml | 6 | ||||
-rw-r--r-- | doc/hackersguide/library.fig | 2 | ||||
-rw-r--r-- | doc/hackersguide/library.sgml | 94 | ||||
-rw-r--r-- | doc/hackersguide/output.sgml | 20 | ||||
-rw-r--r-- | doc/hackersguide/overlays.fig | 2 | ||||
-rw-r--r-- | doc/hackersguide/overview.sgml | 72 | ||||
-rw-r--r-- | doc/hackersguide/post_frame.fig | 2 | ||||
-rw-r--r-- | doc/hackersguide/stream.sgml | 18 |
11 files changed, 192 insertions, 166 deletions
diff --git a/doc/hackersguide/README b/doc/hackersguide/README index c0c0d944a..ef0ac825a 100644 --- a/doc/hackersguide/README +++ b/doc/hackersguide/README @@ -27,7 +27,7 @@ installed TeX system (for example teTeX). sgmltools-lite examples: ------------------------ -to generate html +to generate html $ sgmltools -b onehtml hackersguide.sgml diff --git a/doc/hackersguide/architecture.fig b/doc/hackersguide/architecture.fig index cc035149d..9e420bf42 100644 --- a/doc/hackersguide/architecture.fig +++ b/doc/hackersguide/architecture.fig @@ -2,7 +2,7 @@ Landscape Center Metric -A4 +A4 100.00 Single -2 diff --git a/doc/hackersguide/internals.sgml b/doc/hackersguide/internals.sgml index 9bd1ec684..58a5a3c37 100644 --- a/doc/hackersguide/internals.sgml +++ b/doc/hackersguide/internals.sgml @@ -15,15 +15,15 @@ </caption> </mediaobject> <para> - Media streams usually consist of audio and video data multiplexed + Media streams usually consist of audio and video data multiplexed into one bitstream in the so-called system-layer (e.g. AVI, Quicktime or MPEG). A demuxer plugin is used to parse the system layer and extract audio and video packages. The demuxer uses an input plugin to read the data and stores it - in pre-allocated buffers from the global buffer pool. + in pre-allocated buffers from the global buffer pool. The buffers are then added to the audio or video stream fifo. </para> <para> - From the other end of these fifos the audio and video decoder threads + From the other end of these fifos the audio and video decoder threads consume the buffers and hand them over to the current audio or video decoder plugin for decompression. These plugins then send the decoded data to the output layer. The buffer holding the encoded @@ -64,7 +64,7 @@ <para> support for multiple plugin directories (<filename>$prefix/lib/xine/plugins</filename>, - <filename>$HOME/.xine/plugins</filename>, ...) + <filename>$HOME/.xine/plugins</filename>, …) </para> </listitem> <listitem> @@ -124,7 +124,7 @@ demux_mpeg_block.so decode_mpeg.so video_out_xv.so - ... + … xine-vcdnav-0.9.11 input_vcdnav.so xine-lib-1.2 @@ -135,21 +135,21 @@ demuxers fli.so avi.so - ... + … decoders ffmpeg.so mpeg.so (may contain mpeg 1/2 audio and video decoders) pcm.so - ... + … output video_xv.so audio_oss.so - ... + … xine-lib-3.0 avi.so (avi demuxer) mpeg.so (contains mpeg demuxers and audio/video decoders) video_out_xv.so (Xv video out) - ...</screen> + …</screen> </para> <para> As you can see, every package is free to organize plugins at will @@ -188,7 +188,7 @@ This plugin list is held in an array named <varname>xine_plugin_info</varname>": <programlisting> plugin_info_t xine_plugin_info[] = { - /* type, API, "name", version, special_info, init_function */ + /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 20, "flac", XINE_VERSION_CODE, NULL, demux_flac_init_class }, { PLUGIN_AUDIO_DECODER, 13, "flacdec", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } @@ -236,7 +236,7 @@ same plugin are possible. </para> <para> - If you think this is pretty much an object-oriented aproach, + If you think this is pretty much an object-oriented aproach, then you're right. </para> <para> @@ -244,12 +244,12 @@ 13, found in xine-lib 2.13.7 would then define this plugin list: <programlisting> #include <xine/plugin.h> - ... + … plugin_t *init_api12(void) { input_plugin_t *this; this = malloc(sizeof(input_plugin_t)); - ... + … return (plugin_t *)this; } /* same thing, with different initialization for API 13 */ @@ -278,7 +278,7 @@ <para> Many plugins will need some additional "private" data fields. These should be simply added at the end of the plugin structure. - For example a demuxer plugin called "foo" with two private + For example a demuxer plugin called "foo" with two private fields "xine" and "count" may have a plugin structure declared in the following way: <programlisting> @@ -325,13 +325,13 @@ <para> Metronom serves two purposes: <itemizedlist> - <listitem> + <listitem> <para> Generate vpts (virtual presentation time stamps) from pts (presentation time stamps) for a/v output and synchronization. </para> </listitem> - <listitem> + <listitem> <para> Provide a master clock (system clock reference, scr), possibly provided by external scr plugins (this can be used if some hardware decoder or network @@ -352,7 +352,7 @@ The heuristics used in metronom have always been a field of research. Current metronom's implementation <emphasis>tries</emphasis> to stick to pts values as reported from demuxers, that is, vpts may be obtained by a simple operation of vpts = pts + <varname>vpts_offset</varname>, - where <varname>vpts_offset</varname> takes into account any wraps. Whenever pts is zero, + where <varname>vpts_offset</varname> takes into account any wraps. Whenever pts is zero, metronom will estimate vpts based on previous values. If a difference is found between the estimated and calculated vpts values by above formula, it will be smoothed by using a "drift correction". @@ -369,18 +369,18 @@ delivered for drawing. Unfortunately the same isn't true for audio: all sound systems implement some amount of buffering (or fifo), any data being send to it <emphasis>now</emphasis> will only get played some time in future. audio_out thread - must take this into account for making perfect A-V sync by asking the sound latency + must take this into account for making perfect A-V sync by asking the sound latency to audio driver. </para> <para> - Some audio drivers can't tell the current delay introduced in playback. This is + Some audio drivers can't tell the current delay introduced in playback. This is especially true for most sound servers like ESD or aRts and explain why in such cases the sync is far from perfect. </para> <para> Another problem xine must handle is the sound card clock drift. vpts are compared to the system clock (or even to a different clock provided by a scr plugin) - for presentation but sound card is sampling audio by it's own clocking + for presentation but sound card is sampling audio by its own clocking mechanism, so a small drift may occur. As the playback goes on this error will accumulate possibly resulting in audio gaps or audio drops. To avoid that annoying effect, two countermeasures are available (switchable with xine config @@ -388,15 +388,15 @@ <itemizedlist> <listitem> <para> - The small sound card errors are feedbacked to metronom. The details + The small sound card errors are feedbacked to metronom. The details are given by <filename>audio_out.c</filename> comments: <programlisting> /* By adding gap errors (difference between reported and expected - * sound card clock) into metronom's vpts_offset we can use its + * sound card clock) into metronom's vpts_offset we can use its * smoothing algorithms to correct sound card clock drifts. * obs: previously this error was added to xine scr. * - * audio buf ---> metronom --> audio fifo --> (buf->vpts - hw_vpts) + * audio buf ---> metronom --> audio fifo --> (buf->vpts - hw_vpts) * (vpts_offset + error) gap * <---------- control --------------| * @@ -438,7 +438,7 @@ <sect1 id="osd"> <title>Overlays and OSD</title> <para> - The roots of xine overlay capabilities are DVD subpictures and subtitles support + The roots of xine overlay capabilities are DVD subpictures and subtitles support (also known as 'spu'). The DVD subtitles are encoded in a RLE (Run Length Encoding - the most simple compressing technique) format, with a palette of colors and transparency levels. You probably thought that subtitles were just simple text saved into DVDs, right? @@ -446,9 +446,9 @@ </para> <para> In order to optimize to the most common case, xine's internal format for screen overlays - is a similar representation to the 'spu' data. This brings not only performance + is a similar representation to the 'spu' data. This brings not only performance benefit (since blending functions may skip large image areas due to RLE) but also - compatibility: it's possible to reencode any xine overlay to the original spu format + compatibility: it's possible to re-encode any xine overlay to the original spu format for displaying with mpeg hardware decoders like DXR3. </para> <para> @@ -456,14 +456,14 @@ is done using the same kind of pts/vpts stuff of a-v sync code. DVD subtitles, for example, may request: show this spu at pts1 and hide it at pts2. This brings the concept of the 'video overlay manager', that is a event-driven module for managing - overlay's showing and hiding. + overlay's showing and hiding. </para> <para> The drawback of using internal RLE format is the difficulty in manipulating it as graphic. To overcome that we created the 'OSD renderer', where OSD stands - for On Screen Display just like in TV sets. The osd renderer is a module + for On Screen Display just like in TV sets. The osd renderer is a module providing simple graphic primitives (lines, rectagles, draw text etc) over - a "virtual" bitmap area. Everytime we want to show that bitmap it will + a "virtual" bitmap area. Everytime we want to show that bitmap it will be RLE encoded and sent to the overlay manager for displaying. </para> <mediaobject> @@ -486,38 +486,38 @@ <programlisting> video_overlay_event_t event; - event.object.handle = this->video_overlay->get_handle(this->video_overlay,0); + event.object.handle = this->video_overlay->get_handle(this->video_overlay,0); - memset(this->event.object.overlay, 0, sizeof(*this->event.object.overlay)); + memset(this->event.object.overlay, 0, sizeof(*this->event.object.overlay)); /* set position and size for this overlay */ - event.object.overlay->x = 0; - event.object.overlay->y = 0; - event.object.overlay->width = 100; - event.object.overlay->height = 100; + event.object.overlay->x = 0; + event.object.overlay->y = 0; + event.object.overlay->width = 100; + event.object.overlay->height = 100; - /* clipping region is mostly used by dvd menus for highlighting buttons */ - event.object.overlay->clip_top = 0; - event.object.overlay->clip_bottom = image_height; - event.object.overlay->clip_left = 0; - event.object.overlay->clip_right = image_width; + /* clipping region is mostly used by dvd menus for highlighting buttons */ + event.object.overlay->clip_top = 0; + event.object.overlay->clip_bottom = image_height; + event.object.overlay->clip_left = 0; + event.object.overlay->clip_right = image_width; - /* the hard part: provide a RLE image */ - event.object.overlay->rle = your_rle; - event.object.overlay->data_size = your_size; - event.object.overlay->num_rle = your_rle_count; + /* the hard part: provide a RLE image */ + event.object.overlay->rle = your_rle; + event.object.overlay->data_size = your_size; + event.object.overlay->num_rle = your_rle_count; /* palette must contain YUV values for each color index */ - memcpy(event.object.overlay->clip_color, color, sizeof(color)); + memcpy(event.object.overlay->clip_color, color, sizeof(color)); /* this table contains transparency levels for each color index. 0 = completely transparent, 15 - completely opaque */ - memcpy(event.object.overlay->clip_trans, trans, sizeof(trans)); + memcpy(event.object.overlay->clip_trans, trans, sizeof(trans)); /* set the event type and time for displaying */ event.event_type = EVENT_SHOW_SPU; event.vpts = 0; /* zero is a special vpts value, it means 'now' */ - video_overlay->add_event(video_overlay, &event);</programlisting> + video_overlay->add_event(video_overlay, &event);</programlisting> </para> </sect2> <sect2> @@ -527,15 +527,15 @@ to xine plugins and to frontends. </para> <para> - The first thing you need is to allocate a OSD object for drawing from the + The first thing you need is to allocate a OSD object for drawing from the renderer. The code below allocates a 300x200 area. This size can't be changed - during the lifetime of a OSD object, but it's possible to place it anywhere + during the lifetime of a OSD object, but it's possible to place it anywhere over the image. </para> <programlisting> osd_object_t osd; - osd = this->osd_renderer->new_object(osd_renderer, 300, 200);</programlisting> + osd = this->osd_renderer->new_object(osd_renderer, 300, 200);</programlisting> <para> Now we may want to set font and color for text rendering. Although we will refer to fonts over this document, in fact the OSD can be any kind of bitmap. Font @@ -547,22 +547,22 @@ </para> <programlisting> /* set sans serif 24 font */ - osd_renderer->set_font(osd, "sans", 24); + osd_renderer->set_font(osd, "sans", 24); /* copy pre-defined colors for white, black border, transparent background to starting at the index used by the first text palette */ - osd_renderer->set_text_palette(osd, TEXTPALETTE_WHITE_BLACK_TRANSPARENT, OSD_TEXT1); + osd_renderer->set_text_palette(osd, TEXTPALETTE_WHITE_BLACK_TRANSPARENT, OSD_TEXT1); /* copy pre-defined colors for white, no border, translucid background to starting at the index used by the second text palette */ - osd_renderer->set_text_palette(osd, TEXTPALETTE_WHITE_NONE_TRANSLUCID, OSD_TEXT2);</programlisting> + osd_renderer->set_text_palette(osd, TEXTPALETTE_WHITE_NONE_TRANSLUCID, OSD_TEXT2);</programlisting> <para> Now render the text and show it: <programlisting> - osd_renderer->render_text(osd, 0, 0, "white text, black border", OSD_TEXT1); - osd_renderer->render_text(osd, 0, 30, "white text, no border", OSD_TEXT2); - - osd_renderer->show(osd, 0); /* 0 stands for 'now' */</programlisting> + osd_renderer->render_text(osd, 0, 0, "white text, black border", OSD_TEXT1); + osd_renderer->render_text(osd, 0, 30, "white text, no border", OSD_TEXT2); + + osd_renderer->show(osd, 0); /* 0 stands for 'now' */</programlisting> </para> <para> There's a 1:1 mapping between OSD objects and overlays, therefore the @@ -572,11 +572,11 @@ </para> <programlisting> for( i=0; i < 100; i+=10 ) { - osd_renderer->set_position(osd, i, i ); - osd_renderer->show(osd, 0); + osd_renderer->set_position(osd, i, i ); + osd_renderer->show(osd, 0); sleep(1); } - osd_renderer->hide(osd, 0);</programlisting> + osd_renderer->hide(osd, 0);</programlisting> <para> For additional functions please check osd.h or the public header. </para> @@ -592,7 +592,7 @@ defined a small convention: </para> <programlisting> - /* + /* Palette entries as used by osd fonts: 0: not used by font, always transparent @@ -603,13 +603,13 @@ 6: font border. if the font is to be displayed without border this will probably be adjusted to font background or near. 7-9: transition between border and foreground - 10: font color (foreground) + 10: font color (foreground) */</programlisting> <para> The so called 'transitions' are used to implement font anti-aliasing. That convention requires that any font file must use only the colors from 1 to 10. When we use the set_text_palette() function we are just copying 11 palette - entries to the specified base index. + entries to the specified base index. </para> <para> That base index is the same we pass to render_text() function to use the @@ -618,13 +618,13 @@ </para> <programlisting> /* obtains size the text will occupy */ - renderer->get_text_size(osd, text, &width, &height); + renderer->get_text_size(osd, text, &width, &height); /* draws a box using font background color (translucid) */ - renderer->filled_rect(osd, x1, y1, x1+width, y1+height, OSD_TEXT2 + 1); + renderer->filled_rect(osd, x1, y1, x1+width, y1+height, OSD_TEXT2 + 1); - /* render text */ - renderer->render_text(osd, x1, y1, text, OSD_TEXT2);</programlisting> + /* render text */ + renderer->render_text(osd, x1, y1, text, OSD_TEXT2);</programlisting> </sect3> <sect3> <title>OSD text and palette FAQ</title> @@ -669,8 +669,8 @@ <para> A: osd objects have no shadows by itself, but fonts use 11 colors to produce an anti-aliased effect. - if you set a "text palette" with entries 0-9 being transparent - and 10 being foreground you will get rid of any borders or + if you set a "text palette" with entries 0-9 being transparent + and 10 being foreground you will get rid of any borders or anti-aliasing. </para> </sect3> diff --git a/doc/hackersguide/intro.sgml b/doc/hackersguide/intro.sgml index c7dce6254..cd163e2ee 100644 --- a/doc/hackersguide/intro.sgml +++ b/doc/hackersguide/intro.sgml @@ -4,9 +4,9 @@ <sect1> <title>Where am I?</title> <para> - You are currently looking at a piece of documentation for xine. + You are currently looking at a piece of documentation for xine. xine is a free video player. It lives on - <ulink url="http://xinehq.de/">http://xinehq.de/</ulink>. Specifically + <ulink url="http://www.xine-project.org/">http://www.xine-project.org/</ulink>. Specifically this document goes under the moniker of the "xine Hackers' Guide". </para> </sect1> @@ -36,7 +36,7 @@ </para> <para> New versions of this document can also be obtained from the xine web site: - <ulink url="http://xinehq.de/">http://xinehq.de/</ulink>. + <ulink url="http://www.xine-project.org/">http://www.xine-project.org/</ulink>. </para> </sect1> diff --git a/doc/hackersguide/library.fig b/doc/hackersguide/library.fig index 13dc79f0e..ec33d0f32 100644 --- a/doc/hackersguide/library.fig +++ b/doc/hackersguide/library.fig @@ -2,7 +2,7 @@ Landscape Center Metric -A4 +A4 100.00 Single -2 diff --git a/doc/hackersguide/library.sgml b/doc/hackersguide/library.sgml index 1d987d259..eb51baaaf 100644 --- a/doc/hackersguide/library.sgml +++ b/doc/hackersguide/library.sgml @@ -32,7 +32,7 @@ Details on the OSD feature can be found in the <link linkend="osd">OSD section</link>. </para> </sect1> - + <sect1> <title>Writing a new frontend to xine</title> <para> @@ -51,21 +51,21 @@ <programlisting> /* ** 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. -** +** */ /* @@ -127,7 +127,7 @@ static void dest_size_cb(void *data, int video_width, int video_height, double v /* 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, + int *dest_width, int *dest_height, double *dest_pixel_aspect, int *win_x, int *win_y) { *dest_x = 0; *dest_y = 0; @@ -139,7 +139,7 @@ static void frame_output_cb(void *data, int video_width, int video_height, } static void event_listener(void *user_data, const xine_event_t *event) { - switch(event->type) { + switch(event->type) { case XINE_EVENT_UI_PLAYBACK_FINISHED: running = 0; break; @@ -147,11 +147,11 @@ static void event_listener(void *user_data, const xine_event_t *event) { 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 */ } } @@ -175,7 +175,7 @@ int main(int argc, char **argv) { else if (strcmp(argv[i], "-ao") == 0) { ao_driver = argv[++i]; } - else + else mrl = argv[i]; } @@ -195,7 +195,7 @@ int main(int argc, char **argv) { 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; @@ -212,7 +212,7 @@ int main(int argc, char **argv) { 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); @@ -223,14 +223,14 @@ int main(int argc, char **argv) { 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; @@ -239,7 +239,7 @@ int main(int argc, char **argv) { 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); @@ -249,11 +249,11 @@ int main(int argc, char **argv) { /* 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); @@ -269,12 +269,12 @@ int main(int argc, char **argv) { if( got_event ) XNextEvent(display, &xevent); XUnlockDisplay(display); - + if( !got_event ) { xine_usec_sleep(20000); continue; } - + switch(xevent.type) { case KeyPress: @@ -283,27 +283,27 @@ int main(int argc, char **argv) { 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; @@ -313,36 +313,36 @@ int main(int argc, char **argv) { DefaultRootWindow(display), 0, 0, &xpos, &ypos, &tmp_win); XUnlockDisplay(display); - - xine_port_send_gui_data(vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED, + + 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_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_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) @@ -350,26 +350,26 @@ int main(int argc, char **argv) { 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, @@ -382,26 +382,26 @@ int main(int argc, char **argv) { } } 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_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; }</programlisting> </sect2> diff --git a/doc/hackersguide/output.sgml b/doc/hackersguide/output.sgml index 806e89d0a..64adbd294 100644 --- a/doc/hackersguide/output.sgml +++ b/doc/hackersguide/output.sgml @@ -116,7 +116,7 @@ <programlisting> if (_x_post_dispose(this)) really_free(this);</programlisting> - <function>_x_post_dispose()</function> frees any ressources allocated by any of the + <function>_x_post_dispose()</function> frees any ressources allocated by any of the post plugin helper functions and returns boolean true, if the plugin is not needed any more. </para> @@ -267,7 +267,7 @@ a deep copy of the frame, because the decoder might still use the frame as a reference frame for future decoding. The usual procedure is: <programlisting> - modified_frame = port->original_port->get_frame(port->original_port, ...); + modified_frame = port->original_port->get_frame(port->original_port, …); _x_post_frame_copy_down(frame, modified_frame); copy_and_modify(frame, modified_frame); skip = modified_frame->draw(modified_frame, stream); @@ -434,7 +434,7 @@ <listitem> <para> This function can only be called by the xine engine, plugins do not have access to it. - It ends ticket revocation and hands out new tickets to all threads that applied with a + It ends ticket revocation and hands out new tickets to all threads that applied with a <function>acquire()</function> or <function>renew()</function>. If you revoked the tickets atomic, you have to issue them atomic. </para> @@ -499,7 +499,7 @@ <function>_x_post_rewire()</function> should be used in prominent locations where it is safe to be suspended. Candidates for such locations are at the beginning of the port's <function>open()</function> and - <function>get_frame()</function>/<function>get_buffer()</function> functions. + <function>get_frame()</function>/<function>get_buffer()</function> functions. The default pass through implementations for intercepted ports already do this. </para> <para> @@ -515,7 +515,7 @@ </sect3> </sect2> </sect1> - + <sect1> <title>Video output</title> <para> @@ -539,13 +539,13 @@ </listitem> <listitem> <para> - Most important, the ability to render/copy a given + Most important, the ability to render/copy a given frame to the output device. </para> </listitem> <listitem> <para> - Optionally the copying of the frame from a file dependant + 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). @@ -569,7 +569,7 @@ The <varname>visual_type</varname> 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 + X Windowing system) and also to determine the type of information passed to the <function>open_plugin()</function> function as its <varname>visual</varname> parameter. </para> <para> @@ -590,7 +590,7 @@ The <varname>visual</varname> 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 <type>x11_visual_t</type>, which amongst other things hold the + to a <type>x11_visual_t</type>, which amongst other things hold the <type>Display</type> 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 @@ -609,7 +609,7 @@ 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);</programlisting> - Handle the getting, setting of properties and define their bounds. + Handle the getting, setting of properties and define their bounds. Valid property IDs can be found in the <filename>video_out.h</filename> header file. </para> diff --git a/doc/hackersguide/overlays.fig b/doc/hackersguide/overlays.fig index 0301aead2..78ecda61c 100644 --- a/doc/hackersguide/overlays.fig +++ b/doc/hackersguide/overlays.fig @@ -2,7 +2,7 @@ Portrait Center Metric -A4 +A4 100.00 Single -2 diff --git a/doc/hackersguide/overview.sgml b/doc/hackersguide/overview.sgml index d405ac18c..18cc40396 100644 --- a/doc/hackersguide/overview.sgml +++ b/doc/hackersguide/overview.sgml @@ -201,7 +201,7 @@ <term><filename>libmad</filename> (imported)</term> <listitem> <para> - Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). + Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). ISO/IEC compliant decoder using fixed point math. </para> <para></para> @@ -460,7 +460,7 @@ <para> 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 + (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 @@ -497,7 +497,7 @@ <term><filename>xine-engine</filename></term> <listitem> <para> - The heart of xine - it's engine. Contains code to + The heart of xine – its 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. @@ -529,7 +529,7 @@ <sect1> <title>Object oriented programming in C</title> <para> - xine uses a lot of design principles normally found in + 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. @@ -561,7 +561,7 @@ my_stack_t stack; /* public part */ /* private part follows here */ - int values[MAX_STACK_SIZE]; + int values[MAX_STACK_SIZE]; int stack_size; } intstack_t;</programlisting> Each method is implemented as a static method (static to prevent @@ -573,7 +573,7 @@ <programlisting> 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; + this->values[MAX_STACK_SIZE - ++this->stack_size] = i; }</programlisting> </para> <para> @@ -613,15 +613,15 @@ this = malloc(sizeof(intstack_t)); /* fill in methods */ - this->push = push; - this->add = add; - this->pop = pop; + this->push = push; + this->add = add; + this->pop = pop; /* init data fields */ - this->stack_size = 0; + this->stack_size = 0; /* return public part */ - return &this->stack; + return &this->stack; }</programlisting> </para> <sect2> @@ -646,7 +646,7 @@ </para> </sect2> </sect1> - + <sect1> <title>Coding style and guidelines</title> <para> @@ -655,44 +655,44 @@ Contributions will not be rejected if they do not meet these rules but they will be even more appreciated if they do. <itemizedlist> - <listitem> + <listitem> <para> Comment your interfaces directly in the header files. No doxygen comments, ordinary C comments will do. </para> </listitem> - <listitem> + <listitem> <para> Use C-style comments (/* */), not C++-style (//). </para> </listitem> - <listitem> + <listitem> <para> When in doubt, use lower case. BTW: This thing is called xine, never Xine. </para> </listitem> - <listitem> + <listitem> <para> 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). </para> </listitem> - <listitem> + <listitem> <para> Avoid macros unless they are really useful. Avoid gotos. </para> </listitem> - <listitem> + <listitem> <para> use something like - <programlisting> printf("module: ..."[,...]);</programlisting> + <programlisting> printf("module: ..."[,…]);</programlisting> for console output. All console output goes to stdout and must be prefixed by the module name which generates the output (see example above). </para> </listitem> - <listitem> + <listitem> <para> Refer to emac's C-mode for all questions of proper indentiation. That first of all means: indent with two spaces. @@ -701,7 +701,7 @@ </itemizedlist> </para> </sect1> - + <sect1> <title>The xine logging system</title> <para> @@ -714,7 +714,7 @@ <para> Output which is done thru this function will be displayed for the end user by the frontend. - If <varname>xine->verbosity</varname> is not 0 the messages will also + If <varname>xine->verbosity</varname> is not 0 the messages will also be displayed on the console. Ideally these strings are translated. This function is for information which the user should @@ -727,7 +727,7 @@ <sect2> <title>xprintf</title> <para> - This macro uses the <varname>xine->verbosity</varname> value to decide + This macro uses the <varname>xine->verbosity</varname> value to decide if the string should be printed to the console. Possible values are XINE_VERBOSITY_NONE, XINE_VERBOSITY_LOG or XINE_VERBOSITY_DEBUG. By default nothing is printed. @@ -806,6 +806,32 @@ working on other parts of the code or are simply busy at the moment). </para> + <para> + We prefer to receive patches in a format which is immediately + committable. This normally means that we want your name and email address + (we're not keen on pseudonyms), a subject line which provides a + convenient summary of your changes, and body text which provides a longer + description (if needed). Patches must be generated using <command>hg + diff</command> or <command>cvs -z9 diff</command>, depending on which is + used for the repository, and always from within the top level of the + checked-out source. + </para> + <para> + If your patch is intended for a Mercurial-format repository, then + committing it locally and using + <command>hg export <parameter>.</parameter> ><filename>foo.patch</filename></command> + to create the file to be attached is acceptable (but note that the first + line – up to the first line feed – of the commit message is regarded as + the patch summary; if you're not sure, check with + <command>hg log -r<parameter>.</parameter></command>. + Alternatively, use <token>From:</token> and <token>Subject:</token> lines + in the patch file itself; this is useful when forwarding. + </para> + <para> + Patches should normally be included as attachments. Some mail clients and + webmail services are known to mangle whitespace or wrap lines, either of + which is enough to render a patch potentially useless. + </para> </sect1> </chapter> diff --git a/doc/hackersguide/post_frame.fig b/doc/hackersguide/post_frame.fig index 4f576abdd..efafa31d5 100644 --- a/doc/hackersguide/post_frame.fig +++ b/doc/hackersguide/post_frame.fig @@ -2,7 +2,7 @@ Landscape Center Metric -A4 +A4 100.00 Single -2 diff --git a/doc/hackersguide/stream.sgml b/doc/hackersguide/stream.sgml index d05bbba65..b9690d9fe 100644 --- a/doc/hackersguide/stream.sgml +++ b/doc/hackersguide/stream.sgml @@ -1,11 +1,11 @@ <chapter id="stream"> <title>xine's stream layer</title> - + <sect1> <title>Input layer</title> <para> Many media players expect streams to be stored within files on - some local medium. In actual fact, media may be streamed over a + some local medium. In actual fact, media may be streamed over a network (e.g. via HTTP or RTP), encoded onto a specialized medium (e.g. DVD), etc. To allow you to access all this media, xine supports the concept of an "input plugin". The tasks performed by an @@ -156,7 +156,7 @@ <para> xine's demuxer layer is responsible for taking apart multimedia files or streams so that the engine can decode them and present them to the user. - "Demuxer" is short for demultiplexor, which is the opposite of + "Demuxer" is short for demultiplexor, which is the opposite of multiplexing. This refers to the process of combining 2 or more things into one. Multimedia streams usually, at a minimum, multiplex an audio stream and a video stream together into one stream. Sometimes, there are @@ -329,7 +329,7 @@ <programlisting> void demux_send_headers(demux_plugin_t *this_gen);</programlisting> This function generally reads the headers of the stream, does whatever it has to do to figure out what audio and video codecs are used in the file, - and asks the xine engine to initialize the correct decoders with the + and asks the xine engine to initialize the correct decoders with the proper parameters (like width and height for video, sample rate and channels for audio). </para> @@ -392,9 +392,9 @@ <programlisting> buf_element_t *buf; - buf = stream->video_fifo->buffer_pool_alloc(stream->video_fifo); - buf->type = BUF_CONTROL_START; - stream->video_fifo->put(stream->video_fifo, buf);</programlisting> + buf = stream->video_fifo->buffer_pool_alloc(stream->video_fifo); + buf->type = BUF_CONTROL_START; + stream->video_fifo->put(stream->video_fifo, buf);</programlisting> <para> Buffers must have set the <varname>type</varname> field as shown. All buffer types are defined in <filename>xine-engine/buffer.h</filename>. @@ -410,7 +410,7 @@ To help finding out buffer types for known codecs, functions from <filename>buffer_types.c</filename> may be used to convert "FOURCC" codes or audio format tags (as used in AVI files) to the xine byffer type: - <programlisting> buf->type = fourcc_to_buf_video((void*)this->avi->bih.biCompression);</programlisting> + <programlisting> buf->type = fourcc_to_buf_video((void*)this->avi->bih.biCompression);</programlisting> </para> </sect2> </sect1> @@ -620,7 +620,7 @@ video, subtitles do not form a continuous stream. The decoder will therefore only be called once in a while. The metronom call for timestamping, which for audio and video is done by the engine, has to be done manually for SPU: - <programlisting> vpts = metronom->got_spu_packet(metronom, buf->pts);</programlisting> + <programlisting> vpts = metronom->got_spu_packet(metronom, buf->pts);</programlisting> </para> <para> Another difference is that while both audio and video decoders are automatically |