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>