[MPlayer-dev-eng] RE: compiling vo_v4lw module, please help !!!!
Scott Franzyshen
sfranzyshen at hotmail.com
Thu Apr 27 18:50:02 CEST 2006
>>Author: Raul Lucientes
>>Date: 2004-09-21 02:41 -600
>>To: mplayer-dev-eng
>>Subject: [MPlayer-dev-eng] compiling vo_v4lw module, please help !!!!
>>Hi,
>>
>>Im triyng to compile the mplayer (MPlayer-1.0pre5) with support for
>>"vloopback" (patch vo_v4l-patch-04-09-2002.p1), I have followed the
>>Tilmann´s procedure:
>>
>>http://www1.mplayerhq.hu/pipermail/mplayer-dev-eng/2001-November/002591.html
>>
>>But, when the compiling process arrive to the "vo_v4lw.c" module this
>>error
>>happens :-(
>>
OK! I know this hasn't been in the news lately, but I was think how useful
this would be to have
around. So I hacked it up to work for now, but I would like to work this
back into main stream development. Any help would be greatly appreciated. I
do not know most of the mplayer internal
stuff. Anyway, here is the patch (below) against MPlayer-1.0pre7try2 (for
now ... I am working on
bringing it up to cvs)
Just a reminder to you all about this back in 2001 Tilmann Bitterberg
created this patch;
>>Author: Tilmann Bitterberg
>>Date: 2001-11-27 09:49 -700
>>To: mplayer-dev-eng
>>Subject: [MPlayer-dev-eng] New vo_v4lw video output module
>>Hi,
>>
>>I hacked together a new libvo module called vo_v4lw.c. It
>>provides write support for the video4linux api. This means that
>>mplayer can act as a video4linux device providing (uncompressed)
>>YUV/RGB data to other v4l applications like xawtv, mp1e etc.
So why do I think this would be handy? Well I was thinking about directfb
and how nice it
would be to use the output of mplayer as a videoprovider within a directfb
application. However,
the "-vo directfb" is limited to only outputting fullscreen to the directfb
screen. This doesn't
allow any directfb api interaction. (No overlay, alpha channel, etc.) So, If
I was able to use directfb's
videodev(v4l) videoprovider, I could use an mplayer's ( or mplayers' )
output(s) within a direcfb application rendered to any directfb surface.(not
just the whole screen)
I got this to work using the following setup;
MPlayer-1.0pre7try2 - Might work against CVS (haven't tried yet)
This Patch
vloopback-0.91
linux-2.4.27 - debian sarge source
- I patched MPlayer with this patch
- I built vloopback kernel module and insmod it
(if you don't have a real v4l device don't forget to modprobe videodev
first)
- I then built MPlayer with --enable-v4lw
- Then I start player outputting to v4l;
mplayer -vo v4lw -vf scale=640:480 The.Simpsons.avi
- The I start another instance of MPlayer playing the v4l stream;
mplayer -tv device=/dev/video1:driver=v4l:width=640:height=480 -vo
directfb tv://
- This works for me, however this patch needs to be cleaned up and brought
up to 2006
development standards.
also there seems to be a problem with the current directfb cvs version of
the v4l videoprovider.
It isn't working. I should be able to do something like dfbsee /dev/video1
to watch the v4l stream
... but it don't work :(
Besides directfb. There are tons of applications out there that use the v4l
standard ...
This would also add a level of virtualization to real hardware devices.
Thanks
sfranzyshen
==================== PATCH ====================================
diff -uraN MPlayer-1.0pre7try2/configure MPlayer-1.0pre7try2-v4lw/configure
--- MPlayer-1.0pre7try2/configure 2005-04-13 05:46:35.000000000 -0600
+++ MPlayer-1.0pre7try2-v4lw/configure 2006-04-26 13:54:47.000000000 -0600
@@ -249,6 +249,7 @@
(check for /dev/mga_vid) [autodetect]
--enable-xmga build with mga_vid X Window support
(check for X & /dev/mga_vid) [autodetect]
+ --enable-v4lw build with video4linux write support [autodetect]
--enable-xv build with Xv render support for X 4.x
[autodetect]
--enable-xvmc build with XvMC acceleration for X 4.x [disable]
--enable-vm build with XF86VidMode support for X11
[autodetect]
@@ -1343,6 +1344,7 @@
_real=auto
_live=auto
_xinerama=auto
+_v4lw=auto
_mga=auto
_xmga=auto
_vm=auto
@@ -1550,6 +1552,8 @@
--disable-live) _live=no ;;
--enable-xinerama) _xinerama=yes ;;
--disable-xinerama) _xinerama=no ;;
+ --enable-v4lw) _v4lw=yes ;;
+ --disable-v4lw) _v4lw=no ;;
--enable-mga) _mga=yes ;;
--disable-mga) _mga=no ;;
--enable-xmga) _xmga=yes ;;
@@ -3704,6 +3708,19 @@
fi
echores "$_gl"
+echocheck "/proc/video/vloopback"
+if test "$_v4lw" = auto ; then
+ _v4lw=no
+ test -d /proc/video/vloopback && _v4lw=yes
+fi
+if test "$_v4lw" = yes ; then
+ _def_v4lw='#define HAVE_V4LW 1'
+ _vosrc="$_vosrc vo_v4lw.c"
+ _vomodules="v4lw $_vomodules"
+else
+ _def_v4lw='#undef HAVE_V4LW'
+fi
+echores "$_v4lw"
echocheck "/dev/mga_vid"
if test "$_mga" = auto ; then
@@ -7466,6 +7483,7 @@
$_def_directx
$_def_ggi
$_def_3dfx
+$_def_v4lw
$_def_tdfxfb
$_def_tdfxvid
$_def_directfb
diff -uraN MPlayer-1.0pre7try2/libvo/video_out.c
MPlayer-1.0pre7try2-v4lw/libvo/video_out.c
--- MPlayer-1.0pre7try2/libvo/video_out.c 2004-12-21 13:33:51.000000000
-0700
+++ MPlayer-1.0pre7try2-v4lw/libvo/video_out.c 2006-04-26 13:58:19.000000000
-0600
@@ -80,6 +80,7 @@
extern vo_functions_t video_out_syncfb;
extern vo_functions_t video_out_fbdev;
extern vo_functions_t video_out_fbdev2;
+extern vo_functions_t video_out_v4lw;
extern vo_functions_t video_out_svga;
extern vo_functions_t video_out_png;
extern vo_functions_t video_out_ggi;
@@ -192,6 +193,9 @@
#ifdef HAVE_AA
&video_out_aa,
#endif
+#ifdef HAVE_V4LW
+ &video_out_v4lw,
+#endif
#ifdef HAVE_CACA
&video_out_caca,
#endif
diff -uraN MPlayer-1.0pre7try2/libvo/vo_v4lw.c
MPlayer-1.0pre7try2-v4lw/libvo/vo_v4lw.c
--- MPlayer-1.0pre7try2/libvo/vo_v4lw.c 1969-12-31 17:00:00.000000000 -0700
+++ MPlayer-1.0pre7try2-v4lw/libvo/vo_v4lw.c 2006-04-26 16:02:56.000000000
-0600
@@ -0,0 +1,423 @@
+/*
+ * vo_v4lw.c
+ *
+ * Copyright (C) Tilmann Bitterberg - Nov 2001
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Updated 4/27/2006 - sfranzyshen <sfranzyshen at hotmail.com>
+ * compiled against MPlayer-1.0pre7try2
+ */
+
+/*
+ Quick v4lw loopback howto:
+
+ - get the vloopback kernel module from
+ <http://motion.technolust.cx/vloopback/index.html>
+ or (alternative) my hacked version from
+ <http://tibit.org/video/vloopback-0.90-tibit.tar.gz>
+
+ - if using my version, you don't need to specify dev_offset.
+
+ - untar and compile it
+ tar xzf vloopback-VERSION.tar.gz && cd vloopback-VERSION
+ make
+
+ - load the vloopback module
+ insmod vloopback.o dev_offset=2 pipes=1
+
+ - Make the devices accessible
+ chmod og+rw /dev/v4l/video2
+ chmod og+rw /dev/v4l/video3
+
+ - eventually you have to recompile mplayer to let
+ it see that it can talk v4l.
+ ./configure --enable-v4lw
+ to be sure
+
+ - start mplayer
+ mplayer -vo v4lw movie.avi
+
+ - start xawtv
+ xawtv -c /dev/v4l/video3 -geometry 800x600
+
+ - done
+ easy, isn't it.
+
+ NOTES:
+ - avicap doesn't work yet.
+ I got mp1e to work with a my hacked vloopback.o,
+ you need to specify the exact size.
+ - no scaling of video output is possible right now.
+ - be sure to insmod vloopback with a dev_offset appropriate
+ for your system. If you have a real grabber card (eg. a bttv
+ which is at /dev/v4l/video0) you _HAVE_ to use at least a
+ dev_offset=1 or you'll crash your kernel.
+ - I am on devfs, if you're not you have to use /dev/video2
+ instead of /dev/v4l/video2 and may have to create the
+ devices manually.
+ Eg. for video2: mknod c 81 2 /dev/video2
+ - mplayer will tell you the v4lw output device from which you
+ have to read.
+
+ Performance:
+ System: 2 * 1GHz Intel PIII (Coppermine) #SMP
+ MPEG1 at 768x576
+ mplayer CPU Usage ca. 35%, xawtv 11%
+ Divx at 512x384
+ mplayer CPU Usage ca. 20%, xawtv 10%
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <linux/videodev.h>
+
+#include "config.h"
+#include "video_out.h"
+#include "video_out_internal.h"
+
+#include "fastmemcpy.h"
+#include "sub.h"
+#include "aspect.h"
+#include "mp_msg.h"
+
+static uint32_t image_width, image_height;
+static int devout;
+static uint8_t *image;
+static unsigned int image_format=0;
+static int bpp = 24;
+static int fmt;
+
+static vo_info_t info =
+{
+ "video4linux write output",
+ "v4lw",
+ "Tilmann Bitterberg <god at tibit.org>",
+ "update 4/27/06 sfanzyshen <sfranzyshen at hotmail.com>"
+};
+
+LIBVO_EXTERN(v4lw)
+
+/* stolen from:
+ * vloopback/example/dummy.c
+ * returns 0 on successfull opening, !0 otherwise
+ */
+int check_vidpipe(void)
+{
+ FILE *vloopbacks;
+ char pipepath[255];
+ char buffer[255];
+ char *loop; /* internal loop nr */
+ char *input; /* our output dev */
+ char *istatus;
+ char *output; /* user should read from */
+ char *ostatus;
+
+ vloopbacks=fopen("/proc/video/vloopback/vloopbacks", "r");
+ if (!vloopbacks) {
+ perror ("V4lW: Failed to open '/proc/video/vloopback/vloopbacks'");
+ printf ("V4lW: You need to load the vlooback kernel module\n");
+ return -1;
+ }
+ /* Read vloopback version */
+ fgets(buffer, 255, vloopbacks);
+ /* Read explaination line */
+ fgets(buffer, 255, vloopbacks);
+ while (fgets(buffer, 255, vloopbacks)) {
+ if (strlen(buffer)>1) {
+ buffer[strlen(buffer)-1]=0;
+ loop = strtok(buffer, "\t");
+ input = strtok(NULL, "\t");
+ istatus = strtok(NULL, "\t");
+ output = strtok(NULL, "\t");
+ ostatus = strtok(NULL, "\t");
+ if (istatus[0] == '-') {
+ sprintf(pipepath, "/dev/%s", input);
+ devout = open (pipepath, O_RDWR);
+ if (devout >= 0) {
+ printf("V4lW: I am writing to: /dev/%s\n", input);
+ printf("V4lW: You should read from: /dev/%s\n", output);
+ /* Ok, found one */
+ return 0;
+ } else {
+ printf ("V4lW: Error opening /dev/%s\n", input);
+ perror ("V4lW: Failed to open output video device");
+ /* scan ahead */
+ }
+ }
+ }
+ }
+ printf("V4lW: Unable to find a available vloopback device\n");
+ printf("V4lW: Maybe insmod with a greater pipes= value helps\n");
+ return -1;
+}
+/* copied from
+ * vloopback-0.90/example/invert.c
+ */
+
+int start_pipe (int dev, int width, int height)
+{
+ struct video_capability vid_caps;
+ struct video_window vid_win;
+ struct video_picture vid_pic;
+
+ if (ioctl (dev, VIDIOCGCAP, &vid_caps) == -1) {
+ perror ("ioctl (VIDIOCGCAP)");
+ return (1);
+ }
+ if (ioctl (dev, VIDIOCGPICT, &vid_pic)== -1) {
+ perror ("ioctl VIDIOCGPICT");
+ return (1);
+ }
+ /* this is probably brain dead */
+ /* vid_pic.palette=VIDEO_PALETTE_RGB24; */
+ /* vid_pic.palette=VIDEO_PALETTE_YUV420P; */
+ vid_pic.palette = fmt;
+
+ if (ioctl (dev, VIDIOCSPICT, &vid_pic)== -1) {
+ perror ("ioctl VIDIOCSPICT");
+ return (1);
+ }
+ if (ioctl (dev, VIDIOCGWIN, &vid_win)== -1) {
+ perror ("ioctl VIDIOCGWIN");
+ return (1);
+ }
+ vid_win.width = width;
+ vid_win.height = height;
+ if (ioctl (dev, VIDIOCSWIN, &vid_win)== -1) {
+ perror ("ioctl VIDIOCSWIN");
+ return (1);
+ }
+ return 0;
+}
+
+/* stolen from
+ vo_odivx.c
+ */
+/* orig size -- working */
+static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int
x,int y)
+{
+ uint8_t *s;
+ uint8_t *d;
+ int i;
+ int dstride=image_width;
+ int size = image_width*image_height;
+
+ // copy Y
+ d=image+dstride*y+x;
+ s=src[0];
+ for(i=0;i<h;i++){
+ memcpy(d,s,w);
+ s+=stride[0];
+ d+=dstride;
+ }
+
+ w/=2;h/=2;x/=2;y/=2; dstride/=2;
+
+ // copy U
+ d=image + size + dstride*y+x;
+ s=src[1];
+ for(i=0;i<h;i++){
+ memcpy(d,s,w);
+ s+=stride[1];
+ d+=dstride;
+ }
+
+ // copy V
+ d=image + size + size/4 + dstride*y+x;
+ s=src[2];
+ for(i=0;i<h;i++){
+ memcpy(d,s,w);
+ s+=stride[2];
+ d+=dstride;
+ }
+
+ return 0;
+}
+/*
+ printf("%d, %d, %d, %d, %d, %d, %d\n", stride[0], stride[1], stride[2],
w, h, x, y);
+ 720, 360, 360, 720, 16, 0, 0
+ 720, 360, 360, 720, 16, 0, 16
+ ...
+ 720, 360, 360, 720, 16, 0, 544
+ 720, 360, 360, 720, 16, 0, 560
+*/
+#if 0
+/* Half size */
+static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int
x,int y)
+{
+ uint8_t *s;
+ uint8_t *d;
+ int i;
+ int j;
+ int dstride = image_width;
+ int size = image_width*image_height;
+
+ stride[0]<<=1;
+ stride[1]<<=1;
+ stride[2]<<=1;
+
+ // copy Y
+ d=image+dstride/2*y+x;
+ s=src[0];
+ for(i=0;i<h;i+=2){
+ for (j=0; j<w; j+=2)
+ d[j>>1]=s[j];
+ s+=stride[0];
+ d+=dstride;
+ }
+
+ w/=2;h/=2;x/=2;y/=2; dstride/=2;
+
+ // copy U
+ d=image + size + dstride/2*y+x;
+ s=src[1];
+ for(i=0;i<h;i+=2){
+ for (j=0; j<w; j+=2)
+ d[j>>1]=s[j];
+ s+=stride[1];
+ d+=dstride;
+ }
+
+ // copy V
+ d=image + size + size/4 + dstride/2*y+x;
+ s=src[2];
+ for(i=0;i<h;i+=2){
+ for (j=0; j<w; j+=2)
+ d[j>>1]=s[j];
+ s+=stride[2];
+ d+=dstride;
+ }
+
+ return 0;
+}
+#endif
+static void draw_osd(void)
+{
+}
+
+static void put_image(void)
+{
+ int size = image_width*image_height*3;
+ if (write(devout, image, size) != size) {
+ perror("V4lW: Error writing image to pipe!");
+ }
+}
+
+static void flip_page(void)
+{
+ put_image();
+}
+
+static uint32_t draw_frame(uint8_t *src[])
+{
+ /* untested */
+ memcpy (image, src, image_width * image_height * 3);
+ return 0;
+}
+
+static uint32_t query_format(uint32_t format)
+{
+ switch(format){
+ case IMGFMT_YV12:
+ case IMGFMT_I420:
+ case IMGFMT_YUY2:
+ case IMGFMT_RGB24:
+ case IMGFMT_BGR24:
+ return 1;
+ }
+ return 0;
+}
+
+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)
+{
+
+ image_width = width;
+ image_height = height;
+ image_format = format;
+
+ switch (image_format) {
+ case IMGFMT_YV12:
+ case IMGFMT_I420:
+ fmt = VIDEO_PALETTE_YUV420P;
+ break;
+ case IMGFMT_RGB24:
+ case IMGFMT_BGR24:
+ fmt = VIDEO_PALETTE_RGB24;
+ break;
+ }
+
+ if (check_vidpipe() != 0) {
+ return 1;
+ }
+
+
+ if (start_pipe(devout, width, height) != 0) {
+ return 1;
+ }
+
+ /* printf("V4lW: width: %d; height: %d; format: %d\n", width, height,
format); */
+
+ image = (uint8_t *) malloc(width*height*3);
+
+ if (!image) {
+ close (devout);
+ return 1;
+ }
+ /* clear the buffer, grey */
+ memset(image,0x80,width*height*3);
+
+ return 0;
+}
+
+static const vo_info_t*
+get_info(void)
+{
+ return &info;
+}
+
+static void
+uninit(void)
+{
+ if (image)
+ free(image);
+ close (devout);
+}
+
+
+static void check_events(void)
+{
+}
+static uint32_t preinit(const char *arg)
+{
+ return 0;
+}
+
+static uint32_t control(uint32_t request, void *data, ...)
+{
+ switch (request) {
+ case VOCTRL_QUERY_FORMAT:
+ return query_format(*((uint32_t*)data));
+ }
+ return VO_NOTIMPL;
+}
+
==================== PATCH ====================================
More information about the MPlayer-dev-eng
mailing list