Coverage Report

Created: 2025-09-04 07:15

/src/mpv/audio/out/buffer.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * This file is part of mpv.
3
 *
4
 * mpv is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * mpv 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 Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17
18
#include <stddef.h>
19
#include <inttypes.h>
20
#include <math.h>
21
#include <errno.h>
22
#include <assert.h>
23
24
#include "ao.h"
25
#include "internal.h"
26
#include "audio/aframe.h"
27
#include "audio/format.h"
28
29
#include "common/msg.h"
30
#include "common/common.h"
31
32
#include "filters/f_async_queue.h"
33
#include "filters/filter_internal.h"
34
35
#include "osdep/timer.h"
36
#include "osdep/threads.h"
37
38
struct buffer_state {
39
    // Buffer and AO
40
    mp_mutex lock;
41
    mp_cond wakeup;
42
43
    // AO thread sleep
44
    mp_mutex pt_lock;
45
    mp_cond pt_wakeup;
46
47
    // Access from AO driver's thread only.
48
    char *convert_buffer;
49
50
    // Immutable.
51
    struct mp_async_queue *queue;
52
53
    // --- protected by lock
54
55
    struct mp_filter *filter_root;
56
    struct mp_filter *input;    // connected to queue
57
    struct mp_aframe *pending;  // last, not fully consumed output
58
59
    bool streaming;             // AO streaming active
60
    bool playing;               // logically playing audio from buffer
61
    bool paused;                // logically paused
62
    bool hw_paused;             // driver->set_pause() was used successfully
63
64
    int64_t end_time_ns;        // absolute output time of last played sample
65
    int64_t queued_time_ns;     // duration of samples that have been queued to
66
                                // the device but have not been played.
67
                                // This field is only set in ao_set_paused(),
68
                                // and is considered as a temporary solution;
69
                                // DO NOT USE IT IN OTHER PLACES.
70
71
    // "Push" AOs only (AOs with driver->write).
72
    bool recover_pause;         // non-hw_paused: needs to recover delay
73
    struct mp_pcm_state prepause_state;
74
    mp_thread thread;           // thread shoveling data to AO
75
    bool thread_valid;          // thread is running
76
    struct mp_aframe *temp_buf;
77
78
    // --- protected by pt_lock
79
    bool need_wakeup;
80
    bool terminate;             // exit thread
81
};
82
83
static MP_THREAD_VOID ao_thread(void *arg);
84
85
void ao_wakeup(struct ao *ao)
86
3.20M
{
87
3.20M
    struct buffer_state *p = ao->buffer_state;
88
3.20M
    mp_mutex_lock(&p->pt_lock);
89
3.20M
    p->need_wakeup = true;
90
3.20M
    mp_cond_broadcast(&p->pt_wakeup);
91
3.20M
    mp_mutex_unlock(&p->pt_lock);
92
3.20M
}
93
94
// called locked
95
static void get_dev_state(struct ao *ao, struct mp_pcm_state *state)
96
6.47M
{
97
6.47M
    struct buffer_state *p = ao->buffer_state;
98
99
6.47M
    if (p->paused && p->playing && !ao->stream_silence) {
100
0
        *state = p->prepause_state;
101
0
        return;
102
0
    }
103
104
6.47M
    *state = (struct mp_pcm_state){
105
6.47M
        .free_samples = -1,
106
6.47M
        .queued_samples = -1,
107
6.47M
        .delay = -1,
108
6.47M
    };
109
6.47M
    ao->driver->get_state(ao, state);
110
6.47M
}
111
112
struct mp_async_queue *ao_get_queue(struct ao *ao)
113
29.1k
{
114
29.1k
    struct buffer_state *p = ao->buffer_state;
115
29.1k
    return p->queue;
116
29.1k
}
117
118
// Special behavior with data==NULL: caller uses p->pending.
119
static int read_buffer(struct ao *ao, void **data, int samples, bool *eof,
120
                       bool pad_silence)
121
6.18M
{
122
6.18M
    struct buffer_state *p = ao->buffer_state;
123
6.18M
    int pos = 0;
124
6.18M
    *eof = false;
125
126
10.4M
    while (p->playing && !p->paused && pos < samples) {
127
10.0M
        if (!p->pending || !mp_aframe_get_size(p->pending)) {
128
9.71M
            TA_FREEP(&p->pending);
129
9.71M
            struct mp_frame frame = mp_pin_out_read(p->input->pins[0]);
130
9.71M
            if (!frame.type)
131
5.83M
                break; // we can't/don't want to block
132
3.87M
            if (frame.type != MP_FRAME_AUDIO) {
133
24.7k
                if (frame.type == MP_FRAME_EOF)
134
24.7k
                    *eof = true;
135
24.7k
                mp_frame_unref(&frame);
136
24.7k
                continue;
137
24.7k
            }
138
3.85M
            p->pending = frame.data;
139
3.85M
        }
140
141
4.19M
        if (!data)
142
0
            break;
143
144
4.19M
        int copy = mp_aframe_get_size(p->pending);
145
4.19M
        uint8_t **fdata = mp_aframe_get_data_ro(p->pending);
146
4.19M
        copy = MPMIN(copy, samples - pos);
147
8.62M
        for (int n = 0; n < ao->num_planes; n++) {
148
4.43M
            memcpy((char *)data[n] + pos * ao->sstride,
149
4.43M
                   fdata[n], copy * ao->sstride);
150
4.43M
        }
151
4.19M
        mp_aframe_skip_samples(p->pending, copy);
152
4.19M
        pos += copy;
153
4.19M
        *eof = false;
154
4.19M
    }
155
156
6.18M
    if (!data) {
157
0
        if (!p->pending)
158
0
            return 0;
159
0
        void **pd = (void *)mp_aframe_get_data_rw(p->pending);
160
0
        if (pd)
161
0
            ao_post_process_data(ao, pd, mp_aframe_get_size(p->pending));
162
0
        return 1;
163
0
    }
164
165
    // pad with silence (underflow/paused/eof)
166
6.18M
    if (pad_silence) {
167
12.6M
        for (int n = 0; n < ao->num_planes; n++) {
168
6.47M
            af_fill_silence((char *)data[n] + pos * ao->sstride,
169
6.47M
                    (samples - pos) * ao->sstride,
170
6.47M
                    ao->format);
171
6.47M
        }
172
6.18M
    }
173
174
6.18M
    ao_post_process_data(ao, data, pos);
175
6.18M
    return pos;
176
6.18M
}
177
178
static int ao_read_data_locked(struct ao *ao, void **data, int samples,
179
                               int64_t out_time_ns, bool *eof, bool pad_silence)
180
0
{
181
0
    struct buffer_state *p = ao->buffer_state;
182
0
    mp_assert(!ao->driver->write);
183
184
0
    int pos = read_buffer(ao, data, samples, eof, pad_silence);
185
186
0
    if (pos > 0)
187
0
        p->end_time_ns = out_time_ns;
188
189
0
    if (pos < samples && p->playing && !p->paused) {
190
0
        p->playing = false;
191
0
        ao->wakeup_cb(ao->wakeup_ctx);
192
        // For ao_drain().
193
0
        mp_cond_broadcast(&p->wakeup);
194
0
    }
195
196
0
    return pos;
197
0
}
198
199
// Read the given amount of samples in the user-provided data buffer. Returns
200
// the number of samples copied. If there is not enough data (buffer underrun
201
// or EOF), return the number of samples that could be copied, and fill the
202
// rest of the user-provided buffer with silence.
203
// This basically assumes that the audio device doesn't care about underruns.
204
// If this is called in paused mode, it will always return 0.
205
// The caller should set out_time_ns to the expected delay until the last sample
206
// reaches the speakers, in nanoseconds, using mp_time_ns() as reference.
207
int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_ns, bool *eof, bool pad_silence, bool blocking)
208
0
{
209
0
    struct buffer_state *p = ao->buffer_state;
210
211
0
    if (blocking) {
212
0
        mp_mutex_lock(&p->lock);
213
0
    } else if (mp_mutex_trylock(&p->lock)) {
214
0
        return 0;
215
0
    }
216
217
0
    bool eof_buf;
218
0
    if (eof == NULL) {
219
        // This is a public API. We want to reduce the cognitive burden of the caller.
220
0
        eof = &eof_buf;
221
0
    }
222
223
0
    int pos = ao_read_data_locked(ao, data, samples, out_time_ns, eof, pad_silence);
224
225
0
    mp_mutex_unlock(&p->lock);
226
227
0
    return pos;
228
0
}
229
230
// Same as ao_read_data(), but convert data according to *fmt.
231
// fmt->src_fmt and fmt->channels must be the same as the AO parameters.
232
int ao_read_data_converted(struct ao *ao, struct ao_convert_fmt *fmt,
233
                           void **data, int samples, int64_t out_time_ns)
234
0
{
235
0
    struct buffer_state *p = ao->buffer_state;
236
0
    void *ndata[MP_NUM_CHANNELS] = {0};
237
238
0
    if (!ao_need_conversion(fmt))
239
0
        return ao_read_data(ao, data, samples, out_time_ns, NULL, true, true);
240
241
0
    mp_assert(ao->format == fmt->src_fmt);
242
0
    mp_assert(ao->channels.num == fmt->channels);
243
244
0
    bool planar = af_fmt_is_planar(fmt->src_fmt);
245
0
    int planes = planar ? fmt->channels : 1;
246
0
    int plane_samples = samples * (planar ? 1: fmt->channels);
247
0
    int src_plane_size = plane_samples * af_fmt_to_bytes(fmt->src_fmt);
248
0
    int dst_plane_size = plane_samples * fmt->dst_bits / 8;
249
250
0
    int needed = src_plane_size * planes;
251
0
    if (needed > talloc_get_size(p->convert_buffer) || !p->convert_buffer) {
252
0
        talloc_free(p->convert_buffer);
253
0
        p->convert_buffer = talloc_size(NULL, needed);
254
0
    }
255
256
0
    for (int n = 0; n < planes; n++)
257
0
        ndata[n] = p->convert_buffer + n * src_plane_size;
258
259
0
    int res = ao_read_data(ao, ndata, samples, out_time_ns, NULL, true, true);
260
261
0
    ao_convert_inplace(fmt, ndata, samples);
262
0
    for (int n = 0; n < planes; n++)
263
0
        memcpy(data[n], ndata[n], dst_plane_size);
264
265
0
    return res;
266
0
}
267
268
// Called by pull-based AO to indicate the AO has stopped requesting more data,
269
// usually when EOF is got from ao_read_data().
270
// After this function is called, the core will call ao->driver->start() again
271
// when more audio data after EOF arrives.
272
void ao_stop_streaming(struct ao *ao)
273
0
{
274
0
    struct buffer_state *p = ao->buffer_state;
275
0
    p->streaming = false;
276
0
}
277
278
int ao_control(struct ao *ao, enum aocontrol cmd, void *arg)
279
29.2k
{
280
29.2k
    struct buffer_state *p = ao->buffer_state;
281
29.2k
    int r = CONTROL_UNKNOWN;
282
29.2k
    if (ao->driver->control) {
283
        // Only need to lock in push mode.
284
0
        if (ao->driver->write)
285
0
            mp_mutex_lock(&p->lock);
286
287
0
        r = ao->driver->control(ao, cmd, arg);
288
289
0
        if (ao->driver->write)
290
0
            mp_mutex_unlock(&p->lock);
291
0
    }
292
29.2k
    return r;
293
29.2k
}
294
295
double ao_get_delay(struct ao *ao)
296
284k
{
297
284k
    struct buffer_state *p = ao->buffer_state;
298
299
284k
    mp_mutex_lock(&p->lock);
300
301
284k
    double driver_delay;
302
284k
    if (ao->driver->write) {
303
284k
        struct mp_pcm_state state;
304
284k
        get_dev_state(ao, &state);
305
284k
        driver_delay = state.delay;
306
284k
    } else {
307
0
        int64_t end = p->end_time_ns;
308
0
        int64_t now = mp_time_ns();
309
0
        driver_delay = MPMAX(0, MP_TIME_NS_TO_S(end - now));
310
0
    }
311
312
284k
    int64_t pending = mp_async_queue_get_samples(p->queue);
313
284k
    if (p->pending)
314
312
        pending += mp_aframe_get_size(p->pending);
315
316
284k
    mp_mutex_unlock(&p->lock);
317
284k
    return driver_delay + pending / (double)ao->samplerate;
318
284k
}
319
320
// Fully stop playback; clear buffers, including queue.
321
void ao_reset(struct ao *ao)
322
11.1k
{
323
11.1k
    struct buffer_state *p = ao->buffer_state;
324
11.1k
    bool wakeup = false;
325
11.1k
    bool do_reset = false;
326
327
11.1k
    mp_mutex_lock(&p->lock);
328
329
11.1k
    TA_FREEP(&p->pending);
330
11.1k
    mp_async_queue_reset(p->queue);
331
11.1k
    mp_filter_reset(p->filter_root);
332
11.1k
    mp_async_queue_resume_reading(p->queue);
333
334
11.1k
    if (!ao->stream_silence && ao->driver->reset) {
335
11.1k
        if (ao->driver->write) {
336
11.1k
            ao->driver->reset(ao);
337
11.1k
        } else {
338
            // Pull AOs may wait for ao_read_data() to return.
339
            // That would deadlock if called from within the lock.
340
0
            do_reset = true;
341
0
        }
342
11.1k
        p->streaming = false;
343
11.1k
    }
344
11.1k
    wakeup = p->playing;
345
11.1k
    p->playing = false;
346
11.1k
    p->recover_pause = false;
347
11.1k
    p->hw_paused = false;
348
11.1k
    p->end_time_ns = 0;
349
350
11.1k
    mp_mutex_unlock(&p->lock);
351
352
11.1k
    if (do_reset)
353
0
        ao->driver->reset(ao);
354
355
11.1k
    if (wakeup)
356
4.43k
        ao_wakeup(ao);
357
11.1k
}
358
359
// Initiate playback. This moves from the stop/underrun state to actually
360
// playing (orthogonally taking the paused state into account). Plays all
361
// data in the queue, and goes into underrun state if no more data available.
362
// No-op if already running.
363
void ao_start(struct ao *ao)
364
29.1k
{
365
29.1k
    struct buffer_state *p = ao->buffer_state;
366
29.1k
    bool do_start = false;
367
368
29.1k
    mp_mutex_lock(&p->lock);
369
370
29.1k
    p->playing = true;
371
372
29.1k
    if (!ao->driver->write && !p->paused && !p->streaming) {
373
0
        p->streaming = true;
374
0
        do_start = true;
375
0
    }
376
377
29.1k
    mp_mutex_unlock(&p->lock);
378
379
    // Pull AOs might call ao_read_data() so do this outside the lock.
380
29.1k
    if (do_start)
381
0
        ao->driver->start(ao);
382
383
29.1k
    ao_wakeup(ao);
384
29.1k
}
385
386
void ao_set_paused(struct ao *ao, bool paused, bool eof)
387
29.1k
{
388
29.1k
    struct buffer_state *p = ao->buffer_state;
389
29.1k
    bool wakeup = false;
390
29.1k
    bool do_change_state = false;
391
29.1k
    bool is_hw_paused;
392
393
    // If we are going to pause on eof and ao is still playing,
394
    // be sure to drain the ao first for gapless.
395
29.1k
    if (eof && paused && ao_is_playing(ao))
396
0
        ao_drain(ao);
397
398
29.1k
    mp_mutex_lock(&p->lock);
399
400
29.1k
    if ((p->playing || !ao->driver->write) && !p->paused && paused) {
401
0
        if (p->streaming && !ao->stream_silence) {
402
0
            if (ao->driver->write) {
403
0
                if (!p->recover_pause)
404
0
                    get_dev_state(ao, &p->prepause_state);
405
0
                if (ao->driver->set_pause && ao->driver->set_pause(ao, true)) {
406
0
                    p->hw_paused = true;
407
0
                } else {
408
0
                    ao->driver->reset(ao);
409
0
                    p->streaming = false;
410
0
                    p->recover_pause = !ao->untimed;
411
0
                }
412
0
            } else if (ao->driver->reset || ao->driver->set_pause) {
413
                // See ao_reset() why this is done outside of the lock.
414
0
                do_change_state = true;
415
0
                p->streaming = false;
416
0
                is_hw_paused = p->hw_paused = !!ao->driver->set_pause;
417
0
            }
418
0
        }
419
0
        wakeup = true;
420
29.1k
    } else if (p->playing && p->paused && !paused) {
421
0
        if (ao->driver->write) {
422
0
            if (p->hw_paused)
423
0
                ao->driver->set_pause(ao, false);
424
0
            p->hw_paused = false;
425
0
        } else {
426
0
            if (!p->streaming)
427
0
                do_change_state = true;
428
0
            p->streaming = true;
429
0
            is_hw_paused = p->hw_paused;
430
0
            p->hw_paused = false;
431
0
        }
432
0
        wakeup = true;
433
0
    }
434
29.1k
    p->paused = paused;
435
436
29.1k
    mp_mutex_unlock(&p->lock);
437
438
29.1k
    if (do_change_state) {
439
0
        if (is_hw_paused) {
440
0
            if (paused) {
441
0
                ao->driver->set_pause(ao, true);
442
0
                p->queued_time_ns = p->end_time_ns - mp_time_ns();
443
0
            } else {
444
0
                p->end_time_ns = p->queued_time_ns + mp_time_ns();
445
0
                ao->driver->set_pause(ao, false);
446
0
            }
447
0
        } else {
448
0
            if (paused)
449
0
                ao->driver->reset(ao);
450
0
            else
451
0
                ao->driver->start(ao);
452
0
        }
453
0
    }
454
455
29.1k
    if (wakeup)
456
0
        ao_wakeup(ao);
457
29.1k
}
458
459
// Whether audio is playing. This means that there is still data in the buffers,
460
// and ao_start() was called. This returns true even if playback was logically
461
// paused. On false, EOF was reached, or an underrun happened, or ao_reset()
462
// was called.
463
bool ao_is_playing(struct ao *ao)
464
1.04M
{
465
1.04M
    struct buffer_state *p = ao->buffer_state;
466
467
1.04M
    mp_mutex_lock(&p->lock);
468
1.04M
    bool playing = p->playing;
469
1.04M
    mp_mutex_unlock(&p->lock);
470
471
1.04M
    return playing;
472
1.04M
}
473
474
// Block until the current audio buffer has played completely.
475
void ao_drain(struct ao *ao)
476
4.33k
{
477
4.33k
    struct buffer_state *p = ao->buffer_state;
478
479
4.33k
    mp_mutex_lock(&p->lock);
480
4.34k
    while (!p->paused && p->playing) {
481
4.33k
        mp_mutex_unlock(&p->lock);
482
4.33k
        double delay = ao_get_delay(ao);
483
4.33k
        mp_mutex_lock(&p->lock);
484
485
        // Wait for buffer + arbitrary ~250ms for EOF signal from AO.
486
4.33k
        if (mp_cond_timedwait(&p->wakeup, &p->lock,
487
4.33k
                              MP_TIME_S_TO_NS(MPMAX(delay, 0) + 0.25)))
488
4.33k
        {
489
4.33k
            MP_VERBOSE(ao, "drain timeout\n");
490
4.33k
            break;
491
4.33k
        }
492
493
7
        if (!p->playing && mp_async_queue_get_samples(p->queue)) {
494
0
            MP_WARN(ao, "underrun during draining\n");
495
0
            mp_mutex_unlock(&p->lock);
496
0
            ao_start(ao);
497
0
            mp_mutex_lock(&p->lock);
498
0
        }
499
7
    }
500
4.33k
    mp_mutex_unlock(&p->lock);
501
502
4.33k
    ao_reset(ao);
503
4.33k
}
504
505
static void wakeup_filters(void *ctx)
506
3.17M
{
507
3.17M
    struct ao *ao = ctx;
508
3.17M
    ao_wakeup(ao);
509
3.17M
}
510
511
void ao_uninit(struct ao *ao)
512
29.2k
{
513
29.2k
    struct buffer_state *p = ao->buffer_state;
514
515
29.2k
    if (p && p->thread_valid) {
516
29.1k
        mp_mutex_lock(&p->pt_lock);
517
29.1k
        p->terminate = true;
518
29.1k
        mp_cond_broadcast(&p->pt_wakeup);
519
29.1k
        mp_mutex_unlock(&p->pt_lock);
520
521
29.1k
        mp_thread_join(p->thread);
522
29.1k
        p->thread_valid = false;
523
29.1k
    }
524
525
29.2k
    if (ao->driver_initialized)
526
29.2k
        ao->driver->uninit(ao);
527
528
29.2k
    if (p) {
529
29.2k
        talloc_free(p->filter_root);
530
29.2k
        talloc_free(p->queue);
531
29.2k
        talloc_free(p->pending);
532
29.2k
        talloc_free(p->convert_buffer);
533
29.2k
        talloc_free(p->temp_buf);
534
535
29.2k
        mp_cond_destroy(&p->wakeup);
536
29.2k
        mp_mutex_destroy(&p->lock);
537
538
29.2k
        mp_cond_destroy(&p->pt_wakeup);
539
29.2k
        mp_mutex_destroy(&p->pt_lock);
540
29.2k
    }
541
542
29.2k
    talloc_free(ao);
543
29.2k
}
544
545
void init_buffer_pre(struct ao *ao)
546
29.2k
{
547
29.2k
    ao->buffer_state = talloc_zero(ao, struct buffer_state);
548
29.2k
}
549
550
bool init_buffer_post(struct ao *ao)
551
29.1k
{
552
29.1k
    struct buffer_state *p = ao->buffer_state;
553
554
29.1k
    mp_assert(ao->driver->start);
555
29.1k
    if (ao->driver->write) {
556
29.1k
        mp_assert(ao->driver->reset);
557
29.1k
        mp_assert(ao->driver->get_state);
558
29.1k
    }
559
560
29.1k
    mp_mutex_init(&p->lock);
561
29.1k
    mp_cond_init(&p->wakeup);
562
563
29.1k
    mp_mutex_init(&p->pt_lock);
564
29.1k
    mp_cond_init(&p->pt_wakeup);
565
566
29.1k
    p->queue = mp_async_queue_create();
567
29.1k
    p->filter_root = mp_filter_create_root(ao->global);
568
29.1k
    p->input = mp_async_queue_create_filter(p->filter_root, MP_PIN_OUT, p->queue);
569
570
29.1k
    mp_async_queue_resume_reading(p->queue);
571
572
29.1k
    struct mp_async_queue_config cfg = {
573
29.1k
        .sample_unit = AQUEUE_UNIT_SAMPLES,
574
29.1k
        .max_samples = ao->buffer,
575
29.1k
        .max_bytes = INT64_MAX,
576
29.1k
    };
577
29.1k
    mp_async_queue_set_config(p->queue, cfg);
578
579
29.1k
    if (ao->driver->write) {
580
29.1k
        mp_filter_graph_set_wakeup_cb(p->filter_root, wakeup_filters, ao);
581
582
29.1k
        p->thread_valid = true;
583
29.1k
        if (mp_thread_create(&p->thread, ao_thread, ao)) {
584
0
            p->thread_valid = false;
585
0
            return false;
586
0
        }
587
29.1k
    } else {
588
0
        if (ao->stream_silence) {
589
0
            ao->driver->start(ao);
590
0
            p->streaming = true;
591
0
        }
592
0
    }
593
594
29.1k
    if (ao->stream_silence) {
595
0
        MP_WARN(ao, "The --audio-stream-silence option is set. This will break "
596
0
                "certain player behavior.\n");
597
0
    }
598
599
29.1k
    return true;
600
29.1k
}
601
602
static bool realloc_buf(struct ao *ao, int samples)
603
6.18M
{
604
6.18M
    struct buffer_state *p = ao->buffer_state;
605
606
6.18M
    samples = MPMAX(1, samples);
607
608
6.18M
    if (!p->temp_buf || samples > mp_aframe_get_size(p->temp_buf)) {
609
29.0k
        TA_FREEP(&p->temp_buf);
610
29.0k
        p->temp_buf = mp_aframe_create();
611
29.0k
        if (!mp_aframe_set_format(p->temp_buf, ao->format) ||
612
29.0k
            !mp_aframe_set_chmap(p->temp_buf, &ao->channels) ||
613
29.0k
            !mp_aframe_set_rate(p->temp_buf, ao->samplerate) ||
614
29.0k
            !mp_aframe_alloc_data(p->temp_buf, samples))
615
497
        {
616
497
            TA_FREEP(&p->temp_buf);
617
497
            return false;
618
497
        }
619
29.0k
    }
620
621
6.18M
    return true;
622
6.18M
}
623
624
// called locked
625
static bool ao_play_data(struct ao *ao)
626
6.27M
{
627
6.27M
    struct buffer_state *p = ao->buffer_state;
628
629
6.27M
    if ((!p->playing || p->paused) && !ao->stream_silence)
630
88.6k
        return false;
631
632
6.18M
    struct mp_pcm_state state;
633
6.18M
    get_dev_state(ao, &state);
634
635
6.18M
    if (p->streaming && !state.playing && !ao->untimed)
636
0
        goto eof;
637
638
6.18M
    void **planes = NULL;
639
6.18M
    int space = state.free_samples;
640
6.18M
    if (!space)
641
0
        return false;
642
6.18M
    mp_assert(space >= 0);
643
644
6.18M
    int samples = 0;
645
6.18M
    bool got_eof = false;
646
6.18M
    if (ao->driver->write_frames) {
647
0
        TA_FREEP(&p->pending);
648
0
        samples = read_buffer(ao, NULL, 1, &got_eof, false);
649
0
        planes = (void **)&p->pending;
650
6.18M
    } else {
651
6.18M
        if (!realloc_buf(ao, space)) {
652
497
            MP_ERR(ao, "Failed to allocate buffer.\n");
653
497
            return false;
654
497
        }
655
6.18M
        planes = (void **)mp_aframe_get_data_rw(p->temp_buf);
656
6.18M
        mp_assert(planes);
657
658
6.18M
        if (p->recover_pause) {
659
0
            samples = MPCLAMP(p->prepause_state.delay * ao->samplerate, 0, space);
660
0
            p->recover_pause = false;
661
0
            mp_aframe_set_silence(p->temp_buf, 0, space);
662
0
        }
663
664
6.18M
        if (!samples) {
665
6.18M
            samples = read_buffer(ao, planes, space, &got_eof, true);
666
6.18M
            if (p->paused || (ao->stream_silence && !p->playing))
667
0
                samples = space; // read_buffer() sets remainder to silent
668
6.18M
        }
669
6.18M
    }
670
671
6.18M
    if (samples) {
672
3.35M
        MP_STATS(ao, "start ao fill");
673
3.35M
        if (!ao->driver->write(ao, planes, samples))
674
3.35M
            MP_ERR(ao, "Error writing audio to device.\n");
675
3.35M
        MP_STATS(ao, "end ao fill");
676
677
3.35M
        if (!p->streaming) {
678
28.4k
            MP_VERBOSE(ao, "starting AO\n");
679
28.4k
            ao->driver->start(ao);
680
28.4k
            p->streaming = true;
681
28.4k
            state.playing = true;
682
28.4k
        }
683
3.35M
    }
684
685
6.18M
    MP_TRACE(ao, "in=%d space=%d(%d) pl=%d, eof=%d\n",
686
6.18M
             samples, space, state.free_samples, p->playing, got_eof);
687
688
6.18M
    if (got_eof)
689
24.7k
        goto eof;
690
691
6.16M
    return samples > 0 && (samples < space || ao->untimed);
692
693
24.7k
eof:
694
24.7k
    MP_VERBOSE(ao, "audio end or underrun\n");
695
    // Normal AOs signal EOF on underrun, untimed AOs never signal underruns.
696
24.7k
    if (ao->untimed || !state.playing || ao->stream_silence) {
697
24.7k
        p->streaming = state.playing && !ao->untimed;
698
24.7k
        p->playing = false;
699
24.7k
    }
700
24.7k
    ao->wakeup_cb(ao->wakeup_ctx);
701
    // For ao_drain().
702
24.7k
    mp_cond_broadcast(&p->wakeup);
703
24.7k
    return true;
704
6.18M
}
705
706
static MP_THREAD_VOID ao_thread(void *arg)
707
29.1k
{
708
29.1k
    struct ao *ao = arg;
709
29.1k
    struct buffer_state *p = ao->buffer_state;
710
29.1k
    mp_thread_set_name("ao");
711
6.27M
    while (1) {
712
6.27M
        mp_mutex_lock(&p->lock);
713
714
6.27M
        bool retry = ao_play_data(ao);
715
716
        // Wait until the device wants us to write more data to it.
717
        // Fallback to guessing.
718
6.27M
        int64_t timeout = INT64_MAX;
719
6.27M
        if (p->streaming && !retry && (!p->paused || ao->stream_silence)) {
720
            // Wake up again if half of the audio buffer has been played.
721
            // Since audio could play at a faster or slower pace, wake up twice
722
            // as often as ideally needed.
723
2.82M
            timeout = MP_TIME_S_TO_NS(ao->device_buffer / (double)ao->samplerate * 0.25);
724
2.82M
        }
725
726
6.27M
        mp_mutex_unlock(&p->lock);
727
728
6.27M
        mp_mutex_lock(&p->pt_lock);
729
6.27M
        if (p->terminate) {
730
29.1k
            mp_mutex_unlock(&p->pt_lock);
731
29.1k
            break;
732
29.1k
        }
733
6.24M
        if (!p->need_wakeup && !retry) {
734
2.74M
            MP_STATS(ao, "start audio wait");
735
2.74M
            mp_cond_timedwait(&p->pt_wakeup, &p->pt_lock, timeout);
736
2.74M
            MP_STATS(ao, "end audio wait");
737
2.74M
        }
738
6.24M
        p->need_wakeup = false;
739
6.24M
        mp_mutex_unlock(&p->pt_lock);
740
6.24M
    }
741
29.1k
    MP_THREAD_RETURN();
742
29.1k
}