Mercurial > mplayer.hg
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; |