demux_lavf: don't autoselect attached pictures as video
[mplayer.git] / libao2 / ao_portaudio.c
blob9fa1cdbbeb2ae016faf3f30dd4f55b16082cd18a
1 /*
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/>.
18 #include <stdlib.h>
19 #include <stdbool.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <assert.h>
23 #include <pthread.h>
25 #include <libavutil/common.h>
26 #include <portaudio.h>
28 #include "config.h"
29 #include "subopt-helper.h"
30 #include "libaf/af_format.h"
31 #include "mp_msg.h"
32 #include "audio_out.h"
34 struct priv {
35 PaStream *stream;
36 int framelen;
38 pthread_mutex_t ring_mutex;
40 // protected by ring_mutex
41 unsigned char *ring;
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
51 struct format_map {
52 int mp_format;
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"
72 "\nOptions:\n"
73 " 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)
81 if (ret < 0) {
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",
87 hosterr->errorText);
89 return false;
91 return true;
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);
102 return bytes;
105 static int to_int(const char *s, int return_on_error)
107 char *endptr;
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();
116 check_pa_ret(count);
117 int found = paNoDevice;
118 int index = to_int(name, -1);
119 if (help)
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);
123 if (help) {
124 if (info->maxOutputChannels < 1)
125 continue;
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) {
133 found = n;
134 break;
137 if (found == paNoDevice && !help)
138 mp_msg(MSGT_AO, MSGL_FATAL, "[portaudio] Device '%s' not found!\n",
139 name);
140 return found;
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;
158 return 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;
175 return read_len;
178 static void fill_silence(unsigned char *ptr, int len)
180 memset(ptr, 0, len);
183 static int stream_callback(const void *input,
184 void *output_v,
185 unsigned long frameCount,
186 const PaStreamCallbackTimeInfo *timeInfo,
187 PaStreamCallbackFlags statusFlags,
188 void *userData)
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;
207 len_bytes -= bytes;
208 output += bytes;
210 int read = ring_read(ao, output, len_bytes);
211 len_bytes -= read;
212 output += read;
214 if (len_bytes > 0) {
215 if (priv->play_remaining) {
216 res = paComplete;
217 priv->play_remaining = false;
218 } else {
219 mp_msg(MSGT_AO, MSGL_ERR, "[portaudio] Buffer underflow!\n");
221 fill_silence(output, len_bytes);
224 pthread_mutex_unlock(&priv->ring_mutex);
226 return res;
229 static void uninit(struct ao *ao, bool cut_audio)
231 struct priv *priv = ao->priv;
233 if (priv->stream) {
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);
247 Pa_Terminate();
250 static int init(struct ao *ao, char *params)
252 struct priv *priv = talloc_zero(ao, struct priv);
253 ao->priv = priv;
255 if (!check_pa_ret(Pa_Initialize()))
256 return -1;
258 pthread_mutex_init(&priv->ring_mutex, NULL);
260 char *device = NULL;
261 const opt_t subopts[] = {
262 {"device", OPT_ARG_MSTRZ, &device, NULL},
263 {NULL}
265 if (subopt_parse(params, subopts) != 0) {
266 print_help();
267 goto error_exit;
270 int pa_device = Pa_GetDefaultOutputDevice();
271 if (device)
272 pa_device = find_device(ao, device);
273 if (pa_device == paNoDevice)
274 goto error_exit;
276 PaStreamParameters sp = {
277 .device = pa_device,
278 .channelCount = ao->channels,
279 .suggestedLatency
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)
289 break;
291 fmt++;
293 if (!fmt->pa_format) {
294 mp_msg(MSGT_AO, MSGL_V,
295 "[portaudio] Unsupported format, using default.\n");
296 fmt = format_maps;
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)))
305 goto error_exit;
306 if (!check_pa_ret(Pa_OpenStream(&priv->stream, NULL, &sp, ao->samplerate,
307 paFramesPerBufferUnspecified, paNoFlag,
308 stream_callback, ao)))
309 goto error_exit;
311 priv->ring_size = seconds_to_bytes(ao, 0.5);
312 priv->ring = talloc_zero_size(priv, priv->ring_size);
314 free(device);
315 return 0;
317 error_exit:
318 uninit(ao, true);
319 free(device);
320 return -1;
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));
338 return write_len;
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);
351 return free;
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)
364 / (float)ao->bps;
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);
380 priv->read_len = 0;
381 priv->read_pos = 0;
382 priv->play_remaining = false;
383 priv->play_time = 0;
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));
403 priv->play_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 = {
416 .is_new = true,
417 .info = &(const struct ao_info) {
418 "PortAudio",
419 "portaudio",
420 "wm4",
423 .init = init,
424 .uninit = uninit,
425 .reset = reset,
426 .get_space = get_space,
427 .play = play,
428 .get_delay = get_delay,
429 .pause = pause,
430 .resume = resume,