Mercurial > mplayer.hg
annotate libao2/ao_nas.c @ 24590:2c238fa777ff
ao_alsa: Fix get_space() return values larger than buffersize
After a buffer underrun the ALSA get_space() function sometimes returned
values larger than the ao had set in ao_data.buffersize. Fix this by
replacing the old check against MAX_OUTBURST by one against
ao_data.buffersize. There should be no need for the MAX_OUTBURST check;
the current MPlayer side should no longer have any constant limit on the
amount of data an ao can buffer or request at once.
The get_space() values larger than ao_data.buffersize triggered errors
in audio decoding causing the current attempt to fill audio buffers to
be aborted. I'm not sure how often that caused behavior noticeably worse
then an underrun already is.
author | uau |
---|---|
date | Mon, 24 Sep 2007 21:49:58 +0000 |
parents | acfe034e5386 |
children | f3cd247a4aa3 |
rev | line source |
---|---|
3336
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
1 /* |
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
2 * NAS output plugin for mplayer |
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
3 * |
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
4 * based on the libaudiooss parts rewritten by me, which were |
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
5 * originally based on the NAS output plugin for xmms. |
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
6 * |
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
7 * xmms plugin by Willem Monsuwe |
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
8 * adapted for libaudiooss by Jon Trulson |
23734 | 9 * further modified by Erik Inge Bolsø |
3336
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
10 * largely rewritten and used for this |
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
11 * plugin by Tobias Diedrich |
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
12 * |
7626 | 13 * Theory of operation: |
14 * | |
15 * The NAS consists of two parts, a server daemon and a client. | |
7732 | 16 * We setup the server to use a buffer of size bytes_per_second |
17 * with a low watermark of buffer_size - NAS_FRAG_SIZE. | |
7626 | 18 * Upon starting the flow the server will generate a buffer underrun |
19 * event and the event handler will fill the buffer for the first time. | |
20 * Now the server will generate a lowwater event when the server buffer | |
21 * falls below the low watermark value. The event handler gets called | |
22 * again and refills the buffer by the number of bytes requested by the | |
23 * server (usually a multiple of 4096). To prevent stuttering on | |
24 * startup (start of playing, seeks, unpausing) the client buffer should | |
25 * be bigger than the server buffer. (For debugging we also do some | |
26 * accounting of what we think how much of the server buffer is filled) | |
3336
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
27 */ |
8818c12743a8
patch by Tobias Diedrich <td@informatik.uni-hannover.de>
pl
parents:
3276
diff
changeset
|
28 |
7732 | 29 #include <unistd.h> |
3276 | 30 #include <stdio.h> |
31 #include <stdlib.h> | |
7732 | 32 #include <string.h> |
3276 | 33 #include <pthread.h> |
15741
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
34 #include <limits.h> |
3276 | 35 #include <audio/audiolib.h> |
36 | |
14480
1d3cc596069d
actually mp_msg.h includes config.h, but for consistency better include it
reimar
parents:
14479
diff
changeset
|
37 #include "config.h" |
14123 | 38 #include "mp_msg.h" |
7627 | 39 |
3276 | 40 #include "audio_out.h" |
41 #include "audio_out_internal.h" | |
14245 | 42 #include "libaf/af_format.h" |
3276 | 43 |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
44 #define NAS_FRAG_SIZE 4096 |
3276 | 45 |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
46 static char *nas_event_types[] = { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
47 "Undefined", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
48 "Undefined", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
49 "ElementNotify", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
50 "GrabNotify", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
51 "MonitorNotify", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
52 "BucketNotify", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
53 "DeviceNotify" |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
54 }; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
55 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
56 static char *nas_elementnotify_kinds[] = { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
57 "LowWater", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
58 "HighWater", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
59 "State", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
60 "Unknown" |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
61 }; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
62 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
63 static char *nas_states[] = { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
64 "Stop", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
65 "Start", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
66 "Pause", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
67 "Any" |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
68 }; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
69 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
70 static char *nas_reasons[] = { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
71 "User", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
72 "Underrun", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
73 "Overrun", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
74 "EOF", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
75 "Watermark", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
76 "Hardware", |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
77 "Any" |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
78 }; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
79 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
80 static char* nas_reason(unsigned int reason) |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
81 { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
82 if (reason > 6) reason = 6; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
83 return nas_reasons[reason]; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
84 } |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
85 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
86 static char* nas_elementnotify_kind(unsigned int kind) |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
87 { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
88 if (kind > 2) kind = 3; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
89 return nas_elementnotify_kinds[kind]; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
90 } |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
91 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
92 static char* nas_event_type(unsigned int type) { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
93 if (type > 6) type = 0; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
94 return nas_event_types[type]; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
95 } |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
96 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
97 static char* nas_state(unsigned int state) { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
98 if (state>3) state = 3; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
99 return nas_states[state]; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
100 } |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
101 |
3276 | 102 static ao_info_t info = |
103 { | |
104 "NAS audio output", | |
105 "nas", | |
15741
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
106 "Tobias Diedrich <ranma+mplayer@tdiedrich.de>", |
3276 | 107 "" |
108 }; | |
109 | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
110 struct ao_nas_data { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
111 AuServer *aud; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
112 AuFlowID flow; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
113 AuDeviceID dev; |
12022 | 114 AuFixedPoint gain; |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
115 |
7732 | 116 unsigned int state; |
7626 | 117 int expect_underrun; |
3276 | 118 |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
119 void *client_buffer; |
7449
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
120 void *server_buffer; |
15741
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
121 unsigned int client_buffer_size; |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
122 unsigned int client_buffer_used; |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
123 unsigned int server_buffer_size; |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
124 unsigned int server_buffer_used; |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
125 pthread_mutex_t buffer_mutex; |
3276 | 126 |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
127 pthread_t event_thread; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
128 int stop_thread; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
129 }; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
130 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
131 static struct ao_nas_data *nas_data; |
3276 | 132 |
133 LIBAO_EXTERN(nas) | |
134 | |
18965
24ae1f262dc2
make prefix const. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents:
17566
diff
changeset
|
135 static void nas_print_error(AuServer *aud, const char *prefix, AuStatus as) |
3276 | 136 { |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
137 char s[100]; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
138 AuGetErrorText(aud, as, s, 100); |
7627 | 139 mp_msg(MSGT_AO, MSGL_ERR, "ao_nas: %s: returned status %d (%s)\n", prefix, as, s); |
3276 | 140 } |
141 | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
142 static int nas_readBuffer(struct ao_nas_data *nas_data, int num) |
3276 | 143 { |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
144 AuStatus as; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
145 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
146 pthread_mutex_lock(&nas_data->buffer_mutex); |
7627 | 147 mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: nas_readBuffer(): num=%d client=%d/%d server=%d/%d\n", |
3276 | 148 num, |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
149 nas_data->client_buffer_used, nas_data->client_buffer_size, |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
150 nas_data->server_buffer_used, nas_data->server_buffer_size); |
3276 | 151 |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
152 if (nas_data->client_buffer_used == 0) { |
7627 | 153 mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: buffer is empty, nothing read.\n"); |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
154 pthread_mutex_unlock(&nas_data->buffer_mutex); |
3276 | 155 return 0; |
156 } | |
15741
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
157 if (num > nas_data->client_buffer_used) |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
158 num = nas_data->client_buffer_used; |
3276 | 159 |
7449
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
160 /* |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
161 * It is not appropriate to call AuWriteElement() here because the |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
162 * buffer is locked and delays writing to the network will cause |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
163 * other threads to block waiting for buffer_mutex. Instead the |
15741
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
164 * data is copied to "server_buffer" and written to the network |
7449
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
165 * outside of the locked section of code. |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
166 * |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
167 * (Note: Rather than these two buffers, a single circular buffer |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
168 * could eliminate the memcpy/memmove steps.) |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
169 */ |
15741
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
170 /* make sure we don't overflow the buffer */ |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
171 if (num > nas_data->server_buffer_size) |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
172 num = nas_data->server_buffer_size; |
7449
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
173 memcpy(nas_data->server_buffer, nas_data->client_buffer, num); |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
174 |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
175 nas_data->client_buffer_used -= num; |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
176 nas_data->server_buffer_used += num; |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
177 memmove(nas_data->client_buffer, nas_data->client_buffer + num, nas_data->client_buffer_used); |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
178 pthread_mutex_unlock(&nas_data->buffer_mutex); |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
179 |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
180 /* |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
181 * Now write the new buffer to the network. |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
182 */ |
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
183 AuWriteElement(nas_data->aud, nas_data->flow, 0, num, nas_data->server_buffer, AuFalse, &as); |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
184 if (as != AuSuccess) |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
185 nas_print_error(nas_data->aud, "nas_readBuffer(): AuWriteElement", as); |
3276 | 186 |
187 return num; | |
188 } | |
189 | |
15741
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
190 static int nas_writeBuffer(struct ao_nas_data *nas_data, void *data, int len) |
3276 | 191 { |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
192 pthread_mutex_lock(&nas_data->buffer_mutex); |
7627 | 193 mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: nas_writeBuffer(): len=%d client=%d/%d server=%d/%d\n", |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
194 len, nas_data->client_buffer_used, nas_data->client_buffer_size, |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
195 nas_data->server_buffer_used, nas_data->server_buffer_size); |
3276 | 196 |
15741
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
197 /* make sure we don't overflow the buffer */ |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
198 if (len > nas_data->client_buffer_size - nas_data->client_buffer_used) |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
199 len = nas_data->client_buffer_size - nas_data->client_buffer_used; |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
200 memcpy(nas_data->client_buffer + nas_data->client_buffer_used, data, len); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
201 nas_data->client_buffer_used += len; |
3276 | 202 |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
203 pthread_mutex_unlock(&nas_data->buffer_mutex); |
15741
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
204 |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
205 return len; |
3276 | 206 } |
207 | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
208 static int nas_empty_event_queue(struct ao_nas_data *nas_data) |
3276 | 209 { |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
210 AuEvent ev; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
211 int result = 0; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
212 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
213 while (AuScanForTypedEvent(nas_data->aud, AuEventsQueuedAfterFlush, |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
214 AuTrue, AuEventTypeElementNotify, &ev)) { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
215 AuDispatchEvent(nas_data->aud, &ev); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
216 result = 1; |
3276 | 217 } |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
218 return result; |
3276 | 219 } |
220 | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
221 static void *nas_event_thread_start(void *data) |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
222 { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
223 struct ao_nas_data *nas_data = data; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
224 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
225 do { |
7732 | 226 mp_msg(MSGT_AO, MSGL_DBG2, |
227 "ao_nas: event thread heartbeat (state=%s)\n", | |
228 nas_state(nas_data->state)); | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
229 nas_empty_event_queue(nas_data); |
7732 | 230 usleep(1000); |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
231 } while (!nas_data->stop_thread); |
7732 | 232 |
233 return NULL; | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
234 } |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
235 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
236 static AuBool nas_error_handler(AuServer* aud, AuErrorEvent* ev) |
3276 | 237 { |
238 char s[100]; | |
239 AuGetErrorText(aud, ev->error_code, s, 100); | |
7627 | 240 mp_msg(MSGT_AO, MSGL_ERR, "ao_nas: error [%s]\n" |
3276 | 241 "error_code: %d\n" |
242 "request_code: %d\n" | |
243 "minor_code: %d\n", | |
244 s, | |
245 ev->error_code, | |
246 ev->request_code, | |
247 ev->minor_code); | |
248 | |
249 return AuTrue; | |
250 } | |
251 | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
252 static AuBool nas_event_handler(AuServer *aud, AuEvent *ev, AuEventHandlerRec *hnd) |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
253 { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
254 AuElementNotifyEvent *event = (AuElementNotifyEvent *) ev; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
255 struct ao_nas_data *nas_data = hnd->data; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
256 |
7732 | 257 mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: event_handler(): type %s kind %s state %s->%s reason %s numbytes %d expect_underrun %d\n", |
258 nas_event_type(event->type), | |
259 nas_elementnotify_kind(event->kind), | |
260 nas_state(event->prev_state), | |
261 nas_state(event->cur_state), | |
262 nas_reason(event->reason), | |
263 event->num_bytes, | |
264 nas_data->expect_underrun); | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
265 |
15741
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
266 if (event->num_bytes > INT_MAX) { |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
267 mp_msg(MSGT_AO, MSGL_ERR, "ao_nas: num_bytes > 2GB, server buggy?\n"); |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
268 } |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
269 |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
270 if (event->num_bytes > nas_data->server_buffer_used) |
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
271 event->num_bytes = nas_data->server_buffer_used; |
7732 | 272 nas_data->server_buffer_used -= event->num_bytes; |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
273 |
7732 | 274 switch (event->reason) { |
275 case AuReasonWatermark: | |
276 nas_readBuffer(nas_data, event->num_bytes); | |
277 break; | |
278 case AuReasonUnderrun: | |
279 // buffer underrun -> refill buffer | |
280 nas_data->server_buffer_used = 0; | |
281 if (nas_data->expect_underrun) { | |
282 nas_data->expect_underrun = 0; | |
283 } else { | |
12022 | 284 static int hint = 1; |
7732 | 285 mp_msg(MSGT_AO, MSGL_WARN, |
286 "ao_nas: Buffer underrun.\n"); | |
12022 | 287 if (hint) { |
288 hint = 0; | |
289 mp_msg(MSGT_AO, MSGL_HINT, | |
290 "Possible reasons are:\n" | |
291 "1) Network congestion.\n" | |
292 "2) Your NAS server is too slow.\n" | |
293 "Try renicing your nasd to e.g. -15.\n"); | |
294 } | |
7732 | 295 } |
296 if (nas_readBuffer(nas_data, | |
297 nas_data->server_buffer_size - | |
298 nas_data->server_buffer_used) != 0) { | |
299 event->cur_state = AuStateStart; | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
300 break; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
301 } |
7732 | 302 mp_msg(MSGT_AO, MSGL_DBG2, |
303 "ao_nas: Can't refill buffer, stopping flow.\n"); | |
304 AuStopFlow(nas_data->aud, nas_data->flow, NULL); | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
305 break; |
7732 | 306 default: |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
307 break; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
308 } |
7732 | 309 nas_data->state=event->cur_state; |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
310 return AuTrue; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
311 } |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
312 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
313 static AuDeviceID nas_find_device(AuServer *aud, int nch) |
3276 | 314 { |
315 int i; | |
316 for (i = 0; i < AuServerNumDevices(aud); i++) { | |
317 AuDeviceAttributes *dev = AuServerDevice(aud, i); | |
318 if ((AuDeviceKind(dev) == AuComponentKindPhysicalOutput) && | |
319 AuDeviceNumTracks(dev) == nch) { | |
320 return AuDeviceIdentifier(dev); | |
321 } | |
322 } | |
323 return AuNone; | |
324 } | |
325 | |
7732 | 326 static unsigned int nas_aformat_to_auformat(unsigned int *format) |
3276 | 327 { |
7732 | 328 switch (*format) { |
14245 | 329 case AF_FORMAT_U8: |
7732 | 330 return AuFormatLinearUnsigned8; |
14245 | 331 case AF_FORMAT_S8: |
7732 | 332 return AuFormatLinearSigned8; |
14245 | 333 case AF_FORMAT_U16_LE: |
7732 | 334 return AuFormatLinearUnsigned16LSB; |
14245 | 335 case AF_FORMAT_U16_BE: |
7732 | 336 return AuFormatLinearUnsigned16MSB; |
14245 | 337 case AF_FORMAT_S16_LE: |
7732 | 338 return AuFormatLinearSigned16LSB; |
14245 | 339 case AF_FORMAT_S16_BE: |
7732 | 340 return AuFormatLinearSigned16MSB; |
14245 | 341 case AF_FORMAT_MU_LAW: |
7732 | 342 return AuFormatULAW8; |
12022 | 343 default: |
14245 | 344 *format=AF_FORMAT_S16_NE; |
12022 | 345 return nas_aformat_to_auformat(format); |
3276 | 346 } |
347 } | |
348 | |
349 // to set/get/query special features/parameters | |
9633
12b1790038b0
64bit libao2 fix by Jens Axboe <mplayer-dev@kernel.dk>
alex
parents:
9583
diff
changeset
|
350 static int control(int cmd, void *arg) |
8272 | 351 { |
12022 | 352 AuElementParameters aep; |
8272 | 353 AuStatus as; |
9583 | 354 int retval = CONTROL_UNKNOWN; |
355 | |
8272 | 356 ao_control_vol_t *vol = (ao_control_vol_t *)arg; |
357 | |
358 switch (cmd) { | |
359 case AOCONTROL_GET_VOLUME: | |
360 | |
12022 | 361 vol->right = (float)nas_data->gain/AU_FIXED_POINT_SCALE*50; |
8272 | 362 vol->left = vol->right; |
363 | |
12022 | 364 mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: AOCONTROL_GET_VOLUME: %08x\n", nas_data->gain); |
9583 | 365 retval = CONTROL_OK; |
366 break; | |
8272 | 367 |
368 case AOCONTROL_SET_VOLUME: | |
369 /* | |
370 * kn: we should have vol->left == vol->right but i don't | |
371 * know if something can change it outside of ao_nas | |
372 * so i take the mean of both values. | |
373 */ | |
12022 | 374 nas_data->gain = AU_FIXED_POINT_SCALE*((vol->left+vol->right)/2)/50; |
375 mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: AOCONTROL_SET_VOLUME: %08x\n", nas_data->gain); | |
8272 | 376 |
12022 | 377 aep.parameters[AuParmsMultiplyConstantConstant]=nas_data->gain; |
378 aep.flow = nas_data->flow; | |
379 aep.element_num = 1; | |
380 aep.num_parameters = AuParmsMultiplyConstant; | |
381 | |
382 AuSetElementParameters(nas_data->aud, 1, &aep, &as); | |
8272 | 383 if (as != AuSuccess) { |
384 nas_print_error(nas_data->aud, | |
12022 | 385 "control(): AuSetElementParameters", as); |
9583 | 386 retval = CONTROL_ERROR; |
387 } else retval = CONTROL_OK; | |
388 break; | |
389 }; | |
8272 | 390 |
9583 | 391 return retval; |
3276 | 392 } |
393 | |
394 // open & setup audio device | |
395 // return: 1=success 0=fail | |
396 static int init(int rate,int channels,int format,int flags) | |
397 { | |
398 AuElement elms[3]; | |
399 AuStatus as; | |
7732 | 400 unsigned char auformat = nas_aformat_to_auformat(&format); |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
401 int bytes_per_sample = channels * AuSizeofFormat(auformat); |
7732 | 402 int buffer_size; |
3276 | 403 char *server; |
404 | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
405 nas_data=malloc(sizeof(struct ao_nas_data)); |
6114
34d5c9a67b94
Patch by Tobias Diedrich <td@informatik.uni-hannover.de>:
pl
parents:
5790
diff
changeset
|
406 memset(nas_data, 0, sizeof(struct ao_nas_data)); |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
407 |
7627 | 408 mp_msg(MSGT_AO, MSGL_V, "ao2: %d Hz %d chans %s\n",rate,channels, |
14264 | 409 af_fmt2str_short(format)); |
3276 | 410 |
7732 | 411 ao_data.format = format; |
3276 | 412 ao_data.samplerate = rate; |
413 ao_data.channels = channels; | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
414 ao_data.outburst = NAS_FRAG_SIZE; |
3276 | 415 ao_data.bps = rate * bytes_per_sample; |
7732 | 416 buffer_size = ao_data.bps; /* buffer 1 second */ |
417 /* | |
418 * round up to multiple of NAS_FRAG_SIZE | |
419 * divide by 3 first because of 2:1 split | |
420 */ | |
421 buffer_size = (buffer_size/3 + NAS_FRAG_SIZE-1) & ~(NAS_FRAG_SIZE-1); | |
422 ao_data.buffersize = buffer_size*3; | |
423 | |
424 nas_data->client_buffer_size = buffer_size*2; | |
425 nas_data->client_buffer = malloc(nas_data->client_buffer_size); | |
426 nas_data->server_buffer_size = buffer_size; | |
427 nas_data->server_buffer = malloc(nas_data->server_buffer_size); | |
3276 | 428 |
429 if (!bytes_per_sample) { | |
7627 | 430 mp_msg(MSGT_AO, MSGL_ERR, "ao_nas: init(): Zero bytes per sample -> nosound\n"); |
3276 | 431 return 0; |
432 } | |
433 | |
7646
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
434 if (!(server = getenv("AUDIOSERVER")) && |
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
435 !(server = getenv("DISPLAY"))) { |
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
436 mp_msg(MSGT_AO, MSGL_ERR, "ao_nas: init(): AUDIOSERVER environment variable not set -> nosound\n"); |
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
437 return 0; |
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
438 } |
3276 | 439 |
7627 | 440 mp_msg(MSGT_AO, MSGL_V, "ao_nas: init(): Using audioserver %s\n", server); |
3276 | 441 |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
442 nas_data->aud = AuOpenServer(server, 0, NULL, 0, NULL, NULL); |
7646
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
443 if (!nas_data->aud) { |
7627 | 444 mp_msg(MSGT_AO, MSGL_ERR, "ao_nas: init(): Can't open nas audio server -> nosound\n"); |
3276 | 445 return 0; |
446 } | |
447 | |
23006 | 448 while (channels>0) { |
7646
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
449 nas_data->dev = nas_find_device(nas_data->aud, channels); |
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
450 if (nas_data->dev != AuNone && |
7732 | 451 ((nas_data->flow = AuCreateFlow(nas_data->aud, NULL)) != 0)) |
7646
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
452 break; |
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
453 channels--; |
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
454 } |
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
455 |
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
456 if (nas_data->flow == 0) { |
0761d6ac7ce9
libaf compliance (ao_data) fix by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7627
diff
changeset
|
457 mp_msg(MSGT_AO, MSGL_ERR, "ao_nas: init(): Can't find a suitable output device -> nosound\n"); |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
458 AuCloseServer(nas_data->aud); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
459 nas_data->aud = 0; |
3276 | 460 return 0; |
461 } | |
462 | |
7732 | 463 AuMakeElementImportClient(elms, rate, auformat, channels, AuTrue, |
464 buffer_size / bytes_per_sample, | |
465 (buffer_size - NAS_FRAG_SIZE) / | |
466 bytes_per_sample, 0, NULL); | |
12022 | 467 nas_data->gain = AuFixedPointFromFraction(1, 1); |
468 AuMakeElementMultiplyConstant(elms+1, 0, nas_data->gain); | |
469 AuMakeElementExportDevice(elms+2, 1, nas_data->dev, rate, | |
3276 | 470 AuUnlimitedSamples, 0, NULL); |
12022 | 471 AuSetElements(nas_data->aud, nas_data->flow, AuTrue, sizeof(elms)/sizeof(*elms), elms, &as); |
7732 | 472 if (as != AuSuccess) { |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
473 nas_print_error(nas_data->aud, "init(): AuSetElements", as); |
7732 | 474 AuCloseServer(nas_data->aud); |
475 nas_data->aud = 0; | |
476 return 0; | |
477 } | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
478 AuRegisterEventHandler(nas_data->aud, AuEventHandlerIDMask | |
3276 | 479 AuEventHandlerTypeMask, |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
480 AuEventTypeElementNotify, nas_data->flow, |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
481 nas_event_handler, (AuPointer) nas_data); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
482 AuSetErrorHandler(nas_data->aud, nas_error_handler); |
7732 | 483 nas_data->state=AuStateStop; |
7626 | 484 nas_data->expect_underrun=0; |
3276 | 485 |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
486 pthread_mutex_init(&nas_data->buffer_mutex, NULL); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
487 pthread_create(&nas_data->event_thread, NULL, &nas_event_thread_start, nas_data); |
3276 | 488 |
489 return 1; | |
490 } | |
491 | |
492 // close audio device | |
12145 | 493 static void uninit(int immed){ |
7732 | 494 |
495 mp_msg(MSGT_AO, MSGL_DBG3, "ao_nas: uninit()\n"); | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
496 |
7732 | 497 nas_data->expect_underrun = 1; |
14849
d313f591d1a4
aos should respect the immed uninit flag (quit immediatly vs waiting till file
reimar
parents:
14480
diff
changeset
|
498 if (!immed) |
7732 | 499 while (nas_data->state != AuStateStop) usleep(1000); |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
500 nas_data->stop_thread = 1; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
501 pthread_join(nas_data->event_thread, NULL); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
502 AuCloseServer(nas_data->aud); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
503 nas_data->aud = 0; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
504 free(nas_data->client_buffer); |
7449
28785e6e6900
"One can cause a permanent hang on a seek, and the other just causes
arpi
parents:
6114
diff
changeset
|
505 free(nas_data->server_buffer); |
3276 | 506 } |
507 | |
508 // stop playing and empty buffers (for seeking/pause) | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
15741
diff
changeset
|
509 static void reset(void){ |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
510 AuStatus as; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
511 |
7732 | 512 mp_msg(MSGT_AO, MSGL_DBG3, "ao_nas: reset()\n"); |
7626 | 513 |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
514 pthread_mutex_lock(&nas_data->buffer_mutex); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
515 nas_data->client_buffer_used = 0; |
7732 | 516 pthread_mutex_unlock(&nas_data->buffer_mutex); |
517 while (nas_data->state != AuStateStop) { | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
518 AuStopFlow(nas_data->aud, nas_data->flow, &as); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
519 if (as != AuSuccess) |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
520 nas_print_error(nas_data->aud, "reset(): AuStopFlow", as); |
7732 | 521 usleep(1000); |
3276 | 522 } |
523 } | |
524 | |
525 // stop playing, keep buffers (for pause) | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
15741
diff
changeset
|
526 static void audio_pause(void) |
3276 | 527 { |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
528 AuStatus as; |
7732 | 529 mp_msg(MSGT_AO, MSGL_DBG3, "ao_nas: audio_pause()\n"); |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
530 |
7732 | 531 AuStopFlow(nas_data->aud, nas_data->flow, &as); |
3276 | 532 } |
533 | |
534 // resume playing, after audio_pause() | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
15741
diff
changeset
|
535 static void audio_resume(void) |
3276 | 536 { |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
537 AuStatus as; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
538 |
7732 | 539 mp_msg(MSGT_AO, MSGL_DBG3, "ao_nas: audio_resume()\n"); |
540 | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
541 AuStartFlow(nas_data->aud, nas_data->flow, &as); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
542 if (as != AuSuccess) |
7732 | 543 nas_print_error(nas_data->aud, |
544 "play(): AuStartFlow", as); | |
3276 | 545 } |
546 | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
547 |
3276 | 548 // return: how many bytes can be played without blocking |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
15741
diff
changeset
|
549 static int get_space(void) |
3276 | 550 { |
551 int result; | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
552 |
7732 | 553 mp_msg(MSGT_AO, MSGL_DBG3, "ao_nas: get_space()\n"); |
3276 | 554 |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
555 pthread_mutex_lock(&nas_data->buffer_mutex); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
556 result = nas_data->client_buffer_size - nas_data->client_buffer_used; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
557 pthread_mutex_unlock(&nas_data->buffer_mutex); |
3276 | 558 |
559 return result; | |
560 } | |
561 | |
562 // plays 'len' bytes of 'data' | |
563 // it should round it down to outburst*n | |
564 // return: number of bytes played | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
565 static int play(void* data,int len,int flags) |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
566 { |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
567 int maxbursts, playbursts, writelen; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
568 AuStatus as; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
569 |
7732 | 570 mp_msg(MSGT_AO, MSGL_DBG3, |
571 "ao_nas: play(%p, %d, %d)\n", | |
572 data, len, flags); | |
573 | |
574 if (len == 0) | |
575 return 0; | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
576 |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
577 pthread_mutex_lock(&nas_data->buffer_mutex); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
578 maxbursts = (nas_data->client_buffer_size - |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
579 nas_data->client_buffer_used) / ao_data.outburst; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
580 playbursts = len / ao_data.outburst; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
581 writelen = (playbursts > maxbursts ? maxbursts : playbursts) * |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
582 ao_data.outburst; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
583 pthread_mutex_unlock(&nas_data->buffer_mutex); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
584 |
15741
2beb7a7cdac1
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
ranma
parents:
14849
diff
changeset
|
585 writelen = nas_writeBuffer(nas_data, data, writelen); |
7626 | 586 |
7732 | 587 if (nas_data->state != AuStateStart && |
588 maxbursts == playbursts) { | |
589 mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: play(): Starting flow.\n"); | |
7626 | 590 nas_data->expect_underrun = 1; |
591 AuStartFlow(nas_data->aud, nas_data->flow, &as); | |
592 if (as != AuSuccess) | |
593 nas_print_error(nas_data->aud, "play(): AuStartFlow", as); | |
594 } | |
595 | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
596 return writelen; |
3276 | 597 } |
598 | |
599 // return: delay in seconds between first and last sample in buffer | |
17566
f580a7755ac5
Patch by Stefan Huehner / stefan % huehner ! org \
rathann
parents:
15741
diff
changeset
|
600 static float get_delay(void) |
3276 | 601 { |
602 float result; | |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
603 |
7732 | 604 mp_msg(MSGT_AO, MSGL_DBG3, "ao_nas: get_delay()\n"); |
3276 | 605 |
4775
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
606 pthread_mutex_lock(&nas_data->buffer_mutex); |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
607 result = ((float)(nas_data->client_buffer_used + |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
608 nas_data->server_buffer_used)) / |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
609 (float)ao_data.bps; |
080cf3df3e4e
improved event handling, implemented working pause that does not flush all buffers, work around a deadlock in the new threadsafe version 1.5 of libaudio by Tobias Diedrich
atmos4
parents:
3336
diff
changeset
|
610 pthread_mutex_unlock(&nas_data->buffer_mutex); |
3276 | 611 |
612 return result; | |
613 } |