[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