2 * This file is part of mplayer2.
4 * mplayer2 is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * mplayer2 is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with mplayer2. If not, see <http://www.gnu.org/licenses/>.
25 #include <libavutil/common.h>
26 #include <portaudio.h>
29 #include "subopt-helper.h"
30 #include "libaf/af_format.h"
32 #include "audio_out.h"
38 pthread_mutex_t ring_mutex
;
40 // protected by ring_mutex
42 int ring_size
; // max size of the ring
43 int read_pos
; // points to first byte that can be read
44 int read_len
; // number of bytes that can be read
45 double play_time
; // time when last packet returned to PA is on speaker
46 // 0 is N/A (0 is not a valid PA time value)
47 int play_silence
; // play this many bytes of silence, before real data
48 bool play_remaining
;// play what's left in the buffer, then stop stream
53 PaSampleFormat pa_format
;
56 static const struct format_map format_maps
[] = {
57 // first entry is the default format
58 {AF_FORMAT_S16_NE
, paInt16
},
59 {AF_FORMAT_S24_NE
, paInt24
},
60 {AF_FORMAT_S32_NE
, paInt32
},
61 {AF_FORMAT_S8
, paInt8
},
62 {AF_FORMAT_U8
, paUInt8
},
63 {AF_FORMAT_FLOAT_NE
, paFloat32
},
64 {AF_FORMAT_UNKNOWN
, 0}
67 static void print_help(void)
69 mp_msg(MSGT_AO
, MSGL_FATAL
,
70 "\n-ao portaudio commandline help:\n"
71 "Example: mplayer -ao portaudio:device=subdevice\n"
74 " Audio device PortAudio should use. Devices can be listed\n"
75 " with -ao portaudio:device=help\n"
76 " The subdevice can be passed as index, or as complete name.\n");
79 static bool check_pa_ret(int ret
)
82 mp_msg(MSGT_AO
, MSGL_ERR
, "[portaudio] %s\n",
83 Pa_GetErrorText(ret
));
84 if (ret
== paUnanticipatedHostError
) {
85 const PaHostErrorInfo
* hosterr
= Pa_GetLastHostErrorInfo();
86 mp_msg(MSGT_AO
, MSGL_ERR
, "[portaudio] Host error: %s\n",
94 // Amount of bytes that contain audio of the given duration, aligned to frames.
95 static int seconds_to_bytes(struct ao
*ao
, double duration_seconds
)
97 struct priv
*priv
= ao
->priv
;
99 int bytes
= duration_seconds
* ao
->bps
;
100 if (bytes
% priv
->framelen
)
101 bytes
+= priv
->framelen
- (bytes
% priv
->framelen
);
105 static int to_int(const char *s
, int return_on_error
)
108 int res
= strtol(s
, &endptr
, 10);
109 return (s
[0] && !endptr
[0]) ? res
: return_on_error
;
112 static int find_device(struct ao
*ao
, const char *name
)
114 int help
= strcmp(name
, "help") == 0;
115 int count
= Pa_GetDeviceCount();
117 int found
= paNoDevice
;
118 int index
= to_int(name
, -1);
120 mp_msg(MSGT_AO
, MSGL_INFO
, "PortAudio devices:\n");
121 for (int n
= 0; n
< count
; n
++) {
122 const PaDeviceInfo
* info
= Pa_GetDeviceInfo(n
);
124 if (info
->maxOutputChannels
< 1)
126 mp_msg(MSGT_AO
, MSGL_INFO
, " %d '%s', %d channels, latency: %.2f "
127 "ms, sample rate: %.0f\n", n
, info
->name
,
128 info
->maxOutputChannels
,
129 info
->defaultHighOutputLatency
* 1000,
130 info
->defaultSampleRate
);
132 if (strcmp(name
, info
->name
) == 0 || n
== index
) {
137 if (found
== paNoDevice
&& !help
)
138 mp_msg(MSGT_AO
, MSGL_FATAL
, "[portaudio] Device '%s' not found!\n",
143 static int ring_write(struct ao
*ao
, unsigned char *data
, int len
)
145 struct priv
*priv
= ao
->priv
;
147 int free
= priv
->ring_size
- priv
->read_len
;
148 int write_pos
= (priv
->read_pos
+ priv
->read_len
) % priv
->ring_size
;
149 int write_len
= FFMIN(len
, free
);
150 int len1
= FFMIN(priv
->ring_size
- write_pos
, write_len
);
151 int len2
= write_len
- len1
;
153 memcpy(priv
->ring
+ write_pos
, data
, len1
);
154 memcpy(priv
->ring
, data
+ len1
, len2
);
156 priv
->read_len
+= write_len
;
161 static int ring_read(struct ao
*ao
, unsigned char *data
, int len
)
163 struct priv
*priv
= ao
->priv
;
165 int read_len
= FFMIN(len
, priv
->read_len
);
166 int len1
= FFMIN(priv
->ring_size
- priv
->read_pos
, read_len
);
167 int len2
= read_len
- len1
;
169 memcpy(data
, priv
->ring
+ priv
->read_pos
, len1
);
170 memcpy(data
+ len1
, priv
->ring
, len2
);
172 priv
->read_len
-= read_len
;
173 priv
->read_pos
= (priv
->read_pos
+ read_len
) % priv
->ring_size
;
178 static void fill_silence(unsigned char *ptr
, int len
)
183 static int stream_callback(const void *input
,
185 unsigned long frameCount
,
186 const PaStreamCallbackTimeInfo
*timeInfo
,
187 PaStreamCallbackFlags statusFlags
,
190 struct ao
*ao
= userData
;
191 struct priv
*priv
= ao
->priv
;
192 int res
= paContinue
;
193 unsigned char *output
= output_v
;
194 int len_bytes
= frameCount
* priv
->framelen
;
196 pthread_mutex_lock(&priv
->ring_mutex
);
198 // NOTE: PA + ALSA in dmix mode seems to pretend that there is no latency
199 // (outputBufferDacTime == currentTime)
200 priv
->play_time
= timeInfo
->outputBufferDacTime
201 + len_bytes
/ (float)ao
->bps
;
203 if (priv
->play_silence
> 0) {
204 int bytes
= FFMIN(priv
->play_silence
, len_bytes
);
205 fill_silence(output
, bytes
);
206 priv
->play_silence
-= bytes
;
210 int read
= ring_read(ao
, output
, len_bytes
);
215 if (priv
->play_remaining
) {
217 priv
->play_remaining
= false;
219 mp_msg(MSGT_AO
, MSGL_ERR
, "[portaudio] Buffer underflow!\n");
221 fill_silence(output
, len_bytes
);
224 pthread_mutex_unlock(&priv
->ring_mutex
);
229 static void uninit(struct ao
*ao
, bool cut_audio
)
231 struct priv
*priv
= ao
->priv
;
234 if (!cut_audio
&& Pa_IsStreamActive(priv
->stream
) == 1) {
235 pthread_mutex_lock(&priv
->ring_mutex
);
237 priv
->play_remaining
= true;
239 pthread_mutex_unlock(&priv
->ring_mutex
);
241 check_pa_ret(Pa_StopStream(priv
->stream
));
243 check_pa_ret(Pa_CloseStream(priv
->stream
));
246 pthread_mutex_destroy(&priv
->ring_mutex
);
250 static int init(struct ao
*ao
, char *params
)
252 struct priv
*priv
= talloc_zero(ao
, struct priv
);
255 if (!check_pa_ret(Pa_Initialize()))
258 pthread_mutex_init(&priv
->ring_mutex
, NULL
);
261 const opt_t subopts
[] = {
262 {"device", OPT_ARG_MSTRZ
, &device
, NULL
},
265 if (subopt_parse(params
, subopts
) != 0) {
270 int pa_device
= Pa_GetDefaultOutputDevice();
272 pa_device
= find_device(ao
, device
);
273 if (pa_device
== paNoDevice
)
276 PaStreamParameters sp
= {
278 .channelCount
= ao
->channels
,
280 = Pa_GetDeviceInfo(pa_device
)->defaultHighOutputLatency
,
283 const struct format_map
*fmt
= format_maps
;
284 while (fmt
->pa_format
) {
285 if (fmt
->mp_format
== ao
->format
) {
286 PaStreamParameters test
= sp
;
287 test
.sampleFormat
= fmt
->pa_format
;
288 if (Pa_IsFormatSupported(NULL
, &test
, ao
->samplerate
) == paNoError
)
293 if (!fmt
->pa_format
) {
294 mp_msg(MSGT_AO
, MSGL_V
,
295 "[portaudio] Unsupported format, using default.\n");
299 ao
->format
= fmt
->mp_format
;
300 sp
.sampleFormat
= fmt
->pa_format
;
301 priv
->framelen
= ao
->channels
* (af_fmt2bits(ao
->format
) / 8);
302 ao
->bps
= ao
->samplerate
* priv
->framelen
;
304 if (!check_pa_ret(Pa_IsFormatSupported(NULL
, &sp
, ao
->samplerate
)))
306 if (!check_pa_ret(Pa_OpenStream(&priv
->stream
, NULL
, &sp
, ao
->samplerate
,
307 paFramesPerBufferUnspecified
, paNoFlag
,
308 stream_callback
, ao
)))
311 priv
->ring_size
= seconds_to_bytes(ao
, 0.5);
312 priv
->ring
= talloc_zero_size(priv
, priv
->ring_size
);
323 static int play(struct ao
*ao
, void *data
, int len
, int flags
)
325 struct priv
*priv
= ao
->priv
;
327 pthread_mutex_lock(&priv
->ring_mutex
);
329 int write_len
= ring_write(ao
, data
, len
);
330 if (flags
& AOPLAY_FINAL_CHUNK
)
331 priv
->play_remaining
= true;
333 pthread_mutex_unlock(&priv
->ring_mutex
);
335 if (Pa_IsStreamStopped(priv
->stream
) == 1)
336 check_pa_ret(Pa_StartStream(priv
->stream
));
341 static int get_space(struct ao
*ao
)
343 struct priv
*priv
= ao
->priv
;
345 pthread_mutex_lock(&priv
->ring_mutex
);
347 int free
= priv
->ring_size
- priv
->read_len
;
349 pthread_mutex_unlock(&priv
->ring_mutex
);
354 static float get_delay(struct ao
*ao
)
356 struct priv
*priv
= ao
->priv
;
358 double stream_time
= Pa_GetStreamTime(priv
->stream
);
360 pthread_mutex_lock(&priv
->ring_mutex
);
362 float frame_time
= priv
->play_time
? priv
->play_time
- stream_time
: 0;
363 float buffer_latency
= (priv
->read_len
+ priv
->play_silence
)
366 pthread_mutex_unlock(&priv
->ring_mutex
);
368 return buffer_latency
+ frame_time
;
371 static void reset(struct ao
*ao
)
373 struct priv
*priv
= ao
->priv
;
375 if (Pa_IsStreamStopped(priv
->stream
) != 1)
376 check_pa_ret(Pa_AbortStream(priv
->stream
));
378 pthread_mutex_lock(&priv
->ring_mutex
);
382 priv
->play_remaining
= false;
384 priv
->play_silence
= 0;
386 pthread_mutex_unlock(&priv
->ring_mutex
);
389 static void pause(struct ao
*ao
)
391 struct priv
*priv
= ao
->priv
;
393 check_pa_ret(Pa_AbortStream(priv
->stream
));
395 double stream_time
= Pa_GetStreamTime(priv
->stream
);
397 pthread_mutex_lock(&priv
->ring_mutex
);
399 // When playback resumes, replace the lost audio (due to dropping the
400 // portaudio/driver/hardware internal buffers) with silence.
401 float frame_time
= priv
->play_time
? priv
->play_time
- stream_time
: 0;
402 priv
->play_silence
+= seconds_to_bytes(ao
, FFMAX(frame_time
, 0));
405 pthread_mutex_unlock(&priv
->ring_mutex
);
408 static void resume(struct ao
*ao
)
410 struct priv
*priv
= ao
->priv
;
412 check_pa_ret(Pa_StartStream(priv
->stream
));
415 const struct ao_driver audio_out_portaudio
= {
417 .info
= &(const struct ao_info
) {
426 .get_space
= get_space
,
428 .get_delay
= get_delay
,