From 562cc15a71c2c59fdc63563559c0dc129a7c0aeb Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Sat, 24 Aug 2002 16:48:56 +0000 Subject: text about overlays and osd CVS patchset: 2508 CVS date: 2002/08/24 16:48:56 --- doc/hackersguide/hackersguide.sgml | 197 +++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) (limited to 'doc') diff --git a/doc/hackersguide/hackersguide.sgml b/doc/hackersguide/hackersguide.sgml index 7c1b201d9..90e45e561 100644 --- a/doc/hackersguide/hackersguide.sgml +++ b/doc/hackersguide/hackersguide.sgml @@ -372,6 +372,203 @@ The xine engine from the inside + + Overlays and OSD + + The roots of xine overlays 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? + Wrong, they are bitmaps. + + + In order to optimize to the most common case, xine internal format for screen overlays + 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 + for displaying with mpeg hardware decoders like DXR3. + + + Displaying subtitles requires the ability to sync them to the video stream. This + 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. + + + 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 + providing simple graphic primitives (lines, rectagles, draw text etc) over + a "virtual" bitmap area. Everytime we want to show that bitmap it will + be RLE encoded and sent to the overlay manager for displaying. + + + + + + + + + + overlays architecture + + + + Overlay Manager + + The overlay manager interface is available to any xine plugin. It's a bit unlikely + to be used directly, anyway here's a code snipped for enqueueing an overlay for + displaying: + + video_overlay_event_t event; + + event.object.handle = this->video_overlay->get_handle(this->video_overlay,0); + + 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; + + /* 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 = something; + + /* palette must contain YUV values for each color index */ + memcpy(event.object.overlay->clip_color, color, sizeof(color)); + + /* this table contains transparency level for each color index. + 0 = completely transparent, 15 - completely opaque */ + 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,(void *)&event); + + + + + OSD Renderer + + OSD is a general API for rendereing stuff over playing video. It's available both + to xine plugins and to frontends. + + + 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 + over the image. + + + osd_object_t osd; + + osd = this->osd_renderer->new_object (osd_renderer, 300, 200); + + + Now we may want to set font and color for text rendering. Although we will + refer to fonts over this document, in fact it can be any kind of bitmap. Font + files are searched and loaded during initialization from /usr/[local]/share/xine/fonts/ + and ~/.xine/fonts. There's a sample utility to convert truetype fonts at + /xine-lib/misc/xine-fontconv.c. Palette may be manipulated directly, however most of + the time it's convenient to use pre-defined text palettes. + + + /* set sans serif 24 font */ + 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 ); + + /* 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 ); + + + Now render the text and show it: + + + 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' */ + + There's a 1:1 mapping between OSD objects and overlays, therefore the + second time you send an OSD object for displaying it will actually substitute + the first image. By using set_position() function we can move overlay + over the video. + + + for( i=0; i < 100; i+=10 ) { + osd_renderer->set_position(osd, i, i ); + osd_renderer->show(osd, 0); + sleep(1); + } + osd_renderer->hide(osd, 0); + + + For additional functions please check osd.h. + + + OSD palette notes + + The palette functions demand some additional explanation, skip this if you + just want to write text fast without worring with details! :) + + + We have a 256-entry palette, each one defining yuv and transparency levels. + Although xine fonts are bitmaps and may use any index they want, we have + defined a small convention: + + +/* + Palette entries as used by osd fonts: + + 0: not used by font, always transparent + 1: font background, usually transparent, may be used to implement + translucid boxes where the font will be printed. + 2-5: transition between background and border (usually only alpha + value changes). + 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) +*/ + + + 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. + + + That base index is the same we pass to render_text() function to use the + text palette. With this scheme is possible to have several diferent text + colors at the same time and also draw fonts over custom background. + + + /* obtains size the text will occupy */ + 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 ); + + /* render text */ + renderer->render_text(osd, x1, y1, text, OSD_TEXT2 ); + + + + Plugin architecture -- cgit v1.2.3