X11Renderer Class Reference

This I/O class renders a gray-scale or RGB24/32 stream the used X11-Window is created within this function, incl. CTRL-C/ESC signal/event catchers. More...

#include <X11Renderer.hpp>

Inheritance diagram for X11Renderer:

VideoRenderer IO VThread List of all members.

Public Member Functions

 X11Renderer (const VideoESInfo *es, UncompressedVideoFrame::ColorSpace colorSpace, int width, int height, bool pollEvents=true, bool isLabelResizable=true, bool fixAspectRatio=true, bool allowUpscaleX=false)
 Constructor.
virtual ~X11Renderer ()
 Destructor.
virtual int writeFrame (Frame *frm, ESInfo *out_es=NULL)
 Renders a frame to the destination YUV_Overlay/RGB_Surface.
virtual bool open ()
 Creates internal frame buffers and checks whether the stream to be rendered matches the widget dimensions.

Protected Member Functions

bool updateDisplayRegion ()
 Update frame_info (except size) and display_region.

Detailed Description

This I/O class renders a gray-scale or RGB24/32 stream the used X11-Window is created within this function, incl. CTRL-C/ESC signal/event catchers.

It is intended to be used as a DataSink connected to a DataChannel.

Video frames will be (down or up) scaled to fit into the given size by preserving the aspect ratio given in VideoESInfo.

The expected format of the gray-scale stream is: 1 byte per pixel.

The expected format of the RGB24 stream is: 3 bytes per pixel, in the order RGB (red, green, blue).

The expected format of the RGB32 stream is: 4 bytes per pixel, in the order BGRA (blue, green, red, alpha). This conforms to the PIX_FMT_RGBA32 format defined in ffmpeg/libavcodec/avcodec.h on little endian architectures.

Author:
Michael Kropfberger
Version:
Id
X11Renderer.hpp,v 1.10 2006/05/12 11:32:50 mkropfbe Exp

Definition at line 90 of file X11Renderer.hpp.


Constructor & Destructor Documentation

X11Renderer::X11Renderer const VideoESInfo *  es,
UncompressedVideoFrame::ColorSpace  colorSpace,
int  width,
int  height,
bool  pollEvents = true,
bool  isLabelResizable = true,
bool  fixAspectRatio = true,
bool  allowUpscaleX = false
 

Constructor.

If the parameters are invalid, the open() method will fail.

Parameters:
es elementary stream information about the video stream to be rendered.
colorSpace the color space of the video stream to be rendered; must be one of: UncompressedVideoFrame::ColorSpaceGRAY8, UncompressedVideoFrame::ColorSpaceRGB565, UncompressedVideoFrame::ColorSpaceRGB24, UncompressedVideoFrame::ColorSpaceRGB32, UncompressedVideoFrame::ColorSpaceI420, UncompressedVideoFrame::ColorSpaceYV12
width the width of the SDL window
height the height of the SDL window
pollEvents if true, the SDL event handler is checked for keypresses like CTRL-C or ESC, and a "SDL window close" is detected if such an event occurs, the state of the stream is set to STREAMERR beware, that this polling might grab away ALL events, so implement on on your own, if you want to support eg. joysticks or more keycodes!
isLabelResizable if true, the given width/height is assumed to be flexible, so it will be tried to keep the original video size (plus adhering #fixAspectRatio) setting this to true, width&height may be zero, only the video is used to determine the resolution
fixAspectRatio if true, video frames may be resized according to their ESInfo aspectRatio, which means upscaling in the y-dimension
allowUpscaleX if true, video frames may be upscaled in x-dimension to fit the label, which may result in significant quality loss, since a very simple upscaling algorithm is used (assumes isLabelResizable==false).
Definition at line 54 of file X11Renderer.cpp.

References UncompressedVideoFrame::ColorSpace.

00057 : VideoRenderer(_es, colorSpace, width, height, isLabelResizable, fixAspectRatio, allowUpscaleX) 00058 { 00059 dprintf_full("X11Renderer Construct %s ES %p\n",this->url, this->es); 00060 strcpy(this->url,"X11Renderer"); 00061 this->pollEvents = pollEvents; 00062 }


Member Function Documentation

bool X11Renderer::open  )  [virtual]
 

Creates internal frame buffers and checks whether the stream to be rendered matches the widget dimensions.

Returns:
true on success, false on error.
See also:
IO::open()

Reimplemented from VideoRenderer.

Definition at line 110 of file X11Renderer.cpp.

References UncompressedVideoFrame::mapColorSpaceToBitDepth(), and updateDisplayRegion().

00111 { 00112 if (state != CLOSED) { 00113 dprintf_err("X11Renderer::open state was not CLOSED but state=%i!\n",state); 00114 return false; 00115 } 00116 00117 if (!updateDisplayRegion()) { 00118 state = STREAMERR; 00119 return false; 00120 } 00121 00122 char hostname[MAX_STR_LEN]; 00123 char *envhost = getenv("DISPLAY"); 00124 if (!envhost) 00125 strcpy(hostname,"localhost:0"); 00126 else 00127 strcpy(hostname,envhost); 00128 00129 display = XOpenDisplay(hostname); 00130 assert(display); 00131 screennr = XDefaultScreen(display); 00132 screen = XDefaultScreenOfDisplay(display); 00133 depth = XDefaultDepth(display,screennr); 00134 winAttrib.background_pixel = BlackPixel(display, screennr); 00135 winAttrib.border_pixel = BlackPixel(display, screennr); 00136 winAttrib.backing_store = Always; 00137 winAttrib.bit_gravity = StaticGravity; 00138 XVisualInfo visual_info; 00139 Visual *def_visual = XDefaultVisual(display,screennr); 00140 unsigned int attr_val = CWBackingStore | CWBackPixel | CWBorderPixel; 00141 int visualClass = -1; 00142 00143 setOutputDepth(depth); 00144 00145 /* FIXME: only tested for DirectColor on 16/24 bit X11 display! */ 00146 if (!XMatchVisualInfo(display, screennr, depth, PseudoColor, &visual_info)) { 00147 if (!XMatchVisualInfo(display, screennr, depth, DirectColor, &visual_info)) { 00148 /* No PseudoColor visual available at default_depth; 00149 * some applications might try for a GrayScale 00150 * visual here if they can use gray to advantage, 00151 * before giving up and using black and white */ 00152 dprintf_err("X11Renderer::open() could not find PseudoColor or DirectColor visual!\n"); 00153 ::exit(0); 00154 } else 00155 visualClass = DirectColor; 00156 } else 00157 visualClass = PseudoColor; 00158 00159 dprintf_full("X11Renderer:open outputDepth %i, defaultVisual %p, pseudo/directColor visualID 0x%x\n", 00160 depth, def_visual, (int)visual_info.visualid); 00161 00162 00163 00164 00165 if (visualClass != DirectColor) 00166 XCreateColormap(display, RootWindowOfScreen(screen), visual_info.visual, AllocNone); 00167 else { 00168 XColor cols[256]; 00169 unsigned int cm_size, red_mask, green_mask, blue_mask; 00170 unsigned int k, r, g, b, ru, gu, bu, m, rv, gv, bv, rvu, gvu, bvu; 00171 cm_size = visual_info.colormap_size; 00172 red_mask = visual_info.red_mask; 00173 green_mask = visual_info.green_mask; 00174 blue_mask = visual_info.blue_mask; 00175 ru = (red_mask & (red_mask - 1)) ^ red_mask; 00176 gu = (green_mask & (green_mask - 1)) ^ green_mask; 00177 bu = (blue_mask & (blue_mask - 1)) ^ blue_mask; 00178 rvu = 65536ull * ru / (red_mask + ru); 00179 gvu = 65536ull * gu / (green_mask + gu); 00180 bvu = 65536ull * bu / (blue_mask + bu); 00181 r = g = b = 0; 00182 rv = gv = bv = 0; 00183 m = DoRed | DoGreen | DoBlue; 00184 for (k = 0; k < cm_size; k++) { 00185 unsigned int t; 00186 00187 cols[k].pixel = r | g | b; 00188 cols[k].red = rv; 00189 cols[k].green = gv; 00190 cols[k].blue = bv; 00191 cols[k].flags = m; 00192 t = (r + ru) & red_mask; 00193 if (t < r) 00194 m &= ~DoRed; 00195 r = t; 00196 t = (g + gu) & green_mask; 00197 if (t < g) 00198 m &= ~DoGreen; 00199 g = t; 00200 t = (b + bu) & blue_mask; 00201 if (t < b) 00202 m &= ~DoBlue; 00203 b = t; 00204 rv += rvu; 00205 gv += gvu; 00206 bv += bvu; 00207 } 00208 winAttrib.colormap = XCreateColormap(display, RootWindowOfScreen(screen), visual_info.visual, AllocAll); 00209 XStoreColors(display, winAttrib.colormap, cols, cm_size); 00210 } 00211 00212 XInstallColormap(display, winAttrib.colormap); // put cm into hardware! 00213 00214 attr_val |= CWColormap; 00215 00216 xwin=XCreateWindow(display, XRootWindow(display,screennr) 00217 ,0, 0, out_label_info.width, out_label_info.height, 1 00218 ,depth, InputOutput, 00219 visual_info.visual 00220 //def_visual 00221 , attr_val, &winAttrib); 00222 00223 XStoreName(display, xwin, "ViTooKi X11Renderer"); 00224 XSetIconName(display, xwin, "ViTooKi X11Renderer"); 00225 XSetWindowBackground(display, xwin, 0xFFFFFF); 00226 XMapWindow(display, xwin); 00227 XSync(display, 0); 00228 00229 hideCursor(display,xwin); 00230 00231 /* initialize frameBuffer */ 00232 if (frameBuffer) { 00233 delete frameBuffer; 00234 frameBuffer = NULL; 00235 } 00236 00237 bool gray = false; 00238 switch (colorSpace) { 00239 case UncompressedVideoFrame::ColorSpaceGRAY8: 00240 dprintf_full("X11Renderer::open() ColorSpaceGRAY8\n"); 00241 gray=true; 00242 frame_info.size = frame_info.width * frame_info.height; 00243 break; 00244 case UncompressedVideoFrame::ColorSpaceRGB24: 00245 dprintf_full("X11Renderer::open() ColorSpaceRGB24\n"); 00246 frame_info.size = frame_info.width * frame_info.height * 3; 00247 break; 00248 case UncompressedVideoFrame::ColorSpaceRGB32: 00249 dprintf_full("X11Renderer::open() ColorSpaceRGB32\n"); 00250 frame_info.size = frame_info.width * frame_info.height * 4; 00251 break; 00252 case UncompressedVideoFrame::ColorSpaceRGB565: 00253 dprintf_full("X11Renderer::open() ColorSpaceRGB565\n"); 00254 frame_info.size = frame_info.width * frame_info.height * 2; 00255 break; 00256 case UncompressedVideoFrame::ColorSpaceYV12: 00257 case UncompressedVideoFrame::ColorSpaceI420: 00258 dprintf_err("X11Renderer::open() ColorSpaceYV12 or I420 NOT SUPPORTED on X11!!!\n"); 00259 ::exit(1); 00260 break; 00261 default: 00262 dprintf_err("X11Renderer::open(): invalid color space: %d\n", colorSpace); 00263 state = STREAMERR; 00264 return false; 00265 } 00266 00267 if ( (depth == 16) && //FIXME: sorry, but 24 bitBlt does not seem to work... 32bit is untested 00268 (depth == UncompressedVideoFrame::mapColorSpaceToBitDepth(colorSpace) ) && 00269 (out_label_info.width == frame_info.width) && (out_label_info.height == frame_info.height) && 00270 (display_region.left == 0) && (display_region.top == 0) ) 00271 directBitBlt=true; //optimize via rgbSurface bitBlitting 00272 else 00273 directBitBlt=false; //use slow pixel-per-pixel painting and scaling 00274 00275 00276 frameBuffer = new X11FrameBuffer(display, &xwin, depth, gray, display_region.width, display_region.height ); 00277 00278 if (!frameBuffer) { 00279 dprintf_err("X11Renderer::open(): X11FrameBuffer creation FAILED! (w = %d, h = %d)\n", 00280 display_region.width, display_region.height ); 00281 state = STREAMERR; 00282 return false; 00283 } 00284 00285 state = OPEN; 00286 framesSeen = 0; 00287 currentFrameNumber = 0; 00288 dprintf_small("X11Renderer::open(): initialized frame and display regions:\n" 00289 " frame: width = %d, height = %d, size = %d, scaleX = %5.3f, scaleY = %5.3f\n" 00290 " display: x(%d:%d), y(%d:%d), width = %d, height = %d\n", 00291 frame_info.width, frame_info.height, frame_info.size, 00292 FIXED2DOUBLE(frame_info.scaleX), FIXED2DOUBLE(frame_info.scaleY), 00293 display_region.left, display_region.left + display_region.width, 00294 display_region.top, display_region.top + display_region.height, 00295 display_region.width, display_region.height); 00296 return true; 00297 }

bool X11Renderer::updateDisplayRegion  )  [protected]
 

Update frame_info (except size) and display_region.

This function is not thread-safe, and is internally called by the open() method.

Reimplemented from VideoRenderer.

Definition at line 72 of file X11Renderer.cpp.

References VideoRenderer::updateDisplayRegion().

Referenced by open().

00072 { 00073 00074 if (!es || !es->isVisualStream()) { 00075 dprintf_err("X11Renderer::updateDisplayRegion(): invalid members: es = %p\n",es); 00076 ::exit(1); 00077 return false; 00078 } 00079 00080 return VideoRenderer::updateDisplayRegion(); 00081 }

int X11Renderer::writeFrame Frame frm,
ESInfo out_es = NULL
[virtual]
 

Renders a frame to the destination YUV_Overlay/RGB_Surface.

Returns:
1 on success, 0 on error.

Reimplemented from VideoRenderer.

Definition at line 300 of file X11Renderer.cpp.

References VideoRenderer::writeFrame().

00300 { 00301 return VideoRenderer::writeFrame(frm, out_es); 00302 00303 }


The documentation for this class was generated from the following files: