[MPlayer-dev-eng] [PATCH 4/9] vo_fbdev2: Enable double buffering and direct rendering

Hans-Christian Egtvedt hans-christian.egtvedt at atmel.com
Mon Feb 16 17:16:53 CET 2009


Signed-off-by: Hans-Christian Egtvedt <hans-christian.egtvedt at atmel.com>
---
 libvo/vo_fbdev2.c |   99 +++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 89 insertions(+), 10 deletions(-)

diff --git a/libvo/vo_fbdev2.c b/libvo/vo_fbdev2.c
index a18e9f2..067e24f 100644
--- a/libvo/vo_fbdev2.c
+++ b/libvo/vo_fbdev2.c
@@ -37,6 +37,9 @@
 #include "sub.h"
 #include "mp_msg.h"
 
+/* Draw directly to framebuffer */
+#define USE_CONVERT2FB
+
 static const vo_info_t info = {
 	"Framebuffer Device",
 	"fbdev2",
@@ -193,6 +196,15 @@ static int fb_preinit(int reset)
 	}
 	fb_orig_vinfo = fb_vinfo;
 
+	/* Reset panning offset */
+	fb_vinfo.yoffset = 0;
+	if (ioctl(fb_dev_fd, FBIOPAN_DISPLAY, &fb_vinfo)) {
+		mp_msg(MSGT_VO, MSGL_ERR,
+		       "[fbdev2] FBIOPAN_DISPLAY failed: %s\n",
+		       strerror(errno));
+		return 0;
+	}
+
 	fb_bpp = fb_vinfo.bits_per_pixel;
 
 	/* 16 and 15 bpp is reported as 16 bpp */
@@ -304,6 +316,10 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
 		mp_msg(MSGT_VO, MSGL_ERR, "[fbdev2] Can't malloc next_frame: %s\n", strerror(errno));
 		return 1;
 	}
+#else
+	if ((fb_line_len * fb_vinfo.yres) <= (fb_finfo.smem_len / 2)
+	    && fb_vinfo.yoffset == 0)
+		center += fb_line_len * fb_vinfo.yres;
 #endif
 	if (fs) memset(frame_buffer, '\0', fb_line_len * fb_vinfo.yres);
 
@@ -318,10 +334,18 @@ static int query_format(uint32_t format)
 		int fb_target_bpp = format & 0xff;
 		set_bpp(&fb_vinfo, fb_target_bpp);
 		fb_vinfo.xres_virtual = fb_vinfo.xres;
-		fb_vinfo.yres_virtual = fb_vinfo.yres;
+		fb_vinfo.yres_virtual = fb_vinfo.yres * 2;
 		if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {
-			mp_msg(MSGT_VO, MSGL_ERR, "[fbdev2] Can't put VSCREENINFO: %s\n", strerror(errno));
-			return 0;
+			mp_msg(MSGT_VO, MSGL_WARN,
+			       "[fbdev2] Can't double virtual y resolution: %s\n",
+			       strerror(errno));
+			fb_vinfo.yres_virtual = fb_vinfo.yres;
+			if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {
+				mp_msg(MSGT_VO, MSGL_ERR,
+				       "[fbdev2] Can't put VSCREENINFO: %s\n",
+				       strerror(errno));
+				return -1;
+			}
 		}
 		fb_pixel_size = fb_vinfo.bits_per_pixel / 8;
 		fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length +
@@ -382,16 +406,67 @@ static void check_events(void)
 
 static void flip_page(void)
 {
-#ifndef USE_CONVERT2FB
 	int i, out_offset = 0, in_offset = 0;
 
-	for (i = 0; i < in_height; i++) {
-		fast_memcpy(center + out_offset, next_frame + in_offset,
-				in_width * fb_pixel_size);
-		out_offset += fb_line_len;
-		in_offset += in_width * fb_pixel_size;
-	}
+#ifndef USE_CONVERT2FB
+	if (1) {
+#else
+	if (fb_vinfo.yres_virtual == fb_vinfo.yres) {
 #endif
+		for (i = 0; i < in_height; i++) {
+			fast_memcpy(center + out_offset, next_frame + in_offset,
+			       in_width * fb_pixel_size);
+			out_offset += fb_line_len;
+			in_offset += in_width * fb_pixel_size;
+		}
+	} else {
+		if (fb_vinfo.yoffset == 0) {
+			fb_vinfo.yoffset += fb_vinfo.yres;
+			center -= fb_line_len * fb_vinfo.yres;
+		} else {
+			fb_vinfo.yoffset = 0;
+			center += fb_line_len * fb_vinfo.yres;
+		}
+
+		if (ioctl(fb_dev_fd, FBIOPAN_DISPLAY, &fb_vinfo)) {
+			mp_msg(MSGT_VO, MSGL_ERR,
+			       "[fbdev2] Can't FBIOPAN_DISPLAY: %s\n",
+			       strerror(errno));
+		}
+	}
+}
+
+static uint32_t get_image(mp_image_t *mpi)
+{
+	if(mpi->flags&MP_IMGFLAG_READABLE)
+		return VO_FALSE; // slow video ram
+	if(mpi->type==MP_IMGTYPE_STATIC)
+		return VO_FALSE; // it is not static
+
+	if (mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH)) {
+		// we're lucky or codec accepts stride => ok, let's go!
+
+		//YUY2 and RGB formats
+		mpi->planes[0] = center;
+		mpi->width = in_width;
+		mpi->stride[0] = fb_line_len;
+
+		// center image
+
+		mpi->flags |= MP_IMGFLAG_DIRECT;
+
+		return VO_TRUE;
+	}
+
+	return VO_FALSE;
+}
+
+static uint32_t put_image(mp_image_t *mpi)
+{
+	// already out?
+	if ((mpi->flags & (MP_IMGFLAG_DIRECT | MP_IMGFLAG_DRAW_CALLBACK)))
+		return VO_TRUE;
+	return VO_FALSE;
 }
 
 static void uninit(void)
@@ -418,6 +493,10 @@ static int control(uint32_t request, void *data, ...)
   switch (request) {
   case VOCTRL_QUERY_FORMAT:
     return query_format(*((uint32_t*)data));
+  case VOCTRL_GET_IMAGE:
+    return get_image(data);
+  case VOCTRL_DRAW_IMAGE:
+    return put_image(data);
   }
   return VO_NOTIMPL;
 }
-- 
1.5.6.3




More information about the MPlayer-dev-eng mailing list