xvinfo.c revision d71d4977
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <X11/X.h>
6#include <X11/Xlib.h>
7#include <X11/extensions/Xvlib.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <ctype.h>
12
13static char *progname;
14
15static void _X_NORETURN _X_COLD
16PrintUsage(void)
17{
18    fprintf(stderr, "Usage: %s [-display host:dpy] [-short] [-version]\n",
19            progname);
20    exit(0);
21}
22
23int
24main(int argc, char *argv[])
25{
26    Display *dpy;
27    unsigned int ver, rev, eventB, reqB, errorB;
28    unsigned int nencode, nadaptors;
29    int nscreens, nattr, numImages;
30    XvAdaptorInfo *ainfo;
31    XvAttribute *attributes;
32    XvEncodingInfo *encodings;
33    XvFormat *format;
34    XvImageFormatValues *formats;
35    char *disname = NULL;
36    char shortmode = 0;
37
38    progname = argv[0];
39
40    if ((argc > 4))
41        PrintUsage();
42
43    if (argc != 1) {
44        for (int i = 1; i < argc; i++) {
45            if (!strcmp(argv[i], "-display")) {
46                if (++i >= argc) {
47                    fprintf (stderr, "%s: missing argument to -display\n",
48                             progname);
49                    PrintUsage();
50                }
51                disname = argv[i];
52            }
53            else if (!strcmp(argv[i], "-short"))
54                shortmode = 1;
55            else if (!strcmp(argv[i], "-version")) {
56                printf("%s\n", PACKAGE_STRING);
57                exit(0);
58            }
59            else {
60                fprintf (stderr, "%s: unrecognized argument '%s'\n",
61                         progname, argv[i]);
62                PrintUsage();
63            }
64        }
65    }
66
67    if (!(dpy = XOpenDisplay(disname))) {
68        fprintf(stderr, "%s:  Unable to open display %s\n", progname,
69                (disname != NULL) ? disname : XDisplayName(NULL));
70        exit(-1);
71    }
72
73    if (Success != XvQueryExtension(dpy, &ver, &rev, &reqB, &eventB, &errorB)) {
74        fprintf(stderr, "%s: No X-Video Extension on %s\n", progname,
75                (disname != NULL) ? disname : XDisplayName(NULL));
76        exit(0);
77    }
78    else {
79        fprintf(stdout, "X-Video Extension version %i.%i\n", ver, rev);
80    }
81
82    nscreens = ScreenCount(dpy);
83
84    for (int i = 0; i < nscreens; i++) {
85        fprintf(stdout, "screen #%i\n", i);
86        if (Success != XvQueryAdaptors(dpy, RootWindow(dpy, i), &nadaptors,
87                                       &ainfo)) {
88            fprintf(stderr, "%s:  Failed to query adaptors on display %s\n",
89                    progname, (disname != NULL) ? disname : XDisplayName(NULL));
90            exit(-1);
91        }
92
93        if (!nadaptors) {
94            fprintf(stdout, " no adaptors present\n");
95            continue;
96        }
97
98        for (unsigned int j = 0; j < nadaptors; j++) {
99            fprintf(stdout, "  Adaptor #%i: \"%s\"\n", j, ainfo[j].name);
100            fprintf(stdout, "    number of ports: %li\n", ainfo[j].num_ports);
101            fprintf(stdout, "    port base: %li\n", ainfo[j].base_id);
102            fprintf(stdout, "    operations supported: ");
103            switch (ainfo[j].type & (XvInputMask | XvOutputMask)) {
104            case XvInputMask:
105                if (ainfo[j].type & XvVideoMask)
106                    fprintf(stdout, "PutVideo ");
107                if (ainfo[j].type & XvStillMask)
108                    fprintf(stdout, "PutStill ");
109                if (ainfo[j].type & XvImageMask)
110                    fprintf(stdout, "PutImage ");
111                break;
112            case XvOutputMask:
113                if (ainfo[j].type & XvVideoMask)
114                    fprintf(stdout, "GetVideo ");
115                if (ainfo[j].type & XvStillMask)
116                    fprintf(stdout, "GetStill ");
117                break;
118            default:
119                fprintf(stdout, "none ");
120                break;
121            }
122            fprintf(stdout, "\n");
123
124            format = ainfo[j].formats;
125
126            if (!shortmode) {
127                fprintf(stdout, "    supported visuals:\n");
128                for (unsigned long k = 0; k < ainfo[j].num_formats; k++, format++) {
129                    fprintf(stdout, "      depth %i, visualID 0x%2lx\n",
130                            format->depth, format->visual_id);
131                }
132            }
133
134            attributes = XvQueryPortAttributes(dpy, ainfo[j].base_id, &nattr);
135
136            if (attributes && nattr) {
137                fprintf(stdout, "    number of attributes: %i\n", nattr);
138
139                for (int k = 0; k < nattr; k++) {
140                    fprintf(stdout, "      \"%s\" (range %i to %i)\n",
141                            attributes[k].name,
142                            attributes[k].min_value, attributes[k].max_value);
143
144                    if (attributes[k].flags & XvSettable) {
145                        if (!shortmode)
146                            fprintf(stdout,
147                                    "              client settable attribute\n");
148                        else
149                            fprintf(stdout, "              settable");
150                    }
151
152                    if (attributes[k].flags & XvGettable) {
153                        Atom the_atom;
154
155                        int value;
156
157                        if (!shortmode)
158                            fprintf(stdout,
159                                    "              client gettable attribute");
160                        else
161                            fprintf(stdout, ", gettable");
162
163                        the_atom = XInternAtom(dpy, attributes[k].name, True);
164
165                        if (the_atom != None) {
166                            if ((Success == XvGetPortAttribute(dpy,
167                                                               ainfo[j].base_id,
168                                                               the_atom,
169                                                               &value)))
170                                fprintf(stdout, " (current value is %i)",
171                                        value);
172                        }
173                        fprintf(stdout, "\n");
174                    }
175                    else if (shortmode)
176                        fprintf(stdout, "\n");
177
178                }
179                XFree(attributes);
180            }
181            else {
182                fprintf(stdout, "    no port attributes defined\n");
183            }
184
185            if (Success != XvQueryEncodings(dpy, ainfo[j].base_id, &nencode,
186                                            &encodings)) {
187                fprintf(stderr,
188                        "%s:  Failed to query encodings on display %s\n",
189                        progname,
190                        (disname != NULL) ? disname : XDisplayName(NULL));
191                exit(-1);
192            }
193
194            if (encodings && nencode) {
195                unsigned int ImageEncodings = 0;
196
197                for (unsigned int n = 0; n < nencode; n++) {
198                    if (!strcmp(encodings[n].name, "XV_IMAGE"))
199                        ImageEncodings++;
200                }
201
202                if (nencode - ImageEncodings) {
203                    fprintf(stdout, "    number of encodings: %i\n",
204                            nencode - ImageEncodings);
205
206                    for (unsigned int n = 0; n < nencode; n++) {
207                        if (strcmp(encodings[n].name, "XV_IMAGE")) {
208                            fprintf(stdout, "      encoding ID #%li: \"%s\"\n",
209                                    encodings[n].encoding_id,
210                                    encodings[n].name);
211                            fprintf(stdout, "        size: %li x %li\n",
212                                    encodings[n].width, encodings[n].height);
213                            fprintf(stdout, "        rate: %f\n",
214                                    (float) encodings[n].rate.numerator /
215                                    (float) encodings[n].rate.denominator);
216                        }
217                    }
218                }
219
220                if (ImageEncodings && (ainfo[j].type & XvImageMask)) {
221                    for (unsigned int n = 0; n < nencode; n++) {
222                        if (!strcmp(encodings[n].name, "XV_IMAGE")) {
223                            fprintf(stdout,
224                                    "    maximum XvImage size: %li x %li\n",
225                                    encodings[n].width, encodings[n].height);
226                            break;
227                        }
228                    }
229
230                    formats =
231                        XvListImageFormats(dpy, ainfo[j].base_id, &numImages);
232
233                    fprintf(stdout, "    Number of image formats: %i\n",
234                            numImages);
235
236                    for (int n = 0; n < numImages; n++) {
237                        char imageName[5];
238
239                        snprintf(imageName, sizeof(imageName), "%c%c%c%c",
240                                 formats[n].id & 0xff,
241                                (formats[n].id >> 8) & 0xff,
242                                (formats[n].id >> 16) & 0xff,
243                                (formats[n].id >> 24) & 0xff);
244                        fprintf(stdout, "      id: 0x%x", formats[n].id);
245                        if (isprint(imageName[0]) && isprint(imageName[1]) &&
246                            isprint(imageName[2]) && isprint(imageName[3])) {
247                            fprintf(stdout, " (%s)\n", imageName);
248                        }
249                        else {
250                            fprintf(stdout, "\n");
251                        }
252                        if (!shortmode) {
253                            fprintf(stdout, "        guid: ");
254                            fprintf(stdout, "%02x", (unsigned char)
255                                    formats[n].guid[0]);
256                            fprintf(stdout, "%02x", (unsigned char)
257                                    formats[n].guid[1]);
258                            fprintf(stdout, "%02x", (unsigned char)
259                                    formats[n].guid[2]);
260                            fprintf(stdout, "%02x-", (unsigned char)
261                                    formats[n].guid[3]);
262                            fprintf(stdout, "%02x", (unsigned char)
263                                    formats[n].guid[4]);
264                            fprintf(stdout, "%02x-", (unsigned char)
265                                    formats[n].guid[5]);
266                            fprintf(stdout, "%02x", (unsigned char)
267                                    formats[n].guid[6]);
268                            fprintf(stdout, "%02x-", (unsigned char)
269                                    formats[n].guid[7]);
270                            fprintf(stdout, "%02x", (unsigned char)
271                                    formats[n].guid[8]);
272                            fprintf(stdout, "%02x-", (unsigned char)
273                                    formats[n].guid[9]);
274                            fprintf(stdout, "%02x", (unsigned char)
275                                    formats[n].guid[10]);
276                            fprintf(stdout, "%02x", (unsigned char)
277                                    formats[n].guid[11]);
278                            fprintf(stdout, "%02x", (unsigned char)
279                                    formats[n].guid[12]);
280                            fprintf(stdout, "%02x", (unsigned char)
281                                    formats[n].guid[13]);
282                            fprintf(stdout, "%02x", (unsigned char)
283                                    formats[n].guid[14]);
284                            fprintf(stdout, "%02x\n", (unsigned char)
285                                    formats[n].guid[15]);
286
287                            fprintf(stdout, "        bits per pixel: %i\n",
288                                    formats[n].bits_per_pixel);
289                            fprintf(stdout, "        number of planes: %i\n",
290                                    formats[n].num_planes);
291                            fprintf(stdout, "        type: %s (%s)\n",
292                                    (formats[n].type == XvRGB) ? "RGB" : "YUV",
293                                    (formats[n].format ==
294                                     XvPacked) ? "packed" : "planar");
295
296                            if (formats[n].type == XvRGB) {
297                                fprintf(stdout, "        depth: %i\n",
298                                        formats[n].depth);
299
300                                fprintf(stdout,
301                                        "        red, green, blue masks: "
302                                        "0x%x, 0x%x, 0x%x\n",
303                                        formats[n].red_mask,
304                                        formats[n].green_mask,
305                                        formats[n].blue_mask);
306                            }
307                            else {
308
309                            }
310                        }
311
312                    }
313                    if (formats)
314                        XFree(formats);
315                }
316
317                XvFreeEncodingInfo(encodings);
318            }
319
320        }
321
322        XvFreeAdaptorInfo(ainfo);
323    }
324    return 0;
325}
326