comparison libvo/vo_dxr3.c @ 4685:e8a749c866cf

Using the mplayer SwScaler instead of doing scaling manually (sometimes this dies with sig FPE when not using -vc mpegpes with mpegs (I find it unlikely it would only happen on mpegs though)) Using detection code to check if using NTSC or PAL/SECAM and setting appropriate resolution and GOP-Size based on this information. It now generates a valid mpeg1 stream instead of a hybrid mpeg2 (with mpeg1 headers).
author mswitch
date Wed, 13 Feb 2002 00:38:23 +0000
parents 8497da33a0d2
children 93e959f0a6e4
comparison
equal deleted inserted replaced
4684:db15e0ef6b31 4685:e8a749c866cf
4 * Copyright (C) 2002 David Holm <dholm@iname.com> 4 * Copyright (C) 2002 David Holm <dholm@iname.com>
5 * 5 *
6 */ 6 */
7 7
8 /* ChangeLog added 2002-01-10 8 /* ChangeLog added 2002-01-10
9 * 2002-02-13:
10 * Using the swscaler instead of the old hand coded shit. (Checkout man mplayer and search for sws ;).
11 * Using aspect function to setup a proper mpeg1, no more hassling with odd resolutions or GOP-sizes,
12 * this would only create jitter on some vids!
13 * The swscaler sometimes exits with sig8 on mpegs, I don't know why yet (just use -vc mpegpes in this
14 * case, and report to me if you have any avi's etc which does this...)
15 *
9 * 2002-02-09: 16 * 2002-02-09:
10 * Thanks to the new control() method I have finally been able to enable the em8300 prebuffering. 17 * Thanks to the new control() method I have finally been able to enable the em8300 prebuffering.
11 * This should speed up playback on all systems, the vout cpu usage should rocket since I will be hogging 18 * This should speed up playback on all systems, the vout cpu usage should rocket since I will be hogging
12 * the pci bus. Not to worry though, since frames are prebuffered it should be able to take a few blows 19 * the pci bus. Not to worry though, since frames are prebuffered it should be able to take a few blows
13 * if you start doing other stuff simultaneously. 20 * if you start doing other stuff simultaneously.
33 40
34 #include <linux/em8300.h> 41 #include <linux/em8300.h>
35 #include <sys/ioctl.h> 42 #include <sys/ioctl.h>
36 #include <sys/stat.h> 43 #include <sys/stat.h>
37 #include <sys/types.h> 44 #include <sys/types.h>
45 #include <sys/select.h>
38 #include <unistd.h> 46 #include <unistd.h>
39 #include <stdio.h> 47 #include <stdio.h>
40 #include <stdlib.h> 48 #include <stdlib.h>
41 #include <string.h> 49 #include <string.h>
42 #include <fcntl.h> 50 #include <fcntl.h>
46 #include "config.h" 54 #include "config.h"
47 #include "fastmemcpy.h" 55 #include "fastmemcpy.h"
48 56
49 #include "video_out.h" 57 #include "video_out.h"
50 #include "video_out_internal.h" 58 #include "video_out_internal.h"
59 #include "aspect.h"
51 #include "../postproc/rgb2rgb.h" 60 #include "../postproc/rgb2rgb.h"
61 #include "../postproc/swscale.h"
52 62
53 #ifdef USE_LIBAVCODEC 63 #ifdef USE_LIBAVCODEC
54 #ifdef USE_LIBAVCODEC_SO 64 #ifdef USE_LIBAVCODEC_SO
55 #include <libffmpeg/avcodec.h> 65 #include <libffmpeg/avcodec.h>
56 #else 66 #else
77 static int s_pos_x, s_pos_y; 87 static int s_pos_x, s_pos_y;
78 static int d_pos_x, d_pos_y; 88 static int d_pos_x, d_pos_y;
79 static int osd_w, osd_h; 89 static int osd_w, osd_h;
80 static int noprebuf = 0; 90 static int noprebuf = 0;
81 static int img_format = 0; 91 static int img_format = 0;
92 static SwsContext * sws = NULL;
93 float scalefactor = 1.0;
82 94
83 /* File descriptors */ 95 /* File descriptors */
84 static int fd_control = -1; 96 static int fd_control = -1;
85 static int fd_video = -1; 97 static int fd_video = -1;
86 static int fd_spu = -1; 98 static int fd_spu = -1;
136 } 148 }
137 } 149 }
138 return VO_NOTIMPL; 150 return VO_NOTIMPL;
139 } 151 }
140 152
141 static uint32_t config(uint32_t scr_width, uint32_t scr_height, uint32_t width, uint32_t height, uint32_t fullscreen, char *title, uint32_t format,const vo_tune_info_t *info) 153 static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format,const vo_tune_info_t *info)
142 { 154 {
143 int tmp1, tmp2; 155 int tmp1, tmp2;
144 em8300_register_t reg; 156 em8300_register_t reg;
145 157
158 /* Softzoom turned on, downscale */
146 /* This activates the subpicture processor, you can safely disable this and still send */ 159 /* This activates the subpicture processor, you can safely disable this and still send */
147 /* broken subpics to the em8300, if it's enabled and you send broken subpics you will end */ 160 /* broken subpics to the em8300, if it's enabled and you send broken subpics you will end */
148 /* up in a lockup */ 161 /* up in a lockup */
149 ioval = EM8300_SPUMODE_ON; 162 ioval = EM8300_SPUMODE_ON;
150 if (ioctl(fd_control, EM8300_IOCTL_SET_SPUMODE, &ioval) < 0) { 163 if (ioctl(fd_control, EM8300_IOCTL_SET_SPUMODE, &ioval) < 0) {
178 ioctl(fd_control, EM8300_IOCTL_SCR_SET, &ioval); 191 ioctl(fd_control, EM8300_IOCTL_SCR_SET, &ioval);
179 } 192 }
180 193
181 /* Store some variables statically that we need later in another scope */ 194 /* Store some variables statically that we need later in another scope */
182 img_format = format; 195 img_format = format;
183 v_width = scr_width; 196 v_width = width;
184 v_height = scr_height; 197 v_height = height;
185 198
186 /* libmp1e requires a width and height that is x|16 */ 199 /* libavcodec requires a width and height that is x|16 */
187 s_width = (v_width + 15) / 16; 200 aspect_save_orig(width, height);
188 s_width *= 16; 201 aspect_save_prescale(d_width, d_height);
189 s_height = (v_height + 15) / 16; 202 ioctl(fd_control, EM8300_IOCTL_GET_VIDEOMODE, &ioval);
190 s_height *= 16; 203 if (ioval == EM8300_VIDEOMODE_NTSC) {
204 printf("VO: [dxr3] Setting up for NTSC.\n");
205 aspect_save_screenres(352, 240);
206 } else {
207 printf("VO: [dxr3] Setting up for PAL/SECAM.\n");
208 aspect_save_screenres(352, 288);
209 }
210 aspect(&s_width, &s_height, A_ZOOM);
191 211
192 /* Try to figure out whether to use widescreen output or not */ 212 /* Try to figure out whether to use widescreen output or not */
193 /* Anamorphic widescreen modes makes this a pain in the ass */ 213 /* Anamorphic widescreen modes makes this a pain in the ass */
194 tmp1 = abs(height - ((width / 4) * 3)); 214 tmp1 = abs(d_height - ((d_width / 4) * 3));
195 tmp2 = abs(height - (int) (width / 2.35)); 215 tmp2 = abs(d_height - (int) (d_width / 2.35));
196 if (tmp1 < tmp2) { 216 if (tmp1 < tmp2) {
197 ioval = EM8300_ASPECTRATIO_4_3; 217 ioval = EM8300_ASPECTRATIO_4_3;
198 printf("VO: [dxr3] Setting aspect ratio to 4:3\n"); 218 printf("VO: [dxr3] Setting aspect ratio to 4:3\n");
199 } else { 219 } else {
200 ioval = EM8300_ASPECTRATIO_16_9; 220 ioval = EM8300_ASPECTRATIO_16_9;
212 uninit(); 232 uninit();
213 return -1; 233 return -1;
214 } 234 }
215 avc_context = malloc(sizeof(AVCodecContext)); 235 avc_context = malloc(sizeof(AVCodecContext));
216 memset(avc_context, 0, sizeof(avc_context)); 236 memset(avc_context, 0, sizeof(avc_context));
217 avc_context->width = v_width; 237 avc_context->width = s_width;
218 avc_context->height = v_height; 238 avc_context->height = s_height;
219 avc_context->frame_rate = 30 * FRAME_RATE_BASE; 239 ioctl(fd_control, EM8300_IOCTL_GET_VIDEOMODE, &ioval);
220 avc_context->gop_size = 12; 240 if (ioval == EM8300_VIDEOMODE_NTSC) {
241 avc_context->gop_size = 18;
242 avc_context->frame_rate = 29.97 * FRAME_RATE_BASE;
243 } else {
244 avc_context->gop_size = 15;
245 avc_context->frame_rate = 25 * FRAME_RATE_BASE;
246 }
221 avc_context->bit_rate = 8e6; 247 avc_context->bit_rate = 8e6;
222 avc_context->flags = CODEC_FLAG_HQ | CODEC_FLAG_QSCALE; 248 avc_context->flags = CODEC_FLAG_HQ | CODEC_FLAG_QSCALE;
223 avc_context->quality = 2; 249 avc_context->quality = 2;
224 avc_context->pix_fmt = PIX_FMT_YUV420P; 250 avc_context->pix_fmt = PIX_FMT_YUV420P;
225 if (avcodec_open(avc_context, avc_codec) < 0) { 251 if (avcodec_open(avc_context, avc_codec) < 0) {
226 printf("VO: [dxr3] Unable to open codec\n"); 252 printf("VO: [dxr3] Unable to open codec\n");
227 uninit(); 253 uninit();
254 return -1;
255 }
256
257 sws = getSwsContextFromCmdLine(v_width, v_height, img_format, s_width, s_height, IMGFMT_YV12);
258 if (!sws)
259 {
260 printf("vo_vesa: Can't initialize SwScaler\n");
228 return -1; 261 return -1;
229 } 262 }
230 263
231 /* This stuff calculations the relative position of video and osd on screen */ 264 /* This stuff calculations the relative position of video and osd on screen */
232 /* Old stuff taken from the dvb driver, should be removed when introducing spuenc */ 265 /* Old stuff taken from the dvb driver, should be removed when introducing spuenc */
238 osd_w = s_width; 271 osd_w = s_width;
239 } else { 272 } else {
240 s_pos_x = 0; 273 s_pos_x = 0;
241 } 274 }
242 osd_h = s_height; 275 osd_h = s_height;
243 d_pos_y = (s_height - v_height) / 2; 276 d_pos_y = (s_height - v_width) / 2;
244 if (d_pos_y < 0) { 277 if (d_pos_y < 0) {
245 s_pos_y = -d_pos_y; 278 s_pos_y = -d_pos_y;
246 d_pos_y = 0; 279 d_pos_y = 0;
247 osd_h = s_height; 280 osd_h = s_height;
248 } else { 281 } else {
249 s_pos_y = 0; 282 s_pos_y = 0;
250 } 283 }
251 284
252 /* Create a pixel buffer and set up pointers for color components */ 285 /* Create a pixel buffer and set up pointers for color components */
253 memset(&avc_picture, 0, sizeof(avc_picture)); 286 memset(&avc_picture, 0, sizeof(avc_picture));
254 avc_picture.linesize[0] = v_width; 287 avc_picture.linesize[0] = s_width;
255 avc_picture.linesize[1] = v_width / 2; 288 avc_picture.linesize[1] = s_width / 2;
256 avc_picture.linesize[2] = v_width / 2; 289 avc_picture.linesize[2] = s_width / 2;
257 avc_outbuf = malloc(avc_outbuf_size); 290 avc_outbuf = malloc(avc_outbuf_size);
258 291
259 size = s_width * s_height; 292 size = s_width * s_height;
260 picture_buf = malloc((size * 3) / 2); 293 picture_buf = malloc((size * 3) / 2);
261 avc_picture.data[0] = picture_buf; 294 avc_picture.data[0] = picture_buf;
316 write(fd_video, p->data, p->size); 349 write(fd_video, p->data, p->size);
317 } 350 }
318 return 0; 351 return 0;
319 #ifdef USE_LIBAVCODEC 352 #ifdef USE_LIBAVCODEC
320 } else { 353 } else {
321 int size = s_width * s_height; 354 int size, srcStride = (img_format == IMGFMT_YUY2) ? (v_width * 2) : (v_width * 3);
322 if (img_format == IMGFMT_YUY2) { 355 sws->swScale(sws, src, &srcStride, 0, v_height, avc_picture.data, avc_picture.linesize);
323 yuy2toyv12(src[0], avc_picture.data[0], avc_picture.data[1], avc_picture.data[2],
324 v_width, v_height, avc_picture.linesize[0], avc_picture.linesize[1], v_width*2);
325 } else if (img_format == IMGFMT_BGR24) {
326 rgb24toyv12(src[0], avc_picture.data[0], avc_picture.data[1], avc_picture.data[2],
327 v_width, v_height, avc_picture.linesize[0], avc_picture.linesize[1], v_width*3);
328 }
329 draw_osd(); 356 draw_osd();
330 size = avcodec_encode_video(avc_context, avc_outbuf, avc_outbuf_size, &avc_picture); 357 size = avcodec_encode_video(avc_context, avc_outbuf, avc_outbuf_size, &avc_picture);
331 write(fd_video, avc_outbuf, size); 358 write(fd_video, avc_outbuf, size);
332 return 0; 359 return 0;
333 #endif 360 #endif
335 return -1; 362 return -1;
336 } 363 }
337 364
338 static void flip_page(void) 365 static void flip_page(void)
339 { 366 {
367 fd_set rfds;
368 struct timeval tv;
340 #ifdef USE_LIBAVCODEC 369 #ifdef USE_LIBAVCODEC
341 if (img_format == IMGFMT_YV12) { 370 if (img_format == IMGFMT_YV12) {
342 int out_size = avcodec_encode_video(avc_context, avc_outbuf, avc_outbuf_size, &avc_picture); 371 int out_size = avcodec_encode_video(avc_context, avc_outbuf, avc_outbuf_size, &avc_picture);
343 if (!noprebuf) { 372 if (!noprebuf) {
344 ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts); 373 ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts);
345 } 374 }
346 write(fd_video, avc_outbuf, out_size); 375 write(fd_video, avc_outbuf, out_size);
347 } 376 }
348 #endif 377 #endif
378 tv.tv_sec = 0;
379 tv.tv_usec = 1e6 / floor(vo_fps);
380 FD_ZERO(&rfds);
381 FD_SET(fd_video, &rfds);
382 select(fd_video + 1, NULL, &rfds, NULL, &tv);
349 } 383 }
350 384
351 static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0) 385 static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0)
352 { 386 {
353 #ifdef USE_LIBAVCODEC 387 #ifdef USE_LIBAVCODEC
354 if (img_format == IMGFMT_YV12) { 388 if (img_format == IMGFMT_YV12) {
355 int y; 389 sws->swScale(sws, srcimg, stride, y0, h, avc_picture.data, avc_picture.linesize);
356 unsigned char *s, *s1;
357 unsigned char *d, *d1;
358
359 x0 += d_pos_x;
360 y0 += d_pos_y;
361
362 if ((x0 + w) > avc_picture.linesize[0]) {
363 w = avc_picture.linesize[0] - x0;
364 }
365 if ((y0 + h) > s_height) {
366 h = s_height - y0;
367 }
368
369 s = srcimg[0] + s_pos_x + s_pos_y * stride[0];
370 d = avc_picture.data[0] + x0 + y0 * avc_picture.linesize[0];
371 for(y = 0; y < h; y++) {
372 memcpy(d, s, w);
373 s += stride[0];
374 d += avc_picture.linesize[0];
375 }
376
377 w /= 2;
378 h /= 2;
379 x0 /= 2;
380 y0 /= 2;
381
382 s = srcimg[1] + s_pos_x + (s_pos_y * stride[1]);
383 d = avc_picture.data[1] + x0 + (y0 * avc_picture.linesize[1]);
384 s1 = srcimg[2] + s_pos_x + (s_pos_y * stride[2]);
385 d1 = avc_picture.data[2] + x0 + (y0 * avc_picture.linesize[2]);
386 for(y = 0; y < h; y++) {
387 memcpy(d, s, w);
388 memcpy(d1, s1, w);
389 s += stride[1];
390 s1 += stride[2];
391 d += avc_picture.linesize[1];
392 d1 += avc_picture.linesize[2];
393 }
394 return 0; 390 return 0;
395 } 391 }
396 #endif 392 #endif
397 return -1; 393 return -1;
398 } 394 }
399 395
400 static void uninit(void) 396 static void uninit(void)
401 { 397 {
402 printf("VO: [dxr3] Uninitializing\n"); 398 printf("VO: [dxr3] Uninitializing\n");
399 if (sws) {
400 freeSwsContext(sws);
401 }
403 #ifdef USE_LIBAVCODEC 402 #ifdef USE_LIBAVCODEC
404 if (avc_context) { 403 if (avc_context) {
405 avcodec_close(avc_context); 404 avcodec_close(avc_context);
406 } 405 }
407 if (picture_buf) { 406 if (picture_buf) {