2
xfree 4.0 XV extension desk mode
3
Copyright (C) 2000 Martin Vogt
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU Library General Public License as published by
7
the Free Software Foundation.
9
For more information look at the file COPYRIGHT in this package
13
#include "imageXVDesk.h"
15
ImageXVDesk::ImageXVDesk() {
20
supportedModes = _IMAGE_NONE;
32
ImageXVDesk::~ImageXVDesk() {
33
if (ditherWrapper != NULL) {
39
void ImageXVDesk::init(XWindow* xWindow, YUVPicture*)
42
this->xWindow=xWindow;
47
yuv_shminfo.shmaddr=NULL;
50
if (XShmQueryExtension(xWindow->display)) shmem_flag = 1;
52
printf("no shmem available.\n");
57
if (haveXVSupport(xWindow)==true) {
58
supportedModes = _IMAGE_DESK | _IMAGE_DOUBLE | _IMAGE_FULL | _IMAGE_RESIZE;
64
if (ditherWrapper == NULL) {
65
ditherWrapper=new Dither2YUV();
71
int ImageXVDesk::support() {
75
int ImageXVDesk::openImage(int imageMode) {
78
if (imageMode & _IMAGE_FULL) {
79
XResizeWindow(xWindow->display, xWindow->window,
80
xWindow->screenptr->width, xWindow->screenptr->height);
82
} else if (imageMode & _IMAGE_DOUBLE) {
83
XResizeWindow(xWindow->display, xWindow->window,
84
xWindow->width * 2, xWindow->height * 2);
94
int ImageXVDesk::closeImage() {
99
void ImageXVDesk::ditherImage(YUVPicture* pic) {
105
unsigned int border_width_return;
106
unsigned int depth_return;
111
if (xWindow == NULL) {
112
cout << "ImageXVDesk::ditherImage - you have to call before dithering an image!" << endl;
116
// check for not supported formats and if possible convert them
117
int inputType=pic->getImageType();
118
if (inputType == PICTURE_RGB_FLIPPED) {
119
cout << "xv for flipped rgb not implemented"<<endl;
125
if (imageID != pic->getImageType()) {
126
imageID = pic->getImageType();
128
case PICTURE_YUVMODE_CR_CB:
129
case PICTURE_YUVMODE_CB_CR:
131
id = GUID_YUV12_PLANAR;
133
case PICTURE_YUVMODE_YUY2:
134
id = GUID_YUY2_PACKED;
136
case PICTURE_YUVMODE_UYVY:
137
id = GUID_UYVY_PACKED;
140
cout << "unknown type for yuv image!" << endl;
148
XGetGeometry(xWindow->display,(Drawable)xWindow->window,
149
&_dw, &x_return, &y_return, &_w, &_h,
150
&border_width_return, &depth_return);
152
// now dither the image
154
// we (currently) cannot create yuvPicture _in_
155
// the shared segment here we copy it
157
unsigned char* image=pic->getImagePtr();
158
if (inputType == PICTURE_RGB) {
159
ditherWrapper->doDither(pic,
160
DefaultDepth(xWindow->display,xWindow->screennum),
161
_SIZE_NORMAL, (unsigned char*) yuv_image->data, 0);
163
memcpy(yuv_image->data,image,pic->getImageSize());
167
height = (_w * yuv_image->height) / yuv_image->width;
168
dy = (((int) _h) - height + 1) / 2;
169
XvShmPutImage(xWindow->display, xv_port,xWindow->window,
170
xWindow->gc, yuv_image,
171
0, 0, yuv_image->width, yuv_image->height,
172
0, dy, _w, height, False);
174
XFillRectangle(xWindow->display, xWindow->window,xWindow->gc,
176
XFillRectangle(xWindow->display, xWindow->window,xWindow->gc,
177
0, height+dy-1, _w, dy+1);
180
XvShmPutImage(xWindow->display, xv_port,xWindow->window,
181
xWindow->gc, yuv_image,
182
0, 0, yuv_image->width, yuv_image->height,
183
0, 0, _w, _h, False);
189
void ImageXVDesk::putImage() {
191
//XFlush(xWindow->display);
192
XSync(xWindow->display, false);
195
void ImageXVDesk::setKeepRatio(bool enable)
203
int ImageXVDesk::haveXVSupport(XWindow* xWindow) {
206
unsigned int p_version=0;
207
unsigned int p_release=0;
208
unsigned int p_request_base=0;
209
unsigned int p_event_base=0;
210
unsigned int p_error_base=0;
212
unsigned int p_num_adaptors=0;
214
/**------------------------------- XV ------------------------------------*/
216
/** query and print Xvideo properties */
218
ret = XvQueryExtension(xWindow->display,
219
&p_version, &p_release, &p_request_base,
220
&p_event_base, &p_error_base);
221
if (ret != Success) {
222
if (ret == XvBadExtension) {
223
printf("XvBadExtension returned at XvQueryExtension.\n");
224
} else if (ret == XvBadAlloc) {
225
printf("XvBadAlloc returned at XvQueryExtension.\n");
227
printf("other error happened at XvQueryExtension.\n");
232
printf("========================================\n");
233
printf("XvQueryExtension returned the following:\n");
234
printf("p_version : %u\n", p_version);
235
printf("p_release : %u\n", p_release);
236
printf("p_request_base : %u\n", p_request_base);
237
printf("p_event_base : %u\n", p_event_base);
238
printf("p_error_base : %u\n", p_error_base);
239
printf("========================================\n");
242
ret = XvQueryAdaptors(xWindow->display, DefaultRootWindow(xWindow->display),
243
&p_num_adaptors, &ai);
245
if (ret != Success) {
246
if (ret == XvBadExtension) {
247
printf("XvBadExtension returned at XvQueryExtension.\n");
248
} else if (ret == XvBadAlloc) {
249
printf("XvBadAlloc returned at XvQueryExtension.\n");
251
printf("other error happaned at XvQueryAdaptors.\n");
256
printf("=======================================\n");
257
printf("XvQueryAdaptors returned the following:\n");
258
printf("%d adaptors available.\n", p_num_adaptors);
260
if (p_num_adaptors == 0) {
261
//cout << "no adaptors found. XV not possible"<<endl;
268
for (i = 0; i < p_num_adaptors; i++) {
271
" type: %s%s%s%s%s\n"
273
" first port: %ld\n",
275
(ai[i].type & XvInputMask) ? "input | " : "",
276
(ai[i].type & XvOutputMask) ? "output | " : "",
277
(ai[i].type & XvVideoMask) ? "video | " : "",
278
(ai[i].type & XvStillMask) ? "still | " : "",
279
(ai[i].type & XvImageMask) ? "image | " : "",
283
xv_port = ai[i].base_id;
285
//printf("adaptor %d ; format list:\n", i);
286
for (j = 0; j < ai[i].num_formats; j++) {
288
printf(" depth=%d, visual=%ld\n",
289
ai[i].formats[j].depth,
290
ai[i].formats[j].visual_id);
294
unsigned int encodings;
298
for (p = ai[i].base_id; p < ai[i].base_id+ai[i].num_ports; p++) {
300
//printf(" encoding list for port %d\n", p);
301
if (XvQueryEncodings(xWindow->display, p, &encodings, &ei) != Success) {
302
//printf("XvQueryEncodings failed.\n");
305
for (j = 0; j < encodings; j++) {
307
printf(" id=%ld, name=%s, size=%ldx%ld, numerator=%d, denominator=%d\n",
308
ei[j].encoding_id, ei[j].name, ei[j].width, ei[j].height,
309
ei[j].rate.numerator, ei[j].rate.denominator);
312
XvFreeEncodingInfo(ei);
314
//printf(" attribute list for port %d\n", p);
315
at = XvQueryPortAttributes(xWindow->display, p, &attributes);
316
for (k = 0; k < attributes; k++) {
323
(at[k].flags & XvGettable) ? " get" : "",
324
(at[k].flags & XvSettable) ? " set" : "",
325
at[k].min_value, at[k].max_value);
331
//printf(" image format list for port %d\n", p);
332
fo = XvListImageFormats(xWindow->display, p, &formats);
333
for (k = 0; k < formats; k++) {
335
printf(" 0x%x (%4.4s) %s\n",
338
(fo[k].format == XvPacked) ? "packed" : "planar");
346
if (p_num_adaptors > 0)
347
XvFreeAdaptorInfo(ai);
357
void ImageXVDesk::freeImage() {
359
if (xWindow == NULL) {
362
if (yuv_shminfo.shmid >=0) {
363
XShmDetach(xWindow->display,&yuv_shminfo);
364
if(yuv_shminfo.shmaddr) {
365
shmdt(yuv_shminfo.shmaddr);
367
yuv_shminfo.shmaddr=NULL;
369
XSync(xWindow->display, False);
370
yuv_shminfo.shmid=-1;
376
void ImageXVDesk::createImage(int id) {
378
if (xWindow == NULL) {
379
cout << "ImageXVDesk::freeImage - you have to call init before creating an image!" << endl;
383
yuv_image = XvShmCreateImage(xWindow->display, xv_port,
386
xWindow->height, &yuv_shminfo);
388
yuv_shminfo.shmid = shmget(IPC_PRIVATE,
389
yuv_image->data_size, IPC_CREAT | 0777);
390
yuv_shminfo.shmaddr = yuv_image->data =
391
(char*)shmat(yuv_shminfo.shmid, 0, 0);
392
yuv_shminfo.readOnly = False;
394
if (!XShmAttach(xWindow->display, &yuv_shminfo)) {
395
printf("XShmAttach failed !\n");
399
shmctl(yuv_shminfo.shmid, IPC_RMID, 0);