~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to mpeglib/lib/util/render/x11/imageXVDesk.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  xfree 4.0 XV extension desk mode
 
3
  Copyright (C) 2000  Martin Vogt
 
4
 
 
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.
 
8
 
 
9
  For more information look at the file COPYRIGHT in this package
 
10
 
 
11
 */
 
12
 
 
13
#include "imageXVDesk.h"
 
14
 
 
15
ImageXVDesk::ImageXVDesk() {
 
16
 
 
17
  lSupport=false;
 
18
 
 
19
  ditherWrapper=NULL;
 
20
  supportedModes = _IMAGE_NONE;
 
21
  setIdentifier("XV");
 
22
 
 
23
  xWindow = NULL;
 
24
 
 
25
#ifdef X11_XV
 
26
  keepRatio = false;
 
27
  
 
28
#endif
 
29
}
 
30
 
 
31
 
 
32
ImageXVDesk::~ImageXVDesk() {
 
33
  if (ditherWrapper != NULL) {
 
34
    delete ditherWrapper;
 
35
  }
 
36
  freeImage();
 
37
}
 
38
 
 
39
void ImageXVDesk::init(XWindow* xWindow, YUVPicture*)
 
40
{
 
41
#ifdef X11_XV
 
42
  this->xWindow=xWindow;
 
43
 
 
44
  xv_port=-1;
 
45
  shmem_flag = 0;
 
46
  yuv_image=NULL;
 
47
  yuv_shminfo.shmaddr=NULL;
 
48
  yuv_shminfo.shmid=-1;
 
49
  
 
50
  if (XShmQueryExtension(xWindow->display)) shmem_flag = 1;
 
51
  if (!shmem_flag) {
 
52
    printf("no shmem available.\n");
 
53
    return;
 
54
  }
 
55
  
 
56
 
 
57
  if (haveXVSupport(xWindow)==true) {
 
58
    supportedModes = _IMAGE_DESK | _IMAGE_DOUBLE | _IMAGE_FULL | _IMAGE_RESIZE;
 
59
    lSupport=true;
 
60
  } else {
 
61
    return;
 
62
  }
 
63
 
 
64
  if (ditherWrapper == NULL) {
 
65
    ditherWrapper=new Dither2YUV();
 
66
  }
 
67
  imageID = -1;
 
68
#endif
 
69
}
 
70
 
 
71
int ImageXVDesk::support() {
 
72
  return lSupport;
 
73
}
 
74
 
 
75
int ImageXVDesk::openImage(int imageMode) {
 
76
 
 
77
  
 
78
  if (imageMode & _IMAGE_FULL) {
 
79
    XResizeWindow(xWindow->display, xWindow->window,
 
80
                  xWindow->screenptr->width, xWindow->screenptr->height);
 
81
    setKeepRatio(true);
 
82
  } else if (imageMode & _IMAGE_DOUBLE) {
 
83
    XResizeWindow(xWindow->display, xWindow->window,
 
84
                  xWindow->width * 2, xWindow->height * 2);
 
85
    setKeepRatio(false);
 
86
  } else {
 
87
    setKeepRatio(false);
 
88
  }
 
89
  
 
90
  return true;
 
91
}
 
92
 
 
93
 
 
94
int ImageXVDesk::closeImage() {
 
95
  freeImage();
 
96
  return true;
 
97
}
 
98
 
 
99
void ImageXVDesk::ditherImage(YUVPicture* pic) {
 
100
 
 
101
#ifdef X11_XV
 
102
  int x_return;
 
103
  int y_return;
 
104
  int height, dy; 
 
105
  unsigned int  border_width_return;
 
106
  unsigned int  depth_return;
 
107
  unsigned int  _w;
 
108
  unsigned int  _h;
 
109
  Window        _dw;
 
110
  
 
111
  if (xWindow == NULL) {
 
112
    cout << "ImageXVDesk::ditherImage - you have to call before dithering an image!" << endl;
 
113
    return;
 
114
  }
 
115
  
 
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;
 
120
    return;
 
121
  }
 
122
  
 
123
  // create xv image 
 
124
  int id;
 
125
  if (imageID != pic->getImageType()) {
 
126
    imageID = pic->getImageType();
 
127
    switch (imageID) {
 
128
    case PICTURE_YUVMODE_CR_CB:
 
129
    case PICTURE_YUVMODE_CB_CR:
 
130
    case PICTURE_RGB:
 
131
      id = GUID_YUV12_PLANAR;
 
132
      break;
 
133
    case PICTURE_YUVMODE_YUY2:
 
134
      id = GUID_YUY2_PACKED;
 
135
      break;
 
136
    case PICTURE_YUVMODE_UYVY:
 
137
      id = GUID_UYVY_PACKED;
 
138
      break;
 
139
    default:
 
140
      cout << "unknown type for yuv image!" << endl;
 
141
      return;
 
142
    }
 
143
    freeImage();
 
144
    
 
145
    createImage(id);
 
146
  }
 
147
  
 
148
  XGetGeometry(xWindow->display,(Drawable)xWindow->window,
 
149
               &_dw, &x_return, &y_return, &_w, &_h,
 
150
               &border_width_return, &depth_return);
 
151
  
 
152
  // now dither the image
 
153
  
 
154
  // we (currently) cannot create yuvPicture _in_
 
155
  // the shared segment here we copy it
 
156
  
 
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);
 
162
  } else {
 
163
    memcpy(yuv_image->data,image,pic->getImageSize());
 
164
  }
 
165
        
 
166
  if (keepRatio) {
 
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);
 
173
    if (dy > 0) {
 
174
                XFillRectangle(xWindow->display, xWindow->window,xWindow->gc, 
 
175
                                           0, 0, _w, dy);
 
176
                XFillRectangle(xWindow->display, xWindow->window,xWindow->gc, 
 
177
                                           0, height+dy-1, _w, dy+1);
 
178
        }
 
179
  } else {
 
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);
 
184
  }
 
185
#endif
 
186
}
 
187
 
 
188
 
 
189
void ImageXVDesk::putImage() {
 
190
 
 
191
  //XFlush(xWindow->display);      
 
192
  XSync(xWindow->display, false);      
 
193
}
 
194
 
 
195
void ImageXVDesk::setKeepRatio(bool enable)
 
196
{
 
197
#ifdef X11_XV
 
198
  keepRatio = enable;
 
199
#endif
 
200
}
 
201
 
 
202
 
 
203
int ImageXVDesk::haveXVSupport(XWindow* xWindow) {
 
204
#ifdef X11_XV
 
205
  int ret;
 
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;
 
211
 
 
212
  unsigned int          p_num_adaptors=0;
 
213
 
 
214
  /**------------------------------- XV ------------------------------------*/
 
215
  
 
216
  /** query and print Xvideo properties */
 
217
 
 
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");
 
226
    } else {
 
227
      printf("other error happened at XvQueryExtension.\n");
 
228
    }
 
229
    return false;
 
230
  }
 
231
  /*
 
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");
 
240
  */
 
241
  
 
242
  ret = XvQueryAdaptors(xWindow->display, DefaultRootWindow(xWindow->display),
 
243
                        &p_num_adaptors, &ai);
 
244
  
 
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");
 
250
    } else {
 
251
      printf("other error happaned at XvQueryAdaptors.\n");
 
252
    }
 
253
    return false;
 
254
  }
 
255
  /*
 
256
  printf("=======================================\n");
 
257
  printf("XvQueryAdaptors returned the following:\n");
 
258
  printf("%d adaptors available.\n", p_num_adaptors);
 
259
  */
 
260
  if (p_num_adaptors == 0) {
 
261
    //cout << "no adaptors found. XV not possible"<<endl;
 
262
    return false;
 
263
  }
 
264
 
 
265
  unsigned int i;
 
266
  unsigned int j;
 
267
 
 
268
  for (i = 0; i < p_num_adaptors; i++) {
 
269
    /*
 
270
      printf(" name:        %s\n"
 
271
      " type:        %s%s%s%s%s\n"
 
272
      " ports:       %ld\n"
 
273
      " first port:  %ld\n",
 
274
      ai[i].name,
 
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 | "    : "",
 
280
      ai[i].num_ports,
 
281
      ai[i].base_id);
 
282
    */
 
283
    xv_port = ai[i].base_id;
 
284
    
 
285
    //printf("adaptor %d ; format list:\n", i);
 
286
    for (j = 0; j < ai[i].num_formats; j++) {
 
287
      /*
 
288
        printf(" depth=%d, visual=%ld\n",
 
289
        ai[i].formats[j].depth,
 
290
        ai[i].formats[j].visual_id);
 
291
      */
 
292
    }
 
293
    unsigned int p;
 
294
    unsigned int encodings;
 
295
    int attributes;
 
296
    int formats;
 
297
 
 
298
    for (p = ai[i].base_id; p < ai[i].base_id+ai[i].num_ports; p++) {
 
299
      
 
300
      //printf(" encoding list for port %d\n", p);
 
301
      if (XvQueryEncodings(xWindow->display, p, &encodings, &ei) != Success) {
 
302
        //printf("XvQueryEncodings failed.\n");
 
303
        continue;
 
304
      }
 
305
      for (j = 0; j < encodings; j++) {
 
306
        /*
 
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);
 
310
        */
 
311
      }
 
312
      XvFreeEncodingInfo(ei);
 
313
      int k;
 
314
      //printf(" attribute list for port %d\n", p);
 
315
      at = XvQueryPortAttributes(xWindow->display, p, &attributes);
 
316
      for (k = 0; k < attributes; k++) {
 
317
        /*
 
318
        printf("  name:       %s\n"
 
319
               "  flags:     %s%s\n"
 
320
               "  min_color:  %i\n"
 
321
               "  max_color:  %i\n",
 
322
               at[k].name,
 
323
               (at[k].flags & XvGettable) ? " get" : "",
 
324
               (at[k].flags & XvSettable) ? " set" : "",                                                
 
325
               at[k].min_value, at[k].max_value);
 
326
        */
 
327
      }
 
328
      if (at)
 
329
        XFree(at);
 
330
      
 
331
      //printf(" image format list for port %d\n", p);
 
332
      fo = XvListImageFormats(xWindow->display, p, &formats);
 
333
      for (k = 0; k < formats; k++) {
 
334
        /*
 
335
        printf("  0x%x (%4.4s) %s\n",
 
336
               fo[k].id,
 
337
               (char *)&fo[k].id,
 
338
               (fo[k].format == XvPacked) ? "packed" : "planar");
 
339
        */
 
340
      }
 
341
      if (fo)
 
342
        XFree(fo);
 
343
    }
 
344
    printf("\n");
 
345
  }
 
346
  if (p_num_adaptors > 0)
 
347
    XvFreeAdaptorInfo(ai);
 
348
  if (xv_port == -1) {
 
349
    return false;
 
350
  }
 
351
#endif
 
352
  return true;
 
353
  
 
354
}
 
355
 
 
356
 
 
357
void ImageXVDesk::freeImage() {
 
358
#ifdef X11_XV
 
359
  if (xWindow == NULL) {
 
360
    return;
 
361
  }
 
362
  if (yuv_shminfo.shmid >=0) {
 
363
    XShmDetach(xWindow->display,&yuv_shminfo);
 
364
    if(yuv_shminfo.shmaddr) {
 
365
      shmdt(yuv_shminfo.shmaddr);
 
366
      XFree(yuv_image);
 
367
      yuv_shminfo.shmaddr=NULL;
 
368
    }
 
369
    XSync(xWindow->display, False);
 
370
    yuv_shminfo.shmid=-1;
 
371
  }
 
372
#endif 
 
373
}
 
374
 
 
375
 
 
376
void ImageXVDesk::createImage(int id) {
 
377
#ifdef X11_XV
 
378
  if (xWindow == NULL) {
 
379
    cout << "ImageXVDesk::freeImage - you have to call init before creating an image!" << endl;
 
380
    return;
 
381
  }
 
382
  
 
383
  yuv_image = XvShmCreateImage(xWindow->display, xv_port, 
 
384
                               id, 0, 
 
385
                               xWindow->width,
 
386
                               xWindow->height, &yuv_shminfo);
 
387
  
 
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;
 
393
 
 
394
  if (!XShmAttach(xWindow->display, &yuv_shminfo)) {
 
395
    printf("XShmAttach failed !\n");
 
396
    lSupport=false;
 
397
    return;
 
398
  }
 
399
  shmctl(yuv_shminfo.shmid, IPC_RMID, 0);
 
400
#endif  
 
401
}