[MPlayer-dev-eng] [PATCH] DC10+ (and alike) TV-Out support (fwd)

Alex Beregszaszi alex at naxine.org
Fri Jan 18 15:41:42 CET 2002


Hi,

On Fri, Jan 18, 2002 at 03:21:09PM +0100, Rik Snel wrote:
> Hello,
> 
> On Fri, 18 Jan 2002, Alex Beregszaszi wrote:
> > Are these Zoran chips only supporting mjpeg? If not, have a look at
> > main/RTjpegN.c
> Unfortunately the zoran chips only do JPEG, RTjpeg doesn't produce jpeg
> compatible images according to it's homepage. (but if you know a
> fast jpeg-compressor that can produce YUV422 jpegs from (preferably
> YUV420P) data, I would like to know)

Hmm, i see:
RTjpeg is NOT jpeg! RTjpeg images can only be decompressed using RTjpeg!

I think becouse rtjpeg doesn't stores huffman tables only once.
(NuppelVideo).

Btw, didn't know any realtime jpeg compressor, except rtjpeg :)

--
alex 

> 
> Greetings,
> 
> Rik.
> 
> > 
> > --
> > alex
> > 
> > On Wed, Jan 16, 2002 at 05:25:04PM +0100, Rik Snel wrote:
> > > Sorry,
> > > 
> > > I forgot to attach the patch.... Here it is now.
> > > 
> > > Greetings,
> > > 
> > > Rik
> > > 
> > > --------
> > > Nothing is ever a total loss; it can always serve as a bad example.
> > 
> > > diff -Naur main/Makefile main.dev/Makefile
> > > --- main/Makefile	Wed Jan 16 09:08:21 2002
> > > +++ main.dev/Makefile	Wed Jan 16 09:15:11 2002
> > > @@ -41,7 +41,7 @@
> > >  VO_LIBS = -Llibvo -lvo
> > >  VO_INC = -Ilibvo
> > >  endif
> > > -V_LIBS = $(X_LIB) $(MP1E_LIB) $(GGI_LIB) $(MLIB_LIB) $(PNG_LIB) $(SDL_LIB) $(SVGA_LIB) $(AA_LIB) $(DIRECTFB_LIB)
> > > +V_LIBS = $(X_LIB) $(MP1E_LIB) $(GGI_LIB) $(MLIB_LIB) $(JPEG_LIB) $(PNG_LIB) $(SDL_LIB) $(SVGA_LIB) $(AA_LIB) $(DIRECTFB_LIB)
> > >  
> > >  AO_LIBS = -Llibao2 -lao2
> > >  A_LIBS = $(ALSA_LIB) $(NAS_LIB) $(MAD_LIB) $(VORBIS_LIB) $(SGIAUDIO_LIB)
> > > diff -Naur main/cfg-mplayer.h main.dev/cfg-mplayer.h
> > > --- main/cfg-mplayer.h	Wed Jan 16 09:08:29 2002
> > > +++ main.dev/cfg-mplayer.h	Wed Jan 16 09:55:43 2002
> > > @@ -65,6 +65,10 @@
> > >  extern int vo_aa_parseoption(struct config * conf, char *opt, char * param);
> > >  #endif
> > >  
> > > +#ifdef HAVE_ZR
> > > +extern int vo_zr_parseoption(struct config * conf, char *opt, char * param);
> > > +#endif
> > > +
> > >  #ifdef HAVE_NEW_GUI
> > >  extern char * skinName;
> > >  #endif
> > > @@ -237,6 +241,10 @@
> > >  
> > >  #ifdef HAVE_AA
> > >  	{"aa*",	vo_aa_parseoption,  CONF_TYPE_FUNC_FULL, 0, 0, 0 , NULL},
> > > +#endif
> > > +
> > > +#ifdef HAVE_ZR
> > > +	{"zr*", vo_zr_parseoption, CONF_TYPE_FUNC_FULL, 0, 0, 0 },
> > >  #endif
> > >  
> > >  #ifdef HAVE_LIRC
> > > diff -Naur main/configure main.dev/configure
> > > --- main/configure	Wed Jan 16 09:08:30 2002
> > > +++ main.dev/configure	Wed Jan 16 09:15:11 2002
> > > @@ -153,6 +153,7 @@
> > >    --enable-3dfx          build with 3dfx support [disable]
> > >    --enable-tdfxfb        build with tdfxfb support [disable]
> > >    --enable-directfb      build with DirectFB support [autodetect]
> > > +  --enable-zr            build with ZR36067/ZR36060 support [disable]
> > >  
> > >  Audio:
> > >    --disable-ossaudio     disable OSS sound support [autodetect]
> > > @@ -672,6 +673,7 @@
> > >  _xv=auto
> > >  _sdl=auto
> > >  _nas=auto
> > > +_jpeg=auto
> > >  _png=auto
> > >  _gl=auto
> > >  _ggi=auto
> > > @@ -712,6 +714,7 @@
> > >  _3dfx=no
> > >  _tdfxfb=no
> > >  _directfb=auto
> > > +_zr=no
> > >  _largefiles=no
> > >  _vo2=no
> > >  _language=en
> > > @@ -742,6 +745,8 @@
> > >    --disable-sdl)	_sdl=no		;;
> > >    --enable-nas)		_nas=yes	;;
> > >    --disable-nas)	_nas=no		;;
> > > +  --enable-jpeg)	_jpeg=yes	;;
> > > +  --disable-jpeg)	_jpeg=no	;;
> > >    --enable-png)		_png=yes	;;
> > >    --disable-png)	_png=no		;;
> > >    --enable-gl)		_gl=yes		;;
> > > @@ -818,6 +823,8 @@
> > >    --disable-tdfxfb)	_tdfxfb=no	;;
> > >    --enable-directfb)	_directfb=yes	;;
> > >    --disable-directfb)	_directfb=no	;;
> > > +  --enable-zr)		_zr=yes		;;
> > > +  --disable-zr)	_zr=no		;;
> > >    --enable-mtrr)	_mtrr=yes	;;
> > >    --disable-mtrr)	_mtrr=no	;;
> > >    --enable-largefiles)	_largefiles=yes	;;
> > > @@ -1805,6 +1812,34 @@
> > >  fi
> > >  echores "$_dvb"
> > >  
> > > +echocheck "JPEG support"
> > > +if test "$_jpeg" = auto; then
> > > +  _jpeg=no
> > > +cat > $TMPC << EOF
> > > +#include <stdio.h>
> > > +#include <jpeglib.h>
> > > +int main(void) { return 0; }
> > > +EOF
> > > +  cc_check -ljpeg  && _jpeg=yes
> > > +fi
> > > +echores "$_jpeg"
> > > +
> > > +echocheck "zr"
> > > +if test "$_zr" = yes ; then
> > > +  if test "$_jpeg" = yes ; then
> > > +    _ld_jpeg='-ljpeg'
> > > +    _def_zr='#define HAVE_ZR 1'
> > > +    _vosrc="$_vosrc vo_zr.c"
> > > +    _vomodules="zr $_vomodules"
> > > +    echores "$_zr"
> > > +  else
> > > +    echores "jpeglib is required by zr, sorry"
> > > +    _def_zr='#undef HAVE_ZR'
> > > +  fi
> > > +else
> > > +  _def_zr='#undef HAVE_ZR'
> > > +  echores "$_zr"
> > > +fi
> > >  
> > >  echocheck "PNG support"
> > >  if test "$_png" = auto ; then
> > > @@ -2780,7 +2815,7 @@
> > >  CC = $_cc
> > >  AWK = $_awk
> > >  # OPTFLAGS = -O4 $_profile $_debug $_march $_mcpu -pipe -fomit-frame-pointer -ffast-math
> > > -OPTFLAGS = $CFLAGS
> > > +OPTFLAGS = -Djpeg_fdct_ifast=jpeg_fdct_ifast2 $CFLAGS
> > >  EXTRA_INC = $_inc_extra $_inc_gtk
> > >  WIN32_PATH = -DWIN32_PATH=\\"$_win32libdir\\"
> > >  
> > > @@ -2803,6 +2838,7 @@
> > >  GGI_LIB = $_ld_ggi
> > >  MLIB_LIB =  $_ld_mlib
> > >  MLIB_INC = $_inc_mlib
> > > +JPEG_LIB = $_ld_jpeg
> > >  PNG_LIB = $_ld_png
> > >  SDL_LIB = $_ld_sdl
> > >  SVGA_LIB = $_ld_svga
> > > @@ -3120,6 +3156,7 @@
> > >  $_def_3dfx
> > >  $_def_tdfxfb
> > >  $_def_directfb
> > > +$_def_zr
> > >  $_def_mga
> > >  $_def_xmga
> > >  $_def_syncfb
> > > --- main/libvo/video_out.c	Wed Jan 16 09:09:22 2002
> > > +++ main.dev/libvo/video_out.c	Wed Jan 16 09:15:11 2002
> > > @@ -64,6 +64,7 @@
> > >  extern vo_functions_t video_out_tdfxfb;
> > >  extern vo_functions_t video_out_null;
> > >  //extern vo_functions_t video_out_odivx;
> > > +extern vo_functions_t video_out_zr;
> > >  extern vo_functions_t video_out_pgm;
> > >  extern vo_functions_t video_out_md5;
> > >  extern vo_functions_t video_out_syncfb;
> > > @@ -130,6 +131,9 @@
> > >  #endif
> > >  #ifdef HAVE_DXR3
> > >  	&video_out_dxr3,
> > > +#endif
> > > +#ifdef HAVE_ZR
> > > +	&video_out_zr,
> > >  #endif
> > >  
> > >  #ifdef HAVE_PNG
> > > diff -Naur main/libvo/vo_zr.c main.dev/libvo/vo_zr.c
> > > --- main/libvo/vo_zr.c	Thu Jan  1 01:00:00 1970
> > > +++ main.dev/libvo/vo_zr.c	Wed Jan 16 09:58:19 2002
> > > @@ -0,0 +1,642 @@
> > > +/* 
> > > + * vo_zr.c - playback on zoran cards 
> > > + * Copyright (C) Rik Snel 2001,2002, License GNU GPL v2
> > > + */
> > > +
> > > +#include <stdio.h>
> > > +#include <stdlib.h>
> > > +#include <string.h>
> > > +#include <unistd.h>
> > > +#include <fcntl.h>
> > > +#include <sys/stat.h>
> > > +#include <sys/types.h>
> > > +#include <sys/time.h>
> > > +#include <sys/mman.h>
> > > +#include <sys/ioctl.h>
> > > +#include <linux/types.h>
> > > +#include <linux/videodev.h>
> > > +#include "zoran.h"
> > > +
> > > +#include "config.h"
> > > +#define ZR_USES_LIBJPEG
> > > +
> > > +#include "video_out.h"
> > > +#include "video_out_internal.h"
> > > +#include "../mp_msg.h"
> > > +#include "../cfgparser.h"
> > > +
> > > +LIBVO_EXTERN (zr)
> > > +
> > > +static vo_info_t vo_info = 
> > > +{
> > > +	"Zoran ZR360[56]7/ZR36060 Driver (DC10(+)/buz/lml33/MatroxRR)",
> > > +	"zr",
> > > +	"Rik Snel <snel at phys.uu.nl>",
> > > +	""
> > > +};
> > > +
> > > +/* General variables */
> > > +
> > > +static int image_width;
> > > +static int image_height;
> > > +static int off_y, off_c, stride; /* for use by 'draw slice' */
> > > +static int framenum;
> > > +static int fields = 1; /* currently no interlacing */
> > > +static int forceinter = 0;
> > > +static int vdec = 1;
> > > +static int size;
> > > +static int quality = 70;
> > > +
> > > +typedef struct {
> > > +	int width;
> > > +	int height;
> > > +	int xoff;
> > > +	int yoff;
> > > +	int set;
> > > +} geo;
> > > +geo g = {0, 0, 0, 0, 0};
> > > +
> > > +static uint8_t *image=NULL;
> > > +static uint8_t *buf=NULL;
> > > +
> > > +
> > > +/* Variables needed for Zoran */
> > > +
> > > +int vdes;  /* the file descriptor of the video device */
> > > +int frame = 0, synco = 0, queue = 0; /* buffer management */
> > > +struct zoran_params zp;
> > > +struct zoran_requestbuffers zrq;
> > > +struct zoran_sync zs;
> > > +struct video_capability vc;
> > > +#define MJPEG_NBUFFERS	2
> > > +#define MJPEG_SIZE	1024*256
> > > +
> > > +//should be command line options
> > > +int norm = VIDEO_MODE_AUTO; 
> > > +char *device = "/dev/video";
> > > +
> > > +
> > > +#ifdef ZR_USES_LIBJPEG
> > > +#include<jpeglib.h>
> > > +int ccount;
> > > +unsigned char *ccbuf;
> > > +struct jpeg_compress_struct cinfo;
> > > +struct jpeg_destination_mgr jdest;
> > > +struct jpeg_error_mgr jerr;
> > > +
> > > +/* minimal destination handler to output to buffer */
> > > +METHODDEF(void) init_destination(struct jpeg_compress_struct *cinfo) {
> > > +//	printf("init_destination called %p %d\n", ccbuf, ccount);
> > > +	cinfo->dest->next_output_byte = (JOCTET*)(ccbuf+ccount);
> > > +	cinfo->dest->free_in_buffer = MJPEG_SIZE - ccount;
> > > +}
> > > +
> > > +METHODDEF(boolean) empty_output_buffer(struct jpeg_compress_struct *cinfo) {
> > > +//	printf("empty_output_buffer called\n");
> > > +	mp_msg(MSGT_VO, MSGL_ERR, "empty_output_buffer called, may not happen because buffer must me large enough\n");
> > > +	return(FALSE);
> > > +}
> > > +
> > > +METHODDEF(void) term_destination(struct jpeg_compress_struct *cinfo) {
> > > +//	printf("term_destination called %p %d\n", ccbuf, ccount);
> > > +	ccount = MJPEG_SIZE - cinfo->dest->free_in_buffer;
> > > +}
> > > +/* end of minimal destination handler */
> > > +
> > > +JSAMPARRAY ***jsi;
> > > +
> > > +#else
> > > +#include "../libavcodec/avcodec.h"
> > > +AVCodec *codec;
> > > +AVCodecContext codec_context;
> > > +AVPicture picture;
> > > +#endif 
> > > +
> > > +static int jpegdct = JDCT_IFAST; 
> > > +
> > > +int init_codec() {
> > > +#ifdef ZR_USES_LIBJPEG
> > > +	int i, j, k;
> > > +	cinfo.err = jpeg_std_error(&jerr);
> > > +	jpeg_create_compress(&cinfo);
> > > +
> > > +	cinfo.dest = &jdest;
> > > +	cinfo.dest->init_destination = init_destination;
> > > +	cinfo.dest->empty_output_buffer = empty_output_buffer;
> > > +	cinfo.dest->term_destination = term_destination;
> > > +
> > > +	cinfo.input_components = 3;
> > > +
> > > +	jpeg_set_defaults(&cinfo);
> > > +
> > > +	cinfo.image_width = image_width;
> > > +	cinfo.image_height = image_height/fields;
> > > +	cinfo.input_gamma = 1.0;
> > > +	cinfo.in_color_space = JCS_YCbCr;
> > > +	cinfo.raw_data_in = TRUE;
> > > +	cinfo.comp_info[0].h_samp_factor = 2;
> > > +	cinfo.comp_info[0].v_samp_factor = 1;
> > > +	cinfo.comp_info[1].h_samp_factor = 1;
> > > +	cinfo.comp_info[1].v_samp_factor = 1;
> > > +	cinfo.comp_info[2].h_samp_factor = 1;
> > > +	cinfo.comp_info[2].v_samp_factor = 1;
> > > +	cinfo.dct_method = jpegdct;
> > > +	jpeg_set_quality(&cinfo, quality, FALSE);
> > > +	jsi = malloc(sizeof(JSAMPARRAY**)*fields);
> > > +
> > > +	/* Just some clutter to give libjpeg the pointers,
> > > +	 * and I don't want to recalculate everything everytime
> > > +	 * it is needed */
> > > +	for (k = 0; k < fields; k++) {
> > > +	jsi[k] = malloc(sizeof(JSAMPARRAY*)*image_height/(8*fields));
> > > +
> > > +	for (i = 0; i < image_height/(8*fields); i++) {
> > > +		jsi[k][i] = malloc(3*sizeof(JSAMPARRAY));
> > > +		jsi[k][i][0] = malloc(8*sizeof(JSAMPROW));
> > > +		jsi[k][i][1] = malloc(8*sizeof(JSAMPROW));
> > > +		jsi[k][i][2] = malloc(8*sizeof(JSAMPROW));
> > > +		for (j = 0; j < 8; j++) {
> > > +			jsi[k][i][0][j] = (JSAMPROW)(image + 
> > > +					(fields*(8*i + j) + k)*image_width);
> > > +			jsi[k][i][1][j] = (JSAMPROW)(image + size + 
> > > +					(fields*(8*i + j)/2)*image_width/2);
> > > +			jsi[k][i][2][j] = (JSAMPROW)(image + 3*size/2 + 
> > > +					(fields*(8*i + j)/2)*image_width/2);
> > > +		}
> > > +	}
> > > +
> > > +	}
> > > +#else
> > > +	AVCodecContext *c = &codec_context;
> > > +	codec = avcodec_find_encoder(CODEC_ID_MJPEG);
> > > +	if (!codec) {
> > > +		/* maybe libavcodec was not initialized */
> > > +		avcodec_init();
> > > +		avcodec_register_all();
> > > +		codec = avcodec_find_encoder(CODEC_ID_MJPEG);
> > > +		if (!codec) {
> > > +			mp_msg(MSGT_VO, MSGL_ERR, "MJPG codec not found in libavcodec\n");
> > > +			return 1;
> > > +		}
> > > +	}
> > > +	/* put default values */
> > > +	memset(c, 0, sizeof(*c));
> > > +
> > > +	c->width = image_width;
> > > +	c->height = image_height;
> > > +	c->bit_rate = 4000000;
> > > +	c->frame_rate = 25*FRAME_RATE_BASE;
> > > +	//c->gop_size = 1;
> > > +	c->pix_fmt = PIX_FMT_YUV422P;
> > > +
> > > +	if (avcodec_open(c, codec) < 0) {
> > > +		mp_msg(MSGT_VO, MSGL_ERR, "MJPG codec could not be opened\n");
> > > +		return 1;
> > > +	}
> > > +
> > > +	picture.data[0] = image;
> > > +	picture.data[1] = image + size;
> > > +	picture.data[2] = image + 3*size/2;
> > > +	picture.linesize[0] = image_width;
> > > +	picture.linesize[1] = image_width/2;
> > > +	picture.linesize[2] = image_width/2;
> > > +#endif 
> > > +	return 0;
> > > +}
> > > +
> > > +
> > > +int zoran_getcap() {
> > > +	vdes = open(device, O_RDWR);
> > > +	/* before we can ask for the maximum resolution, we must set 
> > > +	 * the correct tv norm */
> > > +
> > > +	if (ioctl(vdes, BUZIOC_G_PARAMS, &zp) < 0) {
> > > +		mp_msg(MSGT_VO, MSGL_ERR, "device at %s is probably not a DC10(+)/buz/lml33\n", device);
> > > +		return 1;
> > > +	}
> > > +	
> > > +	if (zp.norm != norm && norm != VIDEO_MODE_AUTO) {
> > > +		/* attempt to set requested norm */
> > > +		zp.norm = norm;
> > > +		if (ioctl(vdes, BUZIOC_S_PARAMS, &zp) < 0) {
> > > +			mp_msg(MSGT_VO, MSGL_ERR,
> > > +				"unable to change video norm, use another program to change it (XawTV)\n");
> > > +			return 1;
> > > +		}
> > > +		ioctl(vdes, BUZIOC_G_PARAMS, &zp);
> > > +		if (norm != zp.norm) {
> > > +			mp_msg(MSGT_VO, MSGL_ERR,
> > > +				"unable to change video norm, use another program to change it (XawTV)\n");
> > > +			return 1;
> > > +		}
> > > +	}
> > > +	
> > > +	if (vdes < 0) {
> > > +		mp_msg(MSGT_VO, MSGL_ERR, "error opening %s\n", 
> > > +				device);
> > > +		return 1;
> > > +	}
> > > +
> > > +
> > > +	if (ioctl(vdes, VIDIOCGCAP, &vc) < 0) {
> > > +		mp_msg(MSGT_VO, MSGL_ERR, "error getting video capabilities from %s\n");
> > > +		return 1;
> > > +	}
> > > +	mp_msg(MSGT_VO, MSGL_V, "zr36067 reports: maxwidth=%d, maxheight=%d\n", vc.maxwidth, vc.maxheight);
> > > +	
> > > +	return 0;
> > > +}
> > > +	
> > > +int init_zoran() {
> > > +	/* center the image, and stretch it as far as possible (try to keep
> > > +	 * aspect) and check if it fits */
> > > +	if (image_width > vc.maxwidth) {
> > > +		mp_msg(MSGT_VO, MSGL_ERR, "movie to be played is too wide, max width currenty %d\n", vc.maxwidth);
> > > +		return 1;
> > > +	}
> > > +
> > > +	if (image_height > vc.maxheight) {
> > > +		mp_msg(MSGT_VO, MSGL_ERR, "movie to be played is too high, max height currenty %d\n", vc.maxheight);
> > > +		return 1;
> > > +	}
> > > +
> > > +	zp.decimation = 0;
> > > +	zp.HorDcm = (vc.maxwidth >= 2*(int)image_width) ? 2 : 1;
> > > +	zp.VerDcm = 1;
> > > +	if (zp.HorDcm == 2 && 4*image_width <= vc.maxwidth && 
> > > +			4*image_height/fields <= vc.maxheight) {
> > > +		zp.HorDcm = 4;
> > > +		zp.VerDcm = 2;
> > > +	}
> > > +	if (((forceinter == 0 && vdec >= 2) || (forceinter == 1 && vdec == 4)) && 4*image_height/fields <= vc.maxheight) {
> > > +		zp.VerDcm = 2;
> > > +	}
> > > +	zp.TmpDcm = 1;
> > > +	zp.field_per_buff = fields;
> > > +	zp.img_x = (vc.maxwidth - zp.HorDcm*(int)image_width)/2;
> > > +	zp.img_y = (vc.maxheight - zp.VerDcm*(3-fields)*(int)image_height)/4;
> > > +	zp.img_width = zp.HorDcm*image_width;
> > > +	zp.img_height = zp.VerDcm*image_height/fields;
> > > +	mp_msg(MSGT_VO, MSGL_V, "zr: geometry (after 'scaling'): %dx%d+%d+%d fields=%d, w=%d, h=%d\n", zp.img_width, zp.img_height, zp.img_x, zp.img_y, fields, image_width, image_height);
> > > +
> > > +	if (ioctl(vdes, BUZIOC_S_PARAMS, &zp) < 0) {
> > > +		mp_msg(MSGT_VO, MSGL_ERR, "error setting display parameters\n");
> > > +		return 1;
> > > +	}
> > > +
> > > +	zrq.count = MJPEG_NBUFFERS;
> > > +	zrq.size = MJPEG_SIZE;
> > > +
> > > +	if (ioctl(vdes, BUZIOC_REQBUFS, &zrq)) {
> > > +		mp_msg(MSGT_VO, MSGL_ERR, "error requesting %d buffers of size %d\n", zrq.count, zrq.size);
> > > +		return 1;
> > > +	}
> > > +
> > > +	buf = (char*)mmap(0, zrq.count*zrq.size, PROT_READ|PROT_WRITE,
> > > +			MAP_SHARED, vdes, 0);
> > > +
> > > +	if (buf == MAP_FAILED) {
> > > +		mp_msg(MSGT_VO, MSGL_ERR, "error requesting %d buffers of size %d\n", zrq.count, zrq.size);
> > > +		return 1;
> > > +	}
> > > +	return 0;
> > > +}
> > > +
> > > +void uninit_zoran(void) {
> > > +	if (image) {
> > > +		free(image);
> > > +		image=NULL;
> > > +	}
> > > +	while (queue > synco + 1) {
> > > +		if (ioctl(vdes, BUZIOC_SYNC, &zs) < 0) 
> > > +			mp_msg(MSGT_VO, MSGL_ERR, "error waiting for buffers to become free"); 
> > > +		synco++;
> > > +	}
> > > +	/* stop streaming */
> > > +	frame = -1;
> > > +	if (ioctl(vdes, BUZIOC_QBUF_PLAY, &frame) < 0) 
> > > +		mp_msg(MSGT_VO, MSGL_ERR, "error stopping playback of last frame");
> > > +	close(vdes);
> > > +}
> > > +
> > > +static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, 
> > > +	uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format)
> > > +{
> > > +	int j;
> > > +	/* this allows to crop parts from incoming picture,
> > > +	 * for easy 512x240 -> 352x240 */
> > > +	/* These values must be multples of 2 */
> > > +
> > > +	if (g.set) {
> > > +		if (g.width%2 != 0 || g.height%2 != 0 ||
> > > +				g.xoff%2 != 0 || g.yoff%2 != 0) {
> > > +			mp_msg(MSGT_VO, MSGL_ERR, "arguments in -zrcrop must be multiples of 2\n");
> > > +			return 1;
> > > +		}
> > > +		if (g.width <= 0 || g.height <= 0 ||
> > > +				g.xoff < 0 || g.yoff < 0) {
> > > +			mp_msg(MSGT_VO, MSGL_ERR, "width and height must be positive and offset nonnegative\n");
> > > +			return 1;
> > > +		}
> > > +		if (g.width + g.xoff > width) {
> > > +			mp_msg(MSGT_VO, MSGL_ERR, "width+xoffset (%d+%d>%d) is too big\n", g.width, g.xoff, width);
> > > +			return 1;
> > > +		}
> > > +		if (g.height + g.yoff > height) {
> > > +			mp_msg(MSGT_VO, MSGL_ERR, "height+yoffset (%d+%d>%d) is too big\n", g.height, g.yoff, height);
> > > +			return 1;
> > > +		}
> > > +	} else {
> > > +		g.width = width;
> > > +		g.height = height;
> > > +		g.xoff = 0;
> > > +		g.yoff = 0;
> > > +	}
> > > +	/* we must know the maximum resolution of the device
> > > +	 * it differs for DC10+ and buz for example */
> > > +	zoran_getcap(); /*must be called before init_zoran */
> > > +	if (g.height/vdec > vc.maxheight/2 || (forceinter == 1 && vdec == 1))
> > > +		fields = 2;
> > > +	printf("fields=%d\n", fields);
> > > +	/* the height must be a multiple of fields*8 and the width
> > > +	 * must be a multiple of 16 */
> > > +	/* add some black borders to make it so, and center the image*/
> > > +	image_height = fields*8*((g.height/vdec - 1)/(fields*8) + 1);
> > > +	image_width = 16*((g.width - 1)/16 + 1);
> > > +	off_y = (image_height - g.height/vdec)/2;
> > > +	if (off_y%2 != 0) off_y++;
> > > +	off_y *= image_width;
> > > +	off_c = off_y/4;
> > > +	off_y += (image_width - g.width)/2;
> > > +	if (off_y%2 != 0) off_y--;
> > > +	off_c += (image_width - g.width)/4;
> > > +	framenum = 0;
> > > +	size = image_width*image_height;
> > > +	mp_msg(MSGT_VO, MSGL_V, "input: %dx%d, cropped: %dx%d, output: %dx%d, off_y=%d, off_c=%d\n", width, height, g.width, g.height, image_width, image_height, off_y, off_c);
> > > +	
> > > +	image = malloc(2*size); /* this buffer allows for YUV422 data,
> > > +				 * so it is a bit too big for YUV420 */
> > > +	if (!image) {
> > > +		mp_msg(MSGT_VO, MSGL_ERR, "Memory exhausted\n");
> > > +		return 1;
> > > +	}
> > > +	/* and make sure that the borders are _really_ black */
> > > +	memset(image, 0, image_width*image_height);
> > > +	memset(image + size, 0x80, image_width*image_height/4);
> > > +	memset(image + 3*size/2, 0x80, image_width*image_height/4);
> > > +
> > > +	if (init_codec()) {
> > > +		return 1;
> > > +	}
> > > +	
> > > +	if (init_zoran()) {
> > > +#ifdef ZR_USES_LIBJPEG
> > > +		jpeg_destroy_compress(&cinfo);
> > > +#else
> > > +		avcodec_close(&codec_context);
> > > +#endif
> > > +		return 1;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static const vo_info_t* get_info(void) {
> > > +	return &vo_info;
> > > +}
> > > +
> > > +static void draw_osd(void) {
> > > +}
> > > +
> > > +static void flip_page (void) {
> > > +#ifdef ZR_USES_LIBJPEG
> > > +	int i, j, k;
> > > +#else
> > > +	AVCodecContext *c = &codec_context;
> > > +#endif
> > > +
> > > +	/* do we have a free buffer? */
> > > +	if (queue-synco < zrq.count) {
> > > +		frame = queue;
> > > +	} else {
> > > +		if (ioctl(vdes, BUZIOC_SYNC, &zs) < 0) 
> > > +			mp_msg(MSGT_VO, MSGL_ERR, "error waiting for buffers to become free"); 
> > > +		frame = zs.frame;
> > > +		synco++;
> > > +	}
> > > +
> > > +#ifdef ZR_USES_LIBJPEG
> > > +	ccbuf = buf + frame*zrq.size;
> > > +	ccount = 0;
> > > +	k = fields;
> > > +	for (j=0; j < k; j++) {
> > > +
> > > +	jpeg_start_compress(&cinfo, TRUE);
> > > +	i=0;
> > > +	while (cinfo.next_scanline < cinfo.image_height) {
> > > +		jpeg_write_raw_data(&cinfo, jsi[j][i], 8);
> > > +		i++;
> > > +	}
> > > +	jpeg_finish_compress(&cinfo);
> > > +
> > > +	}
> > > +#else
> > > +	avcodec_encode_video(c, buf + frame*zrq.size, MJPEG_SIZE, &picture);
> > > +#endif
> > > +
> > > +	if (ioctl(vdes, BUZIOC_QBUF_PLAY, &frame) < 0) 
> > > +		mp_msg(MSGT_VO, MSGL_ERR,
> > > +				"error queueing buffer for playback");
> > > +	queue++;
> > > +
> > > +	framenum++;
> > > +	return;
> > > +}
> > > +
> > > +static uint32_t draw_frame(uint8_t * src[]) {
> > > +	return 0;
> > > +}
> > > +
> > > +static uint32_t query_format(uint32_t format) {
> > > +	if(format==IMGFMT_YV12) return 1;
> > > +	return 0;
> > > +}
> > > +
> > > +static void uninit(void) {
> > > +	uninit_zoran();
> > > +
> > > +#ifdef ZR_USES_LIBJPEG
> > > +	jpeg_destroy_compress(&cinfo);
> > > +#else
> > > +	avcodec_close(&codec_context);
> > > +#endif
> > > +}
> > > +
> > > +static void check_events(void) {
> > > +}
> > > +
> > > +
> > > +static uint32_t draw_slice(uint8_t *srcimg[], int stride[],
> > > +		int w, int h, int x, int y) {
> > > +	int i;
> > > +	/* Apply 'geometry', crop unwanted parts */
> > > +	uint8_t *dst;
> > > +	uint8_t *src;
> > > +	//printf("before: w=%d, h=%d, x=%d, y=%d, src0=%p, src1=%p, src2=%p\n", w, h, x, y, srcimg[0], srcimg[1], srcimg[2]);
> > > +	if (x < g.xoff) {
> > > +		srcimg[0] += g.xoff - x;
> > > +		srcimg[1] += (g.xoff - x)/2;
> > > +		srcimg[2] += (g.xoff - x)/2;
> > > +		w -= g.xoff - x;
> > > +		if (w < 0) return 0;
> > > +		x = 0 /*g.xoff*/;
> > > +	} else {
> > > +		x -= g.xoff;
> > > +	}
> > > +	if (x + w > g.width) {
> > > +		w = g.width - x;
> > > +		if (w < 0) return 0;
> > > +	}
> > > +	if (y < g.yoff) {
> > > +		srcimg[0] += (g.yoff - y)*stride[0];
> > > +		srcimg[1] += ((g.yoff - y)/2)*stride[1];
> > > +		srcimg[2] += ((g.yoff - y)/2)*stride[2];
> > > +		h -= g.yoff - y;
> > > +		if (h < 0) return 0;
> > > +		y = 0;
> > > +	} else {
> > > +		y -= g.yoff;
> > > +	}
> > > +	if (y + h > g.height) {
> > > +		h = g.height - y;
> > > +		if (h < 0) return 0;
> > > +	}
> > > +	//printf("after: w=%d, h=%d, x=%d, y=%d, src0=%p, src1=%p, src2=%p\n", w, h, x, y, srcimg[0], srcimg[1], srcimg[2]);
> > > +	dst=image + off_y + image_width*(y/vdec)+x;
> > > +	src=srcimg[0];
> > > +	// copy Y:
> > > +	for (i = 0; i < h; i++) {
> > > +		if ((i + x)%vdec == 0) {
> > > +			memcpy(dst,src,w);
> > > +			dst+=image_width;
> > > +		}
> > > +		src+=stride[0];
> > > +
> > > +	}
> > > +	{
> > > +    		// copy U+V:
> > > +		uint8_t *src1=srcimg[1];
> > > +		uint8_t *src2=srcimg[2];
> > > +		uint8_t *dst1=image + size + off_c+ (y/(vdec*2))*image_width/2+(x/2);
> > > +		uint8_t *dst2=image + 3*size/2 + off_c + 
> > > +			(y/(vdec*2))*image_width/2+(x/2);
> > > +		for (i = 0; i< h/2; i++) {
> > > +			if ((i+x/2)%vdec == 0) {
> > > +				memcpy(dst1,src1,w/2);
> > > +				memcpy(dst2,src2,w/2);
> > > +				dst1+=image_width/2;
> > > +				dst2+=image_width/2;
> > > +			}
> > > +			src1+=stride[1];
> > > +			src2+=stride[2];
> > > +		}
> > > +    	}
> > > + 	return 0;
> > > +}
> > > +
> > > +
> > > +/* copied and adapted from vo_aa_parseoption */
> > > +int
> > > +vo_zr_parseoption(struct config * conf, char *opt, char *param){
> > > +    /* got an option starting with zr */
> > > +    char *x, *help;
> > > +    int i;
> > > +    /* do WE need it ?, always */
> > > +    if (!strcasecmp(opt, "zrdev")) {
> > > +	if (param == NULL) return ERR_MISSING_PARAM;
> > > +	//if ((i=getcolor(param))==-1) return ERR_OUT_OF_RANGE;
> > > +	//aaopt_osdcolor=i;
> > > +	device = malloc(strlen(param)+1);
> > > +	strcpy(device, param);
> > > +	mp_msg(MSGT_VO, MSGL_V, "zr: using device %s\n", device);
> > > +	return 1;
> > > +    } else if (!strcasecmp(opt, "zrfi")) {
> > > +	    if (param != NULL) {
> > > +		    return ERR_OUT_OF_RANGE;
> > > +	    }
> > > +	    forceinter = 1;
> > > +	    return 1;
> > > +    } else if (!strcasecmp(opt, "zrcrop")){
> > > +	if (param == NULL) return ERR_MISSING_PARAM;
> > > +	if (sscanf(param, "%dx%d+%d+%d", &g.width, &g.height, 
> > > +				&g.xoff, &g.yoff) != 4) {
> > > +		g.xoff = 0; g.yoff = 0;
> > > +		if (sscanf(param, "%dx%d", &g.width, &g.height) != 2) {
> > > +			mp_msg(MSGT_VO, MSGL_ERR, "argument to -zrcrop must be of the form 352x288+16+0\n");
> > > +			return ERR_OUT_OF_RANGE;
> > > +		}
> > > +	}
> > > +	g.set = 1;
> > > +	mp_msg(MSGT_VO, MSGL_V, "zr: cropping %s\n", param);
> > > +	return 1;
> > > +    }else if (!strcasecmp(opt, "zrvdec")) {
> > > +        i = atoi(param);
> > > +	if (i != 1 && i != 2 && i != 4) return ERR_OUT_OF_RANGE;
> > > +	vdec = i;
> > > +	return 1;
> > > +    }else if (!strcasecmp(opt, "zrquality")) {
> > > +        i = atoi(param);
> > > +	if (i < 30 || i > 100) return ERR_OUT_OF_RANGE;
> > > +	quality = i;
> > > +	return 1;
> > > +    }else if (!strcasecmp(opt, "zrdct")) {
> > > +	if (param == NULL) return ERR_MISSING_PARAM;
> > > +	if (!strcasecmp(param, "IFAST")) {
> > > +            jpegdct = JDCT_IFAST;
> > > +	    return 1;
> > > +	} else if (!strcasecmp(param, "ISLOW")) {
> > > +            jpegdct = JDCT_ISLOW;
> > > +	    return 1;
> > > +	} else if (!strcasecmp(param, "FLOAT")) {
> > > +            jpegdct = JDCT_FLOAT;
> > > +	    return 1;
> > > +	} else {
> > > +           return ERR_OUT_OF_RANGE;
> > > +        }
> > > +    }else if (!strcasecmp(opt, "zrnorm")) {
> > > +	if (param == NULL) return ERR_MISSING_PARAM;
> > > +	if (!strcasecmp(param, "NTSC")) {
> > > +            mp_msg(MSGT_VO, MSGL_V, "zr: Norm set to NTSC\n");
> > > +            norm = VIDEO_MODE_NTSC;
> > > +	    return 1;
> > > +	} else if (!strcasecmp(param, "PAL")) {
> > > +	    mp_msg(MSGT_VO, MSGL_V, "zr: Norm set to PAL\n");
> > > +            norm = VIDEO_MODE_PAL;
> > > +	    return 1;
> > > +	} else {
> > > +           return ERR_OUT_OF_RANGE;
> > > +        }
> > > +    }else if (!strcasecmp(opt, "zrhelp")){
> > > +	printf("Help for -vo zr: Zoran ZR360[56]7/ZR36060 based MJPEG capture/playback cards\n");
> > > +	printf("\n");
> > > +	printf("Here are the zr options:\n");
> > > +	printf(
> > > +		    "\n"
> > > +		    "  -zrcrop     specify part of the input image that\n"
> > > +		    "              you want to see as an x-style geometry string\n"
> > > +		    "              example: -zrcrop 352x288+16+0\n"
> > > +		    "  -zrvdec     vertical decimation 1, 2 or 4\n"
> > > +		    "  -zrfi       force interlacing ('wide screen')\n"
> > > +		    "              (by default we only interlace if the movie\n"
> > > +		    "              is higher than half of the screen height)\n"
> > > +		    "  -zrquality  jpeg compression quality 30-100\n"
> > > +                    "  -zrdct      specify DCT method: IFAST, ISLOW or FLOAT\n"
> > > +		    "  -zrdev      playback device (example -zrdev /dev/video1\n"
> > > +		    "  -zrnorm     specify norm PAL/NTSC [dev: leave at current setting]\n"
> > > +		    "\n"
> > > +	      );
> > > +	exit(0);
> > > +		
> > > +    }
> > > +    return ERR_NOT_AN_OPTION;
> > > +}
> > > diff -Naur main/libvo/zoran.h main.dev/libvo/zoran.h
> > > --- main/libvo/zoran.h	Thu Jan  1 01:00:00 1970
> > > +++ main.dev/libvo/zoran.h	Wed Jan 16 09:15:11 2002
> > > @@ -0,0 +1,372 @@
> > > +/* 
> > > +    zoran - Iomega Buz driver
> > > +
> > > +    Copyright (C) 1999 Rainer Johanni <Rainer at Johanni.de>
> > > +
> > > +   based on
> > > +
> > > +    zoran.0.0.3 Copyright (C) 1998 Dave Perks <dperks at ibm.net>
> > > +
> > > +   and
> > > +
> > > +    bttv - Bt848 frame grabber driver
> > > +    Copyright (C) 1996,97 Ralph Metzler (rjkm at thp.uni-koeln.de)
> > > +
> > > +    This program 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 of the License, or
> > > +    (at your option) any later version.
> > > +
> > > +    This program 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 this program; if not, write to the Free Software
> > > +    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> > > +*/
> > > +
> > > +#ifndef _BUZ_H_
> > > +#define _BUZ_H_
> > > +
> > > +#include <linux/config.h>
> > > +
> > > +#if LINUX_VERSION_CODE < 0x20212
> > > +typedef struct wait_queue *wait_queue_head_t;
> > > +#endif
> > > +
> > > +/* The Buz only supports a maximum width of 720, but some V4L
> > > +   applications (e.g. xawtv are more happy with 768).
> > > +   If XAWTV_HACK is defined, we try to fake a device with bigger width */
> > > +
> > > +//#define XAWTV_HACK
> > > +
> > > +//#ifdef XAWTV_HACK
> > > +//#define   BUZ_MAX_WIDTH   768   /* never display more than 768 pixels */
> > > +#define   BUZ_MAX_WIDTH   (zr->timing->Wa)
> > > +//#else
> > > +//#define   BUZ_MAX_WIDTH   720   /* never display more than 720 pixels */
> > > +//#endif
> > > +//#define   BUZ_MAX_HEIGHT  576   /* never display more than 576 rows */
> > > +#define   BUZ_MAX_HEIGHT  (zr->timing->Ha)
> > > +#define   BUZ_MIN_WIDTH    32	/* never display less than 32 pixels */
> > > +#define   BUZ_MIN_HEIGHT   24	/* never display less than 24 rows */
> > > +
> > > +struct zoran_requestbuffers {
> > > +	unsigned long count;	/* Number of buffers for MJPEG grabbing */
> > > +	unsigned long size;	/* Size PER BUFFER in bytes */
> > > +};
> > > +
> > > +struct zoran_sync {
> > > +	unsigned long frame;	/* number of buffer that has been free'd */
> > > +	unsigned long length;	/* number of code bytes in buffer (capture only) */
> > > +	unsigned long seq;	/* frame sequence number */
> > > +	struct timeval timestamp;	/* timestamp */
> > > +};
> > > +
> > > +struct zoran_status {
> > > +	int input;		/* Input channel, has to be set prior to BUZIOC_G_STATUS */
> > > +	int signal;		/* Returned: 1 if valid video signal detected */
> > > +	int norm;		/* Returned: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */
> > > +	int color;		/* Returned: 1 if color signal detected */
> > > +};
> > > +
> > > +struct zoran_params {
> > > +
> > > +	/* The following parameters can only be queried */
> > > +
> > > +	int major_version;	/* Major version number of driver */
> > > +	int minor_version;	/* Minor version number of driver */
> > > +
> > > +	/* Main control parameters */
> > > +
> > > +	int input;		/* Input channel: 0 = Composite, 1 = S-VHS */
> > > +	int norm;		/* Norm: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */
> > > +	int decimation;		/* decimation of captured video,
> > > +				   enlargement of video played back.
> > > +				   Valid values are 1, 2, 4 or 0.
> > > +				   0 is a special value where the user
> > > +				   has full control over video scaling */
> > > +
> > > +	/* The following parameters only have to be set if decimation==0,
> > > +	   for other values of decimation they provide the data how the image is captured */
> > > +
> > > +	int HorDcm;		/* Horizontal decimation: 1, 2 or 4 */
> > > +	int VerDcm;		/* Vertical decimation: 1 or 2 */
> > > +	int TmpDcm;		/* Temporal decimation: 1 or 2,
> > > +				   if TmpDcm==2 in capture every second frame is dropped,
> > > +				   in playback every frame is played twice */
> > > +	int field_per_buff;	/* Number of fields per buffer: 1 or 2 */
> > > +	int img_x;		/* start of image in x direction */
> > > +	int img_y;		/* start of image in y direction */
> > > +	int img_width;		/* image width BEFORE decimation,
> > > +				   must be a multiple of HorDcm*16 */
> > > +	int img_height;		/* image height BEFORE decimation,
> > > +				   must be a multiple of VerDcm*8 */
> > > +
> > > +	/* --- End of parameters for decimation==0 only --- */
> > > +
> > > +	/* JPEG control parameters */
> > > +
> > > +	int quality;		/* Measure for quality of compressed images.
> > > +				   Scales linearly with the size of the compressed images.
> > > +				   Must be beetween 0 and 100, 100 is a compression
> > > +				   ratio of 1:4 */
> > > +
> > > +	int odd_even;		/* Which field should come first ??? */
> > > +
> > > +	int APPn;		/* Number of APP segment to be written, must be 0..15 */
> > > +	int APP_len;		/* Length of data in JPEG APPn segment */
> > > +	char APP_data[60];	/* Data in the JPEG APPn segment. */
> > > +
> > > +	int COM_len;		/* Length of data in JPEG COM segment */
> > > +	char COM_data[60];	/* Data in JPEG COM segment */
> > > +
> > > +	unsigned long jpeg_markers;	/* Which markers should go into the JPEG output.
> > > +					   Unless you exactly know what you do, leave them untouched.
> > > +					   Inluding less markers will make the resulting code
> > > +					   smaller, but there will be fewer aplications
> > > +					   which can read it.
> > > +					   The presence of the APP and COM marker is
> > > +					   influenced by APP0_len and COM_len ONLY! */
> > > +#define JPEG_MARKER_DHT (1<<3)	/* Define Huffman Tables */
> > > +#define JPEG_MARKER_DQT (1<<4)	/* Define Quantization Tables */
> > > +#define JPEG_MARKER_DRI (1<<5)	/* Define Restart Interval */
> > > +#define JPEG_MARKER_COM (1<<6)	/* Comment segment */
> > > +#define JPEG_MARKER_APP (1<<7)	/* App segment, driver will allways use APP0 */
> > > +
> > > +	int VFIFO_FB;		/* Flag for enabling Video Fifo Feedback.
> > > +				   If this flag is turned on and JPEG decompressing
> > > +				   is going to the screen, the decompress process
> > > +				   is stopped every time the Video Fifo is full.
> > > +				   This enables a smooth decompress to the screen
> > > +				   but the video output signal will get scrambled */
> > > +
> > > +	/* Misc */
> > > +
> > > +	char reserved[312];	/* Makes 512 bytes for this structure */
> > > +};
> > > +
> > > +/*
> > > +Private IOCTL to set up for displaying MJPEG
> > > +*/
> > > +#define BUZIOC_G_PARAMS       _IOR ('v', BASE_VIDIOCPRIVATE+0,  struct zoran_params)
> > > +#define BUZIOC_S_PARAMS       _IOWR('v', BASE_VIDIOCPRIVATE+1,  struct zoran_params)
> > > +#define BUZIOC_REQBUFS        _IOWR('v', BASE_VIDIOCPRIVATE+2,  struct zoran_requestbuffers)
> > > +#define BUZIOC_QBUF_CAPT      _IOW ('v', BASE_VIDIOCPRIVATE+3,  int)
> > > +#define BUZIOC_QBUF_PLAY      _IOW ('v', BASE_VIDIOCPRIVATE+4,  int)
> > > +#define BUZIOC_SYNC           _IOR ('v', BASE_VIDIOCPRIVATE+5,  struct zoran_sync)
> > > +#define BUZIOC_G_STATUS       _IOWR('v', BASE_VIDIOCPRIVATE+6,  struct zoran_status)
> > > +
> > > +
> > > +#ifdef __KERNEL__
> > > +
> > > +#define BUZ_NUM_STAT_COM    4
> > > +#define BUZ_MASK_STAT_COM   3
> > > +
> > > +#define BUZ_MAX_FRAME     256	/* Must be a power of 2 */
> > > +#define BUZ_MASK_FRAME    255	/* Must be BUZ_MAX_FRAME-1 */
> > > +
> > > +#if VIDEO_MAX_FRAME <= 32
> > > +#   define   V4L_MAX_FRAME   32
> > > +#elif VIDEO_MAX_FRAME <= 64
> > > +#   define   V4L_MAX_FRAME   64
> > > +#else
> > > +#   error   "Too many video frame buffers to handle"
> > > +#endif
> > > +#define   V4L_MASK_FRAME   (V4L_MAX_FRAME - 1)
> > > +
> > > +
> > > +#include "zr36057.h"
> > > +
> > > +enum card_type {
> > > +        UNKNOWN = 0,
> > > +        DC10,
> > > +        DC10plus,
> > > +        LML33,
> > > +        BUZ
> > > +};
> > > +
> > > +enum zoran_codec_mode {
> > > +	BUZ_MODE_IDLE,		/* nothing going on */
> > > +	BUZ_MODE_MOTION_COMPRESS,	/* grabbing frames */
> > > +	BUZ_MODE_MOTION_DECOMPRESS,	/* playing frames */
> > > +	BUZ_MODE_STILL_COMPRESS,	/* still frame conversion */
> > > +	BUZ_MODE_STILL_DECOMPRESS	/* still frame conversion */
> > > +};
> > > +
> > > +enum zoran_buffer_state {
> > > +	BUZ_STATE_USER,		/* buffer is owned by application */
> > > +	BUZ_STATE_PEND,		/* buffer is queued in pend[] ready to feed to I/O */
> > > +	BUZ_STATE_DMA,		/* buffer is queued in dma[] for I/O */
> > > +	BUZ_STATE_DONE		/* buffer is ready to return to application */
> > > +};
> > > +
> > > +struct zoran_gbuffer {
> > > +	u32 *frag_tab;		/* addresses of frag table */
> > > +	u32 frag_tab_bus;	/* same value cached to save time in ISR */
> > > +	enum zoran_buffer_state state;	/* non-zero if corresponding buffer is in use in grab queue */
> > > +	struct zoran_sync bs;	/* DONE: info to return to application */
> > > +};
> > > +
> > > +struct v4l_gbuffer {
> > > +	char *fbuffer;			/* virtual  address of frame buffer */
> > > +	unsigned long fbuffer_phys;	/* physical address of frame buffer */
> > > +	unsigned long fbuffer_bus;	/* bus      address of frame buffer */
> > > +	enum zoran_buffer_state state;	/* state: unused/pending/done */
> > > +};
> > > +
> > > +struct tvnorm {
> > > +	u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart;
> > > +};
> > > +
> > > +struct zoran {
> > > +	struct video_device video_dev;
> > > +	struct i2c_bus i2c;
> > > +
> > > +	int initialized;		/* flag if zoran has been correctly initalized */
> > > +	int user;			/* number of current users (0 or 1) */
> > > +        enum card_type card;
> > > +        struct tvnorm *timing;
> > > +
> > > +	unsigned short id;		/* number of this device */
> > > +	char name[32];			/* name of this device */
> > > +	struct pci_dev *pci_dev;	/* PCI device */
> > > +	unsigned char revision;		/* revision of zr36057 */
> > > +	unsigned int zr36057_adr;	/* bus address of IO mem returned by PCI BIOS */
> > > +	unsigned char *zr36057_mem;	/* pointer to mapped IO memory */
> > > +
> > > +	int map_mjpeg_buffers;		/* Flag which bufferset will map by next mmap() */
> > > +
> > > +	spinlock_t lock;		/* Spinlock irq and hardware */
> > > +	struct semaphore sem;		/* Guard parallel ioctls and mmap */
> > > +
> > > +	/* Video for Linux parameters */
> > > +
> > > +	struct video_picture picture;	/* Current picture params */
> > > +	struct video_buffer buffer;	/* Current buffer params */
> > > +	struct video_window window;	/* Current window params */
> > > +	int buffer_set, window_set;	/* Flags if the above structures are set */
> > > +	int video_interlace;		/* Image on screen is interlaced */
> > > +
> > > +	u32 *overlay_mask;
> > > +        wait_queue_head_t v4l_capq;
> > > +
> > > +	int v4l_overlay_active;		/* Overlay grab is activated */
> > > +	int v4l_memgrab_active;		/* Memory grab is activated */
> > > +
> > > +	int v4l_grab_frame;		/* Frame number being currently grabbed */
> > > +#define NO_GRAB_ACTIVE (-1)
> > > +	int v4l_grab_seq;		/* Number of frames grabbed */
> > > +	int gwidth;			/* Width of current memory capture */
> > > +	int gheight;			/* Height of current memory capture */
> > > +	int gformat;			/* Format of ... */
> > > +	int gbpl;			/* byte per line of ... */
> > > +
> > > +	/* V4L grab queue of frames pending */
> > > +
> > > +	unsigned v4l_pend_head;
> > > +	unsigned v4l_pend_tail;
> > > +	int v4l_pend[V4L_MAX_FRAME];
> > > +
> > > +	struct v4l_gbuffer v4l_gbuf[VIDEO_MAX_FRAME];	/* V4L   buffers' info */
> > > +
> > > +	/* Buz MJPEG parameters */
> > > +
> > > +	unsigned long jpg_nbufs;	/* Number of buffers */
> > > +	unsigned long jpg_bufsize;	/* Size of mjpeg buffers in bytes */
> > > +	int jpg_buffers_allocated;	/* Flag if buffers are allocated  */
> > > +	int need_contiguous;	/* Flag if contiguous buffers are needed */
> > > +
> > > +	enum zoran_codec_mode codec_mode;	/* status of codec */
> > > +	struct zoran_params params;	/* structure with a lot of things to play with */
> > > +
> > > +	wait_queue_head_t jpg_capq;	/* wait here for grab to finish */
> > > +
> > > +	/* grab queue counts/indices, mask with BUZ_MASK_STAT_COM before using as index */
> > > +	/* (dma_head - dma_tail) is number active in DMA, must be <= BUZ_NUM_STAT_COM */
> > > +	/* (value & BUZ_MASK_STAT_COM) corresponds to index in stat_com table */
> > > +	unsigned long jpg_que_head;	/* Index where to put next buffer which is queued */
> > > +	unsigned long jpg_dma_head;	/* Index of next buffer which goes into stat_com  */
> > > +	unsigned long jpg_dma_tail;	/* Index of last buffer in stat_com               */
> > > +	unsigned long jpg_que_tail;	/* Index of last buffer in queue                  */
> > > +	unsigned long jpg_seq_num;	/* count of frames since grab/play started        */
> > > +	unsigned long jpg_err_seq;	/* last seq_num before error                      */
> > > +	unsigned long jpg_err_shift;
> > > +	unsigned long jpg_queued_num;	/* count of frames queued since grab/play started */
> > > +
> > > +	/* zr36057's code buffer table */
> > > +	u32 *stat_com;			/* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */
> > > +
> > > +	/* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */
> > > +	int jpg_pend[BUZ_MAX_FRAME];
> > > +
> > > +	/* array indexed by frame number */
> > > +	struct zoran_gbuffer jpg_gbuf[BUZ_MAX_FRAME];	/* MJPEG buffers' info */
> > > +
> > > +	/* Additional stuff for testing */
> > > +	struct proc_dir_entry *zoran_proc;
> > > +
> > > +	int testing;
> > > +	int jpeg_error;
> > > +	int intr_counter_GIRQ1;
> > > +	int intr_counter_GIRQ0;
> > > +	int intr_counter_CodRepIRQ;
> > > +	int intr_counter_JPEGRepIRQ;
> > > +	int field_counter;
> > > +	int IRQ1_in;
> > > +	int IRQ1_out;
> > > +	int JPEG_in;
> > > +	int JPEG_out;
> > > +	int JPEG_0;
> > > +	int JPEG_1;
> > > +	int END_event_missed;
> > > +	int JPEG_missed;
> > > +	int JPEG_error;
> > > +	int num_errors;
> > > +	int JPEG_max_missed;
> > > +	int JPEG_min_missed;
> > > +
> > > +	u32 last_isr;
> > > +	unsigned long frame_num;
> > > +
> > > +	wait_queue_head_t test_q;
> > > +};
> > > +
> > > +#endif
> > > +
> > > +/*The following should be done in more portable way. It depends on define
> > > +  of _ALPHA_BUZ in the Makefile.*/
> > > +
> > > +#ifdef _ALPHA_BUZ
> > > +#define btwrite(dat,adr)    writel((dat),(char *) (zr->zr36057_adr+(adr)))
> > > +#define btread(adr)         readl(zr->zr36057_adr+(adr))
> > > +#else
> > > +#define btwrite(dat,adr)    writel((dat), (char *) (zr->zr36057_mem+(adr)))
> > > +#define btread(adr)         readl(zr->zr36057_mem+(adr))
> > > +#endif
> > > +
> > > +#define btand(dat,adr)      btwrite((dat) & btread(adr), adr)
> > > +#define btor(dat,adr)       btwrite((dat) | btread(adr), adr)
> > > +#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
> > > +
> > > +#define I2C_TSA5522        0xc2
> > > +#define I2C_TDA9850        0xb6
> > > +#define I2C_HAUPEE         0xa0
> > > +#define I2C_STBEE          0xae
> > > +#define   I2C_SAA7111        0x48
> > > +#define   I2C_SAA7110        0x9c
> > > +#define   I2C_SAA7185        0x88
> > > +//#define   I2C_ADV7175        0xd4
> > > +#define   I2C_ADV7175        0x54
> > > +
> > > +#define TDA9850_CON1       0x04
> > > +#define TDA9850_CON2       0x05
> > > +#define TDA9850_CON3       0x06
> > > +#define TDA9850_CON4       0x07
> > > +#define TDA9850_ALI1       0x08
> > > +#define TDA9850_ALI2       0x09
> > > +#define TDA9850_ALI3       0x0a
> > > +
> > > +#endif
> > 
> > _______________________________________________
> > MPlayer-dev-eng mailing list
> > MPlayer-dev-eng at mplayerhq.hu
> > http://mplayerhq.hu/mailman/listinfo/mplayer-dev-eng
> > 
> 
> --------
> Nothing is ever a total loss; it can always serve as a bad example.
> 
> _______________________________________________
> MPlayer-dev-eng mailing list
> MPlayer-dev-eng at mplayerhq.hu
> http://mplayerhq.hu/mailman/listinfo/mplayer-dev-eng



More information about the MPlayer-dev-eng mailing list