comparison libvo/vo_zr.c @ 29263:0f1b5b68af32

whitespace cosmetics: Remove all trailing whitespace.
author diego
date Wed, 13 May 2009 02:58:57 +0000
parents d97a607821f1
children 358ac046eccc
comparison
equal deleted inserted replaced
29262:7d545a6b8aff 29263:0f1b5b68af32
42 #include "m_option.h" 42 #include "m_option.h"
43 #include "fastmemcpy.h" 43 #include "fastmemcpy.h"
44 44
45 #include "jpeg_enc.h" 45 #include "jpeg_enc.h"
46 46
47 static const vo_info_t info = 47 static const vo_info_t info =
48 { 48 {
49 "Zoran ZR360[56]7/ZR36060 Driver (DC10(+)/buz/lml33/MatroxRR)", 49 "Zoran ZR360[56]7/ZR36060 Driver (DC10(+)/buz/lml33/MatroxRR)",
50 "zr", 50 "zr",
51 "Rik Snel <rsnel@cube.dyndns.org>", 51 "Rik Snel <rsnel@cube.dyndns.org>",
52 "" 52 ""
71 71
72 typedef struct { 72 typedef struct {
73 /* commandline args given for this device (and defaults) */ 73 /* commandline args given for this device (and defaults) */
74 int vdec, hdec; /* requested decimation 1,2,4 */ 74 int vdec, hdec; /* requested decimation 1,2,4 */
75 int fd; /* force decimation */ 75 int fd; /* force decimation */
76 int xdoff, ydoff; /* offset from upperleft of screen 76 int xdoff, ydoff; /* offset from upperleft of screen
77 * default is 'centered' */ 77 * default is 'centered' */
78 int quality; /* jpeg quality 1=best, 20=bad */ 78 int quality; /* jpeg quality 1=best, 20=bad */
79 geo_t g; /* view window (zrcrop) */ 79 geo_t g; /* view window (zrcrop) */
80 char *device; /* /dev/video1 */ 80 char *device; /* /dev/video1 */
81 int bw; /* if bw == 1, display in black&white */ 81 int bw; /* if bw == 1, display in black&white */
103 int fields, stretchy; /* must the *image be interlaced 103 int fields, stretchy; /* must the *image be interlaced
104 or stretched to fit on the screen? */ 104 or stretched to fit on the screen? */
105 } zr_info_t; 105 } zr_info_t;
106 106
107 static zr_info_t zr_info[ZR_MAX_DEVICES] = { 107 static zr_info_t zr_info[ZR_MAX_DEVICES] = {
108 {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0, 108 {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0,
109 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 109 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
110 {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0, 110 {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0,
111 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 111 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
112 {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0, 112 {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0,
113 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 113 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
114 {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0, 114 {1, 1, 1, -1, -1, 2, {0, 0, 0, 0, 0}, NULL, 0, VIDEO_MODE_AUTO, NULL, 0, 0, 0, 0, 0,
115 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; 115 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
116 116
117 117
118 118
119 119
135 "/dev/v4l0", 135 "/dev/v4l0",
136 "/dev/v4l", 136 "/dev/v4l",
137 NULL 137 NULL
138 }; 138 };
139 int i = 0; 139 int i = 0;
140 140
141 do 141 do
142 { 142 {
143 if ((stat(devs[i], &vstat) == 0) && S_ISCHR(vstat.st_mode)) 143 if ((stat(devs[i], &vstat) == 0) && S_ISCHR(vstat.st_mode))
144 { 144 {
145 dev = devs[i]; 145 dev = devs[i];
152 { 152 {
153 mp_msg(MSGT_VO, MSGL_ERR, "zr: unable to find video device\n"); 153 mp_msg(MSGT_VO, MSGL_ERR, "zr: unable to find video device\n");
154 return 1; 154 return 1;
155 } 155 }
156 } 156 }
157 157
158 zr->vdes = open(dev, O_RDWR); 158 zr->vdes = open(dev, O_RDWR);
159 159
160 if (zr->vdes < 0) { 160 if (zr->vdes < 0) {
161 mp_msg(MSGT_VO, MSGL_ERR, "zr: error opening %s: %s\n", 161 mp_msg(MSGT_VO, MSGL_ERR, "zr: error opening %s: %s\n",
162 dev, strerror(errno)); 162 dev, strerror(errno));
163 return 1; 163 return 1;
164 } 164 }
165 165
166 /* before we can ask for the maximum resolution, we must set 166 /* before we can ask for the maximum resolution, we must set
167 * the correct tv norm */ 167 * the correct tv norm */
168 168
169 if (ioctl(zr->vdes, MJPIOC_G_PARAMS, &zr->p) < 0) { 169 if (ioctl(zr->vdes, MJPIOC_G_PARAMS, &zr->p) < 0) {
170 mp_msg(MSGT_VO, MSGL_ERR, "zr: device at %s is probably not a DC10(+)/buz/lml33\n", dev); 170 mp_msg(MSGT_VO, MSGL_ERR, "zr: device at %s is probably not a DC10(+)/buz/lml33\n", dev);
171 return 1; 171 return 1;
172 } 172 }
173 173
174 if (zr->p.norm != zr->norm && zr->norm != VIDEO_MODE_AUTO) { 174 if (zr->p.norm != zr->norm && zr->norm != VIDEO_MODE_AUTO) {
175 /* attempt to set requested norm */ 175 /* attempt to set requested norm */
176 zr->p.norm = zr->norm; 176 zr->p.norm = zr->norm;
177 if (ioctl(zr->vdes, MJPIOC_S_PARAMS, &zr->p) < 0) { 177 if (ioctl(zr->vdes, MJPIOC_S_PARAMS, &zr->p) < 0) {
178 mp_msg(MSGT_VO, MSGL_ERR, 178 mp_msg(MSGT_VO, MSGL_ERR,
184 mp_msg(MSGT_VO, MSGL_ERR, 184 mp_msg(MSGT_VO, MSGL_ERR,
185 "zr: unable to change video norm, use another program to change it (XawTV)\n"); 185 "zr: unable to change video norm, use another program to change it (XawTV)\n");
186 return 1; 186 return 1;
187 } 187 }
188 } 188 }
189 189
190 if (ioctl(zr->vdes, VIDIOCGCAP, &zr->vc) < 0) { 190 if (ioctl(zr->vdes, VIDIOCGCAP, &zr->vc) < 0) {
191 mp_msg(MSGT_VO, MSGL_ERR, "zr: error getting video capabilities from %s\n", dev); 191 mp_msg(MSGT_VO, MSGL_ERR, "zr: error getting video capabilities from %s\n", dev);
192 return 1; 192 return 1;
193 } 193 }
194 mp_msg(MSGT_VO, MSGL_V, "zr: MJPEG card reports maxwidth=%d, maxheight=%d\n", zr->vc.maxwidth, zr->vc.maxheight); 194 mp_msg(MSGT_VO, MSGL_V, "zr: MJPEG card reports maxwidth=%d, maxheight=%d\n", zr->vc.maxwidth, zr->vc.maxheight);
195 195
196 return 0; 196 return 0;
197 } 197 }
198 198
199 int init_zoran(zr_info_t *zr, int stretchx, int stretchy) { 199 int init_zoran(zr_info_t *zr, int stretchx, int stretchy) {
200 /* center the image, and stretch it as far as possible (try to keep 200 /* center the image, and stretch it as far as possible (try to keep
201 * aspect) and check if it fits */ 201 * aspect) and check if it fits */
202 if (zr->image_width > zr->vc.maxwidth) { 202 if (zr->image_width > zr->vc.maxwidth) {
203 mp_msg(MSGT_VO, MSGL_ERR, "zr: movie to be played is too wide, max width currently %d\n", zr->vc.maxwidth); 203 mp_msg(MSGT_VO, MSGL_ERR, "zr: movie to be played is too wide, max width currently %d\n", zr->vc.maxwidth);
208 mp_msg(MSGT_VO, MSGL_ERR, "zr: movie to be played is too high, max height currently %d\n", zr->vc.maxheight); 208 mp_msg(MSGT_VO, MSGL_ERR, "zr: movie to be played is too high, max height currently %d\n", zr->vc.maxheight);
209 return 1; 209 return 1;
210 } 210 }
211 211
212 zr->p.decimation = 0; 212 zr->p.decimation = 0;
213 zr->p.HorDcm = stretchx; 213 zr->p.HorDcm = stretchx;
214 zr->p.VerDcm = stretchy; 214 zr->p.VerDcm = stretchy;
215 zr->p.TmpDcm = 1; 215 zr->p.TmpDcm = 1;
216 zr->p.field_per_buff = zr->fields; 216 zr->p.field_per_buff = zr->fields;
217 if (zr->xdoff == -1) { 217 if (zr->xdoff == -1) {
218 zr->p.img_x = (zr->vc.maxwidth - 218 zr->p.img_x = (zr->vc.maxwidth -
219 zr->p.HorDcm*(int)zr->image_width/zr->hdec)/2; 219 zr->p.HorDcm*(int)zr->image_width/zr->hdec)/2;
220 } else { 220 } else {
221 zr->p.img_x = zr->xdoff; 221 zr->p.img_x = zr->xdoff;
222 } 222 }
223 if (zr->ydoff == -1) { 223 if (zr->ydoff == -1) {
242 mp_msg(MSGT_VO, MSGL_ERR, "zr: error requesting %ld buffers of size %ld\n", zr->zrq.count, zr->zrq.size); 242 mp_msg(MSGT_VO, MSGL_ERR, "zr: error requesting %ld buffers of size %ld\n", zr->zrq.count, zr->zrq.size);
243 return 1; 243 return 1;
244 } 244 }
245 245
246 /* the buffer count allocated may be different to the request */ 246 /* the buffer count allocated may be different to the request */
247 zr->buf = (unsigned char*)mmap(0, zr->zrq.count*zr->zrq.size, 247 zr->buf = (unsigned char*)mmap(0, zr->zrq.count*zr->zrq.size,
248 PROT_READ|PROT_WRITE, MAP_SHARED, zr->vdes, 0); 248 PROT_READ|PROT_WRITE, MAP_SHARED, zr->vdes, 0);
249 249
250 if (zr->buf == MAP_FAILED) { 250 if (zr->buf == MAP_FAILED) {
251 mp_msg(MSGT_VO, MSGL_ERR, "zr: error requesting %ld buffers of size %ld\n", zr->zrq.count, zr->zrq.size); 251 mp_msg(MSGT_VO, MSGL_ERR, "zr: error requesting %ld buffers of size %ld\n", zr->zrq.count, zr->zrq.size);
252 return 1; 252 return 1;
253 } 253 }
254 254
255 mp_msg(MSGT_VO, MSGL_V, "zr: got %ld buffers of size %ld (wanted %d buffers of size %d)\n", zr->zrq.count, zr->zrq.size, MJPEG_NBUFFERS, MJPEG_SIZE); 255 mp_msg(MSGT_VO, MSGL_V, "zr: got %ld buffers of size %ld (wanted %d buffers of size %d)\n", zr->zrq.count, zr->zrq.size, MJPEG_NBUFFERS, MJPEG_SIZE);
256 if (zr->zrq.count < MJPEG_NBUFFERS) { 256 if (zr->zrq.count < MJPEG_NBUFFERS) {
257 mp_msg(MSGT_VO, MSGL_V, "zr: got not enough buffers\n"); 257 mp_msg(MSGT_VO, MSGL_V, "zr: got not enough buffers\n");
258 return 1; 258 return 1;
259 } 259 }
268 if (zr->image) { 268 if (zr->image) {
269 free(zr->image); 269 free(zr->image);
270 zr->image=NULL; 270 zr->image=NULL;
271 } 271 }
272 while (zr->queue > zr->synco + 1) { 272 while (zr->queue > zr->synco + 1) {
273 if (ioctl(zr->vdes, MJPIOC_SYNC, &zr->zs) < 0) 273 if (ioctl(zr->vdes, MJPIOC_SYNC, &zr->zs) < 0)
274 mp_msg(MSGT_VO, MSGL_ERR, "zr: error waiting for buffers to become free\n"); 274 mp_msg(MSGT_VO, MSGL_ERR, "zr: error waiting for buffers to become free\n");
275 zr->synco++; 275 zr->synco++;
276 } 276 }
277 /* stop streaming */ 277 /* stop streaming */
278 zr->frame = -1; 278 zr->frame = -1;
279 if (ioctl(zr->vdes, MJPIOC_QBUF_PLAY, &zr->frame) < 0) 279 if (ioctl(zr->vdes, MJPIOC_QBUF_PLAY, &zr->frame) < 0)
280 mp_msg(MSGT_VO, MSGL_ERR, "zr: error stopping playback of last frame\n"); 280 mp_msg(MSGT_VO, MSGL_ERR, "zr: error stopping playback of last frame\n");
281 if (munmap(zr->buf,zr->zrq.count*zr->zrq.size)) 281 if (munmap(zr->buf,zr->zrq.count*zr->zrq.size))
282 mp_msg(MSGT_VO, MSGL_ERR, "zr: error unmapping buffer\n"); 282 mp_msg(MSGT_VO, MSGL_ERR, "zr: error unmapping buffer\n");
283 close(zr->vdes); 283 close(zr->vdes);
284 } 284 }
288 if (g->width%2 != 0 || g->height%2 != 0 || 288 if (g->width%2 != 0 || g->height%2 != 0 ||
289 g->xoff%2 != 0 || g->yoff%2 != 0) { 289 g->xoff%2 != 0 || g->yoff%2 != 0) {
290 mp_msg(MSGT_VO, MSGL_ERR, "zr: arguments in -zrcrop must be multiples of 2\n"); 290 mp_msg(MSGT_VO, MSGL_ERR, "zr: arguments in -zrcrop must be multiples of 2\n");
291 return 1; 291 return 1;
292 } 292 }
293 if (g->width <= 0 || g->height <= 0 || 293 if (g->width <= 0 || g->height <= 0 ||
294 g->xoff < 0 || g->yoff < 0) { 294 g->xoff < 0 || g->yoff < 0) {
295 mp_msg(MSGT_VO, MSGL_ERR, "zr: width and height must be positive and offset nonnegative\n"); 295 mp_msg(MSGT_VO, MSGL_ERR, "zr: width and height must be positive and offset nonnegative\n");
296 return 1; 296 return 1;
297 } 297 }
298 if (g->width + g->xoff > width) { 298 if (g->width + g->xoff > width) {
312 } 312 }
313 return 0; 313 return 0;
314 } 314 }
315 315
316 316
317 static int config(uint32_t width, uint32_t height, uint32_t d_width, 317 static int config(uint32_t width, uint32_t height, uint32_t d_width,
318 uint32_t d_height, uint32_t flags, char *title, uint32_t format) 318 uint32_t d_height, uint32_t flags, char *title, uint32_t format)
319 { 319 {
320 int i, tmp, stretchx, stretchy; 320 int i, tmp, stretchx, stretchy;
321 framenum = 0; 321 framenum = 0;
322 if (format != IMGFMT_YV12 && format != IMGFMT_YUY2) { 322 if (format != IMGFMT_YV12 && format != IMGFMT_YUY2) {
334 * it differs for DC10+ and buz for example */ 334 * it differs for DC10+ and buz for example */
335 zoran_getcap(zr); /*must be called before init_zoran */ 335 zoran_getcap(zr); /*must be called before init_zoran */
336 /* make the scaling decision 336 /* make the scaling decision
337 * we are capable of stretching the image in the horizontal 337 * we are capable of stretching the image in the horizontal
338 * direction by factors 1, 2 and 4 338 * direction by factors 1, 2 and 4
339 * we can stretch the image in the vertical direction by a 339 * we can stretch the image in the vertical direction by a
340 * factor of 1 and 2 AND we must decide about interlacing */ 340 * factor of 1 and 2 AND we must decide about interlacing */
341 if (g->width > zr->vc.maxwidth/2 || 341 if (g->width > zr->vc.maxwidth/2 ||
342 g->height > zr->vc.maxheight/2) { 342 g->height > zr->vc.maxheight/2) {
343 stretchx = 1; 343 stretchx = 1;
344 stretchy = 1; 344 stretchy = 1;
345 zr->fields = 2; 345 zr->fields = 2;
346 if (zr->vdec == 2) { 346 if (zr->vdec == 2) {
348 } else if (zr->vdec == 4) { 348 } else if (zr->vdec == 4) {
349 zr->fields = 1; 349 zr->fields = 1;
350 stretchy = 2; 350 stretchy = 2;
351 } 351 }
352 stretchx = zr->hdec; 352 stretchx = zr->hdec;
353 } else if (g->width > zr->vc.maxwidth/4 || 353 } else if (g->width > zr->vc.maxwidth/4 ||
354 g->height > zr->vc.maxheight/4) { 354 g->height > zr->vc.maxheight/4) {
355 stretchx = 2; 355 stretchx = 2;
356 stretchy = 1; 356 stretchy = 1;
357 zr->fields = 1; 357 zr->fields = 1;
358 if (zr->vdec == 2) { 358 if (zr->vdec == 2) {
396 tmp = 16*((g->width - 1)/(zr->hdec*16) + 1); 396 tmp = 16*((g->width - 1)/(zr->hdec*16) + 1);
397 if (stretchx*tmp > zr->vc.maxwidth) { 397 if (stretchx*tmp > zr->vc.maxwidth) {
398 g->xoff += 2*((g->width - zr->hdec*(tmp-16))/4); 398 g->xoff += 2*((g->width - zr->hdec*(tmp-16))/4);
399 /* g->off must be a multiple of 2 */ 399 /* g->off must be a multiple of 2 */
400 g->width = zr->hdec*(tmp - 16); 400 g->width = zr->hdec*(tmp - 16);
401 g->set = 0; /* we abuse this field to 401 g->set = 0; /* we abuse this field to
402 report that g has changed*/ 402 report that g has changed*/
403 } 403 }
404 tmp = 8*zr->fields*((g->height - 1)/(zr->vdec*zr->fields*8)+1); 404 tmp = 8*zr->fields*((g->height - 1)/(zr->vdec*zr->fields*8)+1);
405 if (stretchy*tmp > zr->vc.maxheight) { 405 if (stretchy*tmp > zr->vc.maxheight) {
406 g->yoff += 2*((g->height - zr->vdec* 406 g->yoff += 2*((g->height - zr->vdec*
407 (tmp - 8*zr->fields))/4); 407 (tmp - 8*zr->fields))/4);
408 g->height = zr->vdec*(tmp - 8*zr->fields); 408 g->height = zr->vdec*(tmp - 8*zr->fields);
409 g->set = 0; 409 g->set = 0;
410 } 410 }
411 if (!g->set) 411 if (!g->set)
412 mp_msg(MSGT_VO, MSGL_V, "zr: auto(re)cropping %dx%d+%d+%d to make the image fit on the screen\n", g->width, g->height, g->xoff, g->yoff); 412 mp_msg(MSGT_VO, MSGL_V, "zr: auto(re)cropping %dx%d+%d+%d to make the image fit on the screen\n", g->width, g->height, g->xoff, g->yoff);
413 413
414 /* the height must be a multiple of fields*8 and the width 414 /* the height must be a multiple of fields*8 and the width
415 * must be a multiple of 16 */ 415 * must be a multiple of 16 */
416 /* add some black borders to make it so, and center the image*/ 416 /* add some black borders to make it so, and center the image*/
424 zr->off_y += (zr->image_width - g->width)/2; 424 zr->off_y += (zr->image_width - g->width)/2;
425 if (zr->off_y%2 != 0) zr->off_y--; 425 if (zr->off_y%2 != 0) zr->off_y--;
426 zr->off_c += (zr->image_width - g->width)/4; 426 zr->off_c += (zr->image_width - g->width)/4;
427 zr->size = zr->image_width*zr->image_height; 427 zr->size = zr->image_width*zr->image_height;
428 mp_msg(MSGT_VO, MSGL_V, "zr: input: %dx%d, cropped: %dx%d, output: %dx%d, off_y=%d, off_c=%d\n", width, height, g->width, g->height, zr->image_width, zr->image_height, zr->off_y, zr->off_c); 428 mp_msg(MSGT_VO, MSGL_V, "zr: input: %dx%d, cropped: %dx%d, output: %dx%d, off_y=%d, off_c=%d\n", width, height, g->width, g->height, zr->image_width, zr->image_height, zr->off_y, zr->off_c);
429 429
430 zr->image = malloc(2*zr->size); /* this buffer allows for YUV422 data, 430 zr->image = malloc(2*zr->size); /* this buffer allows for YUV422 data,
431 * so it is a bit too big for YUV420 */ 431 * so it is a bit too big for YUV420 */
432 if (!zr->image) { 432 if (!zr->image) {
433 mp_msg(MSGT_VO, MSGL_ERR, "zr: Memory exhausted\n"); 433 mp_msg(MSGT_VO, MSGL_ERR, "zr: Memory exhausted\n");
434 return 1; 434 return 1;
440 memset(zr->image + zr->size, 0x80, zr->size/4); 440 memset(zr->image + zr->size, 0x80, zr->size/4);
441 memset(zr->image + 3*zr->size/2, 0x80, zr->size/4); 441 memset(zr->image + 3*zr->size/2, 0x80, zr->size/4);
442 zr->y_data = zr->image; 442 zr->y_data = zr->image;
443 zr->u_data = zr->image + zr->size; 443 zr->u_data = zr->image + zr->size;
444 zr->v_data = zr->image + 3*zr->size/2; 444 zr->v_data = zr->image + 3*zr->size/2;
445 445
446 zr->y_stride = zr->image_width; 446 zr->y_stride = zr->image_width;
447 zr->u_stride = zr->image_width/2; 447 zr->u_stride = zr->image_width/2;
448 zr->v_stride = zr->image_width/2; 448 zr->v_stride = zr->image_width/2;
449 449
450 zr->j = jpeg_enc_init(zr->image_width/zr->hdec, 450 zr->j = jpeg_enc_init(zr->image_width/zr->hdec,
451 zr->image_height/zr->fields, 451 zr->image_height/zr->fields,
452 zr->hdec, zr->y_stride*zr->fields, 452 zr->hdec, zr->y_stride*zr->fields,
453 zr->hdec, zr->u_stride*zr->fields, 453 zr->hdec, zr->u_stride*zr->fields,
454 zr->hdec, zr->v_stride*zr->fields, 454 zr->hdec, zr->v_stride*zr->fields,
455 1, zr->quality, zr->bw); 455 1, zr->quality, zr->bw);
456 break; 456 break;
457 case IMGFMT_YUY2: 457 case IMGFMT_YUY2:
458 for (tmp = 0; tmp < 2*zr->size; tmp+=4) { 458 for (tmp = 0; tmp < 2*zr->size; tmp+=4) {
459 zr->image[tmp] = 0; 459 zr->image[tmp] = 0;
460 zr->image[tmp+1] = 0x80; 460 zr->image[tmp+1] = 0x80;
461 zr->image[tmp+2] = 0; 461 zr->image[tmp+2] = 0;
462 zr->image[tmp+3] = 0x80; 462 zr->image[tmp+3] = 0x80;
463 } 463 }
464 464
465 zr->y_data = zr->image; 465 zr->y_data = zr->image;
466 zr->u_data = zr->image + 1; 466 zr->u_data = zr->image + 1;
467 zr->v_data = zr->image + 3; 467 zr->v_data = zr->image + 3;
468 468
469 zr->y_stride = 2*zr->image_width; 469 zr->y_stride = 2*zr->image_width;
470 zr->u_stride = 2*zr->image_width; 470 zr->u_stride = 2*zr->image_width;
471 zr->v_stride = 2*zr->image_width; 471 zr->v_stride = 2*zr->image_width;
472 472
473 zr->j = jpeg_enc_init(zr->image_width/zr->hdec, 473 zr->j = jpeg_enc_init(zr->image_width/zr->hdec,
474 zr->image_height/zr->fields, 474 zr->image_height/zr->fields,
475 zr->hdec*2, 475 zr->hdec*2,
476 zr->y_stride*zr->fields, 476 zr->y_stride*zr->fields,
477 zr->hdec*4, 477 zr->hdec*4,
478 zr->u_stride*zr->fields, 478 zr->u_stride*zr->fields,
479 zr->hdec*4, 479 zr->hdec*4,
480 zr->v_stride*zr->fields, 480 zr->v_stride*zr->fields,
481 0, zr->quality, zr->bw); 481 0, zr->quality, zr->bw);
482 break; 482 break;
483 default: 483 default:
484 mp_msg(MSGT_VO, MSGL_FATAL, "zr: internal inconsistency in vo_zr\n"); 484 mp_msg(MSGT_VO, MSGL_FATAL, "zr: internal inconsistency in vo_zr\n");
485 } 485 }
486 486
487 487
488 if (zr->j == NULL) { 488 if (zr->j == NULL) {
489 mp_msg(MSGT_VO, MSGL_ERR, "zr: error initializing the jpeg encoder\n"); 489 mp_msg(MSGT_VO, MSGL_ERR, "zr: error initializing the jpeg encoder\n");
490 return 1; 490 return 1;
491 } 491 }
492 492
493 if (init_zoran(zr, stretchx, stretchy)) { 493 if (init_zoran(zr, stretchx, stretchy)) {
494 return 1; 494 return 1;
495 } 495 }
496 496
497 } 497 }
498 return 0; 498 return 0;
499 } 499 }
500 500
501 static void draw_osd(void) { 501 static void draw_osd(void) {
506 //FILE *fp; 506 //FILE *fp;
507 //char filename[100]; 507 //char filename[100];
508 /* do we have a free buffer? */ 508 /* do we have a free buffer? */
509 for (j = 0; j < zr_count; j++) { 509 for (j = 0; j < zr_count; j++) {
510 zr_info_t *zr = &zr_info[j]; 510 zr_info_t *zr = &zr_info[j];
511 /* using MJPEG_NBUFFERS here, using the real number of 511 /* using MJPEG_NBUFFERS here, using the real number of
512 * buffers may give sync issues (real number of buffers 512 * buffers may give sync issues (real number of buffers
513 * is always sufficient) */ 513 * is always sufficient) */
514 if (zr->queue-zr->synco < MJPEG_NBUFFERS) { 514 if (zr->queue-zr->synco < MJPEG_NBUFFERS) {
515 zr->frame = zr->queue; 515 zr->frame = zr->queue;
516 } else { 516 } else {
517 if (ioctl(zr->vdes, MJPIOC_SYNC, &zr->zs) < 0) 517 if (ioctl(zr->vdes, MJPIOC_SYNC, &zr->zs) < 0)
518 mp_msg(MSGT_VO, MSGL_ERR, "zr: error waiting for buffers to become free\n"); 518 mp_msg(MSGT_VO, MSGL_ERR, "zr: error waiting for buffers to become free\n");
519 zr->frame = zr->zs.frame; 519 zr->frame = zr->zs.frame;
520 zr->synco++; 520 zr->synco++;
521 } 521 }
522 k=0; 522 k=0;
523 for (i = 0; i < zr->fields; i++) 523 for (i = 0; i < zr->fields; i++)
524 k+=jpeg_enc_frame(zr->j, zr->y_data + i*zr->y_stride, 524 k+=jpeg_enc_frame(zr->j, zr->y_data + i*zr->y_stride,
525 zr->u_data + i*zr->u_stride, 525 zr->u_data + i*zr->u_stride,
526 zr->v_data + i*zr->v_stride, 526 zr->v_data + i*zr->v_stride,
527 zr->buf + zr->frame*zr->zrq.size+k); 527 zr->buf + zr->frame*zr->zrq.size+k);
528 if (k > zr->zrq.size) mp_msg(MSGT_VO, MSGL_WARN, "zr: jpeg image too large for maximum buffer size. Lower the jpeg encoding\nquality or the resolution of the movie.\n"); 528 if (k > zr->zrq.size) mp_msg(MSGT_VO, MSGL_WARN, "zr: jpeg image too large for maximum buffer size. Lower the jpeg encoding\nquality or the resolution of the movie.\n");
529 } 529 }
530 /* Warning: Only the first jpeg image contains huffman- and 530 /* Warning: Only the first jpeg image contains huffman- and
531 * quantisation tables, so don't expect files other than 531 * quantisation tables, so don't expect files other than
532 * test0001.jpg to be readable */ 532 * test0001.jpg to be readable */
533 /*sprintf(filename, "test%04d.jpg", framenum); 533 /*sprintf(filename, "test%04d.jpg", framenum);
534 fp = fopen(filename, "w"); 534 fp = fopen(filename, "w");
535 if (!fp) exit(1); 535 if (!fp) exit(1);
536 fwrite(buf+frame*zrq.size, 1, k, fp); 536 fwrite(buf+frame*zrq.size, 1, k, fp);
537 fclose(fp);*/ 537 fclose(fp);*/
538 /*fp = fopen("test1.jpg", "r"); 538 /*fp = fopen("test1.jpg", "r");
539 fread(buf+frame*zrq.size, 1, 2126, fp); 539 fread(buf+frame*zrq.size, 1, 2126, fp);
540 fclose(fp);*/ 540 fclose(fp);*/
541 541
542 for (j = 0; j < zr_count; j++) { 542 for (j = 0; j < zr_count; j++) {
543 zr_info_t *zr = &zr_info[j]; 543 zr_info_t *zr = &zr_info[j];
544 if (ioctl(zr->vdes, MJPIOC_QBUF_PLAY, &zr->frame) < 0) 544 if (ioctl(zr->vdes, MJPIOC_QBUF_PLAY, &zr->frame) < 0)
545 mp_msg(MSGT_VO, MSGL_ERR, "zr: error queueing buffer for playback\n"); 545 mp_msg(MSGT_VO, MSGL_ERR, "zr: error queueing buffer for playback\n");
546 zr->queue++; 546 zr->queue++;
547 } 547 }
548 548
549 framenum++; 549 framenum++;
567 } 567 }
568 return 0; 568 return 0;
569 } 569 }
570 570
571 static int query_format(uint32_t format) { 571 static int query_format(uint32_t format) {
572 if(format==IMGFMT_YV12 || format==IMGFMT_YUY2) 572 if(format==IMGFMT_YV12 || format==IMGFMT_YUY2)
573 return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW; 573 return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW;
574 return 0; 574 return 0;
575 } 575 }
576 576
577 static void uninit(void) { 577 static void uninit(void) {
640 640
641 } 641 }
642 if (!zr->bw) { 642 if (!zr->bw) {
643 // copy U+V: 643 // copy U+V:
644 uint8_t *dst1=zr->image + zr->size + zr->off_c+ (y/(zr->vdec*2))*zr->image_width/2+(x/2); 644 uint8_t *dst1=zr->image + zr->size + zr->off_c+ (y/(zr->vdec*2))*zr->image_width/2+(x/2);
645 uint8_t *dst2=zr->image + 3*zr->size/2 + zr->off_c + 645 uint8_t *dst2=zr->image + 3*zr->size/2 + zr->off_c +
646 (y/(zr->vdec*2))* 646 (y/(zr->vdec*2))*
647 zr->image_width/2+(x/2); 647 zr->image_width/2+(x/2);
648 for (i = 0; i< h/2; i++) { 648 for (i = 0; i< h/2; i++) {
649 if ((i+x/2)%zr->vdec == 0) { 649 if ((i+x/2)%zr->vdec == 0) {
650 fast_memcpy(dst1,src1,w/2); 650 fast_memcpy(dst1,src1,w/2);
700 mp_msg(MSGT_VO, MSGL_ERR, "zr: too many simultaneus display devices requested (max. is 4)\n"); 700 mp_msg(MSGT_VO, MSGL_ERR, "zr: too many simultaneus display devices requested (max. is 4)\n");
701 return ERR_OUT_OF_RANGE; 701 return ERR_OUT_OF_RANGE;
702 } 702 }
703 } 703 }
704 if (param == NULL) return ERR_MISSING_PARAM; 704 if (param == NULL) return ERR_MISSING_PARAM;
705 if (sscanf(param, "%dx%d+%d+%d", &g->width, &g->height, 705 if (sscanf(param, "%dx%d+%d+%d", &g->width, &g->height,
706 &g->xoff, &g->yoff) != 4) { 706 &g->xoff, &g->yoff) != 4) {
707 g->xoff = 0; g->yoff = 0; 707 g->xoff = 0; g->yoff = 0;
708 if (sscanf(param, "%dx%d", &g->width, &g->height) != 2) { 708 if (sscanf(param, "%dx%d", &g->width, &g->height) != 2) {
709 mp_msg(MSGT_VO, MSGL_ERR, "zr: argument to -zrcrop must be of the form 352x288+16+0\n"); 709 mp_msg(MSGT_VO, MSGL_ERR, "zr: argument to -zrcrop must be of the form 352x288+16+0\n");
710 return ERR_OUT_OF_RANGE; 710 return ERR_OUT_OF_RANGE;
770 " -zrquality jpeg compression quality [BEST] 1 - 20 [VERY BAD]\n" 770 " -zrquality jpeg compression quality [BEST] 1 - 20 [VERY BAD]\n"
771 " -zrdev playback device (example -zrdev /dev/video1)\n" 771 " -zrdev playback device (example -zrdev /dev/video1)\n"
772 " -zrnorm specify norm PAL/NTSC (default: leave at current setting)\n" 772 " -zrnorm specify norm PAL/NTSC (default: leave at current setting)\n"
773 "\n" 773 "\n"
774 "Cinerama support: additional occurances of -zrcrop activate cinerama mode,\n" 774 "Cinerama support: additional occurances of -zrcrop activate cinerama mode,\n"
775 "suppose you have a 704x272 movie, two DC10+ cards and two beamers (or tv's),\n" 775 "suppose you have a 704x272 movie, two DC10+ cards and two beamers (or tv's),\n"
776 "then you would issue the following command:\n\n" 776 "then you would issue the following command:\n\n"
777 "mplayer -vo zr -zrcrop 352x272+0+0 -zrdev /dev/video0 -zrcrop 352x272+352+0 \\\n" 777 "mplayer -vo zr -zrcrop 352x272+0+0 -zrdev /dev/video0 -zrcrop 352x272+352+0 \\\n"
778 " -zrdev /dev/video1 movie.avi\n\n" 778 " -zrdev /dev/video1 movie.avi\n\n"
779 "Options appearing after the second -zrcrop apply to the second card, it is\n" 779 "Options appearing after the second -zrcrop apply to the second card, it is\n"
780 "possible to dispay at a different jpeg quality or at different decimations.\n\n" 780 "possible to dispay at a different jpeg quality or at different decimations.\n\n"
782 "The maximum number of zoran cards participating in cinerama is 4, so you can\n" 782 "The maximum number of zoran cards participating in cinerama is 4, so you can\n"
783 "build a 2x2 vidiwall. (untested for obvious reasons, the setup wit a buz and\n" 783 "build a 2x2 vidiwall. (untested for obvious reasons, the setup wit a buz and\n"
784 "a DC10+ (and no beamers) is tested, however)\n" 784 "a DC10+ (and no beamers) is tested, however)\n"
785 ); 785 );
786 exit(0); 786 exit(0);
787 787
788 } 788 }
789 return ERR_NOT_AN_OPTION; 789 return ERR_NOT_AN_OPTION;
790 } 790 }
791 791
792 void vo_zr_revertoption(const m_option_t* opt,const char* param) { 792 void vo_zr_revertoption(const m_option_t* opt,const char* param) {
820 820
821 } 821 }
822 822
823 static int preinit(const char *arg) 823 static int preinit(const char *arg)
824 { 824 {
825 if(arg) 825 if(arg)
826 { 826 {
827 printf("vo_zr: Unknown subdevice: %s\n",arg); 827 printf("vo_zr: Unknown subdevice: %s\n",arg);
828 return ENOSYS; 828 return ENOSYS;
829 } 829 }
830 return 0; 830 return 0;