changeset 3186:1d4fb4d9aab5

Patch by D. Holm to make audio with dxr3 working.
author atmos4
date Wed, 28 Nov 2001 15:33:38 +0000
parents a1205b22a5f4
children ad286d1b7705
files DOCS/DXR3 libao2/ao_dxr3.c libvo/vo_dxr3.c
diffstat 3 files changed, 53 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- 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 <codecname>"), 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, <dholm@iname.com> or by using
 icq: 798427
--- 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 <errno.h>
+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);
 }
 
--- 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 )