CVS: rdesktop proto.h, 1.97, 1.98 rdpsnd.c, 1.23, 1.24 rdpsnd.h, 1.7, 1.8 rdpsnd_alsa.c, 1.7, 1.8 rdpsnd_libao.c, 1.27, 1.28 rdpsnd_oss.c, 1.28, 1.29 rdpsnd_sgi.c, 1.14, 1.15 rdpsnd_sun.c, 1.21, 1.22 xwin.c, 1.214, 1.215
Pierre Ossman <[email protected]> Thu, 26 Oct 2006 02:47:19 -0700
| Newsgroups | gmane.network.rdesktop.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv29893
Modified Files:
proto.h rdpsnd.c rdpsnd.h rdpsnd_alsa.c rdpsnd_libao.c
rdpsnd_oss.c rdpsnd_sgi.c rdpsnd_sun.c xwin.c
Log Message:
Rewrite the queue management a bit so that blocks are not completed until
they have finished playing. This also makes the queue system mandatory for
all backends.
Index: proto.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/proto.h,v
retrieving revision 1.97
retrieving revision 1.98
diff -C2 -d -r1.97 -r1.98
*** proto.h 19 Oct 2006 12:26:55 -0000 1.97
--- proto.h 26 Oct 2006 09:47:17 -0000 1.98
***************
*** 164,176 ****
BOOL rdpdr_abort_io(uint32 fd, uint32 major, NTSTATUS status);
/* rdpsnd.c */
- void rdpsnd_send_completion(uint16 tick, uint8 packet_index);
BOOL rdpsnd_init(char *optarg);
void rdpsnd_show_help(void);
void rdpsnd_play(void);
! void rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index);
struct audio_packet *rdpsnd_queue_current_packet(void);
BOOL rdpsnd_queue_empty(void);
! void rdpsnd_queue_init(void);
! void rdpsnd_queue_next(void);
int rdpsnd_queue_next_tick(void);
/* secure.c */
--- 164,175 ----
BOOL rdpdr_abort_io(uint32 fd, uint32 major, NTSTATUS status);
/* rdpsnd.c */
BOOL rdpsnd_init(char *optarg);
void rdpsnd_show_help(void);
void rdpsnd_play(void);
! void rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv);
! void rdpsnd_check_fds(fd_set * rfds, fd_set * wfds);
struct audio_packet *rdpsnd_queue_current_packet(void);
BOOL rdpsnd_queue_empty(void);
! void rdpsnd_queue_next(unsigned long completed_in_us);
int rdpsnd_queue_next_tick(void);
/* secure.c */
Index: rdpsnd.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -C2 -d -r1.23 -r1.24
*** rdpsnd.c 19 Oct 2006 11:28:53 -0000 1.23
--- rdpsnd.c 26 Oct 2006 09:47:17 -0000 1.24
***************
*** 48,56 ****
static unsigned int format_count;
static unsigned int current_format;
! unsigned int queue_hi, queue_lo;
struct audio_packet packet_queue[MAX_QUEUE];
void (*wave_out_play) (void);
static STREAM
rdpsnd_init_packet(uint16 type, uint16 size)
--- 48,61 ----
static unsigned int format_count;
static unsigned int current_format;
! unsigned int queue_hi, queue_lo, queue_pending;
struct audio_packet packet_queue[MAX_QUEUE];
void (*wave_out_play) (void);
+ static void rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index);
+ static void rdpsnd_queue_init(void);
+ static void rdpsnd_queue_complete_pending(void);
+ static long rdpsnd_queue_next_completion(void);
+
static STREAM
rdpsnd_init_packet(uint16 type, uint16 size)
***************
*** 75,79 ****
}
! void
rdpsnd_send_completion(uint16 tick, uint8 packet_index)
{
--- 80,84 ----
}
! static void
rdpsnd_send_completion(uint16 tick, uint8 packet_index)
{
***************
*** 233,240 ****
memcpy(s->data, missing_bytes, 4);
! current_driver->
! wave_out_write(rdpsnd_dsp_process
! (s, current_driver, &formats[current_format]), tick,
! packet_index);
awaiting_data_packet = False;
return;
--- 238,244 ----
memcpy(s->data, missing_bytes, 4);
! rdpsnd_queue_write(rdpsnd_dsp_process
! (s, current_driver, &formats[current_format]), tick,
! packet_index);
awaiting_data_packet = False;
return;
***************
*** 339,343 ****
#if defined(RDPSND_LIBAO)
*reg = libao_register(options);
! assert(*reg);
reg = &((*reg)->next);
#endif
--- 343,347 ----
#if defined(RDPSND_LIBAO)
*reg = libao_register(options);
! assert(*reg);
reg = &((*reg)->next);
#endif
***************
*** 363,366 ****
--- 367,372 ----
}
+ rdpsnd_queue_init();
+
if (optarg != NULL && strlen(optarg) > 0)
{
***************
*** 425,428 ****
--- 431,468 ----
void
+ rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
+ {
+ long next_pending;
+
+ if (g_dsp_busy)
+ {
+ FD_SET(g_dsp_fd, wfds);
+ *n = (g_dsp_fd > *n) ? g_dsp_fd : *n;
+ }
+
+ next_pending = rdpsnd_queue_next_completion();
+ if (next_pending >= 0)
+ {
+ long cur_timeout;
+
+ cur_timeout = tv->tv_sec * 1000000 + tv->tv_usec;
+ if (cur_timeout > next_pending)
+ {
+ tv->tv_sec = next_pending / 1000000;
+ tv->tv_usec = next_pending % 1000000;
+ }
+ }
+ }
+
+ void
+ rdpsnd_check_fds(fd_set * rfds, fd_set * wfds)
+ {
+ rdpsnd_queue_complete_pending();
+
+ if (g_dsp_busy && FD_ISSET(g_dsp_fd, wfds))
+ rdpsnd_play();
+ }
+
+ static void
rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
{
***************
*** 430,434 ****
unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
! if (next_hi == queue_lo)
{
error("No space to queue audio packet\n");
--- 470,474 ----
unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
! if (next_hi == queue_pending)
{
error("No space to queue audio packet\n");
***************
*** 442,445 ****
--- 482,487 ----
packet->index = index;
+ gettimeofday(&packet->arrive_tv, NULL);
+
if (!g_dsp_busy)
current_driver->wave_out_play();
***************
*** 458,472 ****
}
! void
rdpsnd_queue_init(void)
{
! queue_lo = queue_hi = 0;
}
void
! rdpsnd_queue_next(void)
{
! xfree(packet_queue[queue_lo].s.data);
queue_lo = (queue_lo + 1) % MAX_QUEUE;
}
--- 500,527 ----
}
! static void
rdpsnd_queue_init(void)
{
! queue_pending = queue_lo = queue_hi = 0;
}
void
! rdpsnd_queue_next(unsigned long completed_in_us)
{
! struct audio_packet *packet;
!
! assert(!rdpsnd_queue_empty());
!
! packet = &packet_queue[queue_lo];
!
! gettimeofday(&packet->completion_tv, NULL);
!
! packet->completion_tv.tv_usec += completed_in_us;
! packet->completion_tv.tv_sec += packet->completion_tv.tv_usec / 1000000;
! packet->completion_tv.tv_usec %= 1000000;
!
queue_lo = (queue_lo + 1) % MAX_QUEUE;
+
+ rdpsnd_queue_complete_pending();
}
***************
*** 483,484 ****
--- 538,591 ----
}
}
+
+ static void
+ rdpsnd_queue_complete_pending(void)
+ {
+ struct timeval now;
+ long elapsed;
+ struct audio_packet *packet;
+
+ gettimeofday(&now, NULL);
+
+ while (queue_pending != queue_lo)
+ {
+ packet = &packet_queue[queue_pending];
+
+ if (now.tv_sec < packet->completion_tv.tv_sec)
+ break;
+
+ if ((now.tv_sec == packet->completion_tv.tv_sec) &&
+ (now.tv_usec < packet->completion_tv.tv_usec))
+ break;
+
+ elapsed = (packet->completion_tv.tv_sec - packet->arrive_tv.tv_sec) * 1000000 +
+ (packet->completion_tv.tv_usec - packet->arrive_tv.tv_usec);
+
+ xfree(packet->s.data);
+ rdpsnd_send_completion((packet->tick + elapsed) % 65536, packet->index);
+ queue_pending = (queue_pending + 1) % MAX_QUEUE;
+ }
+ }
+
+ static long
+ rdpsnd_queue_next_completion(void)
+ {
+ struct audio_packet *packet;
+ long remaining;
+ struct timeval now;
+
+ if (queue_pending == queue_lo)
+ return -1;
+
+ gettimeofday(&now, NULL);
+
+ packet = &packet_queue[queue_pending];
+
+ remaining = (packet->completion_tv.tv_sec - now.tv_sec) * 1000000 +
+ (packet->completion_tv.tv_usec - now.tv_usec);
+
+ if (remaining < 0)
+ return 0;
+
+ return remaining;
+ }
Index: rdpsnd.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** rdpsnd.h 19 Oct 2006 12:26:55 -0000 1.7
--- rdpsnd.h 26 Oct 2006 09:47:17 -0000 1.8
***************
*** 24,33 ****
uint16 tick;
uint8 index;
};
struct audio_driver
{
! void (*wave_out_write) (STREAM s, uint16 tick, uint8 index);
! BOOL(*wave_out_open) (void);
void (*wave_out_close) (void);
BOOL(*wave_out_format_supported) (WAVEFORMATEX * pwfx);
--- 24,35 ----
uint16 tick;
uint8 index;
+
+ struct timeval arrive_tv;
+ struct timeval completion_tv;
};
struct audio_driver
{
! BOOL(*wave_out_open) (void);
void (*wave_out_close) (void);
BOOL(*wave_out_format_supported) (WAVEFORMATEX * pwfx);
Index: rdpsnd_alsa.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd_alsa.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** rdpsnd_alsa.c 1 Oct 2006 14:03:43 -0000 1.7
--- rdpsnd_alsa.c 26 Oct 2006 09:47:17 -0000 1.8
***************
*** 38,41 ****
--- 38,42 ----
static short samplewidth;
static int audiochannels;
+ static unsigned int rate;
static char *pcm_name;
***************
*** 52,56 ****
g_dsp_fd = 0;
- rdpsnd_queue_init();
reopened = True;
--- 53,56 ----
***************
*** 64,72 ****
/* Ack all remaining packets */
while (!rdpsnd_queue_empty())
! {
! rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick,
! rdpsnd_queue_current_packet()->index);
! rdpsnd_queue_next();
! }
if (pcm_handle)
--- 64,68 ----
/* Ack all remaining packets */
while (!rdpsnd_queue_empty())
! rdpsnd_queue_next(0);
if (pcm_handle)
***************
*** 114,118 ****
{
snd_pcm_hw_params_t *hwparams = NULL;
- unsigned int rate, exact_rate;
int err;
unsigned int buffertime;
--- 110,113 ----
***************
*** 166,171 ****
#endif
! exact_rate = rate = pwfx->nSamplesPerSec;
! if ((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_rate, 0)) < 0)
{
error("snd_pcm_hw_params_set_rate_near: %s\n", snd_strerror(err));
--- 161,166 ----
#endif
! rate = pwfx->nSamplesPerSec;
! if ((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, 0)) < 0)
{
error("snd_pcm_hw_params_set_rate_near: %s\n", snd_strerror(err));
***************
*** 255,258 ****
--- 250,256 ----
if ((out->p == out->end) || duration > next_tick - packet->tick + 500)
{
+ snd_pcm_sframes_t delay_frames;
+ unsigned long delay_us;
+
prev_s = tv.tv_sec;
prev_us = tv.tv_usec;
***************
*** 265,270 ****
}
! rdpsnd_send_completion(((packet->tick + duration) % 65536), packet->index);
! rdpsnd_queue_next();
}
--- 263,274 ----
}
! if (snd_pcm_delay(pcm_handle, &delay_frames) < 0)
! delay_frames = out->size / (samplewidth * audiochannels);
! if (delay_frames < 0)
! delay_frames = 0;
!
! delay_us = delay_frames * (1000000 / rate);
!
! rdpsnd_queue_next(delay_us);
}
***************
*** 278,282 ****
static struct audio_driver alsa_driver;
- alsa_driver.wave_out_write = rdpsnd_queue_write;
alsa_driver.wave_out_open = alsa_open;
alsa_driver.wave_out_close = alsa_close;
--- 282,285 ----
Index: rdpsnd_libao.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd_libao.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -C2 -d -r1.27 -r1.28
*** rdpsnd_libao.c 14 Oct 2006 22:12:47 -0000 1.27
--- rdpsnd_libao.c 26 Oct 2006 09:47:17 -0000 1.28
***************
*** 66,70 ****
g_dsp_fd = 0;
- rdpsnd_queue_init();
reopened = True;
--- 66,69 ----
***************
*** 79,85 ****
while (!rdpsnd_queue_empty())
{
! rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick,
! rdpsnd_queue_current_packet()->index);
! rdpsnd_queue_next();
}
--- 78,82 ----
while (!rdpsnd_queue_empty())
{
! rdpsnd_queue_next(0);
}
***************
*** 172,177 ****
}
! rdpsnd_send_completion(((packet->tick + duration) % 65536), packet->index);
! rdpsnd_queue_next();
}
--- 169,173 ----
}
! rdpsnd_queue_next(duration);
}
***************
*** 187,191 ****
static char description[101];
- libao_driver.wave_out_write = rdpsnd_queue_write;
libao_driver.wave_out_open = libao_open;
libao_driver.wave_out_close = libao_close;
--- 183,186 ----
Index: rdpsnd_oss.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd_oss.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -d -r1.28 -r1.29
*** rdpsnd_oss.c 1 Oct 2006 18:47:04 -0000 1.28
--- rdpsnd_oss.c 26 Oct 2006 09:47:17 -0000 1.29
***************
*** 34,40 ****
--- 34,43 ----
#include <fcntl.h>
#include <errno.h>
+ #include <unistd.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
#define DEFAULTDEVICE "/dev/dsp"
***************
*** 45,48 ****
--- 48,74 ----
static char *dsp_dev;
static struct audio_driver oss_driver;
+ static BOOL in_esddsp;
+
+ static BOOL
+ detect_esddsp(void)
+ {
+ struct stat s;
+ char *preload;
+
+ if (fstat(g_dsp_fd, &s) == -1)
+ return False;
+
+ if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode))
+ return False;
+
+ preload = getenv("LD_PRELOAD");
+ if (preload == NULL)
+ return False;
+
+ if (strstr(preload, "esddsp") == NULL)
+ return False;
+
+ return True;
+ }
BOOL
***************
*** 55,58 ****
--- 81,86 ----
}
+ in_esddsp = detect_esddsp();
+
return True;
}
***************
*** 203,210 ****
ssize_t len;
STREAM out;
- static long startedat_us;
- static long startedat_s;
- static BOOL started = False;
- struct timeval tv;
if (rdpsnd_queue_empty())
--- 231,234 ----
***************
*** 217,228 ****
out = &packet->s;
- if (!started)
- {
- gettimeofday(&tv, NULL);
- startedat_us = tv.tv_usec;
- startedat_s = tv.tv_sec;
- started = True;
- }
-
len = out->end - out->p;
--- 241,244 ----
***************
*** 237,264 ****
out->p += len;
if (out->p == out->end)
{
! long long duration;
! long elapsed;
!
! gettimeofday(&tv, NULL);
! duration = (out->size * (1000000 / (samplewidth * snd_rate)));
! elapsed = (tv.tv_sec - startedat_s) * 1000000 + (tv.tv_usec - startedat_us);
! if (elapsed >= (duration * 85) / 100)
{
! /* We need to add 50 to tell windows that time has passed while
! * playing this packet */
! rdpsnd_send_completion(packet->tick + 50, packet->index);
! rdpsnd_queue_next();
! started = False;
}
else
{
! g_dsp_busy = 1;
! return;
}
}
! g_dsp_busy = 1;
return;
}
--- 253,296 ----
out->p += len;
+
if (out->p == out->end)
{
! int delay_bytes;
! unsigned long delay_us;
! audio_buf_info info;
! if (in_esddsp)
{
! /* EsounD has no way of querying buffer status, so we have to
! * go with a fixed size. */
! delay_bytes = out->size;
}
else
{
! #ifdef SNDCTL_DSP_GETODELAY
! delay_bytes = 0;
! if (ioctl(g_dsp_fd, SNDCTL_DSP_GETODELAY, &delay_bytes) == -1)
! delay_bytes = -1;
! #else
! delay_bytes = -1;
! #endif
!
! if (delay_bytes == -1)
! {
! if (ioctl(g_dsp_fd, SNDCTL_DSP_GETOSPACE, &info) != -1)
! delay_bytes = info.fragstotal * info.fragsize - info.bytes;
! else
! delay_bytes = out->size;
! }
}
+
+ delay_us = delay_bytes * (1000000 / (samplewidth * snd_rate));
+ rdpsnd_queue_next(delay_us);
}
! else
! {
! g_dsp_busy = 1;
! }
!
return;
}
***************
*** 267,271 ****
oss_register(char *options)
{
- oss_driver.wave_out_write = rdpsnd_queue_write;
oss_driver.wave_out_open = oss_open;
oss_driver.wave_out_close = oss_close;
--- 299,302 ----
Index: rdpsnd_sgi.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd_sgi.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** rdpsnd_sgi.c 1 Oct 2006 14:03:43 -0000 1.14
--- rdpsnd_sgi.c 26 Oct 2006 09:47:17 -0000 1.15
***************
*** 69,74 ****
#endif
- rdpsnd_queue_init();
-
audioconfig = alNewConfig();
if (audioconfig == (ALconfig) 0)
--- 69,72 ----
***************
*** 267,272 ****
if (gf < (4 * maxFillable / 10))
{
! rdpsnd_send_completion(packet->tick, packet->index);
! rdpsnd_queue_next();
}
else
--- 265,269 ----
if (gf < (4 * maxFillable / 10))
{
! rdpsnd_queue_next(0);
}
else
***************
*** 288,292 ****
static struct audio_driver sgi_driver;
- sgi_driver.wave_out_write = rdpsnd_queue_write;
sgi_driver.wave_out_open = sgi_open;
sgi_driver.wave_out_close = sgi_close;
--- 285,288 ----
Index: rdpsnd_sun.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd_sun.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -d -r1.21 -r1.22
*** rdpsnd_sun.c 1 Oct 2006 14:03:43 -0000 1.21
--- rdpsnd_sun.c 26 Oct 2006 09:47:17 -0000 1.22
***************
*** 51,55 ****
fcntl(g_dsp_fd, F_SETFL, fcntl(g_dsp_fd, F_GETFL) | O_NONBLOCK);
- rdpsnd_queue_init();
g_reopened = True;
--- 51,54 ----
***************
*** 236,241 ****
/* We need to add 50 to tell windows that time has passed while
* playing this packet */
! rdpsnd_send_completion(packet->tick + 50, packet->index);
! rdpsnd_queue_next();
sentcompletion = True;
}
--- 235,239 ----
/* We need to add 50 to tell windows that time has passed while
* playing this packet */
! rdpsnd_queue_next(50);
sentcompletion = True;
}
***************
*** 254,258 ****
static struct audio_driver sun_driver;
- sun_driver.wave_out_write = rdpsnd_queue_write;
sun_driver.wave_out_open = sun_open;
sun_driver.wave_out_close = sun_close;
--- 252,255 ----
Index: xwin.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/xwin.c,v
retrieving revision 1.214
retrieving revision 1.215
diff -C2 -d -r1.214 -r1.215
*** xwin.c 17 Sep 2006 11:04:50 -0000 1.214
--- xwin.c 26 Oct 2006 09:47:17 -0000 1.215
***************
*** 2269,2284 ****
FD_SET(g_x_socket, &rfds);
- #ifdef WITH_RDPSND
- /* FIXME: there should be an API for registering fds */
- if (g_dsp_busy)
- {
- FD_SET(g_dsp_fd, &wfds);
- n = (g_dsp_fd > n) ? g_dsp_fd : n;
- }
- #endif
/* default timeout */
tv.tv_sec = 60;
tv.tv_usec = 0;
/* add redirection handles */
rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
--- 2269,2280 ----
FD_SET(g_x_socket, &rfds);
/* default timeout */
tv.tv_sec = 60;
tv.tv_usec = 0;
+ #ifdef WITH_RDPSND
+ rdpsnd_add_fds(&n, &rfds, &wfds, &tv);
+ #endif
+
/* add redirection handles */
rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
***************
*** 2293,2296 ****
--- 2289,2296 ----
case 0:
+ #ifdef WITH_RDPSND
+ rdpsnd_check_fds(&rfds, &wfds);
+ #endif
+
/* Abort serial read calls */
if (s_timeout)
***************
*** 2299,2302 ****
--- 2299,2306 ----
}
+ #ifdef WITH_RDPSND
+ rdpsnd_check_fds(&rfds, &wfds);
+ #endif
+
rdpdr_check_fds(&rfds, &wfds, (BOOL) False);
***************
*** 2304,2311 ****
return 1;
- #ifdef WITH_RDPSND
- if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
- rdpsnd_play();
- #endif
}
}
--- 2308,2311 ----
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642