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>
