Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Oct 2002 07:51:34 +0200 (MEST)
From:      Peter B <pb@ludd.luth.se>
To:        freebsd-multimedia@freebsd.org
Subject:   mplayer patch for brooktree realtime grabbing
Message-ID:  <200210020551.g925pYa23137@brother.ludd.luth.se>

next in thread | raw e-mail | index | archive | help

I posted earlier about using mencoder from the mplayer package with brooktree 
cards. It turned out to be hard to get it working. However I have now modified
mplayer source to accomplish this. Any suggestions on using it?

This patch should be considered "hack" in the current state, but it works! :-)
Cleanup later..

The '-tv on .. :amode=0' option seems to not be honored.

    /Peter


To patch against MPlayer-0.90pre8/libmpdemux/tvi_bsdbt848.c

*** libmpdemux/tvi_bsdbt848.c	Sun Apr 28 19:29:48 2002
--- libmpdemux/tvi_bsdbt848.c	Wed Oct  2 04:52:36 2002
***************
*** 56,61 ****
--- 56,62 ----
  #endif
  #endif
  
+ //#include "../vidix/fourcc.h"		/* XXX */
  #include "../libvo/img_format.h"
  #include "tv.h"
  
***************
*** 73,78 ****
--- 74,80 ----
      char *buf;
  } RBFRAME;
  
+ /*--------------------------------------------------------------------------*/
  /* private data's */
  typedef struct {
  
***************
*** 89,109 ****
      long long dspbytesread;
  
  /* Video */
!     char *btdev;
      int videoready;
!     int btfd;
!     int source;
!     int maxfps;
!     int fps;
!     int iformat;
!     int maxheight;
!     int maxwidth;
!     struct meteor_geomet geom;
!     struct meteor_capframe capframe;
  
  /* Frame Buffer */
  
!     int framebufsize;
      float timestamp;
      int curpaintframe;
      int curbufframe;
--- 91,112 ----
      long long dspbytesread;
  
  /* Video */
!     char *btdev;		/* device /dev/bktr0 */
      int videoready;
!     int btfd;			/* bt file descriptor */
!     int source;			/* meteor_input_ input rca/tuner/rgb/svid etc*/
!     int maxfps;			/* Max fps     */
!     int fps;			/* Current fps */
!     int iformat;		/* Pal/Ntsc/Secam */
!     int	outfmt;			/* imgfmt_uyvy etc.. */
!     int maxheight;		/* Current mode max-Y */
!     int maxwidth;		/* Current mode max-X */
!     struct meteor_geomet geom;		/* row/col/fram/ofmt */
!     struct meteor_capframe capframe;	/* cmd/lo/hi-wat */
  
  /* Frame Buffer */
  
!     int framebufsize;			/* Size of area for video data */
      float timestamp;
      int curpaintframe;
      int curbufframe;
***************
*** 129,140 ****
--- 132,235 ----
  
  } priv_t;
  
+ /*--------------------------------------------------------------------------*/
  #include "tvi_def.h"
  
  static priv_t *G_private=NULL;
  
  static int getinput(int innumber);
  
+ /*--------------------------------------------------------------------------*/
+ /* Mplayer outfmt vidix/fourcc.h to bt848/meteor format */
+ /* outfmt - imgfmt_xxxx
+    type   - 0=ofmt
+             1=bytesiz
+ */
+ static int outfmt2attr(int outfmt,int type)
+ {
+ int	ofmt,bytesiz;
+ 
+ /*
+         printf("outfmt2attr(%c-%c-%c-%c,%d)\n",
+           (unsigned char)((((unsigned)outfmt)&0xFF)>>0),
+           (unsigned char)((((unsigned)outfmt)&0xFF00)>>8),
+           (unsigned char)((((unsigned)outfmt)&0xFF0000)>>16),
+           (unsigned char)((((unsigned)outfmt)&0xFF000000)>>24),
+           type);
+ 
+         printf("outfmt2attr(), outfmt=%d-%d-%d-%d\n",
+           (unsigned char)((((unsigned)outfmt)&0xFF)>>0),
+           (unsigned char)((((unsigned)outfmt)&0xFF00)>>8),
+           (unsigned char)((((unsigned)outfmt)&0xFF0000)>>16),
+           (unsigned char)((((unsigned)outfmt)&0xFF000000)>>24),
+           0);
+ */
+ /* vidix/fourcc.h */
+ /* libmpcodecs/img_format.h /usr/include/machine/ioctl_meteor.h */
+ switch(  outfmt  )
+   {
+ /* fbsd4 man meteor
+   METEOR_GEO_RGB16       RGB 16 bits xrrrrrgg gggbbbbb default 1-5-5-5
+   
+   METEOR_GEO_RGB24       RGB 24 bits packed in 32 bits:
+                           00000000 rrrrrrrr gggggggg bbbbbbbb  8-8-8-8
+ 
+   METEOR_GEO_YUV_PACKED  4-2-2 YUV 16 bits packed byte format:
+                           u0 y0 v0 y1 u1 y2 v1 y3 ...
+   METEOR_GEO_YUV_PLANER  4-2-2 YUV 16 bits planer format:
+   			  rows * columns bytes of y rows *
+   			  column / 4 bytes of even u rows *
+   			  column / 4 bytes of even v rows *
+   			  column / 4 bytes of odd  u rows *
+   			  column / 4 bytes of odd  v
+ MPlayer-0.90pre8
+ outfmt	fourcc
+ yv12    YV12
+ rgb32   .BGR
+ rgb24   wBGR
+ rgb16   oBGR
+ rgb15   .BGR
+ uyvy    UYVY
+ yuy2    YUY2
+ i420    I420
+ */  	
+   case IMGFMT_RGB15:    ofmt=METEOR_GEO_RGB16;     bytesiz=IMGFMT_RGB_DEPTH(outfmt)/8;  break;
+   case IMGFMT_BGR15:    ofmt=METEOR_GEO_RGB16;     bytesiz=IMGFMT_RGB_DEPTH(outfmt)/8;  break;
+   case IMGFMT_RGB16:    ofmt=METEOR_GEO_RGB16;     bytesiz=IMGFMT_RGB_DEPTH(outfmt)/8;  break;
+   case IMGFMT_BGR16:    ofmt=METEOR_GEO_RGB16;     bytesiz=IMGFMT_BGR_DEPTH(outfmt)/8;  break;
+   
+   case IMGFMT_RGB24:    ofmt=METEOR_GEO_RGB24;     bytesiz=IMGFMT_RGB_DEPTH(outfmt)/8;  break;  /* ok? */
+   case IMGFMT_BGR24:    ofmt=METEOR_GEO_RGB24;     bytesiz=IMGFMT_BGR_DEPTH(outfmt)/8;  break;
+   case IMGFMT_RGB32:    ofmt=METEOR_GEO_RGB24;     bytesiz=IMGFMT_RGB_DEPTH(outfmt)/8;  break;  /* ok? */
+   case IMGFMT_BGR32:    ofmt=METEOR_GEO_RGB24;     bytesiz=IMGFMT_BGR_DEPTH(outfmt)/8;  break; // OK-upsidedown
+   
+ /*
+ METEOR_GEO_YUV_PACKED   4-2-2 YUV 16 bits packed
+ METEOR_GEO_YUV_PLANAR   4-2-2 YUV 16 bits planer
+ */
+   case IMGFMT_V655:  ofmt=METEOR_GEO_YUV_PACKED;  bytesiz=16/8; break;
+   case IMGFMT_I420:  ofmt=METEOR_GEO_YUV_PLANAR;  bytesiz=32/8; break;
+   //case IMGFMT_BGR15: ofmt=METEOR_GEO_UNSIGNED;    bytesiz=32/8; break; // OK-upsidedown
+   case IMGFMT_UYVY:  ofmt=METEOR_GEO_YUV_422;     bytesiz=16/8; break;
+   
+   case IMGFMT_YV12:  ofmt=METEOR_GEO_YUV_12;      bytesiz=12/8;  break;  /* ok? */
+   case IMGFMT_YVU9:  ofmt=METEOR_GEO_YUV_9;       bytesiz=9/8;   break;  /* ok? */
+ 
+ //  default:  fprintf(stderr,"outfmt2attr() err outfmt\n"); exit(-1);
+   }
+ 
+ /* XXX */
+ //ofmt=METEOR_GEO_YUV_PACKED;
+ //bytesiz=4;
+   
+ switch(type)
+   {
+   case 0: return ofmt;
+   case 1: return bytesiz;
+   }
+ }
+ 
+ /*--------------------------------------------------------------------------*/
  static void processframe(int signal)
  {
  struct timeval curtime;
***************
*** 161,172 ****
--- 256,269 ----
  return;
  }
  
+ /*--------------------------------------------------------------------------*/
  /* handler creator - entry point ! */
  tvi_handle_t *tvi_init_bsdbt848(char *device)
  {
      return(new_handle());
  }
  
+ /*--------------------------------------------------------------------------*/
  static int control(priv_t *priv, int cmd, void *arg)
  {
      switch(cmd)
***************
*** 297,303 ****
              priv->maxheight = PAL_HEIGHT;
              priv->maxwidth = PAL_WIDTH;
              priv->maxfps = PAL_FPS;
!             priv->fps = PAL_FPS;
  
              if(priv->fps > priv->maxfps) priv->fps = priv->maxfps;
  
--- 394,400 ----
              priv->maxheight = PAL_HEIGHT;
              priv->maxwidth = PAL_WIDTH;
              priv->maxfps = PAL_FPS;
! //            priv->fps = PAL_FPS;
  
              if(priv->fps > priv->maxfps) priv->fps = priv->maxfps;
  
***************
*** 318,324 ****
              priv->maxheight = NTSC_HEIGHT;
              priv->maxwidth = NTSC_WIDTH;
              priv->maxfps = NTSC_FPS;
!             priv->fps = NTSC_FPS;
  
              priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/
                                   priv->fps * (priv->dspstereo+1);
--- 415,421 ----
              priv->maxheight = NTSC_HEIGHT;
              priv->maxwidth = NTSC_WIDTH;
              priv->maxfps = NTSC_FPS;
! //            priv->fps = NTSC_FPS;
  
              priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/
                                   priv->fps * (priv->dspstereo+1);
***************
*** 362,376 ****
          }
      
      case TVI_CONTROL_VID_GET_FORMAT:
          (int)*(void **)arg = IMGFMT_UYVY;
          return(TVI_CONTROL_TRUE);
  
      case TVI_CONTROL_VID_SET_FORMAT:
          {
          int req_fmt = (int)*(void **)arg;
  
!         if(req_fmt != IMGFMT_UYVY) return(TVI_CONTROL_FALSE);
! 
          return(TVI_CONTROL_TRUE);
          }
      case TVI_CONTROL_VID_SET_WIDTH:
--- 459,496 ----
          }
      
      case TVI_CONTROL_VID_GET_FORMAT:
+ // CHANGED
+ printf("TVI_CONTROL_VID_GET_FORMAT\n");fflush(stdout);
          (int)*(void **)arg = IMGFMT_UYVY;
+         (int)*(void **)arg = IMGFMT_YV12; /* vidix/fourcc.h */
+         (int)*(void **)arg = IMGFMT_RGB32;
+         
+         (int)*(void **)arg = priv->outfmt;
          return(TVI_CONTROL_TRUE);
  
      case TVI_CONTROL_VID_SET_FORMAT:
          {
          int req_fmt = (int)*(void **)arg;
  
! printf("TVI_CONTROL_VID_SET_FORMAT\n");fflush(stdout);
! // CHANGED
!         //if(req_fmt != IMGFMT_UYVY)
!         //  return(TVI_CONTROL_FALSE);
! 
!         printf("fmt = %c-%c-%c-%c\n",
!           (unsigned char)((((unsigned)req_fmt)&0xFF)>>0),
!           (unsigned char)((((unsigned)req_fmt)&0xFF00)>>8),
!           (unsigned char)((((unsigned)req_fmt)&0xFF0000)>>16),
!           (unsigned char)((((unsigned)req_fmt)&0xFF000000)>>24),
!           0);
!         printf("fmt = %c%c%c%c\n",
!           (unsigned char)((((unsigned)req_fmt)&0xFF)>>0),
!           (unsigned char)((((unsigned)req_fmt)&0xFF00)>>8),
!           (unsigned char)((((unsigned)req_fmt)&0xFF0000)>>16),
!           (unsigned char)((((unsigned)req_fmt)&0xFF000000)>>24),
!           0);
! /*        priv->outfmt = req_fmt;*/
!         
          return(TVI_CONTROL_TRUE);
          }
      case TVI_CONTROL_VID_SET_WIDTH:
***************
*** 449,482 ****
      return(TVI_CONTROL_UNKNOWN);
  }
  
  static int init(priv_t *priv)
  {
! int marg;
! int count;
  
  G_private = priv; /* Oooh, sick */
  
  /* Video Configuration */
  
! priv->videoready = TRUE;
! priv->btdev = strdup("/dev/bktr0");
  priv->immediatemode = FALSE;
! priv->iformat = METEOR_FMT_PAL;
! priv->maxheight = PAL_HEIGHT;
! priv->maxwidth = PAL_WIDTH;
! priv->maxfps = PAL_FPS;
! priv->source = METEOR_INPUT_DEV0;
! priv->fps = priv->maxfps;
! 
! priv->starttime=0;
! priv->curpaintframe=0;
! priv->curbufframe=0;
! 
! priv->geom.columns = priv->maxwidth;
! priv->geom.rows = priv->maxheight;
! priv->geom.frames = 1;
! priv->geom.oformat = METEOR_GEO_YUV_PACKED;
  
  priv->btfd = open(priv->btdev, O_RDONLY);
  
  if(priv->btfd < 0)
--- 569,631 ----
      return(TVI_CONTROL_UNKNOWN);
  }
  
+ /*--------------------------------------------------------------------------*/
  static int init(priv_t *priv)
  {
! int	marg;
! int	count;
  
  G_private = priv; /* Oooh, sick */
  
  /* Video Configuration */
  
! priv->videoready    = TRUE;
! priv->btdev         = strdup("/dev/bktr0");
  priv->immediatemode = FALSE;
! priv->iformat       = METEOR_FMT_PAL;
! priv->outfmt	    = IMGFMT_UYVY;		/* outfmt at start */
! 
! //priv->outfmt	    = IMGFMT_RGB32;	// R/B swap
! //priv->outfmt	    = IMGFMT_RGB16;	// no codec
! //priv->outfmt	    = IMGFMT_RGB15;	// no codec
! 
! priv->outfmt	    = IMGFMT_BGR32;	// upsidedown-OK
! //priv->outfmt	    = IMGFMT_BGR16;	// snowy
! //priv->outfmt	    = IMGFMT_BGR15;	// upsidedown-OK
! 
! //priv->outfmt	    = IMGFMT_V655;	// no codec
! //priv->outfmt	    = IMGFMT_YV12;	// green snow
! //priv->outfmt	    = IMGFMT_YVU9;	// green snow
! 
! //priv->outfmt	    = IMGFMT_I420;	// segv
! //priv->outfmt	    = IMGFMT_YUY2;	// green-correct pic
! //priv->outfmt	    = IMGFMT_IYUV;
! //priv->outfmt	    = IMGFMT_422P;	// no codec
! //priv->outfmt	    = IMGFMT_IF09;	// no codec
! 
! 
! priv->maxheight     = PAL_HEIGHT;
! priv->maxwidth      = PAL_WIDTH;
! priv->maxfps        = PAL_FPS;
! priv->source        = METEOR_INPUT_DEV0;
! // CHANGED
! priv->fps           = priv->maxfps;
! priv->fps           = 16;			/* ! */
! 
! priv->starttime	    = 0;
! priv->curpaintframe = 0;
! priv->curbufframe   = 0;
! 
! priv->geom.columns  = priv->maxwidth;
! priv->geom.rows     = priv->maxheight;
! priv->geom.frames   = 1;
! // CHANGED        m /usr/include/machine/ioctl_meteor.h
! priv->geom.oformat = METEOR_GEO_YUV_PACKED;  /* YVYU */
! priv->geom.oformat = METEOR_GEO_YUV_12;      /* YV12 */
  
+ priv->geom.oformat = outfmt2attr( priv->outfmt, 0 );
+ 
+ printf("Setup oformat\n");fflush(stdout);
  priv->btfd = open(priv->btdev, O_RDONLY);
  
  if(priv->btfd < 0)
***************
*** 511,518 ****
  
  if(priv->videoready == TRUE)
      {
!     priv->framebufsize = (priv->geom.columns * priv->geom.rows * 2);
! 
      priv->livebuf = (u_char *)mmap((caddr_t)0, priv->framebufsize, PROT_READ,
                                  MAP_SHARED, priv->btfd, (off_t)0);
  
--- 660,667 ----
  
  if(priv->videoready == TRUE)
      {
! // CHANGED
!     priv->framebufsize = (priv->geom.columns * priv->geom.rows * 2*2);
      priv->livebuf = (u_char *)mmap((caddr_t)0, priv->framebufsize, PROT_READ,
                                  MAP_SHARED, priv->btfd, (off_t)0);
  
***************
*** 592,597 ****
--- 741,747 ----
  return(1);
  }
  
+ /*--------------------------------------------------------------------------*/
  /* that's the real start, we'got the format parameters (checked with control) */
  static int start(priv_t *priv)
  {
***************
*** 630,635 ****
--- 780,786 ----
  return(1);
  }
  
+ /*--------------------------------------------------------------------------*/
  static int uninit(priv_t *priv)
  {
  int marg;
***************
*** 664,669 ****
--- 815,821 ----
  }
  
  
+ /*--------------------------------------------------------------------------*/
  static double grabimmediate_video_frame(priv_t *priv, char *buffer, int len)
  {
  struct timeval curtime;
***************
*** 687,692 ****
--- 839,871 ----
  return(0); 
  }
  
+ /*--------------------------------------------------------------------------*/
+ static inline void copy_frame(priv_t *priv, unsigned char *dest, unsigned char *source)
+ {
+ int		i;
+ unsigned char	*sptr;
+ int		bytesperline;
+ 
+ switch(  priv->outfmt  )
+   {
+   case IMGFMT_BGR32:
+         bytesperline = priv->geom.columns * outfmt2attr( priv->outfmt, 1 );
+         sptr = source + (priv->geom.rows-1)*bytesperline;
+         for(i = 0; i < priv->geom.rows; i++)
+             {
+             memcpy(dest, sptr, bytesperline);
+             dest += bytesperline;
+             sptr -= bytesperline;
+             }
+     break;
+     
+   default:
+     break;
+   }
+     	
+ }
+ 
+ /*--------------------------------------------------------------------------*/
  static double grab_video_frame(priv_t *priv, char *buffer, int len)
  {
  struct timeval curtime;
***************
*** 708,714 ****
      alarm(0);
      }
  
! memcpy(buffer, priv->framebuf[priv->curbufframe].buf, len);
  timestamp = priv->framebuf[priv->curbufframe].timestamp;
  priv->framebuf[priv->curbufframe].dirty = TRUE;
  
--- 887,896 ----
      alarm(0);
      }
  
! //memcpy(buffer, priv->framebuf[priv->curbufframe].buf, len);
! copy_frame(priv, buffer, priv->framebuf[priv->curbufframe].buf);
! 
! 
  timestamp = priv->framebuf[priv->curbufframe].timestamp;
  priv->framebuf[priv->curbufframe].dirty = TRUE;
  
***************
*** 718,728 ****
  return(timestamp-priv->starttime);
  }
  
  static int get_video_framesize(priv_t *priv)
  {
! return(priv->geom.columns*priv->geom.rows*16/8);
  }
  
  static double grab_audio_frame(priv_t *priv, char *buffer, int len)
  {
  struct timeval curtime;
--- 900,917 ----
  return(timestamp-priv->starttime);
  }
  
+ /*--------------------------------------------------------------------------*/
  static int get_video_framesize(priv_t *priv)
  {
! int	bytesiz;
! //printf("get_video_framesize()\n");fflush(stdout);
! 
! bytesiz = outfmt2attr( priv->outfmt, 1 );
! /*printf("bytesiz=%d\n",bytesiz);*/
! return( priv->geom.columns * priv->geom.rows * bytesiz );
  }
  
+ /*--------------------------------------------------------------------------*/
  static double grab_audio_frame(priv_t *priv, char *buffer, int len)
  {
  struct timeval curtime;
***************
*** 774,779 ****
--- 963,969 ----
  return(priv->dspbytesread * 1.0 / priv->dsprate);
  }
  
+ /*--------------------------------------------------------------------------*/
  static int get_audio_framesize(priv_t *priv)
  {
  int bytesavail;
***************
*** 794,799 ****
--- 984,990 ----
  return(bytesavail);
  }
  
+ /*--------------------------------------------------------------------------*/
  static int getinput(int innumber)
  {
  switch(innumber)
***************
*** 810,812 ****
--- 1001,1005 ----
  }
  
  #endif /* USE_TV */
+ /*--------------------------------------------------------------------------*/
+ 

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-multimedia" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200210020551.g925pYa23137>