[MPlayer-dev-eng] [PATCH] DXR3 SwScaling

David Holm david at realityrift.com
Sat Feb 9 22:07:38 CET 2002


Hi,
here is a patch that adds proper swscaling to the dxr3 device (wow, this
thing is a goldmine =D. Also adds the switch -scalefactor to set the
factor by which to scale the output (it is only enabled if a dxr3/h+ is
found). Docs updated appropriately.

With this thing even ppl on very slow machines should be able to play
divx through the em8300 (as long as it's fast enough to decode the divx
;). I found it rather useful on my machine as well since I have some
divxs encoded at inhumane resolutions ;)

//David Holm


-------------- next part --------------
Index: DOCS/DXR3
===================================================================
RCS file: /cvsroot/mplayer/main/DOCS/DXR3,v
retrieving revision 1.12
diff -u -r1.12 DXR3
--- DOCS/DXR3	9 Feb 2002 17:54:29 -0000	1.12
+++ DOCS/DXR3	9 Feb 2002 21:16:08 -0000
@@ -20,23 +20,37 @@
 
 2. Usage
 
-    -vo dxr3:<devicenum>		For video output :<devicenum> is not needed unless
-					you have more than one em8300 device in your computer
-    -vo dxr3:noprebuf			Turn of prebuffering. This is only needed if you are
-					having sync issues with normal playback, this will
-					make playback appear less smooth and will not use all
-					available cpu power when playing non-mpeg content.
-					Note: With prebuffering A-V: should be negative, if
-					      it's nonnegative your computer is too slow to
-					      properly play the video and you should disble
-					      prebuffering if you have sync issues.
-					      Without prebuffering this value should stay as
-					      close to 0 at all times.
+     -vo dxr3:<devicenum>		For video output :<devicenum> is not needed unless
+ 					you have more than one em8300 device in your computer
+     -vo dxr3:noprebuf			Turn of prebuffering. This is only needed if you are
+ 					having sync issues with normal playback, this will
+ 					make playback appear less smooth and will not use all
+ 					available cpu power when playing non-mpeg content.
+ 					Note: With prebuffering A-V: should be negative, if
+ 					      it's nonnegative your computer is too slow to
+ 					      properly play the video and you should disble
+ 					      prebuffering if you have sync issues.
+ 					      Without prebuffering this value should stay
+ 					      close to 0 at all times.
+ 					Note2: Some very fast computers seems to have issues
+ 					       with prebuffering. Blame Sigma for that ;).
+ 					       You can safely use :noprebuf since your machines
+ 					       are fast enough to give you smooth playback anyway.
     -ao oss:<devicefile>		For audio output
     -ac hwac3				For digital audio output instead of
 					analog
     -vc mpegpes				For mpeg playback
+    -scalefactor <float>		Set the scale factor for libavcodec.
+					1.0 = Normal res
+					2.0 = Double res
+					0.5 = Half res
+					You get the drift, anyway, this is useful for those of you
+					on slower machines who would want to watch that brand new
+					divx file, just set this to a value as close to 1.0 as
+					possible where you still get decent playback speed.
     -aop list=resample:fout=48000	If samplerate is below 44100Hz
+ 					This does not work with digital audio output
+ 					(-ac hwac3)
     <devicenum>				Number of device to use for playback
 				        (if you	have more than one card.).
 					This can usually be left out (-vo dxr3).
Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.390
diff -u -r1.390 mplayer.c
--- mplayer.c	9 Feb 2002 14:53:49 -0000	1.390
+++ mplayer.c	9 Feb 2002 21:16:09 -0000
@@ -216,6 +216,10 @@
 int allow_dshow=0;
 #endif
 
+#ifdef HAVE_DXR3
+float scalefactor=1.0;
+#endif
+
 // streaming:
 int audio_id=-1;
 int video_id=-1;
Index: cfg-mplayer.h
===================================================================
RCS file: /cvsroot/mplayer/main/cfg-mplayer.h,v
retrieving revision 1.131
diff -u -r1.131 cfg-mplayer.h
--- cfg-mplayer.h	3 Feb 2002 09:28:57 -0000	1.131
+++ cfg-mplayer.h	9 Feb 2002 21:16:09 -0000
@@ -242,6 +242,9 @@
         {"nozoom", &softzoom, CONF_TYPE_FLAG, 0, 1, 0, NULL},
         {"flip", &flip, CONF_TYPE_FLAG, 0, -1, 1, NULL},
         {"noflip", &flip, CONF_TYPE_FLAG, 0, -1, 0, NULL},
+#ifdef HAVE_DXR3
+	{"scalefactor", &scalefactor, CONF_TYPE_FLOAT, CONF_RANGE, 0.1, 1.0, NULL},
+#endif
        
 #ifndef USE_LIBVO2
         {"bpp", &vo_dbpp, CONF_TYPE_INT, CONF_RANGE, 0, 32, NULL},
Index: libvo/vo_dxr3.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/vo_dxr3.c,v
retrieving revision 1.53
diff -u -r1.53 vo_dxr3.c
--- libvo/vo_dxr3.c	9 Feb 2002 17:40:33 -0000	1.53
+++ libvo/vo_dxr3.c	9 Feb 2002 21:16:10 -0000
@@ -49,6 +49,7 @@
 #include "video_out.h"
 #include "video_out_internal.h"
 #include "../postproc/rgb2rgb.h"
+#include "../postproc/swscale.h"
 
 #ifdef USE_LIBAVCODEC
 #ifdef USE_LIBAVCODEC_SO
@@ -79,6 +80,8 @@
 static int osd_w, osd_h;
 static int noprebuf = 0;
 static int img_format = 0;
+static SwsContext * sws = NULL;
+extern float scalefactor;
 
 /* File descriptors */
 static int fd_control = -1;
@@ -143,6 +146,7 @@
 	int tmp1, tmp2;
 	em8300_register_t reg;
     
+	/* Softzoom turned on, downscale */
 	/* This activates the subpicture processor, you can safely disable this and still send */
 	/* broken subpics to the em8300, if it's enabled and you send broken subpics you will end */
 	/* up in a lockup */
@@ -183,10 +187,10 @@
 	v_width = scr_width;
 	v_height = scr_height;
 
-	/* libmp1e requires a width and height that is x|16 */
-	s_width = (v_width + 15) / 16;
+	/* libavcodec requires a width and height that is x|16 */
+	s_width = ((v_width + 15) / 16) * scalefactor;
 	s_width *= 16;
-	s_height = (v_height + 15) / 16;
+	s_height = ((v_height + 15) / 16) * scalefactor;
 	s_height *= 16;
     
 	/* Try to figure out whether to use widescreen output or not */
@@ -214,8 +218,8 @@
 		}
 		avc_context = malloc(sizeof(AVCodecContext));
 		memset(avc_context, 0, sizeof(avc_context));
-		avc_context->width = v_width;
-		avc_context->height = v_height;
+		avc_context->width = s_width;
+		avc_context->height = s_height;
 		avc_context->frame_rate = 30 * FRAME_RATE_BASE;
 		avc_context->gop_size = 12;
 		avc_context->bit_rate = 8e6;
@@ -227,11 +231,18 @@
 			uninit();
 			return -1;
 		}
+		
+		sws = getSwsContextFromCmdLine(v_width, v_height, img_format, s_width, s_height, IMGFMT_YV12);
+		if (!sws)
+		{
+			printf("vo_vesa: Can't initialize SwScaler\n");
+			return -1;
+		}
 	
 		/* This stuff calculations the relative position of video and osd on screen */
 		/* Old stuff taken from the dvb driver, should be removed when introducing spuenc */
 		osd_w = s_width;
-		d_pos_x = (s_width - v_width) / 2;
+		d_pos_x = ((v_width * scalefactor) - s_width) / 2;
 		if (d_pos_x < 0) {
 			s_pos_x = -d_pos_x;
 			d_pos_x = 0;
@@ -240,7 +251,7 @@
 			s_pos_x = 0;
 		}
 		osd_h = s_height;
-		d_pos_y = (s_height - v_height) / 2;
+		d_pos_y = ((v_height * scalefactor) - s_height) / 2;
 		if (d_pos_y < 0) {
 			s_pos_y = -d_pos_y;
 			d_pos_y = 0;
@@ -251,9 +262,9 @@
 
 		/* Create a pixel buffer and set up pointers for color components */
 		memset(&avc_picture, 0, sizeof(avc_picture));
-		avc_picture.linesize[0] = v_width;
-		avc_picture.linesize[1] = v_width / 2;
-		avc_picture.linesize[2] = v_width / 2;
+		avc_picture.linesize[0] = s_width;
+		avc_picture.linesize[1] = s_width / 2;
+		avc_picture.linesize[2] = s_width / 2;
 		avc_outbuf = malloc(avc_outbuf_size);
 
 		size = s_width * s_height;
@@ -318,14 +329,8 @@
 		return 0;
 #ifdef USE_LIBAVCODEC
 	} else {
-		int size = s_width * s_height;
-		if (img_format == IMGFMT_YUY2) {
-			yuy2toyv12(src[0], avc_picture.data[0], avc_picture.data[1], avc_picture.data[2],
-				v_width, v_height, avc_picture.linesize[0], avc_picture.linesize[1], v_width*2);
-		} else if (img_format == IMGFMT_BGR24) {
-			rgb24toyv12(src[0], avc_picture.data[0], avc_picture.data[1], avc_picture.data[2],
-				v_width, v_height, avc_picture.linesize[0], avc_picture.linesize[1], v_width*3);
-		}
+		int size, srcStride = (img_format == IMGFMT_YUY2) ? (v_width * 2) : (v_width * 3);
+		sws->swScale(sws, src, &srcStride, 0, v_height, avc_picture.data, avc_picture.linesize);
 		draw_osd();
 		size = avcodec_encode_video(avc_context, avc_outbuf, avc_outbuf_size, &avc_picture);
 		write(fd_video, avc_outbuf, size);
@@ -352,45 +357,7 @@
 {
 #ifdef USE_LIBAVCODEC
 	if (img_format == IMGFMT_YV12) {
-		int y;
-		unsigned char *s, *s1;
-		unsigned char *d, *d1;
-
-		x0 += d_pos_x;
-		y0 += d_pos_y;
-
-		if ((x0 + w) > avc_picture.linesize[0]) {
-			w = avc_picture.linesize[0] - x0;
-		}
-		if ((y0 + h) > s_height) {
-			h = s_height - y0;
-		}
-
-		s = srcimg[0] + s_pos_x + s_pos_y * stride[0];
-		d = avc_picture.data[0] + x0 + y0 * avc_picture.linesize[0];
-		for(y = 0; y < h; y++) {
-			memcpy(d, s, w);
-			s += stride[0];
-			d += avc_picture.linesize[0];
-		}
-
-		w /= 2;
-		h /= 2;
-		x0 /= 2;
-		y0 /= 2;
-	
-		s = srcimg[1] + s_pos_x + (s_pos_y * stride[1]);
-		d = avc_picture.data[1] + x0 + (y0 * avc_picture.linesize[1]);
-		s1 = srcimg[2] + s_pos_x + (s_pos_y * stride[2]);
-		d1 = avc_picture.data[2] + x0 + (y0 * avc_picture.linesize[2]);
-		for(y = 0; y < h; y++) {
-			memcpy(d, s, w);
-			memcpy(d1, s1, w);
-			s += stride[1];
-			s1 += stride[2];
-			d += avc_picture.linesize[1];
-			d1 += avc_picture.linesize[2];
-		}
+		sws->swScale(sws, srcimg, stride, y0, h, avc_picture.data, avc_picture.linesize);
 		return 0;
 	}
 #endif
@@ -400,6 +367,9 @@
 static void uninit(void)
 {
 	printf("VO: [dxr3] Uninitializing\n");
+	if (sws) {
+		freeSwsContext(sws);
+	}
 #ifdef USE_LIBAVCODEC
 	if (avc_context) {
 		avcodec_close(avc_context);


More information about the MPlayer-dev-eng mailing list