display_x11.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:16k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /* 
  2.  * display_x11.c, X11 interface                                               
  3.  *
  4.  *
  5.  * Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. 
  6.  *
  7.  * Hacked into mpeg2dec by
  8.  * 
  9.  * Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
  10.  *
  11.  * 15 & 16 bpp support added by Franck Sicard <Franck.Sicard@solsoft.fr>
  12.  */
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <X11/Xlib.h>
  16. #include <X11/Xutil.h>
  17. #include <X11/extensions/XShm.h>
  18. #include <string.h>
  19. #include <errno.h>
  20. #include "mpeg2.h"
  21. #include "mpeg2_internal.h"
  22. int Inverse_Table_6_9[8][4] =
  23. {
  24.   {117504, 138453, 13954, 34903}, /* no sequence_display_extension */
  25.   {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
  26.   {104597, 132201, 25675, 53279}, /* unspecified */
  27.   {104597, 132201, 25675, 53279}, /* reserved */
  28.   {104448, 132798, 24759, 53109}, /* FCC */
  29.   {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
  30.   {104597, 132201, 25675, 53279}, /* SMPTE 170M */
  31.   {117579, 136230, 16907, 35559}  /* SMPTE 240M (1987) */
  32. };
  33. /* private prototypes */
  34. static void Display_Image (XImage * myximage, unsigned char *ImageData);
  35. /* local data */
  36. static unsigned char *ImageData;
  37. /* X11 related variables */
  38. static Display *mydisplay;
  39. static Window mywindow;
  40. static GC mygc;
  41. static XImage *myximage;
  42. static int bpp;
  43. static XWindowAttributes attribs;
  44. static int X_already_started = 0;
  45. #define SH_MEM
  46. #ifdef SH_MEM
  47. #include <sys/ipc.h>
  48. #include <sys/shm.h>
  49. #include <X11/extensions/XShm.h>
  50. //static int HandleXError _ANSI_ARGS_((Display * dpy, XErrorEvent * event));
  51. static void InstallXErrorHandler (void);
  52. static void DeInstallXErrorHandler (void);
  53. static int Shmem_Flag;
  54. static int Quiet_Flag;
  55. static XShmSegmentInfo Shminfo1;
  56. static int gXErrorFlag;
  57. static int CompletionType = -1;
  58. /*
  59. static int HandleXfprintf(stderr,Dpy, Event)
  60. Display *Dpy;
  61. XErrorEvent *Event;
  62. {
  63.     gXErrorFlag = 1;
  64.     return 0;
  65. }
  66. */
  67. static void InstallXErrorHandler()
  68. {
  69.     //XSetErrorHandler(HandleXError);
  70.     XFlush(mydisplay);
  71. }
  72. static void DeInstallXErrorHandler()
  73. {
  74.     XSetErrorHandler(NULL);
  75.     XFlush(mydisplay);
  76. }
  77. #endif
  78. // Clamp to [0,255]
  79. static uint_8 clip_tbl[1024]; /* clipping table */
  80. static uint_8 *clip;
  81. uint_32 image_width;
  82. uint_32 image_height;
  83. uint_32 progressive_sequence = 0;
  84. uint_32 matrix_coefficients = 1;
  85. /* connect to server, create and map window,
  86.  * allocate colors and (shared) memory
  87.  */
  88. void display_init(uint_32 width, uint_32 height)
  89. {
  90.    int screen;
  91.    unsigned int fg, bg;
  92.    sint_32 i;
  93.    char *hello = "I hate X11";
  94.    char *name = ":0.0";
  95.    XSizeHints hint;
  96.    XVisualInfo vinfo;
  97.    XEvent xev;
  98.    XGCValues xgcv;
  99.    Colormap theCmap;
  100.    XSetWindowAttributes xswa;
  101.    unsigned long xswamask;
  102.    clip = clip_tbl + 384;
  103.    for (i= -384; i< 640; i++)
  104.       clip[i] = (i < 0) ? 0 : ((i > 255) ? 255 : i);
  105.                 
  106.    image_height = height;
  107.    image_width = width;
  108.    if (X_already_started)
  109.       return;
  110.    if(getenv("DISPLAY"))
  111.       name = getenv("DISPLAY");
  112.    mydisplay = XOpenDisplay(name);
  113.    if (mydisplay == NULL)
  114.       fprintf(stderr,"Can not open displayn");
  115.    screen = DefaultScreen(mydisplay);
  116.    hint.x = 0;
  117.    hint.y = 10;
  118.    hint.width = image_width;
  119.    hint.height = image_height;
  120.    hint.flags = PPosition | PSize;
  121.    /* Get some colors */
  122.    bg = WhitePixel(mydisplay, screen);
  123.    fg = BlackPixel(mydisplay, screen);
  124.    /* Make the window */
  125.    XGetWindowAttributes(mydisplay, DefaultRootWindow(mydisplay), &attribs);
  126.    bpp = attribs.depth;
  127.    if (bpp != 15 && bpp != 16 && bpp != 24 && bpp != 32) {
  128.       fprintf(stderr,"Only 15,16,24, and 32bpp supported. Trying 24bpp!n");
  129.       bpp = 24;
  130.    }
  131.    //BEGIN HACK
  132.    //mywindow = XCreateSimpleWindow(mydisplay, DefaultRootWindow(mydisplay),
  133.    //hint.x, hint.y, hint.width, hint.height, 4, fg, bg);
  134.    //
  135.    XMatchVisualInfo(mydisplay,screen,bpp,TrueColor,&vinfo);
  136.    printf("visual id is  %lxn",vinfo.visualid);
  137.    theCmap   = XCreateColormap(mydisplay, RootWindow(mydisplay,screen), 
  138.                                vinfo.visual, AllocNone);
  139.    xswa.background_pixel = 0;
  140.    xswa.border_pixel     = 1;
  141.    xswa.colormap         = theCmap;
  142.    xswamask = CWBackPixel | CWBorderPixel |CWColormap;
  143.    mywindow = XCreateWindow(mydisplay, RootWindow(mydisplay,screen),
  144.                             hint.x, hint.y, hint.width, hint.height, 4, bpp,CopyFromParent,vinfo.visual,xswamask,&xswa);
  145.    XSelectInput(mydisplay, mywindow, StructureNotifyMask);
  146.    /* Tell other applications about this window */
  147.    XSetStandardProperties(mydisplay, mywindow, hello, hello, None, NULL, 0, &hint);
  148.    /* Map window. */
  149.    XMapWindow(mydisplay, mywindow);
  150.    /* Wait for map. */
  151.    do {
  152.       XNextEvent(mydisplay, &xev);
  153.    }
  154.    while (xev.type != MapNotify || xev.xmap.event != mywindow);
  155.    XSelectInput(mydisplay, mywindow, NoEventMask);
  156.    XFlush(mydisplay);
  157.    XSync(mydisplay, False);
  158.     
  159.    mygc = XCreateGC(mydisplay, mywindow, 0L, &xgcv);
  160.     
  161. #ifdef SH_MEM
  162.    if (XShmQueryExtension(mydisplay))
  163.       Shmem_Flag = 1;
  164.    else 
  165.    {
  166.       Shmem_Flag = 0;
  167.       if (!Quiet_Flag)
  168.          fprintf(stderr, "Shared memory not supportednReverting to normal Xlibn");
  169.    }
  170.    if (Shmem_Flag)
  171.       CompletionType = XShmGetEventBase(mydisplay) + ShmCompletion;
  172.    InstallXErrorHandler();
  173.    if (Shmem_Flag) {
  174.       myximage = XShmCreateImage(mydisplay, vinfo.visual, bpp, 
  175.                                  ZPixmap, NULL, &Shminfo1, width, 
  176.                                  image_height);
  177.       /* If no go, then revert to normal Xlib calls. */
  178.       if (myximage == NULL ) 
  179.       {
  180.          if (myximage != NULL)
  181.             XDestroyImage(myximage);
  182.          if (!Quiet_Flag)
  183.             fprintf(stderr, "Shared memory error, disabling (Ximage error)n");
  184.          goto shmemerror;
  185.       }
  186.       /* Success here, continue. */
  187.       Shminfo1.shmid = shmget(IPC_PRIVATE, 
  188.                               myximage->bytes_per_line * myximage->height ,
  189.                               IPC_CREAT | 0777);
  190.       if (Shminfo1.shmid < 0 ) {
  191.          XDestroyImage(myximage);
  192.          if (!Quiet_Flag)
  193.          {
  194.             printf("%sn",strerror(errno));
  195.             perror(strerror(errno));
  196.             fprintf(stderr, "Shared memory error, disabling (seg id error)n");
  197.          }
  198.          goto shmemerror;
  199.       }
  200.       Shminfo1.shmaddr = (char *) shmat(Shminfo1.shmid, 0, 0);
  201.       
  202.       if (Shminfo1.shmaddr == ((char *) -1)) {
  203.          XDestroyImage(myximage);
  204.          if (Shminfo1.shmaddr != ((char *) -1))
  205.             shmdt(Shminfo1.shmaddr);
  206.          if (!Quiet_Flag) {
  207.             fprintf(stderr, "Shared memory error, disabling (address error)n");
  208.          }
  209.          goto shmemerror;
  210.       }
  211.       myximage->data = Shminfo1.shmaddr;
  212.       ImageData = (unsigned char *) myximage->data;
  213.       Shminfo1.readOnly = False;
  214.       XShmAttach(mydisplay, &Shminfo1);
  215.       
  216.       XSync(mydisplay, False);
  217.       if (gXErrorFlag) {
  218.          /* Ultimate failure here. */
  219.          XDestroyImage(myximage);
  220.          shmdt(Shminfo1.shmaddr);
  221.          if (!Quiet_Flag)
  222.             fprintf(stderr, "Shared memory error, disabling.n");
  223.          gXErrorFlag = 0;
  224.          goto shmemerror;
  225.       } else {
  226.          shmctl(Shminfo1.shmid, IPC_RMID, 0);
  227.       }
  228.       if (!Quiet_Flag) {
  229.          fprintf(stderr, "Sharing memory.n");
  230.       }
  231.    } else {
  232.  shmemerror:
  233.       Shmem_Flag = 0;
  234. #endif
  235.       myximage = XGetImage(mydisplay, mywindow, 0, 0,
  236.                            width, image_height, AllPlanes, ZPixmap);
  237.       ImageData = myximage->data;
  238. #ifdef SH_MEM
  239.    }
  240.    DeInstallXErrorHandler();
  241. #endif
  242.    X_already_started++;
  243.  bpp = myximage->bits_per_pixel;
  244. }
  245. void Terminate_Display_Process() {
  246.    getchar(); /* wait for enter to remove window */
  247. #ifdef SH_MEM
  248.     if (Shmem_Flag) {
  249. XShmDetach(mydisplay, &Shminfo1);
  250. XDestroyImage(myximage);
  251. shmdt(Shminfo1.shmaddr);
  252.     }
  253. #endif
  254.     XDestroyWindow(mydisplay, mywindow);
  255.     XCloseDisplay(mydisplay);
  256.     X_already_started = 0;
  257. }
  258. static void Display_Image(myximage, ImageData)
  259. XImage *myximage;
  260. unsigned char *ImageData;
  261. {
  262. #ifdef SH_MEM
  263.     if (Shmem_Flag) {
  264. XShmPutImage(mydisplay, mywindow, mygc, myximage,
  265. 0, 0, 0, 0, myximage->width, myximage->height, True);
  266. XFlush(mydisplay);
  267. #if 0
  268. //I don't know why this code is here, but it craashes
  269. //when I don't compile with -pg. Very odd.
  270. while (1) {
  271.     XEvent xev;
  272.     XNextEvent(mydisplay, &xev);
  273.     if (xev.type == CompletionType)
  274. break;
  275. }
  276. #endif
  277.     } else
  278. #endif
  279. XPutImage(mydisplay, mywindow, mygc, myximage, 0, 0,
  280. 0, 0, myximage->width, myximage->height);
  281. }
  282. void Display_First_Field(void) { /* nothing */ }
  283. void Display_Second_Field(void) { /* nothing */ }
  284. unsigned char *dst, *py, *pu, *pv;
  285. static void display_frame_32bpp_420(const uint_8 * py, const uint_8 * pv,
  286.                                     const uint_8 * pu, uint_8 * image,
  287.                                     int h_size, int v_size, int bpp);
  288. static void display_frame_24bpp_420(const uint_8 * py, const uint_8 * pv,
  289.                                     const uint_8 * pu, uint_8 * image,
  290.                                     int h_size, int v_size, int bpp);
  291. static void display_frame_16bpp_420(const uint_8 * py, const uint_8 * pv,
  292.                                     const uint_8 * pu, uint_8 * image,
  293.                                     int h_size, int v_size, int bpp);
  294. void display_frame(uint_8 *src[])
  295. {
  296.    if (bpp==32) 
  297.  {
  298.       display_frame_32bpp_420(src[0],src[1],src[2],ImageData, 
  299. image_width, image_height, bpp);
  300.    } 
  301.  else if (bpp==24) 
  302.  {
  303.       display_frame_24bpp_420(src[0],src[1],src[2],ImageData, 
  304. image_width, image_height, bpp);
  305.    } 
  306.  else if (bpp == 15 || bpp == 16) 
  307.  {
  308.       display_frame_16bpp_420(src[0],src[1],src[2],ImageData, 
  309. image_width, image_height, bpp);
  310.    }
  311.    Display_Image(myximage, ImageData);
  312. }
  313. /* do 32 bpp output */
  314. static void display_frame_32bpp_420(const uint_8 * py, const uint_8 * pv, 
  315. const uint_8 * pu, uint_8 * image, int h_size, int v_size, int bpp)
  316. {
  317. sint_32 Y,U,V;
  318. sint_32 g_common,b_common,r_common;
  319. uint_32 x,y;
  320. uint_8 *dst_line_1;
  321. uint_8 *dst_line_2;
  322. const uint_8* py_line_1;
  323. const uint_8* py_line_2;
  324. volatile char prefetch;
  325. int byte_per_line=h_size*(bpp/8);
  326. int crv,cbu,cgu,cgv;
  327. /* matrix coefficients */
  328. crv = Inverse_Table_6_9[matrix_coefficients][0];
  329. cbu = Inverse_Table_6_9[matrix_coefficients][1];
  330. cgu = Inverse_Table_6_9[matrix_coefficients][2];
  331. cgv = Inverse_Table_6_9[matrix_coefficients][3];
  332. dst_line_1 = dst_line_2 =  image;
  333. dst_line_2 = dst_line_1 + byte_per_line;
  334. py_line_1 = py;
  335. py_line_2 = py + h_size;
  336. for (y = 0; y < v_size / 2; y++) 
  337. {
  338. for (x = 0; x < h_size / 2; x++) 
  339. {
  340. //Common to all four pixels
  341. prefetch = pu[32];
  342. U = (*pu++) - 128;
  343. prefetch = pv[32];
  344. V = (*pv++) - 128;
  345. g_common = cgu * U + cgv * V - 32768;
  346. b_common = cbu * U + 32768;
  347. r_common = crv * V;
  348. //Pixel I
  349. prefetch = py_line_1[32];
  350. Y = 76309 * ((*py_line_1++) - 16);
  351. *dst_line_1++ = clip[(Y+r_common)>>16];
  352. *dst_line_1++ = clip[(Y-g_common)>>16];
  353. *dst_line_1++ = clip[(Y+b_common)>>16];
  354. dst_line_1++;
  355. //Pixel II
  356. Y = 76309 * ((*py_line_1++) - 16);
  357. *dst_line_1++ = clip[(Y+r_common)>>16];
  358. *dst_line_1++ = clip[(Y-g_common)>>16];
  359. *dst_line_1++ = clip[(Y+b_common)>>16];
  360. dst_line_1++;
  361. //Pixel III
  362. prefetch = py_line_2[32];
  363. Y = 76309 * ((*py_line_2++) - 16);
  364. *dst_line_2++ = clip[(Y+r_common)>>16];
  365. *dst_line_2++ = clip[(Y-g_common)>>16];
  366. *dst_line_2++ = clip[(Y+b_common)>>16];
  367. dst_line_2++;
  368. //Pixel IV
  369. Y = 76309 * ((*py_line_2++) - 16);
  370. *dst_line_2++ = clip[(Y+r_common)>>16];
  371. *dst_line_2++ = clip[(Y-g_common)>>16];
  372. *dst_line_2++ = clip[(Y+b_common)>>16];
  373. dst_line_2++;
  374. }
  375. py_line_1 += h_size;
  376. py_line_2 += h_size;
  377. dst_line_1 += byte_per_line;
  378. dst_line_2 += byte_per_line;
  379. }
  380. }
  381. /* do 24 bpp output */
  382. static void display_frame_24bpp_420(const uint_8 * py, const uint_8 * pv, 
  383. const uint_8 * pu, uint_8 * image, int h_size, int v_size, int bpp)
  384. {
  385. sint_32 Y,U,V;
  386. sint_32 g_common,b_common,r_common;
  387. uint_32 x,y;
  388. uint_8 *dst_line_1;
  389. uint_8 *dst_line_2;
  390. const uint_8* py_line_1;
  391. const uint_8* py_line_2;
  392. volatile char prefetch;
  393. int byte_per_line=h_size*(bpp/8);
  394. int crv,cbu,cgu,cgv;
  395. /* matrix coefficients */
  396. crv = Inverse_Table_6_9[matrix_coefficients][0];
  397. cbu = Inverse_Table_6_9[matrix_coefficients][1];
  398. cgu = Inverse_Table_6_9[matrix_coefficients][2];
  399. cgv = Inverse_Table_6_9[matrix_coefficients][3];
  400. dst_line_1 = dst_line_2 =  image;
  401. dst_line_2 = dst_line_1 + byte_per_line;
  402. py_line_1 = py;
  403. py_line_2 = py + h_size;
  404. for (y = 0; y < v_size / 2; y++) 
  405. {
  406. for (x = 0; x < h_size / 2; x++) 
  407. {
  408. //Common to all four pixels
  409. prefetch = pu[32];
  410. U = (*pu++) - 128;
  411. prefetch = pv[32];
  412. V = (*pv++) - 128;
  413. g_common = cgu * U + cgv * V - 32768;
  414. b_common = cbu * U + 32768;
  415. r_common = crv * V;
  416. //Pixel I
  417. prefetch = py_line_1[32];
  418. Y = 76309 * ((*py_line_1++) - 16);
  419. *dst_line_1++ = clip[(Y+r_common)>>16];
  420. *dst_line_1++ = clip[(Y-g_common)>>16];
  421. *dst_line_1++ = clip[(Y+b_common)>>16];
  422. if (bpp==32)
  423. {
  424. dst_line_1++;
  425. }
  426. //Pixel II
  427. Y = 76309 * ((*py_line_1++) - 16);
  428. *dst_line_1++ = clip[(Y+r_common)>>16];
  429. *dst_line_1++ = clip[(Y-g_common)>>16];
  430. *dst_line_1++ = clip[(Y+b_common)>>16];
  431. if (bpp==32)
  432. {
  433. dst_line_1++;
  434. }
  435. //Pixel III
  436. prefetch = py_line_2[32];
  437. Y = 76309 * ((*py_line_2++) - 16);
  438. *dst_line_2++ = clip[(Y+r_common)>>16];
  439. *dst_line_2++ = clip[(Y-g_common)>>16];
  440. *dst_line_2++ = clip[(Y+b_common)>>16];
  441. if (bpp==32)
  442. {
  443. dst_line_1++;
  444. }
  445. //Pixel IV
  446. Y = 76309 * ((*py_line_2++) - 16);
  447. *dst_line_2++ = clip[(Y+r_common)>>16];
  448. *dst_line_2++ = clip[(Y-g_common)>>16];
  449. *dst_line_2++ = clip[(Y+b_common)>>16];
  450. if (bpp==32)
  451. {
  452. dst_line_1++;
  453. }
  454. }
  455. py_line_1 += h_size;
  456. py_line_2 += h_size;
  457. dst_line_1 += byte_per_line;
  458. dst_line_2 += byte_per_line;
  459. }
  460. }
  461. /* do 16 and 15 bpp output */
  462. static void display_frame_16bpp_420(const uint_8 * py, const uint_8 * pv, 
  463. const uint_8 * pu, uint_8 * image, int h_size, int v_size, int bpp)
  464. {
  465. uint_32 U,V;
  466. uint_32 pixel_idx;
  467. uint_32 x,y;
  468. uint_16 *dst_line_1;
  469. uint_16 *dst_line_2;
  470. const uint_8* py_line_1;
  471. const uint_8* py_line_2;
  472. uint_8  r,v,b;
  473. static uint_16 * lookUpTable=NULL;
  474. int i,j,k;
  475. //not sure if this is a win using the LUT. Can someone try
  476. //the direct calculation (like in the 32bpp) and compare?
  477. if (lookUpTable==NULL) 
  478. {
  479. lookUpTable=malloc((1<<18)*sizeof(uint_16));
  480. for (i=0;i<(1<<6);++i) 
  481. { /* Y */
  482. int Y=i<<2;
  483. for(j=0;j<(1<<6);++j) 
  484. { /* Cr */
  485. int Cb=j<<2;
  486. for(k=0;k<(1<<6);k++) 
  487. { /* Cb */
  488. int Cr=k<<2;
  489. /*
  490. R = clp[(int)(*Y + 1.371*(*Cr-128))];  
  491. V = clp[(int)(*Y - 0.698*(*Cr-128) - 0.336*(*Cr-128))]; 
  492. B = clp[(int)(*Y++ + 1.732*(*Cb-128))];
  493. */
  494. r=clip[(Y*1000 + 1371*(Cr-128))/1000] >>3;
  495. v=clip[(Y*1000 - 698*(Cr-128) - 336*(Cr-128))/1000] >> (bpp==16?2:3);
  496. b=clip[(Y*1000 + 1732*(Cb-128))/1000] >> 3;
  497. lookUpTable[i|(j<<6)|(k<<12)] = r | (v << 5) | (b <<  (bpp==16?11:10));
  498. }
  499. }
  500. }
  501. }
  502. dst_line_1 = dst_line_2 =  (uint_16*) image;
  503. dst_line_2 = dst_line_1 + h_size;
  504. py_line_1 = py;
  505. py_line_2 = py + h_size;
  506. for (y = 0; y < v_size / 2; y++) 
  507. {
  508. for (x = 0; x < h_size / 2; x++) 
  509. {
  510. //Common to all four pixels
  511. U = (*pu++)>>2;
  512. V = (*pv++)>>2;
  513. pixel_idx=U<<6|V<<12;
  514. //Pixel I
  515. *dst_line_1++=lookUpTable[(*py_line_1++)>>2|pixel_idx];
  516. //Pixel II
  517. *dst_line_1++=lookUpTable[(*py_line_1++)>>2|pixel_idx];
  518. //Pixel III
  519. *dst_line_2++=lookUpTable[(*py_line_2++)>>2|pixel_idx];
  520. //Pixel IV
  521. *dst_line_2++=lookUpTable[(*py_line_2++)>>2|pixel_idx];
  522. }
  523. py_line_1 += h_size;
  524. py_line_2 += h_size;
  525. dst_line_1 += h_size;
  526. dst_line_2 += h_size;
  527. }
  528. }