~ubuntu-branches/ubuntu/maverick/vice/maverick

« back to all changes in this revision

Viewing changes to src/arch/unix/x11/renderxv.c

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2010-02-11 18:30:16 UTC
  • mfrom: (1.1.8 upstream) (9.2.2 sid)
  • Revision ID: james.westby@ubuntu.com-20100211183016-f6n8usn3tzp0u6dp
Tags: 2.2.dfsg-1
* New upstream release, C64 DTV is included so update package description
  and add it to the menu.
* Drop patch fixing build failure with gcc-4.4 , applied upstream.
* Fix some lintian problems and clean up debian/rules .

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
 *
25
25
 */
26
26
 
27
 
 
28
27
/* The PAL Y/C and PAL Composite emulation is based on work by John
29
28
   Selck <graham@cruise.de>. The Xv probing and allocation code is
30
29
   loosely based on testxv.c (by Andr� Werthmann) and VideoLAN. */
48
47
#if defined(__QNX__) || defined(MINIX_SUPPORT)
49
48
Status XShmAttach(Display *display, XShmSegmentInfo *shminfo)
50
49
{
51
 
  return 0;
 
50
    return 0;
52
51
}
53
52
 
54
53
Status XShmDetach(Display *display, XShmSegmentInfo *shminfo)
55
54
{
56
 
  return 0;
 
55
    return 0;
57
56
}
58
57
#endif
59
58
 
60
59
#ifdef MINIX_SUPPORT
61
60
typedef long key_t;
62
61
 
63
 
struct ipc_perm
64
 
{
65
 
  key_t          key;
66
 
  unsigned short uid;
67
 
  unsigned short gid;
68
 
  unsigned short cuid;
69
 
  unsigned short cgid;
70
 
  unsigned short mode;
71
 
  unsigned short seq;
 
62
struct ipc_perm {
 
63
    key_t key;
 
64
    unsigned short uid;
 
65
    unsigned short gid;
 
66
    unsigned short cuid;
 
67
    unsigned short cgid;
 
68
    unsigned short mode;
 
69
    unsigned short seq;
72
70
};
73
71
 
74
 
struct shmid_ds
75
 
{
76
 
  struct          ipc_perm shm_perm;
77
 
  int             shm_segsz;
78
 
  time_t          shm_atime;
79
 
  time_t          shm_dtime;
80
 
  time_t          shm_ctime;
81
 
  unsigned short  shm_cpid;
82
 
  unsigned short  shm_lpid;
83
 
  short           shm_nattch;
84
 
  unsigned short  shm_npages;
85
 
  unsigned long   *shm_pages;
 
72
struct shmid_ds {
 
73
    struct ipc_perm shm_perm;
 
74
    int shm_segsz;
 
75
    time_t shm_atime;
 
76
    time_t shm_dtime;
 
77
    time_t shm_ctime;
 
78
    unsigned short shm_cpid;
 
79
    unsigned short shm_lpid;
 
80
    short shm_nattch;
 
81
    unsigned short shm_npages;
 
82
    unsigned long *shm_pages;
86
83
};
87
84
 
88
85
#define IPC_PRIVATE ((key_t)0)
91
88
 
92
89
int shmget(key_t key, int size, int shmflag)
93
90
{
94
 
  return -1;
 
91
    return -1;
95
92
}
96
93
 
97
94
void *shmat(int shmid, const void *shmaddr, int shmflag)
100
97
 
101
98
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
102
99
{
103
 
  return -1;
 
100
    return -1;
104
101
}
105
102
 
106
103
int shmdt(const void *shmaddr)
107
104
{
108
 
  return -1;
 
105
    return -1;
109
106
}
110
107
#endif
111
108
 
112
109
/* YUV formats in preferred order. */
113
110
fourcc_t fourcc_list[] = {
114
 
  /* YUV 4:2:2 formats: */
115
 
  { FOURCC_UYVY },
116
 
  { FOURCC_YUY2 },
117
 
  { FOURCC_YVYU },
118
 
  /* YUV 4:1:1 formats: */
119
 
  { FOURCC_YV12 },
120
 
  { FOURCC_I420 },
121
 
  { FOURCC_IYUV }, /* IYUV is a duplicate of I420. */
 
111
    /* YUV 4:2:2 formats: */
 
112
    { FOURCC_UYVY },
 
113
    { FOURCC_YUY2 },
 
114
    { FOURCC_YVYU },
 
115
    /* YUV 4:1:1 formats: */
 
116
    { FOURCC_YV12 },
 
117
    { FOURCC_I420 },
 
118
    { FOURCC_IYUV }, /* IYUV is a duplicate of I420. */
122
119
};
123
120
 
124
121
int find_yuv_port(Display* display, XvPortID* port, fourcc_t* format)
125
122
{
126
 
  int i, j, k;
127
 
 
128
 
  /* XvQueryExtension */
129
 
  unsigned int version, release, request_base, event_base, error_base;
130
 
 
131
 
  /* XvQueryAdaptors */
132
 
  unsigned int num_adaptors;
133
 
  XvAdaptorInfo* adaptor_info = NULL;
134
 
  XvPortID port_id;
135
 
 
136
 
  /* XvListImageFormats */
137
 
  int num_formats;
138
 
  XvImageFormatValues* format_list = NULL;
139
 
 
140
 
  switch (XvQueryExtension(display, &version, &release,
141
 
                           &request_base, &event_base, &error_base))
142
 
  {
143
 
  case Success:
144
 
    break;
145
 
  case XvBadExtension:
146
 
    printf("XvQueryExtension returned XvBadExtension.\n");
147
 
    return 0;
148
 
  case XvBadAlloc:
149
 
    printf("XvQueryExtension returned XvBadAlloc.\n");
150
 
    return 0;
151
 
  default:
152
 
    printf("XvQueryExtension returned unknown error.\n");
153
 
    return 0;
154
 
  }
155
 
 
156
 
  switch (XvQueryAdaptors(display, DefaultRootWindow(display),
157
 
                          &num_adaptors, &adaptor_info))
158
 
  {
159
 
  case Success:
160
 
    break;
161
 
  case XvBadExtension:
162
 
    printf("XvQueryAdaptors returned XvBadExtension.\n");
163
 
    return 0;
164
 
  case XvBadAlloc:
165
 
    printf("XvQueryAdaptors returned XvBadAlloc.\n");
166
 
    return 0;
167
 
  default:
168
 
    printf("XvQueryAdaptors returned unknown error.\n");
169
 
    return 0;
170
 
  }
171
 
 
172
 
  /* Find YUV capable adaptor. */
173
 
  for (i = 0; i < (int)num_adaptors; i++) {
174
 
    if (!(adaptor_info[i].type & XvInputMask
175
 
          && adaptor_info[i].type & XvImageMask))
176
 
    {
177
 
      continue;
178
 
    }
179
 
 
180
 
    format_list = XvListImageFormats(display, adaptor_info[i].base_id,
181
 
                                     &num_formats);
182
 
 
183
 
    for (j = 0; j < (int)(sizeof(fourcc_list) / sizeof(*fourcc_list)); j++) {
184
 
      if (format->id && fourcc_list[j].id != format->id) {
185
 
        continue;
186
 
      }
187
 
      for (k = 0; k < num_formats; k++) {
188
 
        if (format_list[k].id != fourcc_list[j].id) {
189
 
          continue;
190
 
        }
191
 
 
192
 
        for (port_id = adaptor_info[i].base_id;
193
 
             port_id < adaptor_info[i].base_id + adaptor_info[i].num_ports;
194
 
             port_id++)
195
 
          {
196
 
            if (XvGrabPort(display, port_id, CurrentTime) != Success) {
197
 
              continue;
198
 
            }
199
 
            *port = port_id;
200
 
            *format = fourcc_list[j];
201
 
            XFree(format_list);
202
 
            XvFreeAdaptorInfo(adaptor_info);
203
 
            return 1;
204
 
          }
205
 
      }
206
 
    }
207
 
 
208
 
    XFree(format_list);
209
 
  }
210
 
 
211
 
  XvFreeAdaptorInfo(adaptor_info);
212
 
  printf("No suitable Xv YUV adaptor/port available.\n");
213
 
  return 0;
214
 
}
215
 
 
216
 
 
217
 
XvImage* create_yuv_image(Display* display, XvPortID port, fourcc_t format,
218
 
                          int width, int height, XShmSegmentInfo* shminfo)
219
 
{
220
 
  XvImage* image;
221
 
 
222
 
  if (shminfo) {
223
 
    if (!(image = XvShmCreateImage(display, port, format.id, NULL,
224
 
                                   width, height, shminfo)))
225
 
    {
226
 
      printf("Unable to create shm XvImage\n");
227
 
      return NULL;
228
 
    }
229
 
      
230
 
    if ((shminfo->shmid = shmget(IPC_PRIVATE, image->data_size, IPC_CREAT | 0777)) == -1)
231
 
    {
232
 
      printf("Unable to allocate shared memory\n");
233
 
      XFree(image);
234
 
      return NULL;
235
 
    }
236
 
    if (!(shminfo->shmaddr = shmat(shminfo->shmid, 0, 0))) {
237
 
      printf("Unable to attach shared memory\n");
238
 
      XFree(image);
239
 
      shmctl(shminfo->shmid, IPC_RMID, 0);
240
 
      return NULL;
241
 
    }
242
 
    shminfo->readOnly = False;
243
 
 
244
 
    image->data = shminfo->shmaddr;
245
 
 
246
 
    if (!XShmAttach(display, shminfo)) {
247
 
      printf("XShmAttach failed\n");
248
 
      XFree(image);
249
 
      shmctl(shminfo->shmid, IPC_RMID, 0);
250
 
      shmdt(shminfo->shmaddr);
251
 
      return NULL;
252
 
    }
253
 
 
254
 
    /* Send image to X server. This instruction is required, since having
255
 
     * built a Shm XImage and not using it causes an error on XCloseDisplay. */
256
 
    XSync(display, False);
257
 
 
258
 
    /* Mark the segment to be automatically removed when the last
259
 
       attachment is broken (i.e. on shmdt or process exit). */
260
 
    shmctl(shminfo->shmid, IPC_RMID, 0);
261
 
  }
262
 
  else {
263
 
    if (!(image = XvCreateImage(display, port, format.id, NULL,
264
 
                                width, height)))
265
 
    {
266
 
      printf("Unable to create XvImage\n");
267
 
      return NULL;
268
 
    }
269
 
    image->data = malloc(image->data_size);
270
 
  }
271
 
 
272
 
  return image;
273
 
}
274
 
 
275
 
 
276
 
void destroy_yuv_image(Display* display, XvImage* image,
277
 
                       XShmSegmentInfo* shminfo)
278
 
{
279
 
  if (shminfo) {
280
 
    XShmDetach(display, shminfo);
281
 
    XFree(image);
282
 
    shmdt(shminfo->shmaddr);
283
 
  }
284
 
  else {
285
 
    XFree(image);
286
 
  }
287
 
}
288
 
 
289
 
 
290
 
void display_yuv_image(Display* display, XvPortID port, Drawable d, GC gc,
291
 
                       XvImage* image,
292
 
                       XShmSegmentInfo* shminfo,
293
 
                       int src_x, int src_y,
294
 
                       unsigned int src_w, unsigned int src_h,
295
 
                       unsigned int dest_w, unsigned int dest_h,
296
 
                       double aspect_ratio)
297
 
{
298
 
  int dest_x = 0, dest_y = 0;
299
 
 
300
 
  /* Keep aspect ratio of src image. */
301
 
  if (dest_w*src_h < src_w*aspect_ratio*dest_h) {
302
 
    dest_y = dest_h;
303
 
    dest_h = dest_w*src_h/(src_w*aspect_ratio);
304
 
    dest_y = (dest_y - dest_h)/2;
305
 
  }
306
 
  else {
307
 
    dest_x = dest_w;
308
 
    dest_w = dest_h*src_w*aspect_ratio/src_h;
309
 
    dest_x = (dest_x - dest_w)/2;
310
 
  }
311
 
 
312
 
  if (shminfo) {
313
 
    XvShmPutImage(display, port, d, gc, image,
314
 
                  src_x, src_y, src_w, src_h,
315
 
                  dest_x, dest_y, dest_w, dest_h, False);
316
 
  }
317
 
  else {
318
 
    XvPutImage(display, port, d, gc, image,
319
 
               src_x, src_y, src_w, src_h,
320
 
               dest_x, dest_y, dest_w, dest_h);
321
 
  }
 
123
    int i, j, k;
 
124
 
 
125
    /* XvQueryExtension */
 
126
    unsigned int version, release, request_base, event_base, error_base;
 
127
 
 
128
    /* XvQueryAdaptors */
 
129
    unsigned int num_adaptors;
 
130
    XvAdaptorInfo* adaptor_info = NULL;
 
131
    XvPortID port_id;
 
132
 
 
133
    /* XvListImageFormats */
 
134
    int num_formats;
 
135
    XvImageFormatValues* format_list = NULL;
 
136
 
 
137
    switch (XvQueryExtension(display, &version, &release, &request_base, &event_base, &error_base)) {
 
138
        case Success:
 
139
            break;
 
140
        case XvBadExtension:
 
141
            printf("XvQueryExtension returned XvBadExtension.\n");
 
142
            return 0;
 
143
        case XvBadAlloc:
 
144
            printf("XvQueryExtension returned XvBadAlloc.\n");
 
145
            return 0;
 
146
        default:
 
147
            printf("XvQueryExtension returned unknown error.\n");
 
148
            return 0;
 
149
    }
 
150
 
 
151
    switch (XvQueryAdaptors(display, DefaultRootWindow(display), &num_adaptors, &adaptor_info)) {
 
152
        case Success:
 
153
            break;
 
154
        case XvBadExtension:
 
155
            printf("XvQueryAdaptors returned XvBadExtension.\n");
 
156
            return 0;
 
157
        case XvBadAlloc:
 
158
            printf("XvQueryAdaptors returned XvBadAlloc.\n");
 
159
            return 0;
 
160
        default:
 
161
            printf("XvQueryAdaptors returned unknown error.\n");
 
162
            return 0;
 
163
    }
 
164
 
 
165
    /* Find YUV capable adaptor. */
 
166
    for (i = 0; i < (int)num_adaptors; i++) {
 
167
        if (!(adaptor_info[i].type & XvInputMask && adaptor_info[i].type & XvImageMask)) {
 
168
            continue;
 
169
        }
 
170
 
 
171
        format_list = XvListImageFormats(display, adaptor_info[i].base_id, &num_formats);
 
172
 
 
173
        for (j = 0; j < (int)(sizeof(fourcc_list) / sizeof(*fourcc_list)); j++) {
 
174
            if (format->id && fourcc_list[j].id != format->id) {
 
175
                continue;
 
176
            }
 
177
            for (k = 0; k < num_formats; k++) {
 
178
                if (format_list[k].id != fourcc_list[j].id) {
 
179
                    continue;
 
180
                }
 
181
 
 
182
                for (port_id = adaptor_info[i].base_id; port_id < adaptor_info[i].base_id + adaptor_info[i].num_ports; port_id++) {
 
183
                    if (XvGrabPort(display, port_id, CurrentTime) != Success) {
 
184
                        continue;
 
185
                    }
 
186
                    *port = port_id;
 
187
                    *format = fourcc_list[j];
 
188
                    XFree(format_list);
 
189
                    XvFreeAdaptorInfo(adaptor_info);
 
190
                    return 1;
 
191
                }
 
192
            }
 
193
        }
 
194
 
 
195
        XFree(format_list);
 
196
    }
 
197
 
 
198
    XvFreeAdaptorInfo(adaptor_info);
 
199
    printf("No suitable Xv YUV adaptor/port available.\n");
 
200
    return 0;
 
201
}
 
202
 
 
203
XvImage* create_yuv_image(Display* display, XvPortID port, fourcc_t format, int width, int height, XShmSegmentInfo* shminfo)
 
204
{
 
205
    XvImage* image;
 
206
 
 
207
    if (shminfo) {
 
208
        if (!(image = XvShmCreateImage(display, port, format.id, NULL, width, height, shminfo))) {
 
209
            printf("Unable to create shm XvImage\n");
 
210
            return NULL;
 
211
        }
 
212
 
 
213
        if ((shminfo->shmid = shmget(IPC_PRIVATE, image->data_size, IPC_CREAT | 0777)) == -1) {
 
214
            printf("Unable to allocate shared memory\n");
 
215
            XFree(image);
 
216
            return NULL;
 
217
        }
 
218
        if (!(shminfo->shmaddr = shmat(shminfo->shmid, 0, 0))) {
 
219
            printf("Unable to attach shared memory\n");
 
220
            XFree(image);
 
221
            shmctl(shminfo->shmid, IPC_RMID, 0);
 
222
            return NULL;
 
223
        }
 
224
        shminfo->readOnly = False;
 
225
 
 
226
        image->data = shminfo->shmaddr;
 
227
 
 
228
        if (!XShmAttach(display, shminfo)) {
 
229
            printf("XShmAttach failed\n");
 
230
            XFree(image);
 
231
            shmctl(shminfo->shmid, IPC_RMID, 0);
 
232
            shmdt(shminfo->shmaddr);
 
233
            return NULL;
 
234
        }
 
235
 
 
236
        /* Send image to X server. This instruction is required, since having
 
237
         * built a Shm XImage and not using it causes an error on XCloseDisplay. */
 
238
        XSync(display, False);
 
239
 
 
240
        /* Mark the segment to be automatically removed when the last
 
241
           attachment is broken (i.e. on shmdt or process exit). */
 
242
        shmctl(shminfo->shmid, IPC_RMID, 0);
 
243
    } else {
 
244
        if (!(image = XvCreateImage(display, port, format.id, NULL, width, height))) {
 
245
            printf("Unable to create XvImage\n");
 
246
            return NULL;
 
247
        }
 
248
        image->data = malloc(image->data_size);
 
249
    }
 
250
 
 
251
    return image;
 
252
}
 
253
 
 
254
void destroy_yuv_image(Display* display, XvImage* image, XShmSegmentInfo* shminfo)
 
255
{
 
256
    if (shminfo) {
 
257
        XShmDetach(display, shminfo);
 
258
        XFree(image);
 
259
        shmdt(shminfo->shmaddr);
 
260
    } else {
 
261
        XFree(image);
 
262
    }
 
263
}
 
264
 
 
265
void display_yuv_image(Display* display, XvPortID port, Drawable d, GC gc, XvImage* image, XShmSegmentInfo* shminfo,
 
266
                       int src_x, int src_y, unsigned int src_w, unsigned int src_h, unsigned int dest_w, unsigned int dest_h,
 
267
                       double aspect_ratio)
 
268
{
 
269
    int dest_x = 0, dest_y = 0;
 
270
 
 
271
    /* Keep aspect ratio of src image. */
 
272
    if (dest_w * src_h < src_w * aspect_ratio * dest_h) {
 
273
        dest_y = dest_h;
 
274
        dest_h = dest_w * src_h / (src_w * aspect_ratio);
 
275
        dest_y = (dest_y - dest_h) / 2;
 
276
    } else {
 
277
        dest_x = dest_w;
 
278
        dest_w = dest_h * src_w * aspect_ratio / src_h;
 
279
        dest_x = (dest_x - dest_w) / 2;
 
280
    }
 
281
 
 
282
    if (shminfo) {
 
283
        XvShmPutImage(display, port, d, gc, image, src_x, src_y, src_w, src_h, dest_x, dest_y, dest_w, dest_h, False);
 
284
    } else {
 
285
        XvPutImage(display, port, d, gc, image, src_x, src_y, src_w, src_h, dest_x, dest_y, dest_w, dest_h);
 
286
    }
322
287
}
323
288
 
324
289
#endif /* HAVE_XVIDEO */