[Bug 16001] XVideo gamma curve is wrong at least for r300 chips

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Tue May 20 23:13:39 PDT 2008


http://bugs.freedesktop.org/show_bug.cgi?id=16001





--- Comment #8 from Tobias Diedrich <ranma+freedesktop at tdiedrich.de>  2008-05-20 23:13:37 PST ---
(In reply to comment #6)
> (In reply to comment #5)
> > > I know there were some earlier complaints about gamma tables being wrong, but
> > > IIRC noone really investigated this a bit deeper.
> > 
> > I never noticed the problem on my r200 and the r300 with my old TFT (6bit S-IPS
> > panel + dither), but on my new Samsung (8bit S-PVA panel) it much easier to
> > spot .
> How did you generate the test image to see this? I've got a r200 here (and the
> panel should be 8bit s-pva too) and could look at it.

I found some XV test code on the net and modified it
(You may have to set XV_AUTOPAINT_COLORKEY):

/* -------------------------------------------
 * ---            XV Testcode              ---
 * ---              by AW                  ---*/


#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xv.h>
#include <X11/extensions/Xvlib.h>
#include <X11/extensions/XShm.h>


extern int      XShmQueryExtension(Display*);
extern int      XShmGetEventBase(Display*);
extern XvImage  *XvShmCreateImage(Display*, XvPortID, int, char*, int, int,
XShmSegmentInfo*);

int main (int argc, char* argv[]) {
  int           yuv_width = 48;
  int           yuv_height = 48;

#define FRAME_SIZE  (768*576 + (768*576/4)*2)

  int           xv_port = -1;
  int           adaptor, encodings, attributes, formats;
  int           i, j, ret, p, _d, _w, _h;

  char          *buf = malloc(FRAME_SIZE);
  char          *buf2 = malloc(FRAME_SIZE);
  char          *temp;

  int           vidfd = open("/dev/video0", O_RDWR);

  XvAdaptorInfo         *ai;
  XvEncodingInfo        *ei;
  XvAttribute           *at;
  XvImageFormatValues   *fo;

  XvImage               *yuv_image;

#define GUID_YUV12_PLANAR 0x32315659
#define GUID_YUY2_PACKED 0x32595559

  unsigned int          p_version, p_release,
                        p_request_base, p_event_base, p_error_base;
  int                   p_num_adaptors;

  Display               *dpy;
  Window                window, _dw;
  XSizeHints            hint;
  XSetWindowAttributes  xswa;
  XVisualInfo           vinfo;
  int                   screen;
  unsigned long         mask;
  XEvent                event;
  GC                    gc;

  /** for shm */
  int                   shmem_flag = 0;
  XShmSegmentInfo       yuv_shminfo;
  int                   CompletionType;

  int                   dist = 2;


  printf("starting up video testapp...\n\n");

  adaptor = -1;

  dpy = XOpenDisplay(NULL);
  if (dpy == NULL) {
    printf("Cannot open Display.\n");
    exit (-1);
  }

  screen = DefaultScreen(dpy);

  /** find best display */
  if (XMatchVisualInfo(dpy, screen, 24, TrueColor, &vinfo)) {
    printf(" found 24bit TrueColor\n");
  } else
    if (XMatchVisualInfo(dpy, screen, 16, TrueColor, &vinfo)) {
      printf(" found 16bit TrueColor\n");
    } else
      if (XMatchVisualInfo(dpy, screen, 15, TrueColor, &vinfo)) {
        printf(" found 15bit TrueColor\n");
      } else
        if (XMatchVisualInfo(dpy, screen, 8, PseudoColor, &vinfo)) {
          printf(" found 8bit PseudoColor\n");
        } else
          if (XMatchVisualInfo(dpy, screen, 8, GrayScale, &vinfo)) {
            printf(" found 8bit GrayScale\n");
          } else
            if (XMatchVisualInfo(dpy, screen, 8, StaticGray, &vinfo)) {
              printf(" found 8bit StaticGray\n");
            } else
              if (XMatchVisualInfo(dpy, screen, 1, StaticGray, &vinfo)) {
                printf(" found 1bit StaticGray\n");
              } else {
                printf("requires 16 bit display\n");
                exit (-1);
              }

  CompletionType = -1;  

  hint.x = 1;
  hint.y = 1;
  hint.width = yuv_width;
  hint.height = yuv_height;
  hint.flags = PPosition | PSize;

  xswa.colormap =  XCreateColormap(dpy, DefaultRootWindow(dpy), vinfo.visual,
AllocNone);
  xswa.event_mask = StructureNotifyMask | ExposureMask;
  xswa.background_pixel = 0;
  xswa.border_pixel = 0;

  mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;

  window = XCreateWindow(dpy, DefaultRootWindow(dpy),
                         0, 0,
                         yuv_width,
                         yuv_height,
                         0, vinfo.depth,
                         InputOutput,
                         vinfo.visual,
                         mask, &xswa);

  XStoreName(dpy, window, "firstxv");
  XSetIconName(dpy, window, "firstxv");

  XSelectInput(dpy, window, StructureNotifyMask);

  /** Map window */
  XMapWindow(dpy, window);

  /** Wait for map. */
  do {
    XNextEvent(dpy, &event);
  }
  while (event.type != MapNotify || event.xmap.event != window);

  if (XShmQueryExtension(dpy)) shmem_flag = 1;
  if (!shmem_flag) {
    printf("no shmem available.\n");
    exit (-1);
  }

  if (shmem_flag==1) CompletionType = XShmGetEventBase(dpy) + ShmCompletion;


  /**--------------------------------- XV
------------------------------------*/
  printf("beginning to parse the Xvideo extension...\n\n");

  /** query and print Xvideo properties */
  ret = XvQueryExtension(dpy, &p_version, &p_release, &p_request_base,
                         &p_event_base, &p_error_base);
  if (ret != Success) {
    if (ret == XvBadExtension)
      printf("XvBadExtension returned at XvQueryExtension.\n");
    else
      if (ret == XvBadAlloc)
        printf("XvBadAlloc returned at XvQueryExtension.\n");
      else
        printf("other error happened at XvQueryExtension.\n");
  }
  printf("========================================\n");
  printf("XvQueryExtension returned the following:\n");
  printf("p_version      : %u\n", p_version);
  printf("p_release      : %u\n", p_release);
  printf("p_request_base : %u\n", p_request_base);
  printf("p_event_base   : %u\n", p_event_base);
  printf("p_error_base   : %u\n", p_error_base);
  printf("========================================\n");

  ret = XvQueryAdaptors(dpy, DefaultRootWindow(dpy),
                        &p_num_adaptors, &ai);

  if (ret != Success) {
    if (ret == XvBadExtension)
      printf("XvBadExtension returned at XvQueryExtension.\n");
    else
      if (ret == XvBadAlloc)
        printf("XvBadAlloc returned at XvQueryExtension.\n");
      else
        printf("other error happaned at XvQueryAdaptors.\n");
  }
  printf("=======================================\n");
  printf("XvQueryAdaptors returned the following:\n");
  printf("%d adaptors available.\n", p_num_adaptors);
  for (i = 0; i < p_num_adaptors; i++) {
    printf(" name:        %s\n"
           " type:        %s%s%s%s%s\n"
           " ports:       %ld\n"
           " first port:  %ld\n",
           ai[i].name,
           (ai[i].type & XvInputMask)   ? "input | "    : "",
           (ai[i].type & XvOutputMask)  ? "output | "   : "",
           (ai[i].type & XvVideoMask)   ? "video | "    : "",
           (ai[i].type & XvStillMask)   ? "still | "    : "",
           (ai[i].type & XvImageMask)   ? "image | "    : "",
           ai[i].num_ports,
           ai[i].base_id);
    xv_port = ai[i].base_id;

    printf("adaptor %d ; format list:\n", i);
    for (j = 0; j < ai[i].num_formats; j++) {
      printf(" depth=%d, visual=%ld\n",
             ai[i].formats[j].depth,
             ai[i].formats[j].visual_id);
    }
    for (p = ai[i].base_id; p < ai[i].base_id+ai[i].num_ports; p++) {

      printf(" encoding list for port %d\n", p);
      if (XvQueryEncodings(dpy, p, &encodings, &ei) != Success) {
        printf("XvQueryEncodings failed.\n");
        continue;
      }
      for (j = 0; j < encodings; j++) {
        printf("  id=%ld, name=%s, size=%ldx%ld, numerator=%d,
denominator=%d\n",
               ei[j].encoding_id, ei[j].name, ei[j].width, ei[j].height,
               ei[j].rate.numerator, ei[j].rate.denominator);
      }
      XvFreeEncodingInfo(ei);

      printf(" attribute list for port %d\n", p);
      at = XvQueryPortAttributes(dpy, p, &attributes);
      for (j = 0; j < attributes; j++) {
        printf("  name:       %s\n"
               "  flags:     %s%s\n"
               "  min_color:  %i\n"
               "  max_color:  %i\n",
               at[j].name,
               (at[j].flags & XvGettable) ? " get" : "",
               (at[j].flags & XvSettable) ? " set" : "",                        
               at[j].min_value, at[j].max_value);
      }
      if (at)
        XFree(at);

      printf(" image format list for port %d\n", p);
      fo = XvListImageFormats(dpy, p, &formats);
      for (j = 0; j < formats; j++) {
        printf("  0x%x (%4.4s) %s\n",
               fo[j].id,
               (char *)&fo[j].id,
               (fo[j].format == XvPacked) ? "packed" : "planar");
      }
      if (fo)
        XFree(fo);
    }
    printf("\n");
  }
  if (p_num_adaptors > 0)
    XvFreeAdaptorInfo(ai);
  if (xv_port == -1)
    exit (0);

  printf("using xv_port %d\n", xv_port);

  gc = XCreateGC(dpy, window, 0, 0);            

  yuv_image = XvCreateImage(dpy, xv_port, GUID_YUV12_PLANAR, 0, yuv_width,
yuv_height);
  yuv_image->data = malloc(yuv_image->data_size);

  memset(yuv_image->data, 128, yuv_image->data_size);

  for (i = 0; i < yuv_image->height; i++) {
        memset(&yuv_image->data[yuv_image->width*i], i, yuv_image->width);
  }

  while (1) {
    XGetGeometry(dpy, window, &_dw, &_d, &_d, &_w, &_h, &_d, &_d);

    XvPutImage(dpy, xv_port, window, gc, yuv_image,
               0, 0, yuv_image->width, yuv_image->height,
               0, 0, _w, _h);
    XFlush(dpy);
    usleep(500000);
  }

  return 0;
}


> > > Maybe we should try to get rid of the tables entirely for
> > > r200/r300 and just calculate all the segment values as needed, with arbitrary
> > > gamma value.
> > 
> > Something like this?  (Still my debugging stuff, but works for me :))
> Yes, that's what I had in mind (of course without the debug xvattr values...).
> Not sure it's entirely correct, where does that 1000 divide come from?

Because XV_GAMMA 1000 == Gamma 1.0


-- 
Configure bugmail: http://bugs.freedesktop.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.


More information about the xorg-driver-ati mailing list