Mercurial > mplayer.hg
comparison libvo/vo_zr.c @ 4348:d4acef803c94
use the new jpeg encoder - patch by Rik Snel <rsnel@cube.dyndns.org>
author | arpi |
---|---|
date | Sat, 26 Jan 2002 00:53:29 +0000 |
parents | f96a2b9b41eb |
children | ed5b85b713a3 |
comparison
equal
deleted
inserted
replaced
4347:d036a9992baf | 4348:d4acef803c94 |
---|---|
16 #include <linux/types.h> | 16 #include <linux/types.h> |
17 #include <linux/videodev.h> | 17 #include <linux/videodev.h> |
18 #include "zoran.h" | 18 #include "zoran.h" |
19 | 19 |
20 #include "config.h" | 20 #include "config.h" |
21 #define ZR_USES_LIBJPEG | |
22 | 21 |
23 #include "video_out.h" | 22 #include "video_out.h" |
24 #include "video_out_internal.h" | 23 #include "video_out_internal.h" |
25 #include "../mp_msg.h" | 24 #include "../mp_msg.h" |
26 #include "../cfgparser.h" | 25 #include "../cfgparser.h" |
38 | 37 |
39 /* General variables */ | 38 /* General variables */ |
40 | 39 |
41 static int image_width; | 40 static int image_width; |
42 static int image_height; | 41 static int image_height; |
43 static int off_y, off_c, stride; /* for use by 'draw slice' */ | 42 static int off_y, off_c, stride; /* for use by 'draw slice/frame' */ |
44 static int framenum; | 43 static int framenum; |
45 static int fields = 1; /* currently no interlacing */ | 44 static int fields = 1; /* currently no interlacing */ |
46 static int forceinter = 0; | 45 static int zrfd = 0; |
46 static int bw = 0; /* if bw == 1, then display in black&white */ | |
47 static int vdec = 1; | 47 static int vdec = 1; |
48 static int hdec = 1; | |
48 static int size; | 49 static int size; |
49 static int quality = 70; | 50 static int quality = 1; |
50 | 51 |
51 typedef struct { | 52 typedef struct { |
52 int width; | 53 int width; |
53 int height; | 54 int height; |
54 int xoff; | 55 int xoff; |
78 #define VO_ZR_DEFAULT_DEVICE "/dev/video" | 79 #define VO_ZR_DEFAULT_DEVICE "/dev/video" |
79 #endif | 80 #endif |
80 char *device = NULL; | 81 char *device = NULL; |
81 | 82 |
82 | 83 |
83 #ifdef ZR_USES_LIBJPEG | 84 extern int mjpeg_encode_frame(char *bufr, int field); |
84 #include<jpeglib.h> | 85 extern void mjpeg_encoder_init(int w, int h, unsigned char *y, |
85 int ccount; | 86 int y_psize, int y_rsize, unsigned char *u, |
86 unsigned char *ccbuf; | 87 int u_psize, int u_rsize, unsigned char *v, |
87 struct jpeg_compress_struct cinfo; | 88 int v_psize, int v_rsize, int f, int cu, int q, int b); |
88 struct jpeg_destination_mgr jdest; | |
89 struct jpeg_error_mgr jerr; | |
90 | |
91 /* minimal destination handler to output to buffer */ | |
92 METHODDEF(void) init_destination(struct jpeg_compress_struct *cinfo) { | |
93 // printf("init_destination called %p %d\n", ccbuf, ccount); | |
94 cinfo->dest->next_output_byte = (JOCTET*)(ccbuf+ccount); | |
95 cinfo->dest->free_in_buffer = MJPEG_SIZE - ccount; | |
96 } | |
97 | |
98 METHODDEF(boolean) empty_output_buffer(struct jpeg_compress_struct *cinfo) { | |
99 // printf("empty_output_buffer called\n"); | |
100 mp_msg(MSGT_VO, MSGL_ERR, "empty_output_buffer called, may not happen because buffer must me large enough\n"); | |
101 return(FALSE); | |
102 } | |
103 | |
104 METHODDEF(void) term_destination(struct jpeg_compress_struct *cinfo) { | |
105 // printf("term_destination called %p %d\n", ccbuf, ccount); | |
106 ccount = MJPEG_SIZE - cinfo->dest->free_in_buffer; | |
107 } | |
108 /* end of minimal destination handler */ | |
109 | |
110 JSAMPARRAY ***jsi; | |
111 | |
112 #else | |
113 #include "../libavcodec/avcodec.h" | |
114 AVCodec *codec; | |
115 AVCodecContext codec_context; | |
116 AVPicture picture; | |
117 #endif | |
118 | |
119 static int jpegdct = JDCT_IFAST; | |
120 | |
121 int init_codec() { | |
122 #ifdef ZR_USES_LIBJPEG | |
123 int i, j, k; | |
124 cinfo.err = jpeg_std_error(&jerr); | |
125 jpeg_create_compress(&cinfo); | |
126 | |
127 cinfo.dest = &jdest; | |
128 cinfo.dest->init_destination = init_destination; | |
129 cinfo.dest->empty_output_buffer = empty_output_buffer; | |
130 cinfo.dest->term_destination = term_destination; | |
131 | |
132 cinfo.input_components = 3; | |
133 | |
134 jpeg_set_defaults(&cinfo); | |
135 | |
136 cinfo.image_width = image_width; | |
137 cinfo.image_height = image_height/fields; | |
138 cinfo.input_gamma = 1.0; | |
139 cinfo.in_color_space = JCS_YCbCr; | |
140 cinfo.raw_data_in = TRUE; | |
141 cinfo.comp_info[0].h_samp_factor = 2; | |
142 cinfo.comp_info[0].v_samp_factor = 1; | |
143 cinfo.comp_info[1].h_samp_factor = 1; | |
144 cinfo.comp_info[1].v_samp_factor = 1; | |
145 cinfo.comp_info[2].h_samp_factor = 1; | |
146 cinfo.comp_info[2].v_samp_factor = 1; | |
147 cinfo.dct_method = jpegdct; | |
148 jpeg_set_quality(&cinfo, quality, FALSE); | |
149 jsi = malloc(sizeof(JSAMPARRAY**)*fields); | |
150 | |
151 /* Just some clutter to give libjpeg the pointers, | |
152 * and I don't want to recalculate everything everytime | |
153 * it is needed */ | |
154 for (k = 0; k < fields; k++) { | |
155 jsi[k] = malloc(sizeof(JSAMPARRAY*)*image_height/(8*fields)); | |
156 | |
157 for (i = 0; i < image_height/(8*fields); i++) { | |
158 jsi[k][i] = malloc(3*sizeof(JSAMPARRAY)); | |
159 jsi[k][i][0] = malloc(8*sizeof(JSAMPROW)); | |
160 jsi[k][i][1] = malloc(8*sizeof(JSAMPROW)); | |
161 jsi[k][i][2] = malloc(8*sizeof(JSAMPROW)); | |
162 for (j = 0; j < 8; j++) { | |
163 jsi[k][i][0][j] = (JSAMPROW)(image + | |
164 (fields*(8*i + j) + k)*image_width); | |
165 jsi[k][i][1][j] = (JSAMPROW)(image + size + | |
166 (fields*(8*i + j)/2)*image_width/2); | |
167 jsi[k][i][2][j] = (JSAMPROW)(image + 3*size/2 + | |
168 (fields*(8*i + j)/2)*image_width/2); | |
169 } | |
170 } | |
171 | |
172 } | |
173 #else | |
174 AVCodecContext *c = &codec_context; | |
175 codec = avcodec_find_encoder(CODEC_ID_MJPEG); | |
176 if (!codec) { | |
177 /* maybe libavcodec was not initialized */ | |
178 avcodec_init(); | |
179 avcodec_register_all(); | |
180 codec = avcodec_find_encoder(CODEC_ID_MJPEG); | |
181 if (!codec) { | |
182 mp_msg(MSGT_VO, MSGL_ERR, "MJPG codec not found in libavcodec\n"); | |
183 return 1; | |
184 } | |
185 } | |
186 /* put default values */ | |
187 memset(c, 0, sizeof(*c)); | |
188 | |
189 c->width = image_width; | |
190 c->height = image_height; | |
191 c->bit_rate = 4000000; | |
192 c->frame_rate = 25*FRAME_RATE_BASE; | |
193 //c->gop_size = 1; | |
194 c->pix_fmt = PIX_FMT_YUV422P; | |
195 | |
196 if (avcodec_open(c, codec) < 0) { | |
197 mp_msg(MSGT_VO, MSGL_ERR, "MJPG codec could not be opened\n"); | |
198 return 1; | |
199 } | |
200 | |
201 picture.data[0] = image; | |
202 picture.data[1] = image + size; | |
203 picture.data[2] = image + 3*size/2; | |
204 picture.linesize[0] = image_width; | |
205 picture.linesize[1] = image_width/2; | |
206 picture.linesize[2] = image_width/2; | |
207 #endif | |
208 return 0; | |
209 } | |
210 | |
211 | 89 |
212 int zoran_getcap() { | 90 int zoran_getcap() { |
213 char* dev = device ? device : VO_ZR_DEFAULT_DEVICE; | 91 char* dev = device ? device : VO_ZR_DEFAULT_DEVICE; |
214 vdes = open(dev, O_RDWR); | 92 vdes = open(dev, O_RDWR); |
215 /* before we can ask for the maximum resolution, we must set | 93 /* before we can ask for the maximum resolution, we must set |
250 mp_msg(MSGT_VO, MSGL_V, "zr36067 reports: maxwidth=%d, maxheight=%d\n", vc.maxwidth, vc.maxheight); | 128 mp_msg(MSGT_VO, MSGL_V, "zr36067 reports: maxwidth=%d, maxheight=%d\n", vc.maxwidth, vc.maxheight); |
251 | 129 |
252 return 0; | 130 return 0; |
253 } | 131 } |
254 | 132 |
255 int init_zoran() { | 133 int init_zoran(int zrhdec, int zrvdec) { |
256 /* center the image, and stretch it as far as possible (try to keep | 134 /* center the image, and stretch it as far as possible (try to keep |
257 * aspect) and check if it fits */ | 135 * aspect) and check if it fits */ |
258 if (image_width > vc.maxwidth) { | 136 if (image_width/hdec > vc.maxwidth) { |
259 mp_msg(MSGT_VO, MSGL_ERR, "movie to be played is too wide, max width currenty %d\n", vc.maxwidth); | 137 mp_msg(MSGT_VO, MSGL_ERR, "movie to be played is too wide, max width currenty %d\n", vc.maxwidth); |
260 return 1; | 138 return 1; |
261 } | 139 } |
262 | 140 |
263 if (image_height > vc.maxheight) { | 141 if (image_height > vc.maxheight) { |
264 mp_msg(MSGT_VO, MSGL_ERR, "movie to be played is too high, max height currenty %d\n", vc.maxheight); | 142 mp_msg(MSGT_VO, MSGL_ERR, "movie to be played is too high, max height currenty %d\n", vc.maxheight); |
265 return 1; | 143 return 1; |
266 } | 144 } |
267 | 145 |
268 zp.decimation = 0; | 146 zp.decimation = 0; |
269 zp.HorDcm = (vc.maxwidth >= 2*(int)image_width) ? 2 : 1; | 147 zp.HorDcm = zrhdec; |
270 zp.VerDcm = 1; | 148 zp.VerDcm = zrvdec; |
271 if (zp.HorDcm == 2 && 4*image_width <= vc.maxwidth && | |
272 4*image_height/fields <= vc.maxheight) { | |
273 zp.HorDcm = 4; | |
274 zp.VerDcm = 2; | |
275 } | |
276 if (((forceinter == 0 && vdec >= 2) || (forceinter == 1 && vdec == 4)) && 4*image_height/fields <= vc.maxheight) { | |
277 zp.VerDcm = 2; | |
278 } | |
279 zp.TmpDcm = 1; | 149 zp.TmpDcm = 1; |
280 zp.field_per_buff = fields; | 150 zp.field_per_buff = fields; |
281 zp.img_x = (vc.maxwidth - zp.HorDcm*(int)image_width)/2; | 151 zp.img_x = (vc.maxwidth - zp.HorDcm*(int)image_width/hdec)/2; |
282 zp.img_y = (vc.maxheight - zp.VerDcm*(3-fields)*(int)image_height)/4; | 152 zp.img_y = (vc.maxheight - zp.VerDcm*(3-fields)*(int)image_height)/4; |
283 zp.img_width = zp.HorDcm*image_width; | 153 zp.img_width = zp.HorDcm*image_width/hdec; |
284 zp.img_height = zp.VerDcm*image_height/fields; | 154 zp.img_height = zp.VerDcm*image_height/fields; |
285 mp_msg(MSGT_VO, MSGL_V, "zr: geometry (after 'scaling'): %dx%d+%d+%d fields=%d, w=%d, h=%d\n", zp.img_width, zp.img_height, zp.img_x, zp.img_y, fields, image_width, image_height); | 155 mp_msg(MSGT_VO, MSGL_V, "zr: geometry (after 'scaling'): %dx%d+%d+%d fields=%d, w=%d, h=%d\n", zp.img_width, (3-fields)*zp.img_height, zp.img_x, zp.img_y, fields, image_width/hdec, image_height); |
286 | 156 |
287 if (ioctl(vdes, BUZIOC_S_PARAMS, &zp) < 0) { | 157 if (ioctl(vdes, BUZIOC_S_PARAMS, &zp) < 0) { |
288 mp_msg(MSGT_VO, MSGL_ERR, "error setting display parameters\n"); | 158 mp_msg(MSGT_VO, MSGL_ERR, "error setting display parameters\n"); |
289 return 1; | 159 return 1; |
290 } | 160 } |
325 } | 195 } |
326 | 196 |
327 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, | 197 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, |
328 uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format) | 198 uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format) |
329 { | 199 { |
330 int j; | 200 int j, stretchx, stretchy; |
331 /* this allows to crop parts from incoming picture, | 201 /* this allows to crop parts from incoming picture, |
332 * for easy 512x240 -> 352x240 */ | 202 * for easy 512x240 -> 352x240 */ |
333 /* These values must be multples of 2 */ | 203 /* These values must be multples of 2 */ |
334 | 204 if (format != IMGFMT_YV12 && format != IMGFMT_YUY2) { |
205 printf("vo_zr called with wrong format"); | |
206 exit(1); | |
207 } | |
208 stride = 2*width; | |
335 if (g.set) { | 209 if (g.set) { |
336 if (g.width%2 != 0 || g.height%2 != 0 || | 210 if (g.width%2 != 0 || g.height%2 != 0 || |
337 g.xoff%2 != 0 || g.yoff%2 != 0) { | 211 g.xoff%2 != 0 || g.yoff%2 != 0) { |
338 mp_msg(MSGT_VO, MSGL_ERR, "arguments in -zrcrop must be multiples of 2\n"); | 212 mp_msg(MSGT_VO, MSGL_ERR, "arguments in -zrcrop must be multiples of 2\n"); |
339 return 1; | 213 return 1; |
358 g.yoff = 0; | 232 g.yoff = 0; |
359 } | 233 } |
360 /* we must know the maximum resolution of the device | 234 /* we must know the maximum resolution of the device |
361 * it differs for DC10+ and buz for example */ | 235 * it differs for DC10+ and buz for example */ |
362 zoran_getcap(); /*must be called before init_zoran */ | 236 zoran_getcap(); /*must be called before init_zoran */ |
363 if (g.height/vdec > vc.maxheight/2 || (forceinter == 1 && vdec == 1)) | 237 /* make the scaling decision |
238 * we are capable of stretching the image in the horizontal | |
239 * direction by factors 1, 2 and 4 | |
240 * we can stretch the image in the vertical direction by a factor | |
241 * of 1 and 2 AND we must decide about interlacing */ | |
242 if (g.width > vc.maxwidth/2 || g.height > vc.maxheight/2) { | |
243 stretchx = 1; | |
244 stretchy = 1; | |
364 fields = 2; | 245 fields = 2; |
365 printf("fields=%d\n", fields); | 246 if (vdec == 2) { |
247 fields = 1; | |
248 } else if (vdec == 4) { | |
249 stretchy = 2; | |
250 } | |
251 stretchx = hdec; | |
252 } else if (g.width > vc.maxwidth/4 || g.height > vc.maxheight/4) { | |
253 stretchx = 2; | |
254 stretchy = 1; | |
255 fields = 1; | |
256 if (vdec == 2) { | |
257 stretchy = 2; | |
258 } else if (vdec == 4) { | |
259 if (!zrfd) { | |
260 mp_msg(MSGT_VO, MSGL_WARN, "vo_zr: vertical decimation too high, changing to 2 (use -zrfd to keep vdec=4)\n"); | |
261 vdec = 2; | |
262 } | |
263 stretchy = 2; | |
264 } | |
265 if (hdec == 2) { | |
266 stretchx = 4; | |
267 } else if (hdec == 4){ | |
268 if (!zrfd) { | |
269 mp_msg(MSGT_VO, MSGL_WARN, "vo_zr: horizontal decimation too high, changing to 2 (use -zrfd to keep hdec=4)\n"); | |
270 hdec = 2; | |
271 } | |
272 stretchx = 4; | |
273 } | |
274 } else { | |
275 /* output image is maximally stretched */ | |
276 stretchx = 4; | |
277 stretchy = 2; | |
278 fields = 1; | |
279 if (vdec != 1 && !zrfd) { | |
280 mp_msg(MSGT_VO, MSGL_WARN, "vo_zr: vertical decimation too high, changing to 1 (use -zrfd to keep vdec=%d)\n", vdec); | |
281 vdec = 1; | |
282 } | |
283 | |
284 if (hdec != 1 && !zrfd) { | |
285 mp_msg(MSGT_VO, MSGL_WARN, "vo_zr: vertical decimation too high, changing to 1 (use -zrfd to keep hdec=%d)\n", hdec); | |
286 hdec = 1; | |
287 } | |
288 } | |
366 /* the height must be a multiple of fields*8 and the width | 289 /* the height must be a multiple of fields*8 and the width |
367 * must be a multiple of 16 */ | 290 * must be a multiple of 16 */ |
368 /* add some black borders to make it so, and center the image*/ | 291 /* add some black borders to make it so, and center the image*/ |
369 image_height = fields*8*((g.height/vdec - 1)/(fields*8) + 1); | 292 image_height = fields*8*((g.height/vdec - 1)/(fields*8) + 1); |
370 image_width = 16*((g.width - 1)/16 + 1); | 293 image_width = (hdec*16)*((g.width - 1)/(hdec*16) + 1); |
371 off_y = (image_height - g.height/vdec)/2; | 294 off_y = (image_height - g.height/vdec)/2; |
372 if (off_y%2 != 0) off_y++; | 295 if (off_y%2 != 0) off_y++; |
373 off_y *= image_width; | 296 off_y *= image_width; |
374 off_c = off_y/4; | 297 off_c = off_y/4; |
375 off_y += (image_width - g.width)/2; | 298 off_y += (image_width - g.width)/2; |
376 if (off_y%2 != 0) off_y--; | 299 if (off_y%2 != 0) off_y--; |
377 off_c += (image_width - g.width)/4; | 300 off_c += (image_width - g.width)/4; |
378 framenum = 0; | 301 framenum = 0; |
379 size = image_width*image_height; | 302 size = image_width*image_height; |
380 mp_msg(MSGT_VO, MSGL_V, "input: %dx%d, cropped: %dx%d, output: %dx%d, off_y=%d, off_c=%d\n", width, height, g.width, g.height, image_width, image_height, off_y, off_c); | 303 mp_msg(MSGT_VO, MSGL_V, "input: %dx%d, cropped: %dx%d, output: %dx%d, off_y=%d, off_c=%d\n", width/hdec, height, g.width, g.height, image_width, image_height, off_y, off_c); |
381 | 304 |
382 image = malloc(2*size); /* this buffer allows for YUV422 data, | 305 image = malloc(2*size); /* this buffer allows for YUV422 data, |
383 * so it is a bit too big for YUV420 */ | 306 * so it is a bit too big for YUV420 */ |
384 if (!image) { | 307 if (!image) { |
385 mp_msg(MSGT_VO, MSGL_ERR, "Memory exhausted\n"); | 308 mp_msg(MSGT_VO, MSGL_ERR, "Memory exhausted\n"); |
386 return 1; | 309 return 1; |
387 } | 310 } |
388 /* and make sure that the borders are _really_ black */ | 311 /* and make sure that the borders are _really_ black */ |
389 memset(image, 0, image_width*image_height); | 312 switch (format) { |
390 memset(image + size, 0x80, image_width*image_height/4); | 313 case IMGFMT_YV12: |
391 memset(image + 3*size/2, 0x80, image_width*image_height/4); | 314 memset(image, 0, image_width*image_height); |
392 | 315 memset(image + size, 0x80, image_width*image_height/4); |
393 if (init_codec()) { | 316 memset(image + 3*size/2, 0x80, image_width*image_height/4); |
394 return 1; | 317 mjpeg_encoder_init(image_width/hdec, image_height, |
395 } | 318 image, hdec, image_width, |
396 | 319 image + image_width*image_height, |
397 if (init_zoran()) { | 320 hdec, image_width/2, |
398 #ifdef ZR_USES_LIBJPEG | 321 image + 3*image_width*image_height/2, |
399 jpeg_destroy_compress(&cinfo); | 322 hdec, image_width/2, fields, 1, |
400 #else | 323 quality, bw); |
401 avcodec_close(&codec_context); | 324 break; |
402 #endif | 325 case IMGFMT_YUY2: |
326 for (j = 0; j < 2*size; j+=4) { | |
327 image[j] = 0; | |
328 image[j+1] = 0x80; | |
329 image[j+2] = 0; | |
330 image[j+3] = 0x80; | |
331 } | |
332 mjpeg_encoder_init(image_width/hdec, image_height, | |
333 image, hdec*2, image_width*2, | |
334 image + 1, hdec*4, image_width*2, | |
335 image + 3, hdec*4, image_width*2, | |
336 fields, 0, quality, bw); | |
337 break; | |
338 default: | |
339 mp_msg(MSGT_VO, MSGL_FATAL, "internal inconsistency in vo_zr\n"); | |
340 } | |
341 | |
342 | |
343 if (init_zoran(stretchx, stretchy)) { | |
403 return 1; | 344 return 1; |
404 } | 345 } |
405 | 346 |
406 return 0; | 347 return 0; |
407 } | 348 } |
412 | 353 |
413 static void draw_osd(void) { | 354 static void draw_osd(void) { |
414 } | 355 } |
415 | 356 |
416 static void flip_page (void) { | 357 static void flip_page (void) { |
417 #ifdef ZR_USES_LIBJPEG | |
418 int i, j, k; | 358 int i, j, k; |
419 #else | 359 /*FILE *fp; |
420 AVCodecContext *c = &codec_context; | 360 char filename[100];*/ |
421 #endif | |
422 | |
423 /* do we have a free buffer? */ | 361 /* do we have a free buffer? */ |
424 if (queue-synco < zrq.count) { | 362 if (queue-synco < zrq.count) { |
425 frame = queue; | 363 frame = queue; |
426 } else { | 364 } else { |
427 if (ioctl(vdes, BUZIOC_SYNC, &zs) < 0) | 365 if (ioctl(vdes, BUZIOC_SYNC, &zs) < 0) |
428 mp_msg(MSGT_VO, MSGL_ERR, "error waiting for buffers to become free"); | 366 mp_msg(MSGT_VO, MSGL_ERR, "error waiting for buffers to become free"); |
429 frame = zs.frame; | 367 frame = zs.frame; |
430 synco++; | 368 synco++; |
431 } | 369 } |
432 | 370 k=0; |
433 #ifdef ZR_USES_LIBJPEG | 371 for (i = 0; i < fields; i++) |
434 ccbuf = buf + frame*zrq.size; | 372 k+=mjpeg_encode_frame(buf+frame*zrq.size+k, i); |
435 ccount = 0; | 373 /* Warning, Quantization and Huffman tables are only |
436 k = fields; | 374 * written in the first frame by default (to preserver bandwidth) */ |
437 for (j=0; j < k; j++) { | 375 /*sprintf(filename, "test%04d.jpg", framenum); |
438 | 376 fp = fopen(filename, "w"); |
439 jpeg_start_compress(&cinfo, TRUE); | 377 if (!fp) exit(1); |
440 i=0; | 378 fwrite(buf+frame*zrq.size, 1, k, fp); |
441 while (cinfo.next_scanline < cinfo.image_height) { | 379 fclose(fp);*/ |
442 jpeg_write_raw_data(&cinfo, jsi[j][i], 8); | 380 /*fp = fopen("test1.jpg", "r"); |
443 i++; | 381 fread(buf+frame*zrq.size, 1, 2126, fp); |
444 } | 382 fclose(fp);*/ |
445 jpeg_finish_compress(&cinfo); | 383 |
446 | |
447 } | |
448 #else | |
449 avcodec_encode_video(c, buf + frame*zrq.size, MJPEG_SIZE, &picture); | |
450 #endif | |
451 | |
452 if (ioctl(vdes, BUZIOC_QBUF_PLAY, &frame) < 0) | 384 if (ioctl(vdes, BUZIOC_QBUF_PLAY, &frame) < 0) |
453 mp_msg(MSGT_VO, MSGL_ERR, | 385 mp_msg(MSGT_VO, MSGL_ERR, |
454 "error queueing buffer for playback"); | 386 "error queueing buffer for playback"); |
455 queue++; | 387 queue++; |
456 | 388 |
457 framenum++; | 389 framenum++; |
458 return; | 390 return; |
459 } | 391 } |
460 | 392 |
461 static uint32_t draw_frame(uint8_t * src[]) { | 393 static uint32_t draw_frame(uint8_t * src[]) { |
394 int i; | |
395 char *source, *dest; | |
396 //printf("draw frame called\n"); | |
397 source = src[0] + 2*g.yoff*image_width + 2*g.xoff; | |
398 dest = image + 2*off_y; | |
399 for (i = 0; i < g.height/vdec; i++) { | |
400 memcpy(dest, source, image_width*2); | |
401 dest += 2*image_width; | |
402 source += vdec*stride; | |
403 } | |
462 return 0; | 404 return 0; |
463 } | 405 } |
464 | 406 |
465 static uint32_t query_format(uint32_t format) { | 407 static uint32_t query_format(uint32_t format) { |
466 if(format==IMGFMT_YV12) return 1; | 408 if(format==IMGFMT_YV12) return 1; |
409 if(format==IMGFMT_YUY2) return 1; | |
467 return 0; | 410 return 0; |
468 } | 411 } |
469 | 412 |
470 static void uninit(void) { | 413 static void uninit(void) { |
471 uninit_zoran(); | 414 uninit_zoran(); |
472 | |
473 #ifdef ZR_USES_LIBJPEG | |
474 jpeg_destroy_compress(&cinfo); | |
475 #else | |
476 avcodec_close(&codec_context); | |
477 #endif | |
478 } | 415 } |
479 | 416 |
480 static void check_events(void) { | 417 static void check_events(void) { |
481 } | 418 } |
482 | 419 |
526 dst+=image_width; | 463 dst+=image_width; |
527 } | 464 } |
528 src+=stride[0]; | 465 src+=stride[0]; |
529 | 466 |
530 } | 467 } |
531 { | 468 if (!bw) { |
532 // copy U+V: | 469 // copy U+V: |
533 uint8_t *src1=srcimg[1]; | 470 uint8_t *src1=srcimg[1]; |
534 uint8_t *src2=srcimg[2]; | 471 uint8_t *src2=srcimg[2]; |
535 uint8_t *dst1=image + size + off_c+ (y/(vdec*2))*image_width/2+(x/2); | 472 uint8_t *dst1=image + size + off_c+ (y/(vdec*2))*image_width/2+(x/2); |
536 uint8_t *dst2=image + 3*size/2 + off_c + | 473 uint8_t *dst2=image + 3*size/2 + off_c + |
563 //aaopt_osdcolor=i; | 500 //aaopt_osdcolor=i; |
564 device = malloc(strlen(param)+1); | 501 device = malloc(strlen(param)+1); |
565 strcpy(device, param); | 502 strcpy(device, param); |
566 mp_msg(MSGT_VO, MSGL_V, "zr: using device %s\n", device); | 503 mp_msg(MSGT_VO, MSGL_V, "zr: using device %s\n", device); |
567 return 1; | 504 return 1; |
568 } else if (!strcasecmp(opt, "zrfi")) { | 505 } else if (!strcasecmp(opt, "zrbw")) { |
569 if (param != NULL) { | 506 if (param != NULL) { |
570 return ERR_OUT_OF_RANGE; | 507 return ERR_OUT_OF_RANGE; |
571 } | 508 } |
572 forceinter = 1; | 509 bw = 1; |
510 return 1; | |
511 } else if (!strcasecmp(opt, "zrfd")) { | |
512 if (param != NULL) { | |
513 return ERR_OUT_OF_RANGE; | |
514 } | |
515 zrfd = 1; | |
573 return 1; | 516 return 1; |
574 } else if (!strcasecmp(opt, "zrcrop")){ | 517 } else if (!strcasecmp(opt, "zrcrop")){ |
575 if (param == NULL) return ERR_MISSING_PARAM; | 518 if (param == NULL) return ERR_MISSING_PARAM; |
576 if (sscanf(param, "%dx%d+%d+%d", &g.width, &g.height, | 519 if (sscanf(param, "%dx%d+%d+%d", &g.width, &g.height, |
577 &g.xoff, &g.yoff) != 4) { | 520 &g.xoff, &g.yoff) != 4) { |
582 } | 525 } |
583 } | 526 } |
584 g.set = 1; | 527 g.set = 1; |
585 mp_msg(MSGT_VO, MSGL_V, "zr: cropping %s\n", param); | 528 mp_msg(MSGT_VO, MSGL_V, "zr: cropping %s\n", param); |
586 return 1; | 529 return 1; |
530 }else if (!strcasecmp(opt, "zrhdec")) { | |
531 i = atoi(param); | |
532 if (i != 1 && i != 2 && i != 4) return ERR_OUT_OF_RANGE; | |
533 hdec = i; | |
534 return 1; | |
587 }else if (!strcasecmp(opt, "zrvdec")) { | 535 }else if (!strcasecmp(opt, "zrvdec")) { |
588 i = atoi(param); | 536 i = atoi(param); |
589 if (i != 1 && i != 2 && i != 4) return ERR_OUT_OF_RANGE; | 537 if (i != 1 && i != 2 && i != 4) return ERR_OUT_OF_RANGE; |
590 vdec = i; | 538 vdec = i; |
591 return 1; | 539 return 1; |
592 }else if (!strcasecmp(opt, "zrquality")) { | 540 }else if (!strcasecmp(opt, "zrquality")) { |
593 i = atoi(param); | 541 i = atoi(param); |
594 if (i < 30 || i > 100) return ERR_OUT_OF_RANGE; | 542 if (i < 1 || i > 20) return ERR_OUT_OF_RANGE; |
595 quality = i; | 543 quality = i; |
596 return 1; | 544 return 1; |
597 }else if (!strcasecmp(opt, "zrdct")) { | |
598 if (param == NULL) return ERR_MISSING_PARAM; | |
599 if (!strcasecmp(param, "IFAST")) { | |
600 jpegdct = JDCT_IFAST; | |
601 return 1; | |
602 } else if (!strcasecmp(param, "ISLOW")) { | |
603 jpegdct = JDCT_ISLOW; | |
604 return 1; | |
605 } else if (!strcasecmp(param, "FLOAT")) { | |
606 jpegdct = JDCT_FLOAT; | |
607 return 1; | |
608 } else { | |
609 return ERR_OUT_OF_RANGE; | |
610 } | |
611 }else if (!strcasecmp(opt, "zrnorm")) { | 545 }else if (!strcasecmp(opt, "zrnorm")) { |
612 if (param == NULL) return ERR_MISSING_PARAM; | 546 if (param == NULL) return ERR_MISSING_PARAM; |
613 if (!strcasecmp(param, "NTSC")) { | 547 if (!strcasecmp(param, "NTSC")) { |
614 mp_msg(MSGT_VO, MSGL_V, "zr: Norm set to NTSC\n"); | 548 mp_msg(MSGT_VO, MSGL_V, "zr: Norm set to NTSC\n"); |
615 norm = VIDEO_MODE_NTSC; | 549 norm = VIDEO_MODE_NTSC; |
629 "\n" | 563 "\n" |
630 " -zrcrop specify part of the input image that\n" | 564 " -zrcrop specify part of the input image that\n" |
631 " you want to see as an x-style geometry string\n" | 565 " you want to see as an x-style geometry string\n" |
632 " example: -zrcrop 352x288+16+0\n" | 566 " example: -zrcrop 352x288+16+0\n" |
633 " -zrvdec vertical decimation 1, 2 or 4\n" | 567 " -zrvdec vertical decimation 1, 2 or 4\n" |
634 " -zrfi force interlacing ('wide screen')\n" | 568 " -zrhdec horizontal decimation 1, 2 or 4\n" |
635 " (by default we only interlace if the movie\n" | 569 " -zrfd decimation is only done if the primitive\n" |
636 " is higher than half of the screen height)\n" | 570 " hardware upscaler can correct for the decimation,\n" |
637 " -zrquality jpeg compression quality 30-100\n" | 571 " this switch allows you to see the effects\n" |
638 " -zrdct specify DCT method: IFAST, ISLOW or FLOAT\n" | 572 " of too much decimation\n" |
573 " -zrbw display in black&white (speed increase)\n" | |
574 " -zrquality jpeg compression quality [BEST] 1 - 20 [VERY BAD]\n" | |
639 " -zrdev playback device (example -zrdev /dev/video1\n" | 575 " -zrdev playback device (example -zrdev /dev/video1\n" |
640 " -zrnorm specify norm PAL/NTSC [dev: leave at current setting]\n" | 576 " -zrnorm specify norm PAL/NTSC [dev: leave at current setting]\n" |
641 "\n" | 577 "\n" |
642 ); | 578 ); |
643 exit(0); | 579 exit(0); |
650 | 586 |
651 if (!strcasecmp(param, "zrdev")) { | 587 if (!strcasecmp(param, "zrdev")) { |
652 if(device) | 588 if(device) |
653 free(device); | 589 free(device); |
654 device=NULL; | 590 device=NULL; |
655 } else if (!strcasecmp(param, "zrfi")) | 591 } else if (!strcasecmp(param, "zrbw")) |
656 forceinter=0; | 592 bw=0; |
593 else if (!strcasecmp(param, "zrfd")) | |
594 zrfd=0; | |
657 else if (!strcasecmp(param, "zrcrop")) | 595 else if (!strcasecmp(param, "zrcrop")) |
658 g.set = g.xoff = g.yoff = 0; | 596 g.set = g.xoff = g.yoff = 0; |
597 else if (!strcasecmp(param, "zrhdec")) | |
598 hdec = 1; | |
659 else if (!strcasecmp(param, "zrvdec")) | 599 else if (!strcasecmp(param, "zrvdec")) |
660 vdec = 1; | 600 vdec = 1; |
661 else if (!strcasecmp(param, "zrquality")) | 601 else if (!strcasecmp(param, "zrquality")) |
662 quality = 70; | 602 quality = 1; |
663 else if (!strcasecmp(param, "zrdct")) | |
664 jpegdct = JDCT_IFAST; | |
665 else if (!strcasecmp(param, "zrnorm")) | 603 else if (!strcasecmp(param, "zrnorm")) |
666 norm = VIDEO_MODE_AUTO; | 604 norm = VIDEO_MODE_AUTO; |
667 | 605 |
668 } | 606 } |