?? display.cc
字號:
/* File: display.cc By: Alex de Jong (original by MSSG) Created: March 1996 Description: Multi-Threaded display class. Displays class is able to synchronize frames with a synchronoization object, which in turn is updates by a decoder timer.*/#ifdef __GNUG__#pragma implementation#endif#include "athread.hh"#include <stdio.h>#include <fstream.h>#include <sys/time.h>#include "error.hh"#include "debug.hh"#include "util.hh"#include "videoconst.hh"#include "sync.hh"#include "display.hh"extern int quiet;extern int coded_picture_width;extern int coded_picture_height;extern int prog_seq;extern int chroma_format;extern int chrom_width;extern int pict_struct, topfirst;extern int convmat[8][4];extern int matrix_coefficients;extern int playedlastframe;// #define USE_DGA 1 /* enable this to use DGA extention */#ifdef SH_MEM// Dummies to get rid of warningsextern "C" {int XShmQueryExtension(Display*);int XShmGetEventBase(Display*);}#ifdef USE_DGA#include <X11/extensions/xf86dga.h>#include <X11/extensions/xf86vmode.h>#endif#endif#ifdef SOLARIS_SDK_XILXil_boolean error_handler(XilError error){ xil_call_next_error_handler(error); error("XIL received an error: exiting!"); exit(1); return True;}#endif // SOLARIS_SDK_XILDisplayX11::DisplayX11(const char* title, Synchronization* s){ TRACER("DisplayX11::DisplayX11(const char* title, Synchronization* s)"); int crv, cbu, cgu, cgv; int y, u, v, r, g, b; int i, j; Colormap cmap; XColor xcolor; unsigned int fg, bg; XSizeHints hint; unsigned long tmp_pixel; XWindowAttributes xwa; int screen; // init to avoid invalid destroy in destructor ximage=0; ximage2=0; // Synchronization with decoder clock sync=s; // Init display lock/condition to prevent threads to pass eachother source=0;#ifdef SOLARIS_SDK_XIL resized=0; // window has not been resized horizontal_size=100; vertical_size=100; horizontal_factor=1.0; vertical_factor=1.0;#else#ifdef SH_MEM CompletionType = -1;#endif#endif // create clipping table clp=new unsigned char[1024]; // clip table clp += 384; for (i=-384; i<640; i++) clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i); if (!(display=XOpenDisplay(0))){ error("Can not open display\n"); athr_exit(0); }#ifdef TRACE XSynchronize(display, 1);#endif screen = DefaultScreen(display); // find best display if (XMatchVisualInfo(display, screen, 24, TrueColor, &vinfo)){ } else#if (defined(LINUX)&&defined(MMX)) if (XMatchVisualInfo(display, screen, 16, TrueColor, &vinfo)){ } else#endif if (XMatchVisualInfo(display, screen, 8, PseudoColor, &vinfo)){ } else if (XMatchVisualInfo(display, screen, 8, GrayScale, &vinfo)){ } else if (XMatchVisualInfo(display, screen, 8, StaticGray, &vinfo)){ } else if (XMatchVisualInfo(display, screen, 1, StaticGray, &vinfo)) { }#ifdef LINUX else error("requires 16 bit display\n");#else else error("requires 8 bit or 24 bit display\n");#endif // Make the window hint.x = 200; hint.y = 200; hint.width = 100; hint.height= 100; hint.flags = PPosition | PSize; bpp = vinfo.depth; if (vinfo.red_mask == 0x7c00) rgb_mode = 1; // RGB555 for more modes see yuv12-rgb.s else rgb_mode = 0; // RGB565 if (vinfo.c_class==TrueColor && bpp == 24 ){#ifdef SOLARIS_SDK_XIL bands=3;#endif cmap=XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone); XSetWindowAttributes xswa; xswa.colormap = cmap; xswa.event_mask = StructureNotifyMask; xswa.border_pixel = BlackPixel(display, screen); window=XCreateWindow(display, DefaultRootWindow(display), hint.x, hint.y, hint.width, hint.height, 0, vinfo.depth, InputOutput, vinfo.visual, CWBorderPixel | CWColormap | CWEventMask, &xswa); } else {#ifdef SOLARIS_SDK_XIL bands=1;#endif // Get some colors bg = WhitePixel(display, screen); fg = BlackPixel(display, screen); window=XCreateSimpleWindow(display, DefaultRootWindow (display), hint.x, hint.y, hint.width, hint.height, 4, fg, bg); } // Tell other applications about this window XSetStandardProperties(display, window, title, title, None, NULL, 0, &hint); XSelectInput(display, window, StructureNotifyMask); // Map window XMapWindow(display, window); // Wait for map. do { XNextEvent(display, &event); } while (event.type != MapNotify || event.xmap.event != window); XSelectInput(display, window, NoEventMask); if (vinfo.c_class==PseudoColor){ // Do dithering before display int privte=0; // allocate colors gc = DefaultGC(display, screen); cmap = DefaultColormap(display, screen); // matrix coefficients crv = convmat[matrix_coefficients][0]; cbu = convmat[matrix_coefficients][1]; cgu = convmat[matrix_coefficients][2]; cgv = convmat[matrix_coefficients][3]; /* color allocation: * i is the (internal) 8 bit color number, it consists of separate * bit fields for Y, U and V: i = (yyyyuuvv), we don't use yyyy=0000 * yyyy=0001 and yyyy=1111, this leaves 48 colors for other applications * * the allocated colors correspond to the following Y, U and V values: * Y: 40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232 * U,V: -48, -16, 16, 48 * * U and V values span only about half the color space; this gives * usually much better quality, although highly saturated colors can * not be displayed properly * * translation to R,G,B is implicitly done by the color look-up table */ // THIS IS REALLY SLOW on a 24 Bit display. Please drop me a line if // you know how to do this faster (alex.dejong@nist.gov) // DON'T ALLOCATE 240 COLORS!! Just 215 will do and stops Solaris // from colors blinking when moving the cursor#if (defined(SOLARIS)) int number_of_colors=215;#endif#if (defined(IRIX)|| defined(LINUX)) int number_of_colors=240;#endif for (i=32; i<number_of_colors; i++){ /* color space conversion */ y = 16*((i>>4)&15) + 8; u = 32*((i>>2)&3) - 48; v = 32*(i&3) - 48; y = 76309 * (y - 16); /* (255/219)*65536 */ r = clp[(y + crv*v + 32768)>>16]; g = clp[(y - cgu*u -cgv*v + 32768)>>16]; b = clp[(y + cbu*u + 32786)>>16]; /* X11 colors are 16 bit */ xcolor.red = r << 8; xcolor.green = g << 8; xcolor.blue = b << 8; if (XAllocColor(display, cmap, &xcolor) != 0) pixel[i] = xcolor.pixel; else { /* allocation failed, have to use a private colormap */ if (privte) error("Couldn't allocate private colormap"); privte = 1; if (!quiet) fprintf(stderr, "Using private colormap (%d colors were available)\n", i-32); /* Free colors. */ while (--i >= 32){ tmp_pixel = pixel[i]; /* because XFreeColors expects unsigned long */ XFreeColors(display, cmap, &tmp_pixel, 1, 0); } /* i is now 31, this restarts the outer loop */ /* create private colormap */ XGetWindowAttributes(display, window, &xwa); cmap = XCreateColormap(display, window, xwa.visual, AllocNone); XSetWindowColormap(display, window, cmap); } } } else gc = DefaultGC(display, screen);/* Init dither 4x4 ordered dither threshold pattern: 0 8 2 10 12 4 14 6 3 11 1 9 15 7 13 5*/ unsigned char ctab[256+32]; for (i=0; i<256+16; i++){ v = (i-8)>>4; if (v<2) v=2; else if (v>14) v=14; for (j=0; j<16; j++) ytab[16*i+j] = pixel[(v<<4)+j]; } for (i=0; i<256+32; i++){ v = (i+48-128)>>5; if (v<0) v=0; else if (v>3) v=3; ctab[i]=v; } for (i=0; i<255+15; i++) for (j=0; j<255+15; j++) uvtab[256*i+j]=(ctab[i+16]<<6)|(ctab[j+16]<<4)|(ctab[i]<<2)|ctab[j];}DisplayX11::~DisplayX11(){ TRACER("DisplayX11::~DisplayX11()"); display_lock.lock(); if (!terminated) athr_join(thread_id); exit_display(); delete clp; // delete clipping table display_lock.unlock();}void* DisplayX11::dither_thread(DisplayX11* d){ d->display_lock.lock(); d->terminated=0; d->dither_image(d->source); d->display_image(d->ximage, d->dithered_image); d->source=0; d->display_cond.signal(); d->terminated=1; d->display_lock.unlock(); #if !defined(IRIX) && !defined(SOLARIS_SDK_XIL) && !defined(LINUX) athr_exit(0);#endif return 0;}void* DisplayX11::display_thread(DisplayX11* d){#ifndef LINUX d->display_lock.lock(); d->terminated=0; d->display_image(d->ximage2, d->dithered_image2); d->terminated=1; d->display_lock.unlock();#if !defined(IRIX) && !defined(SOLARIS_SDK_XIL) && !defined(LINUX) athr_exit(0);#endif#endif return 0;}int DisplayX11::init(int h_size, int v_size){ TRACER("void DisplayX11::init(int h_size, int v_size)"); display_lock.lock(); // lock the display from others access for now // resize window horizontal_size=h_size; vertical_size=v_size; XResizeWindow(display, window, horizontal_size, vertical_size);#ifdef SOLARIS_SDK_XIL if ((State = xil_open()) == NULL) exit(1); // XIL sends an error message to stderr if xil_open fails // Install error handler if (xil_install_error_handler(State, error_handler) == XIL_FAILURE)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -