Hallo!
Urspruenglich waren mal die Voodoo-Karten die best unterstuetzten
Karten unter Linux - leider habe ich den Eindruck, dass sich das
mittlerweile gelegt hat. Mein konkretes Problem ist Folgendes:
Viele der neuen Video-Programme (xmovie, ich glaube auch avifile)
machen mittlerweile Gebrauch von den X11 Xv-Extensions (damit
wird zum Bsp. eine Hardware-Skalierung realisiert). Auf Rechnern
mit einer normalen Matrox-Karte funktioniert das ganze auch
einwandfrei: Bild grosszeiehen oder Vollbild und die Hardware
der Grafikkarte sorgt fuer den Rest. Bei meiner Voodoo-Karte
bekomme ich alternativ einen schwarzen Bildschirm oder aber eine
Software-Skalierung, die bei 1600x1200 mein System ziemlich in die
Knie zwingt :-)
Meine Frage also: Gibt es jemanden, der eine XFree Version laufen
hat, die das unterstuetzt? Ich erinnere mich, dass vor einiger
Zeit einmal Patches im Umlauf waren, die das ermoeglichen sollten.
Leider hab ich die nie gefunden :-(
Wer es ausprobieren moechte kann sich einfach ein kleines C-Programm
(s.unten: textxv.c) kompilieren. Normalerweise sollte (bei Xv-Support)
dann ein buntes Bildchen kommen - bei mir bricht es aber nur ab ...
Infos willkommen,
Marcel
---------------- CUT HERE ----------------------------
/* -------------------------------------------
* --- XV Testcode ---
* --- by AW ---*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.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*);
void put_pixel(char* data, int x, int y, int maxx, int p) {
data[y*maxx + x] = p;
}
int main (int argc, char* argv[]) {
int yuv_width = 640;
int yuv_height = 480;
int xv_port = -1;
int adaptor, encodings, attributes, formats;
int i, j, ret, p, _d, _w, _h;
long secsb, secsa, frames;
XvAdaptorInfo *ai;
XvEncodingInfo *ei;
XvAttribute *at;
XvImageFormatValues *fo;
XvImage *yuv_image;
#define GUID_YUV12_PLANAR 0x32315659
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;
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);
gc = XCreateGC(dpy, window, 0, 0);
yuv_image = XvShmCreateImage(dpy, xv_port, GUID_YUV12_PLANAR, 0, yuv_width, yuv_height, &yuv_shminfo);
yuv_shminfo.shmid = shmget(IPC_PRIVATE, yuv_image->data_size, IPC_CREAT | 0777);
yuv_shminfo.shmaddr = yuv_image->data = shmat(yuv_shminfo.shmid, 0, 0);
yuv_shminfo.readOnly = False;
if (!XShmAttach(dpy, &yuv_shminfo)) {
printf("XShmAttach failed !\n");
exit (-1);
}
for (i = 0; i < yuv_image->height; i++) {
for (j = 0; j < yuv_image->width; j++) {
yuv_image->data[yuv_image->width*i + j] = i*j;
}
}
printf("%d\n", yuv_image->data_size);
while (1) {
frames = secsa = secsb = 0;
time(&secsa);
while (frames < 200) {
XGetGeometry(dpy, window, &_dw, &_d, &_d, &_w, &_h, &_d, &_d);
XvShmPutImage(dpy, xv_port, window, gc, yuv_image,
0, 0, yuv_image->width, yuv_image->height,
0, 0, _w, _h, True);
/* XFlush(dpy); */
frames++;
}
time(&secsb);
printf("%ld frames in %ld seconds; %.4f fps\n", frames, secsb-secsa, (double) frames/(secsb-secsa));
}
return 0;
}
---------------------- CUT HERE --------------------------