[Mplayer-cvslog] CVS: main/libao2 ao_sun.c,1.2,1.3

Felix Buenemann atmosfear at users.sourceforge.net
Fri Jun 22 23:37:15 CEST 2001


Update of /cvsroot/mplayer/main/libao2
In directory usw-pr-cvs1:/tmp/cvs-serv2113

Modified Files:
	ao_sun.c 
Log Message:
Applied patch by Jürgen Keil (jk at tools.de), improves smoothness of video playback.


Index: ao_sun.c
===================================================================
RCS file: /cvsroot/mplayer/main/libao2/ao_sun.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** ao_sun.c	2001/06/08 23:31:06	1.2
--- ao_sun.c	2001/06/22 21:37:13	1.3
***************
*** 1,11 ****
  #include <stdio.h>
  #include <stdlib.h>
  
- #include <sys/ioctl.h>
  #include <unistd.h>
  #include <sys/time.h>
  #include <sys/types.h>
  #include <sys/stat.h>
- #include <fcntl.h>
  #include <sys/audioio.h>
  #ifdef	__svr4__
--- 1,13 ----
  #include <stdio.h>
  #include <stdlib.h>
+ #include <string.h>
  
  #include <unistd.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <sys/ioctl.h>
  #include <sys/time.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/audioio.h>
  #ifdef	__svr4__
***************
*** 21,28 ****
  static ao_info_t info = 
  {
! 	"Sun audio output",
! 	"sun",
! 	"jk at tools.de",
! 	""
  };
  
--- 23,30 ----
  static ao_info_t info = 
  {
!     "Sun audio output",
!     "sun",
!     "jk at tools.de",
!     ""
  };
  
***************
*** 30,37 ****
  
  
  #ifndef	AUDIO_PRECISION_8
! #define AUDIO_PRECISION_8  8
! #define AUDIO_PRECISION_16 16
  #endif
  
  
--- 32,44 ----
  
  
+ /* These defines are missing on NetBSD */
  #ifndef	AUDIO_PRECISION_8
! #define AUDIO_PRECISION_8	8
! #define AUDIO_PRECISION_16	16
  #endif
+ #ifndef	AUDIO_CHANNELS_MONO
+ #define	AUDIO_CHANNELS_MONO	1
+ #define	AUDIO_CHANNELS_STEREO	2
+ #endif
  
  
***************
*** 44,50 ****
  // ao_buffersize
  
! static char *dsp="/dev/audio";
  static int queued_bursts = 0;
! static int audio_fd=-1;
  
  // convert an OSS audio format specification into a sun audio encoding
--- 51,67 ----
  // ao_buffersize
  
! static char *audio_dev = "/dev/audio";
  static int queued_bursts = 0;
! static int queued_samples = 0;
! static int bytes_per_sample = 0;
! static int audio_fd = -1;
! static enum {
!     RTSC_UNKNOWN = 0,
!     RTSC_ENABLED,
!     RTSC_DISABLED
! } enable_sample_timing;
! 
! extern int verbose;
! 
  
  // convert an OSS audio format specification into a sun audio encoding
***************
*** 69,82 ****
  }
  
  // to set/get/query special features/parameters
  static int control(int cmd,int arg){
!     switch(cmd){
! 	case AOCONTROL_SET_DEVICE:
! 	    dsp=(char*)arg;
! 	    return CONTROL_OK;
! 	case AOCONTROL_QUERY_FORMAT:
! 	    return CONTROL_TRUE;
!     }
!     return CONTROL_UNKNOWN;
  }
  
--- 86,210 ----
  }
  
+ // try to figure out, if the soundcard driver provides usable (precise)
+ // sample counter information
+ static int realtime_samplecounter_available(char *dev)
+ {
+     int fd = -1;
+     audio_info_t info;
+     int rtsc_ok = RTSC_DISABLED;
+     int len;
+     void *silence = NULL;
+     struct timeval start, end;
+     struct timespec delay;
+     int usec_delay;
+     unsigned last_samplecnt;
+     unsigned increment;
+     unsigned min_increment;
+ 
+     len = 44100 * 4 / 4;    // amount of data for 0.25sec of 44.1khz, stereo, 16bit
+     silence = calloc(1, len);
+     if (silence == NULL)
+ 	goto error;
+     
+     if ((fd = open(dev, O_WRONLY)) < 0)
+ 	goto error;
+ 
+     AUDIO_INITINFO(&info);
+     info.play.sample_rate = 44100;
+     info.play.channels = AUDIO_CHANNELS_STEREO;
+     info.play.precision = AUDIO_PRECISION_16;
+     info.play.encoding = AUDIO_ENCODING_LINEAR;
+     info.play.samples = 0;
+     if (ioctl(fd, AUDIO_SETINFO, &info)) {
+ 	if (verbose)
+ 	    printf("rtsc: SETINFO failed\n");
+ 	goto error;
+     }
+     
+     if (write(fd, silence, len) != len) {
+ 	if (verbose)
+ 	    printf("rtsc: write failed");
+ 	goto error;
+     }
+ 
+     if (ioctl(fd, AUDIO_GETINFO, &info)) {
+ 	if (verbose)
+ 	    perror("rtsc: GETINFO1");
+ 	goto error;
+     }
+ 
+     last_samplecnt = info.play.samples;
+     min_increment = ~0;
+ 
+     gettimeofday(&start, NULL);
+     for (;;) {
+ 	delay.tv_sec = 0;
+ 	delay.tv_nsec = 10000000;
+ 	nanosleep(&delay, NULL);
+ 	gettimeofday(&end, NULL);
+ 	usec_delay = (end.tv_sec - start.tv_sec) * 1000000
+ 	    + end.tv_usec - start.tv_usec;
+ 
+ 	// stop monitoring sample counter after 0.2 seconds
+ 	if (usec_delay > 200000)
+ 	    break;
+ 
+ 	if (ioctl(fd, AUDIO_GETINFO, &info)) {
+ 	    if (verbose)
+ 		perror("rtsc: GETINFO2 failed");
+ 	    goto error;
+ 	}
+ 	if (info.play.samples < last_samplecnt) {
+ 	    if (verbose)
+ 		printf("rtsc: %d > %d?\n", last_samplecnt, info.play.samples);
+ 	    goto error;
+ 	}
+ 
+ 	if ((increment = info.play.samples - last_samplecnt) > 0) {
+ 	    if (verbose)
+ 		printf("ao_sun: sample counter increment: %d\n", increment);
+ 	    if (increment < min_increment) {
+ 		min_increment = increment;
+ 		if (min_increment < 2000)
+ 		    break;	// looks good
+ 	    }
+ 	}
+ 	last_samplecnt = info.play.samples;
+     }
+ 
+     if (min_increment < 2000)
+ 	rtsc_ok = RTSC_ENABLED;
+ 
+     if (verbose)
+ 	printf("ao_sun: minimum sample counter increment per 10msec interval: %d\n"
+ 	       "\t%susing sample counter based timing code\n",
+ 	       min_increment, rtsc_ok == RTSC_ENABLED ? "" : "not ");
+     
+ 
+ error:
+     if (silence != NULL) free(silence);
+     if (fd >= 0) {
+ #ifdef	__svr4__
+ 	// remove the 0 bytes from the above measurement from the
+ 	// audio driver's STREAMS queue
+ 	ioctl(fd, I_FLUSH, FLUSHW);
+ #endif
+ 	//ioctl(fd, AUDIO_DRAIN, 0);
+ 	close(fd);
+     }
+ 
+     return rtsc_ok;
+ }
+ 
  // to set/get/query special features/parameters
  static int control(int cmd,int arg){
!   switch(cmd){
!     case AOCONTROL_SET_DEVICE:
!       audio_dev=(char*)arg;
!       return CONTROL_OK;
!     case AOCONTROL_QUERY_FORMAT:
!       return CONTROL_TRUE;
!   }
!   return CONTROL_UNKNOWN;
  }
  
***************
*** 88,96 ****
    int byte_per_sec;
  
!   printf("ao2: %d Hz  %d chans  0x%X\n",rate,channels,format);
  
!   audio_fd=open(dsp, O_WRONLY);
    if(audio_fd<0){
!     printf("Can't open audio device %s  -> nosound\n",dsp);
      return 0;
    }
--- 216,230 ----
    int byte_per_sec;
  
!   if (enable_sample_timing == RTSC_UNKNOWN
!       && !getenv("AO_SUN_DISABLE_SAMPLE_TIMING")) {
!       enable_sample_timing = realtime_samplecounter_available(audio_dev);
!   }
  
!   printf("ao2: %d Hz  %d chans  %s [0x%X]\n",
! 	 rate,channels,audio_out_format_name(format),format);
! 
!   audio_fd=open(audio_dev, O_WRONLY);
    if(audio_fd<0){
!     printf("Can't open audio device %s, %s  -> nosound\n", audio_dev, strerror(errno));
      return 0;
    }
***************
*** 102,114 ****
    info.play.precision = (format==AFMT_S16_LE? AUDIO_PRECISION_16:AUDIO_PRECISION_8);
    info.play.channels = ao_channels = channels;
-   --ao_channels;
    info.play.sample_rate = ao_samplerate = rate;
-   info.play.samples = 0;
-   info.play.eof = 0;
    if(ioctl (audio_fd, AUDIO_SETINFO, &info)<0)
      printf("audio_setup: your card doesn't support %d channel, %s, %d Hz samplerate\n",channels,audio_out_format_name(format),rate);
!   byte_per_sec = (channels * info.play.precision * rate);
!   ao_outburst=byte_per_sec > 100000 ? 16384 : 8192;
!   queued_bursts = 0;
  
    if(ao_buffersize==-1){
--- 236,245 ----
    info.play.precision = (format==AFMT_S16_LE? AUDIO_PRECISION_16:AUDIO_PRECISION_8);
    info.play.channels = ao_channels = channels;
    info.play.sample_rate = ao_samplerate = rate;
    if(ioctl (audio_fd, AUDIO_SETINFO, &info)<0)
      printf("audio_setup: your card doesn't support %d channel, %s, %d Hz samplerate\n",channels,audio_out_format_name(format),rate);
!   bytes_per_sample = channels * info.play.precision / 8;
!   byte_per_sec = bytes_per_sample * rate;
!   ao_outburst = byte_per_sec > 100000 ? 16384 : 8192;
  
    if(ao_buffersize==-1){
***************
*** 141,150 ****
  #endif
    }
  
!     return 1;
  }
  
  // close audio device
  static void uninit(){
      close(audio_fd);
  }
--- 272,294 ----
  #endif
    }
+ 
+   AUDIO_INITINFO(&info);
+   info.play.samples = 0;
+   info.play.eof = 0;
+   info.play.error = 0;
+   ioctl (audio_fd, AUDIO_SETINFO, &info);
+ 
+   queued_bursts = 0;
+   queued_samples = 0;
  
!   return 1;
  }
  
  // close audio device
  static void uninit(){
+ #ifdef	__svr4__
+     // throw away buffered data in the audio driver's STREAMS queue
+     ioctl(audio_fd, I_FLUSH, FLUSHW);
+ #endif
      close(audio_fd);
  }
***************
*** 154,165 ****
      audio_info_t info;
  
- #ifdef	__svr4__
-     // throw away buffered data in the audio driver's STREAMS queue
-     ioctl(audio_fd, I_FLUSH, FLUSHW);
- #endif
      uninit();
!     audio_fd=open(dsp, O_WRONLY);
      if(audio_fd<0){
! 	printf("\nFatal error: *** CANNOT RE-OPEN / RESET AUDIO DEVICE ***\n");
  	return;
      }
--- 298,305 ----
      audio_info_t info;
  
      uninit();
!     audio_fd=open(audio_dev, O_WRONLY);
      if(audio_fd<0){
! 	printf("\nFatal error: *** CANNOT RE-OPEN / RESET AUDIO DEVICE (%s) ***\n", strerror(errno));
  	return;
      }
***************
*** 170,179 ****
      info.play.encoding = oss2sunfmt(ao_format);
      info.play.precision = (ao_format==AFMT_S16_LE? AUDIO_PRECISION_16:AUDIO_PRECISION_8);
!     info.play.channels = ao_channels+1;
      info.play.sample_rate = ao_samplerate;
      info.play.samples = 0;
      info.play.eof = 0;
      ioctl (audio_fd, AUDIO_SETINFO, &info);
      queued_bursts = 0;
  }
  
--- 310,321 ----
      info.play.encoding = oss2sunfmt(ao_format);
      info.play.precision = (ao_format==AFMT_S16_LE? AUDIO_PRECISION_16:AUDIO_PRECISION_8);
!     info.play.channels = ao_channels;
      info.play.sample_rate = ao_samplerate;
      info.play.samples = 0;
      info.play.eof = 0;
+     info.play.error = 0;
      ioctl (audio_fd, AUDIO_SETINFO, &info);
      queued_bursts = 0;
+     queued_samples = 0;
  }
  
***************
*** 199,223 ****
  // return: how many bytes can be played without blocking
  static int get_space(){
!   int playsize=ao_outburst;
  
      // check buffer
  #ifdef HAVE_AUDIO_SELECT
!     {  fd_set rfds;
!        struct timeval tv;
!        FD_ZERO(&rfds);
!        FD_SET(audio_fd, &rfds);
!        tv.tv_sec = 0;
!        tv.tv_usec = 0;
!        if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) return 0; // not block!
      }
  #endif
  
-   {
-     audio_info_t info;
      ioctl(audio_fd, AUDIO_GETINFO, &info);
!     if(queued_bursts - info.play.eof > 2)
!       return 0;
!   }
!   return ao_outburst;
  }
  
--- 341,365 ----
  // return: how many bytes can be played without blocking
  static int get_space(){
!     int playsize = ao_outburst;
!     audio_info_t info;
  
      // check buffer
  #ifdef HAVE_AUDIO_SELECT
!     {
! 	fd_set rfds;
! 	struct timeval tv;
! 	FD_ZERO(&rfds);
! 	FD_SET(audio_fd, &rfds);
! 	tv.tv_sec = 0;
! 	tv.tv_usec = 0;
! 	if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) return 0; // not block!
      }
  #endif
  
      ioctl(audio_fd, AUDIO_GETINFO, &info);
!     if (queued_bursts - info.play.eof > 2)
! 	return 0;
! 
!     return ao_outburst;
  }
  
***************
*** 226,246 ****
  // return: number of bytes played
  static int play(void* data,int len,int flags){
!     len/=ao_outburst;
!     len=write(audio_fd,data,len*ao_outburst);
!     if(len>0) {
!       queued_bursts ++;
!       write(audio_fd,data,0);
      }
      return len;
  }
  
- static int audio_delay_method=2;
  
  // return: how many unplayed bytes are in the buffer
  static int get_delay(){
-     int q;
      audio_info_t info;
      ioctl(audio_fd, AUDIO_GETINFO, &info);
!     return (queued_bursts - info.play.eof) * ao_outburst;
  }
  
--- 368,393 ----
  // return: number of bytes played
  static int play(void* data,int len,int flags){
!     if (len < ao_outburst) return 0;
!     len /= ao_outburst;
!     len = write(audio_fd, data, len*ao_outburst);
!     if(len > 0) {
!       queued_samples += len / bytes_per_sample;
!       if (write(audio_fd,data,0) < 0)
! 	  perror("ao_sun: send EOF audio record");
!       else
! 	  queued_bursts ++;
      }
      return len;
  }
  
  
  // return: how many unplayed bytes are in the buffer
  static int get_delay(){
      audio_info_t info;
      ioctl(audio_fd, AUDIO_GETINFO, &info);
!     if (info.play.samples && enable_sample_timing == RTSC_ENABLED)
! 	return (queued_samples - info.play.samples) * bytes_per_sample;
!     else
! 	return (queued_bursts - info.play.eof) * ao_outburst;
  }
  


_______________________________________________
Mplayer-cvslog mailing list
Mplayer-cvslog at lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/mplayer-cvslog



More information about the MPlayer-cvslog mailing list