display.cc.openptc
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:31k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.    File: display.cc
  3.    By: Alex de Jong (original by MSSG)
  4.    Created: March 1996
  5.    
  6.    Description:
  7.    Multi-Threaded display class. Displays class is able to 
  8.    synchronize frames with a synchronoization object, which
  9.    in turn is updates by a decoder timer.
  10. */
  11. #define USE_PTC 1
  12. #ifdef __GNUG__
  13. #pragma implementation
  14. #endif
  15. #include "athread.hh"
  16. #include <stdio.h>
  17. #include <fstream.h>
  18. #include <sys/time.h>
  19. #ifdef USE_PTC
  20. #include <ptc/ptc.h>
  21. #endif
  22. #include "error.hh"
  23. #include "debug.hh"
  24. #include "util.hh"
  25. #include "videoconst.hh"
  26. #include "sync.hh"
  27. #include "display.hh"
  28. extern int quiet;
  29. extern int coded_picture_width;
  30. extern int coded_picture_height;
  31. extern int prog_seq;
  32. extern int chroma_format;
  33. extern int chrom_width;
  34. extern int pict_struct, topfirst;
  35. extern int convmat[8][4];
  36. extern int matrix_coefficients;
  37. extern int playedlastframe;
  38. // #define USE_DGA 1               /* enable this to use DGA extention */
  39. #ifdef SH_MEM
  40. // Dummies to get rid of warnings
  41. extern "C" {
  42. int XShmQueryExtension(Display*);
  43. int XShmGetEventBase(Display*);
  44. }
  45. #ifdef USE_DGA
  46. #include <X11/extensions/xf86dga.h>
  47. #include <X11/extensions/xf86vmode.h>
  48. #endif
  49. #endif
  50. DisplayX11::DisplayX11(const char* title, Synchronization* s){
  51.   TRACER("DisplayX11::DisplayX11(const char* title, Synchronization* s)");
  52.   int crv, cbu, cgu, cgv;
  53.   int y, u, v, r, g, b;
  54.   int i, j;
  55.   Colormap cmap;
  56.   XColor xcolor;
  57.   unsigned int fg, bg;
  58.   XSizeHints hint;
  59.   unsigned long tmp_pixel;
  60.   XWindowAttributes xwa;
  61.   int screen;
  62.   static Console console;
  63.   con = &console;
  64.   
  65.   // init to avoid invalid destroy in destructor
  66.   ximage=0;
  67.   ximage2=0;
  68.   // Synchronization with decoder clock
  69.   sync=s;
  70.   // Init display lock/condition to prevent threads to pass eachother
  71.   source=0;
  72. #ifdef SH_MEM
  73.   CompletionType = -1;
  74. #endif
  75.   // create clipping table
  76.   clp=new unsigned char[1024];  // clip table
  77.   clp += 384;
  78.   for (i=-384; i<640; i++) 
  79.     clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
  80.   if (!(display=XOpenDisplay(0))){
  81.     error("Can not open displayn");
  82.     athr_exit(0);
  83.   }
  84. #ifdef TRACE
  85.   XSynchronize(display, 1);
  86. #endif
  87.     
  88.   screen = DefaultScreen(display);
  89.   // find  display
  90.   if (XMatchVisualInfo(display, screen, 16, TrueColor, &vinfo)){
  91.   } else
  92.    error("requires 16 bit displayn");
  93.   // Make the window
  94.   hint.x = 200;
  95.   hint.y = 200;
  96.   hint.width = 100;
  97.   hint.height= 100;
  98.   hint.flags = PPosition | PSize;
  99.   bpp = vinfo.depth;
  100.   if (vinfo.red_mask == 0x7c00)
  101.     rgb_mode = 1; // RGB555    for more modes see yuv12-rgb.s
  102.   else
  103.     rgb_mode = 0; // RGB565
  104. //  if (rgb_mode == 0) 
  105. //    Format format(16,0xf800,0x7e0,0x1f);
  106. //  else
  107. //    Format format(16,0x7c00,0x3e0,0x1f);
  108. //  form = &format;
  109. #if 0
  110.   // Get some colors
  111.   bg = WhitePixel(display, screen);
  112.   fg = BlackPixel(display, screen);
  113.   window=XCreateSimpleWindow(display, DefaultRootWindow (display),
  114.                                hint.x, hint.y, hint.width, hint.height, 4, fg, bg);
  115.   // Tell other applications about this window
  116.   XSetStandardProperties(display, window, title, title, None, NULL, 0, &hint);
  117.   XSelectInput(display, window, StructureNotifyMask);
  118.   // Map window
  119.   XMapWindow(display, window);
  120.   // Wait for map.
  121.   do {
  122.     XNextEvent(display, &event);
  123.   }
  124.   while (event.type != MapNotify || event.xmap.event != window);
  125.   XSelectInput(display, window, NoEventMask);
  126.   gc = DefaultGC(display, screen);
  127. /*
  128.    Init dither
  129.    4x4 ordered dither
  130.    threshold pattern:
  131.     0  8  2 10
  132.    12  4 14  6
  133.     3 11  1  9
  134.    15  7 13  5
  135. */
  136.   unsigned char ctab[256+32];
  137.   
  138.   for (i=0; i<256+16; i++){
  139.     v = (i-8)>>4;
  140.     if (v<2) v=2;
  141.     else if (v>14) v=14;
  142.     for (j=0; j<16; j++) 
  143.       ytab[16*i+j] = pixel[(v<<4)+j];
  144.   }
  145.   for (i=0; i<256+32; i++){
  146.     v = (i+48-128)>>5;
  147.     if (v<0) v=0;
  148.     else if (v>3) v=3;
  149.     ctab[i]=v;
  150.   }
  151.   for (i=0; i<255+15; i++)
  152.     for (j=0; j<255+15; j++)
  153.       uvtab[256*i+j]=(ctab[i+16]<<6)|(ctab[j+16]<<4)|(ctab[i]<<2)|ctab[j];
  154. #endif
  155. }
  156. DisplayX11::~DisplayX11(){ 
  157.   TRACER("DisplayX11::~DisplayX11()");
  158.   display_lock.lock();
  159.   if (!terminated) athr_join(thread_id);
  160.   exit_display();
  161.   delete clp; // delete clipping table
  162.   display_lock.unlock();
  163. }
  164. void* DisplayX11::dither_thread(DisplayX11* d){
  165.   d->display_lock.lock();
  166.   d->terminated=0;
  167.   d->dither_image(d->source);
  168.   d->display_image(d->ximage, d->dithered_image); 
  169.   d->source=0;
  170.   d->display_cond.signal();
  171.   d->terminated=1;
  172.   d->display_lock.unlock(); 
  173. #if !defined(IRIX) && !defined(SOLARIS_SDK_XIL) && !defined(LINUX)
  174.   athr_exit(0);
  175. #endif
  176.   return 0;
  177. }
  178. void* DisplayX11::display_thread(DisplayX11* d){
  179. #ifndef LINUX
  180.   d->display_lock.lock();
  181.   d->terminated=0;
  182.   d->display_image(d->ximage2, d->dithered_image2); 
  183.   d->terminated=1;
  184.   d->display_lock.unlock();
  185. #if !defined(IRIX) && !defined(SOLARIS_SDK_XIL) && !defined(LINUX)
  186.   athr_exit(0);
  187. #endif
  188. #endif
  189.   return 0;
  190. }
  191. int DisplayX11::init(int h_size, int v_size){
  192.   TRACER("void DisplayX11::init(int h_size, int v_size)");
  193.   display_lock.lock();  // lock the display from others access for now
  194.   // resize window
  195.   horizontal_size=h_size;
  196.   vertical_size=v_size;
  197.   Format format(16,0x7c00,0x3e0,0x1f);
  198.   con->option("dga pedantic init");
  199.   con->open("MPEG2 Player",h_size,v_size,format,0);
  200.   if (con->format() != format) message("Unable to get  format");
  201. #if 0
  202.   XResizeWindow(display, window, horizontal_size, vertical_size);
  203. #ifdef SH_MEM
  204.   char dummy;
  205.   shmem_flag = 0;
  206. #ifdef USE_DGA             /* enable this if you want to have DGA support */
  207.   int EventBase, ErrorBase, flags,vp_width,vp_height,bank,ram;
  208.   if (XF86DGAQueryExtension (display, &EventBase, &ErrorBase)) {
  209.       XF86DGAQueryDirectVideo (display, XDefaultScreen (display), &flags);
  210.       if ((flags & XF86DGADirectPresent) == 0) {
  211.           if (!quiet) message ("dga: no direct present");
  212.       }
  213.       else {
  214.           shmem_flag = 2;
  215.           if (!quiet) message ("using DGA ");
  216.       }
  217.       XF86DGAGetVideo (display, XDefaultScreen (display), (char **) &dithered_image,
  218.                         &xwidth, &bank, &ram);
  219.       dithered_image2 = dithered_image;
  220.       XF86DGAGetViewPortSize (display, XDefaultScreen (display),
  221.                         &vp_width, &vp_height);
  222.       if (vp_height < v_size || vp_width < h_size) {
  223.         if (!quiet) message("View Port too small for DGA");
  224.         shmem_flag = 0;
  225.       }
  226.       else {
  227.         XF86DGASetViewPort (display, XDefaultScreen (display), 0, 0);
  228.         XF86DGADirectVideo (display, XDefaultScreen (display),XF86DGADirectGraphics );
  229.       }
  230.   }
  231. #endif
  232.   if (!shmem_flag) 
  233.     if (XShmQueryExtension(display)) shmem_flag = 1;
  234.     else {
  235.       shmem_flag = 0;
  236.       if (!quiet){
  237.         message("Shared memory not supported");
  238.         message("Reverting to normal Xlib");
  239.       }
  240.     }
  241.   if (shmem_flag==1) CompletionType = XShmGetEventBase(display) + ShmCompletion;
  242.   InstallXErrorHandler();
  243.   if (shmem_flag==1){
  244.     ximage = XShmCreateImage(display, None, bpp, ZPixmap, NULL,
  245.                              &shminfo1,
  246.                              coded_picture_width, coded_picture_height);
  247.     if (!prog_seq)
  248.       ximage2 = XShmCreateImage(display, None, bpp, ZPixmap, NULL,
  249.                                 &shminfo2,
  250.                                 coded_picture_width, coded_picture_height);
  251.     /* If no go, then revert to normal Xlib calls. */
  252.     if (ximage==NULL || (!prog_seq && ximage2==NULL)){
  253.       if (ximage!=NULL) XDestroyImage(ximage);
  254.       if (!prog_seq && ximage2!=NULL) XDestroyImage(ximage2);
  255.       if (!quiet)
  256.         fprintf(stderr, "Shared memory error, disabling (Ximage error)n");
  257.       goto shmemerror;
  258.     }
  259.     /* Success here, continue. */
  260.     shminfo1.shmid = shmget(IPC_PRIVATE, 
  261.                             ximage->bytes_per_line * ximage->height,
  262.                             IPC_CREAT | 0777);
  263.     if (!prog_seq)
  264.       shminfo2.shmid = shmget(IPC_PRIVATE, 
  265.                               ximage2->bytes_per_line * ximage2->height,
  266.                               IPC_CREAT | 0777);
  267.     if (shminfo1.shmid<0 || (!prog_seq && shminfo2.shmid<0)){
  268.       XDestroyImage(ximage);
  269.       if (!prog_seq) XDestroyImage(ximage2);
  270.       if (!quiet)
  271.         fprintf(stderr, "Shared memory error, disabling (seg id error)n");
  272.       goto shmemerror;
  273.     }
  274.     shminfo1.shmaddr = (char *) shmat(shminfo1.shmid, 0, 0);
  275.     shminfo2.shmaddr = (char *) shmat(shminfo2.shmid, 0, 0);
  276.     if (shminfo1.shmaddr==((char *) -1) ||
  277.         (!prog_seq && shminfo2.shmaddr==((char *) -1))){
  278.       XDestroyImage(ximage);
  279.       if (shminfo1.shmaddr!=((char *) -1)) shmdt(shminfo1.shmaddr);
  280.       if (!prog_seq){
  281.         XDestroyImage(ximage2);
  282.         if (shminfo2.shmaddr!=((char *) -1))
  283.           shmdt(shminfo2.shmaddr);
  284.       }
  285.       if (!quiet)
  286.       {
  287.         fprintf(stderr, "Shared memory error, disabling (address error)n");
  288.       }
  289.       goto shmemerror;
  290.     }
  291.     ximage->data = shminfo1.shmaddr;
  292.     dithered_image = (unsigned char *)ximage->data;
  293.     shminfo1.readOnly = False;
  294.     XShmAttach(display, &shminfo1);
  295.     if (!prog_seq){
  296.       ximage2->data = shminfo2.shmaddr;
  297.       dithered_image2 = (unsigned char *)ximage2->data;
  298.       shminfo2.readOnly = False;
  299.       XShmAttach(display, &shminfo2);
  300.     }
  301.     XSync(display, False);
  302.     if (gXErrorFlag){
  303.       /* Ultimate failure here. */
  304.       XDestroyImage(ximage);
  305.       shmdt(shminfo1.shmaddr);
  306.       if (!prog_seq){
  307.         XDestroyImage(ximage2);
  308.         shmdt(shminfo2.shmaddr);
  309.       }
  310.       if (!quiet)
  311.         fprintf(stderr, "Shared memory error, disabling.n");
  312.       gXErrorFlag = 0;
  313.       goto shmemerror;
  314.     }
  315.     else {
  316.       shmctl(shminfo1.shmid, IPC_RMID, 0);
  317.       if (!prog_seq)
  318.         shmctl(shminfo2.shmid, IPC_RMID, 0);
  319.     }
  320.     if (!quiet){
  321.       fprintf(stderr, "Sharing memory.n");
  322.     }
  323.   }
  324.   else if (shmem_flag != 2) {
  325. shmemerror:
  326.     shmem_flag = 0;
  327. #endif
  328.     ximage = XCreateImage(display,None,bpp,ZPixmap,0,&dummy,
  329.                           coded_picture_width,coded_picture_height,8,0);
  330.     if (!(dithered_image = new unsigned char[coded_picture_width*
  331.                                                    coded_picture_height]))
  332.       error("new failed");
  333.     if (!prog_seq){
  334.       ximage2 = XCreateImage(display,None,bpp,ZPixmap,0,&dummy,
  335.                              coded_picture_width,coded_picture_height,8,0);
  336.       if (!(dithered_image2 = new unsigned char[coded_picture_width*
  337.                                                       coded_picture_height]))
  338.         error("new failed");
  339.     }
  340. #ifdef SH_MEM
  341.   }
  342.   DeInstallXErrorHandler();
  343. #endif
  344. #endif
  345.   display_lock.unlock();
  346.   return 1;
  347. }
  348. void DisplayX11::exit_display(){
  349. #ifdef SH_MEM
  350. #ifdef USE_DGA
  351.   if (shmem_flag==2)
  352.     XF86DGADirectVideo (display, XDefaultScreen (display), 0);
  353. #endif
  354.   if (shmem_flag==1){
  355.     XShmDetach(display, &shminfo1);
  356.     shmdt(shminfo1.shmaddr);
  357.     if (!prog_seq){
  358.       XShmDetach(display, &shminfo2);
  359.       XDestroyImage(ximage2);
  360.       shmdt(shminfo2.shmaddr);
  361.     }
  362.   }
  363. #else
  364.   XDestroyImage(ximage);
  365. #endif
  366. }
  367. #ifdef SOLARIS_SDK_XIL
  368. void DisplayX11::display_image(XilImage ximg, unsigned char *dithered_img){
  369. #else
  370. void DisplayX11::display_image(XImage *ximg, unsigned char *dithered_img){
  371. #endif
  372.   DEBUGGER("void DisplayX11::display_image(ximage, unsigned char *dithered_image)");
  373.   playedlastframe=1;  // indicate that frame is displayed
  374.   if (sync) 
  375.     sync->wait(1);    // wait for presentation time stamp (PTS), id=1
  376. #ifdef SH_MEM                            // display dithered image
  377.   if (shmem_flag==2)
  378.     return;
  379. #endif
  380.  return;
  381. #ifdef SOLARIS_SDK_XIL
  382.   xil_import(ximg, TRUE);
  383.   if (resized){
  384.     // , general and linear are Ok (These is no good for this: bilinear, bicubic)
  385.     xil_scale(ximage, resized_image, "general", horizontal_factor, vertical_factor);
  386.     // if (bands==1)   // Use XIL for color conversion
  387.     xil_copy(resized_image, displayimage);
  388.     // else 
  389.     //   xil_color_convert(resized_image, displayimage);
  390.   }
  391.   else {
  392.     // if (bands==1)   // Use XIL for color conversion
  393.     xil_copy(ximg, displayimage);
  394.     // else 
  395.     //   xil_color_convert(ximg, displayimage);
  396.   }
  397.   // check for geometry changes
  398.   if (XCheckWindowEvent(display, window, StructureNotifyMask, &event))  resize();
  399. #else
  400. #ifdef SH_MEM                            // display dithered image
  401.   if (shmem_flag==1){
  402.     XShmPutImage(display, window, gc, ximg, 0,0,0,0,ximg->width,ximg->height,True);
  403.     XFlush(display);
  404.   }
  405.   else 
  406. #endif // SH_MEM
  407.   {
  408.     ximg->data=(char*) dithered_img;
  409.     XPutImage(display, window, gc, ximg, 0, 0, 0, 0, ximg->width, ximg->height);
  410.   }
  411. #endif // SOLARIS_SDK_XIL
  412. }
  413. #ifdef SOLARIS_SDK_XIL
  414. int DisplayX11::dither_image_rgb24(unsigned char* src[], unsigned char* dithered_img){
  415.   register int h=0, w=-1;
  416.   register unsigned char *Y, *Cb, *Cr;  
  417.   Y=src[0];
  418.   Cb=src[1];
  419.   Cr=src[2];
  420.   register Xil_unsigned8* data;
  421.   data=dithered_img;
  422.   
  423.   //  map data in XIL image  
  424.   for (h=0; h<coded_picture_height; h++){
  425.     for (w=0; w<coded_picture_width; w++){
  426.       *data++ = clp[(int)(*Y + 1.371*(*Cr-128))];  
  427.       *data++ = clp[(int)(*Y - 0.698*(*Cr-128) - 0.336*(*Cr-128))]; 
  428.       *data++ = clp[(int)(*Y++ + 1.732*(*Cb-128))];
  429.       if ((w % 4)==0){
  430.         Cr++;
  431.         Cb++;
  432.       }
  433.     }
  434.   }
  435.   return 0;
  436. };
  437. #endif
  438. #ifdef LINUX
  439. extern "C" void yuv_2_rgb(void *,void *,void *,int,int,int,int,int,void *,int,int,int,int);
  440. int DisplayX11::dither_image_rgb16(unsigned char* src[], unsigned char* dithered_img){
  441.   int height,width,display_width;
  442.   height=coded_picture_height;
  443.   dithered_img = (unsigned char *)con->lock();
  444.   if (shmem_flag == 2)
  445.     display_width = xwidth;
  446.   else
  447.     display_width=coded_picture_width;
  448.   width=coded_picture_width;
  449.   display_width = con->pitch() ;
  450.   yuv_2_rgb(src[0],src[1],src[2],width,height,width,width/2,0,dithered_img,0,0,display_width,rgb_mode);
  451.   con->unlock();
  452.   con->update();
  453.   return 0;
  454. }
  455. #endif
  456. void DisplayX11::dither_image(unsigned char *src[]){
  457. #ifdef SOLARIS_SDK_XIL
  458.   dithered_image=getImage1Data();
  459. #endif
  460.   if (prog_seq){
  461.     if (chroma_format!=CHROMA444){
  462. #ifdef SOLARIS_SDK_XIL
  463.       if (vinfo.c_class==TrueColor && vinfo.depth==24){
  464.         dither_image_rgb24(src, dithered_image);
  465.         return;
  466.       }
  467. #endif
  468. #ifdef LINUX 
  469.       if (bpp == 16 ) {
  470.         dither_image_rgb16(src, dithered_image);
  471.         return;
  472.       }
  473. #endif
  474.       ditherframe(src);
  475.     }
  476.     else
  477.       ditherframe444(src);
  478.   }
  479.   else {
  480. #ifdef SOLARIS_SDK_XIL
  481.     dithered_image2=getImage2Data();
  482. #endif
  483. #ifdef LINUX 
  484.       if (bpp == 16 ){
  485.         dither_image_rgb16(src, dithered_image);
  486.         return;
  487.       }
  488. #endif
  489.     if ((pict_struct==FRAME_PICTURE && topfirst) || pict_struct==BOTTOM_FIELD){
  490.       /* top field first */
  491.       if (chroma_format!=CHROMA444){
  492.         dithertop(src,dithered_image);
  493.         ditherbot(src,dithered_image2);
  494.       }
  495.       else {
  496.         dithertop444(src,dithered_image);
  497.         ditherbot444(src,dithered_image2);
  498.       }
  499.     }
  500.     else {
  501.       /* bottom field first */
  502.       if (chroma_format!=CHROMA444){
  503.         ditherbot(src,dithered_image);
  504.         dithertop(src,dithered_image2);
  505.       }
  506.       else {
  507.         ditherbot444(src,dithered_image);
  508.         dithertop444(src,dithered_image2);
  509.       }
  510.     }
  511.   }
  512. }
  513. /* only for 4:2:0 and 4:2:2! */
  514. void DisplayX11::ditherframe(unsigned char *src[]){
  515.   int i;
  516.   register unsigned int uv;
  517.   register unsigned char *py,*pu,*pv,*dst;
  518.   py = src[0];
  519.   pu = src[1];
  520.   pv = src[2];
  521.   dst = dithered_image;
  522.   for (int j=0; j<coded_picture_height; j+=4){
  523.     /* line j + 0 */
  524.     for (i=0; i<coded_picture_width; i+=8){
  525.       uv = uvtab[(*pu++<<8)|*pv++];
  526.       *dst++ = ytab[((*py++)<<4)|(uv&15)];
  527.       *dst++ = ytab[((*py++ +8)<<4)|(uv>>4)];
  528.       uv = uvtab[((*pu++<<8)|*pv++)+1028];
  529.       *dst++ = ytab[((*py++ +2)<<4)|(uv&15)];
  530.       *dst++ = ytab[((*py++ +10)<<4)|(uv>>4)];
  531.       uv = uvtab[(*pu++<<8)|*pv++];
  532.       *dst++ = ytab[((*py++)<<4)|(uv&15)];
  533.       *dst++ = ytab[((*py++ +8)<<4)|(uv>>4)];
  534.       uv = uvtab[((*pu++<<8)|*pv++)+1028];
  535.       *dst++ = ytab[((*py++ +2)<<4)|(uv&15)];
  536.       *dst++ = ytab[((*py++ +10)<<4)|(uv>>4)];
  537.     }
  538.     if (chroma_format==CHROMA420){
  539.       pu -= chrom_width;
  540.       pv -= chrom_width;
  541.     }
  542.     /* line j + 1 */
  543.     for (i=0; i<coded_picture_width; i+=8){
  544.       uv = uvtab[((*pu++<<8)|*pv++)+2056];
  545.       *dst++ = ytab[((*py++ +12)<<4)|(uv>>4)];
  546.       *dst++ = ytab[((*py++ +4)<<4)|(uv&15)];
  547.       uv = uvtab[((*pu++<<8)|*pv++)+3084];
  548.       *dst++ = ytab[((*py++ +14)<<4)|(uv>>4)];
  549.       *dst++ = ytab[((*py++ +6)<<4)|(uv&15)];
  550.       uv = uvtab[((*pu++<<8)|*pv++)+2056];
  551.       *dst++ = ytab[((*py++ +12)<<4)|(uv>>4)];
  552.       *dst++ = ytab[((*py++ +4)<<4)|(uv&15)];
  553.       uv = uvtab[((*pu++<<8)|*pv++)+3084];
  554.       *dst++ = ytab[((*py++ +14)<<4)|(uv>>4)];
  555.       *dst++ = ytab[((*py++ +6)<<4)|(uv&15)];
  556.     }
  557.     /* line j + 2 */
  558.     for (i=0; i<coded_picture_width; i+=8){
  559.       uv = uvtab[((*pu++<<8)|*pv++)+1542];
  560.       *dst++ = ytab[((*py++ +3)<<4)|(uv&15)];
  561.       *dst++ = ytab[((*py++ +11)<<4)|(uv>>4)];
  562.       uv = uvtab[((*pu++<<8)|*pv++)+514];
  563.       *dst++ = ytab[((*py++ +1)<<4)|(uv&15)];
  564.       *dst++ = ytab[((*py++ +9)<<4)|(uv>>4)];
  565.       uv = uvtab[((*pu++<<8)|*pv++)+1542];
  566.       *dst++ = ytab[((*py++ +3)<<4)|(uv&15)];
  567.       *dst++ = ytab[((*py++ +11)<<4)|(uv>>4)];
  568.       uv = uvtab[((*pu++<<8)|*pv++)+514];
  569.       *dst++ = ytab[((*py++ +1)<<4)|(uv&15)];
  570.       *dst++ = ytab[((*py++ +9)<<4)|(uv>>4)];
  571.     }
  572.     if (chroma_format==CHROMA420){
  573.       pu -= chrom_width;
  574.       pv -= chrom_width;
  575.     }
  576.     /* line j + 3 */
  577.     for (i=0; i<coded_picture_width; i+=8){
  578.       uv = uvtab[((*pu++<<8)|*pv++)+3598];
  579.       *dst++ = ytab[((*py++ +15)<<4)|(uv>>4)];
  580.       *dst++ = ytab[((*py++ +7)<<4)|(uv&15)];
  581.       uv = uvtab[((*pu++<<8)|*pv++)+2570];
  582.       *dst++ = ytab[((*py++ +13)<<4)|(uv>>4)];
  583.       *dst++ = ytab[((*py++ +5)<<4)|(uv&15)];
  584.       uv = uvtab[((*pu++<<8)|*pv++)+3598];
  585.       *dst++ = ytab[((*py++ +15)<<4)|(uv>>4)];
  586.       *dst++ = ytab[((*py++ +7)<<4)|(uv&15)];
  587.       uv = uvtab[((*pu++<<8)|*pv++)+2570];
  588.       *dst++ = ytab[((*py++ +13)<<4)|(uv>>4)];
  589.       *dst++ = ytab[((*py++ +5)<<4)|(uv&15)];
  590.     }
  591.   }
  592. }
  593. void DisplayX11::dithertop(unsigned char *src[], unsigned char *dst){
  594.   int i;
  595.   unsigned int y,uv1,uv2;
  596.   unsigned char *py,*py2,*pu,*pv,*dst2;
  597.   py = src[0];
  598.   py2 = src[0] + (coded_picture_width<<1);
  599.   pu = src[1];
  600.   pv = src[2];
  601.   dst2 = dst + coded_picture_width;
  602.   for (int j=0; j<coded_picture_height; j+=4){
  603.     /* line j + 0, j + 1 */
  604.     for (i=0; i<coded_picture_width; i+=4){
  605.       y = *py++;
  606.       uv2 = (*pu++<<8)|*pv++;
  607.       uv1 = uvtab[uv2];
  608.       uv2 = uvtab[uv2+2056];
  609.       *dst++  = ytab[((y)<<4)|(uv1&15)];
  610.       *dst2++ = ytab[((((y + *py2++)>>1)+12)<<4)|(uv2>>4)];
  611.       y = *py++;
  612.       *dst++  = ytab[((y+8)<<4)|(uv1>>4)];
  613.       *dst2++ = ytab[((((y + *py2++)>>1)+4)<<4)|(uv2&15)];
  614.       y = *py++;
  615.       uv2 = (*pu++<<8)|*pv++;
  616.       uv1 = uvtab[uv2+1028];
  617.       uv2 = uvtab[uv2+3072];
  618.       *dst++  = ytab[((y+2)<<4)|(uv1&15)];
  619.       *dst2++ = ytab[((((y + *py2++)>>1)+14)<<4)|(uv2>>4)];
  620.       y = *py++;
  621.       *dst++  = ytab[((y+10)<<4)|(uv1>>4)];
  622.       *dst2++ = ytab[((((y + *py2++)>>1)+6)<<4)|(uv2&15)];
  623.     }
  624.     py += coded_picture_width;
  625.     if (j!=(coded_picture_height-4)) py2 += coded_picture_width;
  626.     else                             py2 -= coded_picture_width;
  627.     dst += coded_picture_width;
  628.     dst2 += coded_picture_width;
  629.     if (chroma_format==CHROMA420){
  630.       pu -= chrom_width;
  631.       pv -= chrom_width;
  632.     }
  633.     else {
  634.       pu += chrom_width;
  635.       pv += chrom_width;
  636.     }
  637.     /* line j + 2, j + 3 */
  638.     for (i=0; i<coded_picture_width; i+=4){
  639.       y = *py++;
  640.       uv2 = (*pu++<<8)|*pv++;
  641.       uv1 = uvtab[uv2+1542];
  642.       uv2 = uvtab[uv2+3598];
  643.       *dst++  = ytab[((y+3)<<4)|(uv1&15)];
  644.       *dst2++ = ytab[((((y + *py2++)>>1)+15)<<4)|(uv2>>4)];
  645.       y = *py++;
  646.       *dst++  = ytab[((y+11)<<4)|(uv1>>4)];
  647.       *dst2++ = ytab[((((y + *py2++)>>1)+7)<<4)|(uv2&15)];
  648.       y = *py++;
  649.       uv2 = (*pu++<<8)|*pv++;
  650.       uv1 = uvtab[uv2+514];
  651.       uv2 = uvtab[uv2+2570];
  652.       *dst++  = ytab[((y+1)<<4)|(uv1&15)];
  653.       *dst2++ = ytab[((((y + *py2++)>>1)+13)<<4)|(uv2>>4)];
  654.       y = *py++;
  655.       *dst++  = ytab[((y+9)<<4)|(uv1>>4)];
  656.       *dst2++ = ytab[((((y + *py2++)>>1)+5)<<4)|(uv2&15)];
  657.     }
  658.     py += coded_picture_width;
  659.     py2 += coded_picture_width;
  660.     dst += coded_picture_width;
  661.     dst2 += coded_picture_width;
  662.     pu += chrom_width;
  663.     pv += chrom_width;
  664.   }
  665. }
  666. void DisplayX11::ditherbot(unsigned char *src[], unsigned char *dst){
  667.   int i;
  668.   unsigned int y2,uv1,uv2;
  669.   unsigned char *py,*py2,*pu,*pv,*dst2;
  670.   py = src[0] + coded_picture_width;
  671.   py2 = py;
  672.   pu = src[1] + chrom_width;
  673.   pv = src[2] + chrom_width;
  674.   dst2 = dst + coded_picture_width;
  675.   for (int j=0; j<coded_picture_height; j+=4){
  676.     /* line j + 0, j + 1 */
  677.     for (i=0; i<coded_picture_width; i+=4){
  678.       y2 = *py2++;
  679.       uv2 = (*pu++<<8)|*pv++;
  680.       uv1 = uvtab[uv2];
  681.       uv2 = uvtab[uv2+2056];
  682.       *dst++  = ytab[((((*py++ + y2)>>1))<<4)|(uv1&15)];
  683.       *dst2++ = ytab[((y2+12)<<4)|(uv2>>4)];
  684.       y2 = *py2++;
  685.       *dst++  = ytab[((((*py++ + y2)>>1)+8)<<4)|(uv1>>4)];
  686.       *dst2++ = ytab[((y2+4)<<4)|(uv2&15)];
  687.       y2 = *py2++;
  688.       uv2 = (*pu++<<8)|*pv++;
  689.       uv1 = uvtab[uv2+1028];
  690.       uv2 = uvtab[uv2+3072];
  691.       *dst++  = ytab[((((*py++ + y2)>>1)+2)<<4)|(uv1&15)];
  692.       *dst2++ = ytab[((y2+14)<<4)|(uv2>>4)];
  693.       y2 = *py2++;
  694.       *dst++  = ytab[((((*py++ + y2)>>1)+10)<<4)|(uv1>>4)];
  695.       *dst2++ = ytab[((y2+6)<<4)|(uv2&15)];
  696.     }
  697.     if (j==0) py -= coded_picture_width;
  698.     else      py += coded_picture_width;
  699.     py2 += coded_picture_width;
  700.     dst += coded_picture_width;
  701.     dst2 += coded_picture_width;
  702.     if (chroma_format==CHROMA420){
  703.       pu -= chrom_width;
  704.       pv -= chrom_width;
  705.     }
  706.     else {
  707.       pu += chrom_width;
  708.       pv += chrom_width;
  709.     }
  710.     /* line j + 2, j + 3 */
  711.     for (i=0; i<coded_picture_width; i+=4){
  712.       y2 = *py2++;
  713.       uv2 = (*pu++<<8)|*pv++;
  714.       uv1 = uvtab[uv2+1542];
  715.       uv2 = uvtab[uv2+3598];
  716.       *dst++  = ytab[((((*py++ + y2)>>1)+3)<<4)|(uv1&15)];
  717.       *dst2++ = ytab[((y2+15)<<4)|(uv2>>4)];
  718.       y2 = *py2++;
  719.       *dst++  = ytab[((((*py++ + y2)>>1)+11)<<4)|(uv1>>4)];
  720.       *dst2++ = ytab[((y2+7)<<4)|(uv2&15)];
  721.       y2 = *py2++;
  722.       uv2 = (*pu++<<8)|*pv++;
  723.       uv1 = uvtab[uv2+514];
  724.       uv2 = uvtab[uv2+2570];
  725.       *dst++  = ytab[((((*py++ + y2)>>1)+1)<<4)|(uv1&15)];
  726.       *dst2++ = ytab[((y2+13)<<4)|(uv2>>4)];
  727.       y2 = *py2++;
  728.       *dst++  = ytab[((((*py++ + y2)>>1)+9)<<4)|(uv1>>4)];
  729.       *dst2++ = ytab[((y2+5)<<4)|(uv2&15)];
  730.     }
  731.     py += coded_picture_width;
  732.     py2 += coded_picture_width;
  733.     dst += coded_picture_width;
  734.     dst2 += coded_picture_width;
  735.     pu += chrom_width;
  736.     pv += chrom_width;
  737.   }
  738. }
  739. /* only for 4:4:4 */
  740. void DisplayX11::ditherframe444(unsigned char *src[]){
  741.   int i;
  742.   unsigned char *py=src[0], *pu=src[1], *pv=src[2], *dst=dithered_image;
  743.   for (int j=0; j<coded_picture_height; j+=4){
  744.     /* line j + 0 */
  745.     for (i=0; i<coded_picture_width; i+=8){
  746.       *dst++ = ytab[((*py++)<<4)|(uvtab[(*pu++<<8)|*pv++]&15)];
  747.       *dst++ = ytab[((*py++ +8)<<4)|(uvtab[(*pu++<<8)|*pv++]>>4)];
  748.       *dst++ = ytab[((*py++ +2)<<4)|(uvtab[((*pu++<<8)|*pv++)+1028]&15)];
  749.       *dst++ = ytab[((*py++ +10)<<4)|(uvtab[((*pu++<<8)|*pv++)+1028]>>4)];
  750.       *dst++ = ytab[((*py++)<<4)|(uvtab[(*pu++<<8)|*pv++]&15)];
  751.       *dst++ = ytab[((*py++ +8)<<4)|(uvtab[(*pu++<<8)|*pv++]>>4)];
  752.       *dst++ = ytab[((*py++ +2)<<4)|(uvtab[((*pu++<<8)|*pv++)+1028]&15)];
  753.       *dst++ = ytab[((*py++ +10)<<4)|(uvtab[((*pu++<<8)|*pv++)+1028]>>4)];
  754.     }
  755.     /* line j + 1 */
  756.     for (i=0; i<coded_picture_width; i+=8){
  757.       *dst++ = ytab[((*py++ +12)<<4)|(uvtab[((*pu++<<8)|*pv++)+2056]>>4)];
  758.       *dst++ = ytab[((*py++ +4)<<4)|(uvtab[((*pu++<<8)|*pv++)+2056]&15)];
  759.       *dst++ = ytab[((*py++ +14)<<4)|(uvtab[((*pu++<<8)|*pv++)+3084]>>4)];
  760.       *dst++ = ytab[((*py++ +6)<<4)|(uvtab[((*pu++<<8)|*pv++)+3084]&15)];
  761.       *dst++ = ytab[((*py++ +12)<<4)|(uvtab[((*pu++<<8)|*pv++)+2056]>>4)];
  762.       *dst++ = ytab[((*py++ +4)<<4)|(uvtab[((*pu++<<8)|*pv++)+2056]&15)];
  763.       *dst++ = ytab[((*py++ +14)<<4)|(uvtab[((*pu++<<8)|*pv++)+3084]>>4)];
  764.       *dst++ = ytab[((*py++ +6)<<4)|(uvtab[((*pu++<<8)|*pv++)+3084]&15)];
  765.     }
  766.     /* line j + 2 */
  767.     for (i=0; i<coded_picture_width; i+=8){
  768.       *dst++ = ytab[((*py++ +3)<<4)|(uvtab[((*pu++<<8)|*pv++)+1542]&15)];
  769.       *dst++ = ytab[((*py++ +11)<<4)|(uvtab[((*pu++<<8)|*pv++)+1542]>>4)];
  770.       *dst++ = ytab[((*py++ +1)<<4)|(uvtab[((*pu++<<8)|*pv++)+514]&15)];
  771.       *dst++ = ytab[((*py++ +9)<<4)|(uvtab[((*pu++<<8)|*pv++)+514]>>4)];
  772.       *dst++ = ytab[((*py++ +3)<<4)|(uvtab[((*pu++<<8)|*pv++)+1542]&15)];
  773.       *dst++ = ytab[((*py++ +11)<<4)|(uvtab[((*pu++<<8)|*pv++)+1542]>>4)];
  774.       *dst++ = ytab[((*py++ +1)<<4)|(uvtab[((*pu++<<8)|*pv++)+514]&15)];
  775.       *dst++ = ytab[((*py++ +9)<<4)|(uvtab[((*pu++<<8)|*pv++)+514]>>4)];
  776.     }
  777.     /* line j + 3 */
  778.     for (i=0; i<coded_picture_width; i+=8){
  779.       *dst++ = ytab[((*py++ +15)<<4)|(uvtab[((*pu++<<8)|*pv++)+3598]>>4)];
  780.       *dst++ = ytab[((*py++ +7)<<4)|(uvtab[((*pu++<<8)|*pv++)+3598]&15)];
  781.       *dst++ = ytab[((*py++ +13)<<4)|(uvtab[((*pu++<<8)|*pv++)+2570]>>4)];
  782.       *dst++ = ytab[((*py++ +5)<<4)|(uvtab[((*pu++<<8)|*pv++)+2570]&15)];
  783.       *dst++ = ytab[((*py++ +15)<<4)|(uvtab[((*pu++<<8)|*pv++)+3598]>>4)];
  784.       *dst++ = ytab[((*py++ +7)<<4)|(uvtab[((*pu++<<8)|*pv++)+3598]&15)];
  785.       *dst++ = ytab[((*py++ +13)<<4)|(uvtab[((*pu++<<8)|*pv++)+2570]>>4)];
  786.       *dst++ = ytab[((*py++ +5)<<4)|(uvtab[((*pu++<<8)|*pv++)+2570]&15)];
  787.     }
  788.   }
  789. }
  790. void DisplayX11::dithertop444(unsigned char *src[], unsigned char *dst){
  791.   int i;
  792.   unsigned int y,uv;
  793.   unsigned char *py,*py2,*pu,*pv,*dst2;
  794.   py = src[0];
  795.   py2 = src[0] + (coded_picture_width<<1);
  796.   pu = src[1];
  797.   pv = src[2];
  798.   dst2 = dst + coded_picture_width;
  799.   for (int j=0; j<coded_picture_height; j+=4){
  800.     /* line j + 0, j + 1 */
  801.     for (i=0; i<coded_picture_width; i+=4){
  802.       y = *py++;
  803.       uv = (*pu++<<8)|*pv++;
  804.       *dst++  = ytab[((y)<<4)|(uvtab[uv]&15)];
  805.       *dst2++ = ytab[((((y + *py2++)>>1)+12)<<4)|(uvtab[uv+2056]>>4)];
  806.       y = *py++;
  807.       uv = (*pu++<<8)|*pv++;
  808.       *dst++  = ytab[((y+8)<<4)|(uvtab[uv]>>4)];
  809.       *dst2++ = ytab[((((y + *py2++)>>1)+4)<<4)|(uvtab[uv+2056]&15)];
  810.       y = *py++;
  811.       uv = (*pu++<<8)|*pv++;
  812.       *dst++  = ytab[((y+2)<<4)|(uvtab[uv+1028]&15)];
  813.       *dst2++ = ytab[((((y + *py2++)>>1)+14)<<4)|(uvtab[uv+3072]>>4)];
  814.       y = *py++;
  815.       uv = (*pu++<<8)|*pv++;
  816.       *dst++  = ytab[((y+10)<<4)|(uvtab[uv+1028]>>4)];
  817.       *dst2++ = ytab[((((y + *py2++)>>1)+6)<<4)|(uvtab[uv+3072]&15)];
  818.     }
  819.     py += coded_picture_width;
  820.     if (j!=(coded_picture_height-4))
  821.       py2 += coded_picture_width;
  822.     else
  823.       py2 -= coded_picture_width;
  824.     dst += coded_picture_width;
  825.     dst2 += coded_picture_width;
  826.     pu += chrom_width;
  827.     pv += chrom_width;
  828.     /* line j + 2, j + 3 */
  829.     for (i=0; i<coded_picture_width; i+=4){
  830.       y = *py++;
  831.       uv = (*pu++<<8)|*pv++;
  832.       *dst++  = ytab[((y+3)<<4)|(uvtab[uv+1542]&15)];
  833.       *dst2++ = ytab[((((y + *py2++)>>1)+15)<<4)|(uvtab[uv+3598]>>4)];
  834.       y = *py++;
  835.       uv = (*pu++<<8)|*pv++;
  836.       *dst++  = ytab[((y+11)<<4)|(uvtab[uv+1542]>>4)];
  837.       *dst2++ = ytab[((((y + *py2++)>>1)+7)<<4)|(uvtab[uv+3598]&15)];
  838.       y = *py++;
  839.       uv = (*pu++<<8)|*pv++;
  840.       *dst++  = ytab[((y+1)<<4)|(uvtab[uv+514]&15)];
  841.       *dst2++ = ytab[((((y + *py2++)>>1)+13)<<4)|(uvtab[uv+2570]>>4)];
  842.       y = *py++;
  843.       uv = (*pu++<<8)|*pv++;
  844.       *dst++  = ytab[((y+9)<<4)|(uvtab[uv+514]>>4)];
  845.       *dst2++ = ytab[((((y + *py2++)>>1)+5)<<4)|(uvtab[uv+2570]&15)];
  846.     }
  847.     py += coded_picture_width;
  848.     py2 += coded_picture_width;
  849.     dst += coded_picture_width;
  850.     dst2 += coded_picture_width;
  851.     pu += chrom_width;
  852.     pv += chrom_width;
  853.   }
  854. }
  855. void DisplayX11::ditherbot444(unsigned char *src[], unsigned char *dst){
  856.   int i;
  857.   unsigned int y2,uv;
  858.   unsigned char *py,*py2,*pu,*pv,*dst2;
  859.   py = src[0] + coded_picture_width;
  860.   py2 = py;
  861.   pu = src[1] + chrom_width;
  862.   pv = src[2] + chrom_width;
  863.   dst2 = dst + coded_picture_width;
  864.   for (int j=0; j<coded_picture_height; j+=4){
  865.     /* line j + 0, j + 1 */
  866.     for (i=0; i<coded_picture_width; i+=4){
  867.       y2 = *py2++;
  868.       uv = (*pu++<<8)|*pv++;
  869.       *dst++  = ytab[((((*py++ + y2)>>1))<<4)|(uvtab[uv]&15)];
  870.       *dst2++ = ytab[((y2+12)<<4)|(uvtab[uv+2056]>>4)];
  871.       y2 = *py2++;
  872.       uv = (*pu++<<8)|*pv++;
  873.       *dst++  = ytab[((((*py++ + y2)>>1)+8)<<4)|(uvtab[uv]>>4)];
  874.       *dst2++ = ytab[((y2+4)<<4)|(uvtab[uv+2056]&15)];
  875.       y2 = *py2++;
  876.       uv = (*pu++<<8)|*pv++;
  877.       *dst++  = ytab[((((*py++ + y2)>>1)+2)<<4)|(uvtab[uv+1028]&15)];
  878.       *dst2++ = ytab[((y2+14)<<4)|(uvtab[uv+3072]>>4)];
  879.       y2 = *py2++;
  880.       uv = (*pu++<<8)|*pv++;
  881.       *dst++  = ytab[((((*py++ + y2)>>1)+10)<<4)|(uvtab[uv+1028]>>4)];
  882.       *dst2++ = ytab[((y2+6)<<4)|(uvtab[uv+3072]&15)];
  883.     }
  884.     if (j==0)
  885.       py -= coded_picture_width;
  886.     else
  887.       py += coded_picture_width;
  888.     py2 += coded_picture_width;
  889.     dst += coded_picture_width;
  890.     dst2 += coded_picture_width;
  891.     pu += chrom_width;
  892.     pv += chrom_width;
  893.     /* line j + 2, j + 3 */
  894.     for (i=0; i<coded_picture_width; i+=4){
  895.       y2 = *py2++;
  896.       uv = (*pu++<<8)|*pv++;
  897.       *dst++  = ytab[((((*py++ + y2)>>1)+3)<<4)|(uvtab[uv+1542]&15)];
  898.       *dst2++ = ytab[((y2+15)<<4)|(uvtab[uv+3598]>>4)];
  899.       y2 = *py2++;
  900.       uv = (*pu++<<8)|*pv++;
  901.       *dst++  = ytab[((((*py++ + y2)>>1)+11)<<4)|(uvtab[uv+1542]>>4)];
  902.       *dst2++ = ytab[((y2+7)<<4)|(uvtab[uv+3598]&15)];
  903.       y2 = *py2++;
  904.       uv = (*pu++<<8)|*pv++;
  905.       *dst++  = ytab[((((*py++ + y2)>>1)+1)<<4)|(uvtab[uv+514]&15)];
  906.       *dst2++ = ytab[((y2+13)<<4)|(uvtab[uv+2570]>>4)];
  907.       y2 = *py2++;
  908.       uv = (*pu++<<8)|*pv++;
  909.       *dst++  = ytab[((((*py++ + y2)>>1)+9)<<4)|(uvtab[uv+514]>>4)];
  910.       *dst2++ = ytab[((y2+5)<<4)|(uvtab[uv+2570]&15)];
  911.     }
  912.     py += coded_picture_width;
  913.     py2 += coded_picture_width;
  914.     dst += coded_picture_width;
  915.     dst2 += coded_picture_width;
  916.     pu += chrom_width;
  917.     pv += chrom_width;
  918.   }
  919. }
  920. #ifdef SOLARIS_SDK_XIL
  921. int DisplayX11::resize(){
  922.   TRACER("int DisplayX11::resize()");
  923.   Window root;
  924.   int x, y;
  925.   unsigned int w, h, b, d;
  926.   XGetGeometry(display, window, &root, &x, &y, &w, &h, &b, &d);
  927.   // indicate resize
  928.   resized=1;
  929.   horizontal_factor=((float) w)/horizontal_size;
  930.   vertical_factor=((float) h)/vertical_size;
  931.   // to avoid new events for the time being
  932.   XSelectInput(display, window, NoEventMask);
  933.   
  934.   // Create new image with new geometry
  935.   xil_destroy(displayimage);
  936.   displayimage=xil_create_from_window(State, display, window);
  937.   xil_destroy(resized_image);
  938.   resized_image=xil_create(State, w, h, bands, XIL_BYTE);
  939. /*
  940.   if (bands==3){
  941.     XilColorspace cspace=xil_colorspace_get_by_name(State, "ycc601");
  942.     xil_set_colorspace(resized_image, cspace);
  943.     cspace=xil_colorspace_get_by_name(State, "rgb709");
  944.     xil_set_colorspace(displayimage, cspace);
  945.   }
  946. */
  947.   XSelectInput(display, window, StructureNotifyMask);
  948.   return 1;
  949. }
  950. #endif // SOLARIS_SDK_XIL