# HG changeset patch # User atmos4 # Date 1006961618 0 # Node ID 1d4fb4d9aab5adedda484008d3dd4cc97f9de8d6 # Parent a1205b22a5f45eb9a521a52845f1883398c647e8 Patch by D. Holm to make audio with dxr3 working. diff -r a1205b22a5f4 -r 1d4fb4d9aab5 DOCS/DXR3 --- a/DOCS/DXR3 Wed Nov 28 15:32:56 2001 +0000 +++ b/DOCS/DXR3 Wed Nov 28 15:33:38 2001 +0000 @@ -1,6 +1,11 @@ DXR3/H+ video/audio output plugins manual by David Holm ======================================================= +2001-11-27: -ao dxr3 now works, still a few bugs though + you might have to reload the em8300 modules + after a playback or you might get static the + next time you use the dxr3 audio interface. + 1. Introduction The DXR3 and Hollywood+ are two not too different mpeg-(1/2) and ac3 @@ -64,8 +69,7 @@ After installation you will have two new outdevices in mplayer: -vo dxr3 For video output - -ao dxr3 For audio output (due to an unresolved bug - this is not recommended/useful!) + -ao dxr3 For audio output MPEG-1, MPEG-2, VCD and DVD Notes There are some notes to take into account here for optimum playback. @@ -83,22 +87,17 @@ to run faster tell me which one because I'll be interested in how it could possibly be any faster than OpenDivX4Linux... -Unsupported Codecs: -If you ever get a codec unsupported message, lookup the codec in the -codecs.conf file (search for "videocodec "), copy the entire -codec section and send it to me and I'll make sure it works with the -next patch (or the next after that if I have a thousand things to take -care of first ;) my e-mail is at the bottom of this page. - -4. Todo - - * Scale video played using windows codecs (High) - * Make the osd use the subpic feature of the dxr3 (almost done)(High) - * Driver options (probably not until libvo2) (Medium) +Other codecs: +Currently they don't work. I'm working on implementing libvo2 which +will be a much more convenient and faster way of working with +vo<->codec interaction. If libvo2 takes longer to develop than I +have estimated perhaps I'll add more codec support to libvo. Otherwise +you'll just have to wait for libvo2. (there is an implementation +for other codecs, but I think it's pretty broken currently ;) -5. Contacting me +4. Contacting me You can contact me either by e-mailing me, or by using icq: 798427 diff -r a1205b22a5f4 -r 1d4fb4d9aab5 libao2/ao_dxr3.c --- a/libao2/ao_dxr3.c Wed Nov 28 15:32:56 2001 +0000 +++ b/libao2/ao_dxr3.c Wed Nov 28 15:33:38 2001 +0000 @@ -16,6 +16,9 @@ #include "audio_out.h" #include "audio_out_internal.h" +void perror( const char *s ); +#include +int sys_nerr; extern int verbose; static ao_info_t info = @@ -28,15 +31,6 @@ LIBAO_EXTERN(dxr3) -// there are some globals: -// ao_samplerate -// ao_channels -// ao_format -// ao_bps -// ao_outburst -// ao_buffersize - -//static char *em8300_ma="/dev/em8300_ma"; static audio_buf_info dxr3_buf_info; static int fd_control = 0, fd_audio = 0; @@ -73,30 +67,33 @@ printf("AO: [dxr3] Can't open em8300 control /dev/em8300\n"); return 0; } - - ao_format = format; - if( ioctl (fd_audio, SNDCTL_DSP_SETFMT, &ao_format) < 0 ) + + ioctl(fd_audio, SNDCTL_DSP_RESET, NULL); + ao_data.format = format; + if( ioctl (fd_audio, SNDCTL_DSP_SETFMT, &ao_data.format) < 0 ) printf( "AO: [dxr3] Unable to set audio format\n" ); - if(format == AFMT_AC3 && ao_format != AFMT_AC3) + if(format == AFMT_AC3 && ao_data.format != AFMT_AC3) { printf("AO: [dxr3] Can't set audio device /dev/em8300_ma to AC3 output\n"); return 0; } printf("AO: [dxr3] Sample format: %s (requested: %s)\n", - audio_out_format_name(ao_format), audio_out_format_name(format)); + audio_out_format_name(ao_data.format), audio_out_format_name(format)); if(format != AFMT_AC3) { - ao_channels=channels-1; - if( ioctl (fd_audio, SNDCTL_DSP_STEREO, &ao_channels) < 0 ) + ao_data.channels=channels-1; + if( ioctl (fd_audio, SNDCTL_DSP_STEREO, &ao_data.channels) < 0 ) printf( "AO: [dxr3] Unable to set number of channels\n" ); // set rate - ao_samplerate=rate; - if( ioctl (fd_audio, SNDCTL_DSP_SPEED, &ao_samplerate) < 0 ) + ao_data.bps = (channels+1)*rate; + ao_data.samplerate=rate; + if( ioctl (fd_audio, SNDCTL_DSP_SPEED, &ao_data.samplerate) < 0 ) printf( "AO: [dxr3] Unable to set samplerate\n" ); - printf("AO: [dxr3] Using %d Hz samplerate (requested: %d)\n",ao_samplerate,rate); + printf("AO: [dxr3] Using %d Hz samplerate (requested: %d)\n",ao_data.samplerate,rate); } + else ao_data.bps *= 2; if( ioctl(fd_audio, SNDCTL_DSP_GETOSPACE, &dxr3_buf_info)==-1 ) { @@ -104,44 +101,20 @@ printf("AO: [dxr3] Driver doesn't support SNDCTL_DSP_GETOSPACE :-(\n"); if( ioctl( fd_audio, SNDCTL_DSP_GETBLKSIZE, &r) ==-1 ) { - printf( "AO: [dxr3] %d bytes/frag (config.h)\n", ao_outburst ); + printf( "AO: [dxr3] %d bytes/frag (config.h)\n", ao_data.outburst ); } else { - ao_outburst=r; - printf( "AO: [dxr3] %d bytes/frag (GETBLKSIZE)\n",ao_outburst); + ao_data.outburst=r; + printf( "AO: [dxr3] %d bytes/frag (GETBLKSIZE)\n",ao_data.outburst); } } else { printf("AO: [dxr3] frags: %3d/%d (%d bytes/frag) free: %6d\n", dxr3_buf_info.fragments+1, dxr3_buf_info.fragstotal, dxr3_buf_info.fragsize, dxr3_buf_info.bytes); - if(ao_buffersize==-1) ao_buffersize=dxr3_buf_info.bytes; - ao_outburst=dxr3_buf_info.fragsize; - } - - if(ao_buffersize==-1){ - // Measuring buffer size: - void* data; - ao_buffersize=0; -#ifdef HAVE_AUDIO_SELECT - data=malloc(ao_outburst); memset(data,0,ao_outburst); - while(ao_buffersize<0x40000){ - fd_set rfds; - struct timeval tv; - FD_ZERO(&rfds); FD_SET(fd_audio,&rfds); - tv.tv_sec=0; tv.tv_usec = 0; - if(!select(fd_audio+1, NULL, &rfds, NULL, &tv)) break; - write(fd_audio,data,ao_outburst); - ao_buffersize+=ao_outburst; - } - free(data); - if(ao_buffersize==0){ - printf("\nAO: [dxr3] *** Your audio driver DOES NOT support select() ***\n"); - printf("Recompile mplayer with #undef HAVE_AUDIO_SELECT in config.h !\n\n"); - return 0; - } -#endif + ao_data.buffersize=(dxr3_buf_info.bytes/2)-1; + ao_data.outburst=dxr3_buf_info.fragsize; } ioval = EM8300_PLAYMODE_PLAY; @@ -159,6 +132,7 @@ if( ioctl(fd_audio, SNDCTL_DSP_RESET, NULL) < 0 ) printf( "AO: [dxr3] Unable to reset device\n" ); close( fd_audio ); + close( fd_control ); /* Just in case */ } // stop playing and empty buffers (for seeking/pause) @@ -171,8 +145,6 @@ // stop playing, keep buffers (for pause) static void audio_pause() { - // for now, just call reset(); -// reset(); int ioval; fd_control = open( "/dev/em8300", O_WRONLY ); if( fd_control < 0 ) @@ -202,35 +174,35 @@ } } - // return: how many bytes can be played without blocking static int get_space() { int space = 0; - if( ioctl(fd_audio, SNDCTL_DSP_GETOSPACE, &dxr3_buf_info) < 0 ) + if( ioctl(fd_audio, SNDCTL_DSP_GETODELAY, &space) < 0 ) { - printf( "AO: [dxr3] Unable to get free space in buffer\n" ); - return 0; + printf( "AO: [dxr3] Unable to get unplayed bytes in buffer\n" ); + return ao_data.outburst; } - - space = dxr3_buf_info.fragments*dxr3_buf_info.fragsize; + space = ao_data.buffersize - space; return space; } static int play(void* data,int len,int flags) { - int pts = ao_pts; - if( ioctl( fd_audio, EM8300_IOCTL_AUDIO_SETPTS, &pts ) < 0 ) + if( ioctl( fd_audio, EM8300_IOCTL_AUDIO_SETPTS, &ao_data.pts ) < 0 ) printf( "AO: [dxr3] Unable to set pts\n" ); return write(fd_audio,data,len); } // return: how many unplayed bytes are in the buffer -static int get_delay() +static float get_delay() { - int r=0; - if( ioctl(fd_audio, SNDCTL_DSP_GETODELAY, &r) < 0 ) + int r=0; + if( ioctl(fd_audio, SNDCTL_DSP_GETODELAY, &r) < 0 ) + { printf( "AO: [dxr3] Unable to get unplayed bytes in buffer\n" ); - return r; + return ((float)ao_data.buffersize)/(float)ao_data.bps; + } + return (((float)r)/(float)ao_data.bps); } diff -r a1205b22a5f4 -r 1d4fb4d9aab5 libvo/vo_dxr3.c --- a/libvo/vo_dxr3.c Wed Nov 28 15:32:56 2001 +0000 +++ b/libvo/vo_dxr3.c Wed Nov 28 15:33:38 2001 +0000 @@ -381,7 +381,7 @@ /* open it */ if (avcodec_open(&codec_context, codec) < 0) { - printf(stderr, "VO: [dxr3] Could not open codec\n"); + printf( "VO: [dxr3] Could not open codec\n" ); return -1; } @@ -424,7 +424,6 @@ static uint32_t draw_frame(uint8_t * src[]) { - int pts = 0; if( img_format == IMGFMT_MPEGPES ) { int data_left; @@ -432,8 +431,7 @@ unsigned char *data = p->data; data_left = p->size; - pts = p->timestamp; - if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &pts ) < 0 ) + if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts ) < 0 ) printf( "VO: [dxr3] Unable to set PTS in draw_frame\n" ); while( data_left ) data_left -= write( fd_video, &((unsigned char*)p->data)[p->size-data_left], data_left ); @@ -516,8 +514,7 @@ #undef ONE_HALF #undef FIX(x) //End of ffmpeg code, see ffmpeg.sourceforge.net for terms of license - pts = vo_pts; - if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &pts ) < 0 ) + if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts ) < 0 ) printf( "VO: [dxr3] Unable to set PTS in draw_frame\n" ); tmp_size = out_size = avcodec_encode_video(&codec_context, outbuf, outbuf_size, &picture); while( out_size ) @@ -535,8 +532,8 @@ { } } - pts = vo_pts; - if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &pts ) < 0 ) + + if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts ) < 0 ) printf( "VO: [dxr3] Unable to set PTS in draw_frame\n" ); tmp_size = out_size = avcodec_encode_video(&codec_context, outbuf, outbuf_size, &picture); while( out_size )