diff -Naur -x CVS -x .* main/configure main.ap/configure --- main/configure Wed Oct 31 19:25:28 2001 +++ main.ap/configure Thu Nov 1 23:00:35 2001 @@ -182,6 +182,7 @@ --enable-sdl build with SDL render support [autodetect] --enable-aa build with AAlib render support [autodetect] --enable-ggi build with GGI render support [autodetect] + --enable-dxr3 build with DXR3/H+ render support [autodetect] --enable-mga build with mga_vid support (check for /dev/mga_vid) [autodetect] --enable-xmga build with mga_vid X Window support @@ -560,6 +561,7 @@ _dga2=no _svga=no _fbdev=no +_dxr3=no linux && _fbdev=yes _lirc=no _css=no @@ -584,6 +586,7 @@ _x11lib= _xineramalib= _iconvlib= +_dxr3lib= _select='#define HAVE_AUDIO_SELECT' @@ -642,6 +645,7 @@ #include int main( void ) { return 0; } EOF +_libavcodec_so=no cc_check $_extraincdir $_extralibdir -lffmpeg && _libavcodec_so=yes if test -c /dev/mga_vid ; then @@ -906,6 +910,9 @@ _aa=no cc_check $_extraincdir $_extralibdir -laa && _aa=yes +_dxr3=no +cc_check $_extraincdir $_extralibdir -ldxr3 && _dxr3=yes + _divx4linux=no cc_check $_extraincdir $_extralibdir -ldivxdecore -lm && _divx4linux=yes @@ -1346,6 +1353,9 @@ --enable-fbdev) _fbdev=yes ;; + --enable-dxr3) + _dxr3=yes + ;; --enable-iconv) _iconv=yes ;; @@ -1462,6 +1472,9 @@ --disable-fbdev) _fbdev=no ;; + --disable-dxr3) + _dxr3=no + ;; --disable-iconv) _iconv=no ;; @@ -1713,6 +1726,7 @@ echo "Checking for Xf86VM ... $_vm" echo "Checking for SVGAlib ... $_svga" echo "Checking for FBDev ... $_fbdev" +echo "Checking for DXR3/H+ ... $_dxr3" echo "Checking for OSS Audio ... $_oss_audio" echo "Checking for ALSA Audio ... $_alsaver" echo "Checking for ESD Audio ... $_esd" @@ -2362,6 +2376,15 @@ _fbdev='#undef HAVE_FBDEV' fi +if test "$_dxr3" = yes ; then + _dxr3='#define HAVE_DXR3' + _dxr3lib='-ldxr3' + _vosrc=$_vosrc' vo_dxr3.c' + _aosrc=$_aosrc' ao_dxr3.c' +else + _dxr3='#undef HAVE_DXR3' +fi + if test "$_gui" = yes ; then _gui_def='#define HAVE_NEW_GUI' _gui_lib='-LGui -lgui $(GTKLIB) $(GLIBLIB)' @@ -2407,7 +2430,7 @@ X11_INC=$_x11incdir X11DIR=$_x11libdir -X_LIBS=$_x11libdir $_extralibdir $_gllib $_ggilib $_sdllib $_dgalib $_x11lib $_xvlib $_vmlib $_svgalib $_libpng $_socklib $_aalib $_libvorbis $_xineramalib $_libmad $_zlib +X_LIBS=$_x11libdir $_extralibdir $_gllib $_ggilib $_sdllib $_dxr3lib $_dgalib $_x11lib $_xvlib $_vmlib $_svgalib $_libpng $_socklib $_aalib $_libvorbis $_xineramalib $_libmad $_zlib TERMCAP_LIB=$_libtermcap XMM_LIBS = $_xmmplibs @@ -2569,7 +2592,7 @@ /* ffmpeg's libavcodec support (requires libavcodec source) */ $_libavcodec -$_libavcodecso +$_libavcodec_so /* use only decoders from libavcodec: */ #define CONFIG_DECODERS @@ -2674,6 +2697,7 @@ $_xmga $_syncfb $_fbdev +$_dxr3 $_svga $_have_xdpms $_aa diff -Naur -x CVS -x .* main/libao2/ao_dxr3.c main.ap/libao2/ao_dxr3.c --- main/libao2/ao_dxr3.c Thu Jan 1 01:00:00 1970 +++ main.ap/libao2/ao_dxr3.c Thu Nov 1 22:28:05 2001 @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include "../config.h" + +#include "afmt.h" + +#include "audio_out.h" +#include "audio_out_internal.h" + +struct +{ + int ao_format; + int ao_rate; + int ao_channels; +} ao_device; + +static ao_info_t info = +{ + "DXR3/H+ audio out", + "dxr3", + "David Holm ", + "" +}; + +LIBAO_EXTERN(dxr3) + +// there are some globals: +// ao_samplerate +// ao_channels +// ao_format +// ao_bps +// ao_outburst +// ao_buffersize + +// to set/get/query special features/parameters +static int control(int cmd,int arg) +{ + switch(cmd) + { + case AOCONTROL_SET_DEVICE: + return CONTROL_OK; + case AOCONTROL_QUERY_FORMAT: + return CONTROL_TRUE; + case AOCONTROL_GET_VOLUME: + case AOCONTROL_SET_VOLUME: + { + return CONTROL_OK; + } + } + return CONTROL_TRUE; +} + +// open & setup audio device +// return: 1=success 0=fail +static int init(int rate,int channels,int format,int flags) +{ + ao_device.ao_format = format; + ao_device.ao_rate = rate; + ao_device.ao_channels = channels; + + if( dxr3_get_status() == DXR3_STATUS_CLOSED ) + { + if( dxr3_open( "/dev/em8300", "/etc/dxr3.ux" ) != 0 ) printf( "Error loading /dev/em8300 with /etc/dxr3.ux microcode\n" ); + printf( "DXR3 status: &s\n", dxr3_get_status() ? "opened":"closed" ); + } + else + printf( "DXR3 already open\n" ); + + if( dxr3_set_playmode( DXR3_PLAYMODE_PLAY ) != 0 ) printf( "Error setting playmode of DXR3\n" ); + + if( format == AFMT_AC3 ) + { + if( dxr3_audio_set_mode( DXR3_AUDIOMODE_DIGITALAC3 ) != 0 ) + { + printf( "Cannot set DXR3 to AC3 playback!\n" ); + return -1; + } + } + else + { + if( dxr3_audio_set_mode( DXR3_AUDIOMODE_ANALOG ) != 0 ) + { + printf( "Cannot set DXR3 to analog playback!\n" ); + return -1; + } + if( format == AFMT_U8 ) + dxr3_audio_set_samplesize( 8 ); + else if( format == AFMT_S16_LE ) + dxr3_audio_set_samplesize( 16 ); + else + { + printf( "Unsupported audio format\n" ); + return -1; + } + } + + dxr3_audio_set_stereo( (channels > 1) ? "true":"false" ); + dxr3_audio_set_rate( rate ); + + return 1; +} + +// close audio device +static void uninit() +{ + dxr3_close(); +} + +// stop playing and empty buffers (for seeking/pause) +static void reset() +{ + uninit(); + if( !init( ao_device.ao_rate, ao_device.ao_channels, ao_device.ao_format, 0 ) ) + printf("\nFatal error: *** CANNOT RE-OPEN / RESET AUDIO DEVICE ***\n"); +} + +// stop playing, keep buffers (for pause) +static void audio_pause() +{ + // for now, just call reset(); + reset(); +} + +// resume playing, after audio_pause() +static void audio_resume() +{ +} + + +// return: how many bytes can be played without blocking +static int get_space() +{ + return dxr3_audio_get_buffersize()-dxr3_audio_get_bytesleft(); +} + +// plays 'len' bytes of 'data' +// it should round it down to outburst*n +// return: number of bytes played +static int play(void* data,int len,int flags) +{ + if(len) + if( ao_device.ao_format == AFMT_AC3 ) + return dxr3_audio_write_ac3( data, len ); + else + return dxr3_audio_write_ac3( data, len ); + + printf( "Invalid audio data\n" ); + return 0; +} + +// return: how many unplayed bytes are in the buffer +static int get_delay() +{ + return dxr3_audio_get_bytesleft(); +} + diff -Naur -x CVS -x .* main/libao2/audio_out.c main.ap/libao2/audio_out.c --- main/libao2/audio_out.c Wed Oct 24 16:02:18 2001 +++ main.ap/libao2/audio_out.c Thu Nov 1 22:28:05 2001 @@ -37,6 +37,9 @@ #ifdef USE_SGI_AUDIO extern ao_functions_t audio_out_sgi; #endif +#ifdef HAVE_DXR3 +extern ao_functions_t audio_out_dxr3; +#endif extern ao_functions_t audio_out_pcm; extern ao_functions_t audio_out_pss; @@ -63,6 +66,9 @@ #endif #ifdef HAVE_SDL &audio_out_sdl, +#endif +#ifdef HAVE_DXR3 + &audio_out_dxr3, #endif &audio_out_pcm, // &audio_out_pss, diff -Naur -x CVS -x .* main/libvo/video_out.c main.ap/libvo/video_out.c --- main/libvo/video_out.c Wed Oct 31 23:04:28 2001 +++ main.ap/libvo/video_out.c Thu Nov 1 22:28:05 2001 @@ -70,6 +70,7 @@ extern vo_functions_t video_out_ggi; extern vo_functions_t video_out_aa; extern vo_functions_t video_out_mpegpes; +extern vo_functions_t video_out_dxr3; #ifdef TARGET_LINUX extern vo_functions_t video_out_vesa; #endif @@ -118,6 +119,9 @@ #endif #ifdef HAVE_AA &video_out_aa, +#endif +#ifdef HAVE_DXR3 + &video_out_dxr3, #endif #ifdef HAVE_PNG diff -Naur -x CVS -x .* main/libvo/vo_dxr3.c main.ap/libvo/vo_dxr3.c --- main/libvo/vo_dxr3.c Thu Jan 1 01:00:00 1970 +++ main.ap/libvo/vo_dxr3.c Thu Nov 1 22:51:39 2001 @@ -0,0 +1,323 @@ +#define PES_MAX_SIZE 2048 +/* + * vo_dxr3.c - DXR3/H+ video out + * + * Copyright (C) 2001 David Holm + * + * libav - MPEG-PS multiplexer, part of ffmpeg + * Copyright Gerard Lantau (see http://ffmpeg.sf.net) + * + */ + +#include "fastmemcpy.h" +#include +#include +#include + +#include +#include +#include + +#include + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" + +#include "yuv2rgb.h" +#ifdef HAVE_MMX +#include "mmx.h" +#endif + +LIBVO_EXTERN (dxr3) + +#ifdef USE_LIBAVCODEC + +#ifdef USE_LIBAVCODEC_SO +#include +#else +#include "../libavcodec/avcodec.h" +#endif +static AVPicture picture; +static AVCodec *codec=NULL; +static AVCodecContext codec_context; +extern int avcodec_inited; +#endif + +static unsigned char *picture_buf=NULL; +static unsigned char *outbuf=NULL; +static int outbuf_size = 100000; +static int s_pos_x,s_pos_y; +static int d_pos_x,d_pos_y; +static int osd_w,osd_h; +static uint32_t img_format = 0; + +static vo_info_t vo_info = +{ + "DXR3/H+ video out", + "dxr3", + "David Holm ", + "" +}; + +static uint32_t +init(uint32_t s_width, uint32_t s_height, uint32_t width, uint32_t height, uint32_t fullscreen, char *title, uint32_t format) +{ + if( dxr3_get_status() == DXR3_STATUS_CLOSED ) + { + if( dxr3_open( "/dev/em8300", "/etc/dxr3.ux" ) != 0 ) printf( "Error loading /dev/em8300 with /etc/dxr3.ux microcode file\n" ); + printf( "DXR3 status: %s\n", dxr3_get_status() ? "opened":"closed" ); + } + else + printf( "DXR3 already open\n" ); + + if( dxr3_set_playmode( DXR3_PLAYMODE_PLAY ) !=0 ) printf( "Error setting playmode of DXR3\n" ); + + img_format = format; + picture_buf=NULL; + if( format == IMGFMT_YV12 ) + { +#ifdef USE_LIBAVCODEC + + int size; + + printf("Format: YV12\n"); + + if(!avcodec_inited){ + avcodec_init(); + avcodec_register_all(); + avcodec_inited=1; + } + + /* find the mpeg1 video encoder */ + codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); + if (!codec) { + fprintf(stderr, "mpeg1 codec not found\n"); + return -1; + } + + memset(&codec_context,0,sizeof(codec_context)); + codec_context.bit_rate=100000; // not used + codec_context.frame_rate=25*FRAME_RATE_BASE; // !!!!! + codec_context.gop_size=0; // I frames only + codec_context.flags=CODEC_FLAG_QSCALE; + codec_context.quality=1; // quality! 1..31 (1=best,slowest) + codec_context.pix_fmt = PIX_FMT_RGB24; + if(width<=352 && height<=288){ + codec_context.width=352; + codec_context.height=288; + } else + if(width<=352 && height<=576){ + codec_context.width=352; + codec_context.height=576; + } else + if(width<=480 && height<=576){ + codec_context.width=480; + codec_context.height=576; + } else + if(width<=544 && height<=576){ + codec_context.width=544; + codec_context.height=576; + } else { + codec_context.width=704; + codec_context.height=576; + } + + osd_w=s_width; + d_pos_x=(codec_context.width-(int)s_width)/2; + if(d_pos_x<0){ + s_pos_x=-d_pos_x;d_pos_x=0; + osd_w=codec_context.width; + } else s_pos_x=0; + + osd_h=s_height; + d_pos_y=(codec_context.height-(int)s_height)/2; + if(d_pos_y<0){ + s_pos_y=-d_pos_y;d_pos_y=0; + osd_h=codec_context.height; + } else s_pos_y=0; + + printf("[vo] position mapping: %d;%d => %d;%d\n",s_pos_x,s_pos_y,d_pos_x,d_pos_y); + + /* open it */ + if (avcodec_open(&codec_context, codec) < 0) { + fprintf(stderr, "could not open codec\n"); + return -1; + } + + outbuf_size=10000+width*height; // must be enough! + outbuf = malloc(outbuf_size); + + size = codec_context.width*codec_context.height; + picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */ + + picture.data[0] = picture_buf; + picture.data[1] = picture.data[0] + size; + picture.data[2] = picture.data[1] + size / 4; + picture.linesize[0] = codec_context.width; + picture.linesize[1] = codec_context.width / 2; + picture.linesize[2] = codec_context.width / 2; + return 0; +#endif + return -1; + } + else if(format==IMGFMT_MPEGPES) + { + printf( "Format: MPEG-PES\n" ); + return 0; + } + + printf( "Format: Unsupported\n" ); + return -1; +} + +static const vo_info_t* +get_info(void) +{ + return &vo_info; +} + +static void draw_alpha(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride) +{ + int x,y; + if( img_format == IMGFMT_YV12 ) + vo_draw_alpha_yv12(w,h,src,srca,stride,picture.data[0]+(x0+d_pos_x)+(y0+d_pos_y)*picture.linesize[0],picture.linesize[0]); +} + +static void draw_osd(void) +{ + if( img_format == IMGFMT_YV12 ) + { + vo_draw_text(osd_w,osd_h,draw_alpha); + } +} + +static uint32_t draw_frame(uint8_t * src[]) +{ + int data_left; + if( img_format == IMGFMT_MPEGPES ) + { + vo_mpegpes_t *p=(vo_mpegpes_t *)src[0]; + + data_left = p->size; + while( data_left ) + data_left -= dxr3_video_write( &((unsigned char*)p->data)[p->size-data_left], data_left ); + + return 0; + } +#ifdef USE_LIBAVCODEC + else if( img_format == IMGFMT_YV12 ) + { + printf("ERROR: Uninplemented\n"); + } +#endif + + printf( "Error in draw_frame(...)" ); + return -1; +} + +static void flip_page (void) +{ +#ifdef USE_LIBAVCODEC + if( img_format == IMGFMT_YV12 ) + { + int out_size, tmp_size; + /* encode the image */ + tmp_size = out_size = avcodec_encode_video(&codec_context, outbuf, outbuf_size, &picture); + while( out_size ) + out_size -= dxr3_video_write( &outbuf[tmp_size-out_size], out_size ); + } +#endif +} + +static uint32_t draw_slice( uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0 ) +{ + int y; + unsigned char* s; + unsigned char* d; + int data_left; + vo_mpegpes_t *p = (vo_mpegpes_t *)srcimg[0]; + + if( img_format == IMGFMT_YV12 ) + { + x0+=d_pos_x; + y0+=d_pos_y; + if(x0+w>picture.linesize[0]) w=picture.linesize[0]-x0; // !! + if(y0+h>codec_context.height) h=codec_context.height-y0; + + // Y + s=srcimg[0]+s_pos_x+s_pos_y*stride[0]; + d=picture.data[0]+x0+y0*picture.linesize[0]; + for( y = 0; y < h; y++) + { + memcpy(d,s,w); + s+=stride[0]; + d+=picture.linesize[0]; + } + + w/=2;h/=2;x0/=2;y0/=2; + + // U + s=srcimg[1]+(s_pos_x/2)+(s_pos_y/2)*stride[1]; + d=picture.data[1]+x0+y0*picture.linesize[1]; + for( y = 0; y < h; y++) + { + memcpy(d,s,w); + s+=stride[1]; + d+=picture.linesize[1]; + } + + // V + s=srcimg[2]+(s_pos_x/2)+(s_pos_y/2)*stride[2]; + d=picture.data[2]+x0+y0*picture.linesize[2]; + for(y=0;ysize; + while( data_left ) + data_left -= dxr3_video_write( &((unsigned char*)p->data)[p->size-data_left], data_left ); + return 0; + } + + return -1; +} + + +static uint32_t +query_format(uint32_t format) +{ + if(format==IMGFMT_MPEGPES) return 1; +#ifdef USE_LIBAVCODEC + if(format==IMGFMT_YV12) return 1; +#endif + return 0; +} + +static void +uninit(void) +{ +#ifdef USE_LIBAVCODEC + if( img_format == IMGFMT_YV12 ) + { + free(outbuf); + free(picture_buf); + } +#endif + dxr3_close( ); +} + + +static void check_events(void) +{ +} +