• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013 Lukasz Marek <lukasz.m.luki@gmail.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <math.h>
22 #include <pulse/pulseaudio.h>
23 #include <pulse/error.h>
24 #include "libavformat/avformat.h"
25 #include "libavformat/internal.h"
26 #include "libavformat/mux.h"
27 #include "libavformat/version.h"
28 #include "libavutil/channel_layout.h"
29 #include "libavutil/internal.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/time.h"
32 #include "libavutil/log.h"
33 #include "libavutil/attributes.h"
34 #include "pulse_audio_common.h"
35 
36 typedef struct PulseData {
37     AVClass *class;
38     const char *server;
39     const char *name;
40     const char *stream_name;
41     const char *device;
42     int64_t timestamp;
43     int buffer_size;               /**< Buffer size in bytes */
44     int buffer_duration;           /**< Buffer size in ms, recalculated to buffer_size */
45     int prebuf;
46     int minreq;
47     int last_result;
48     pa_threaded_mainloop *mainloop;
49     pa_context *ctx;
50     pa_stream *stream;
51     int nonblocking;
52     int mute;
53     pa_volume_t base_volume;
54     pa_volume_t last_volume;
55 } PulseData;
56 
pulse_audio_sink_device_cb(pa_context * ctx,const pa_sink_info * dev,int eol,void * userdata)57 static void pulse_audio_sink_device_cb(pa_context *ctx, const pa_sink_info *dev,
58                                        int eol, void *userdata)
59 {
60     PulseData *s = userdata;
61 
62     if (s->ctx != ctx)
63         return;
64 
65     if (eol) {
66         pa_threaded_mainloop_signal(s->mainloop, 0);
67     } else {
68         if (dev->flags & PA_SINK_FLAT_VOLUME)
69             s->base_volume = dev->base_volume;
70         else
71             s->base_volume = PA_VOLUME_NORM;
72         av_log(s, AV_LOG_DEBUG, "base volume: %u\n", s->base_volume);
73     }
74 }
75 
76 /* Mainloop must be locked before calling this function as it uses pa_threaded_mainloop_wait. */
pulse_update_sink_info(AVFormatContext * h)77 static int pulse_update_sink_info(AVFormatContext *h)
78 {
79     PulseData *s = h->priv_data;
80     pa_operation *op;
81     if (!(op = pa_context_get_sink_info_by_name(s->ctx, s->device,
82                                                 pulse_audio_sink_device_cb, s))) {
83         av_log(s, AV_LOG_ERROR, "pa_context_get_sink_info_by_name failed.\n");
84         return AVERROR_EXTERNAL;
85     }
86     while (pa_operation_get_state(op) == PA_OPERATION_RUNNING)
87         pa_threaded_mainloop_wait(s->mainloop);
88     pa_operation_unref(op);
89     return 0;
90 }
91 
pulse_audio_sink_input_cb(pa_context * ctx,const pa_sink_input_info * i,int eol,void * userdata)92 static void pulse_audio_sink_input_cb(pa_context *ctx, const pa_sink_input_info *i,
93                                       int eol, void *userdata)
94 {
95     AVFormatContext *h = userdata;
96     PulseData *s = h->priv_data;
97 
98     if (s->ctx != ctx)
99         return;
100 
101     if (!eol) {
102         double val;
103         pa_volume_t vol = pa_cvolume_avg(&i->volume);
104         if (s->mute < 0 || (s->mute && !i->mute) || (!s->mute && i->mute)) {
105             s->mute = i->mute;
106             avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_MUTE_STATE_CHANGED, &s->mute, sizeof(s->mute));
107         }
108 
109         vol = pa_sw_volume_divide(vol, s->base_volume);
110         if (s->last_volume != vol) {
111             val = (double)vol / PA_VOLUME_NORM;
112             avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_VOLUME_LEVEL_CHANGED, &val, sizeof(val));
113             s->last_volume = vol;
114         }
115     }
116 }
117 
118 /* This function creates new loop so may be called from PA callbacks.
119    Mainloop must be locked before calling this function as it operates on streams. */
pulse_update_sink_input_info(AVFormatContext * h)120 static int pulse_update_sink_input_info(AVFormatContext *h)
121 {
122     PulseData *s = h->priv_data;
123     pa_operation *op;
124     enum pa_operation_state op_state;
125     pa_mainloop *ml = NULL;
126     pa_context *ctx = NULL;
127     int ret = 0;
128 
129     if ((ret = ff_pulse_audio_connect_context(&ml, &ctx, s->server, "Update sink input information")) < 0)
130         return ret;
131 
132     if (!(op = pa_context_get_sink_input_info(ctx, pa_stream_get_index(s->stream),
133                                               pulse_audio_sink_input_cb, h))) {
134         ret = AVERROR_EXTERNAL;
135         goto fail;
136     }
137 
138     while ((op_state = pa_operation_get_state(op)) == PA_OPERATION_RUNNING)
139         pa_mainloop_iterate(ml, 1, NULL);
140     pa_operation_unref(op);
141     if (op_state != PA_OPERATION_DONE) {
142         ret = AVERROR_EXTERNAL;
143         goto fail;
144     }
145 
146   fail:
147     ff_pulse_audio_disconnect_context(&ml, &ctx);
148     if (ret)
149         av_log(s, AV_LOG_ERROR, "pa_context_get_sink_input_info failed.\n");
150     return ret;
151 }
152 
pulse_event(pa_context * ctx,pa_subscription_event_type_t t,uint32_t idx,void * userdata)153 static void pulse_event(pa_context *ctx, pa_subscription_event_type_t t,
154                         uint32_t idx, void *userdata)
155 {
156     AVFormatContext *h = userdata;
157     PulseData *s = h->priv_data;
158 
159     if (s->ctx != ctx)
160         return;
161 
162     if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) {
163         if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_CHANGE)
164             // Calling from mainloop callback. No need to lock mainloop.
165             pulse_update_sink_input_info(h);
166     }
167 }
168 
pulse_stream_writable(pa_stream * stream,size_t nbytes,void * userdata)169 static void pulse_stream_writable(pa_stream *stream, size_t nbytes, void *userdata)
170 {
171     AVFormatContext *h = userdata;
172     PulseData *s = h->priv_data;
173     int64_t val = nbytes;
174 
175     if (stream != s->stream)
176         return;
177 
178     avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_BUFFER_WRITABLE, &val, sizeof(val));
179     pa_threaded_mainloop_signal(s->mainloop, 0);
180 }
181 
pulse_overflow(pa_stream * stream,void * userdata)182 static void pulse_overflow(pa_stream *stream, void *userdata)
183 {
184     AVFormatContext *h = userdata;
185     avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_BUFFER_OVERFLOW, NULL, 0);
186 }
187 
pulse_underflow(pa_stream * stream,void * userdata)188 static void pulse_underflow(pa_stream *stream, void *userdata)
189 {
190     AVFormatContext *h = userdata;
191     avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_BUFFER_UNDERFLOW, NULL, 0);
192 }
193 
pulse_stream_state(pa_stream * stream,void * userdata)194 static void pulse_stream_state(pa_stream *stream, void *userdata)
195 {
196     PulseData *s = userdata;
197 
198     if (stream != s->stream)
199         return;
200 
201     switch (pa_stream_get_state(s->stream)) {
202         case PA_STREAM_READY:
203         case PA_STREAM_FAILED:
204         case PA_STREAM_TERMINATED:
205             pa_threaded_mainloop_signal(s->mainloop, 0);
206         default:
207             break;
208     }
209 }
210 
pulse_stream_wait(PulseData * s)211 static int pulse_stream_wait(PulseData *s)
212 {
213     pa_stream_state_t state;
214 
215     while ((state = pa_stream_get_state(s->stream)) != PA_STREAM_READY) {
216         if (state == PA_STREAM_FAILED || state == PA_STREAM_TERMINATED)
217             return AVERROR_EXTERNAL;
218         pa_threaded_mainloop_wait(s->mainloop);
219     }
220     return 0;
221 }
222 
pulse_context_state(pa_context * ctx,void * userdata)223 static void pulse_context_state(pa_context *ctx, void *userdata)
224 {
225     PulseData *s = userdata;
226 
227     if (s->ctx != ctx)
228         return;
229 
230     switch (pa_context_get_state(ctx)) {
231         case PA_CONTEXT_READY:
232         case PA_CONTEXT_FAILED:
233         case PA_CONTEXT_TERMINATED:
234             pa_threaded_mainloop_signal(s->mainloop, 0);
235         default:
236             break;
237     }
238 }
239 
pulse_context_wait(PulseData * s)240 static int pulse_context_wait(PulseData *s)
241 {
242     pa_context_state_t state;
243 
244     while ((state = pa_context_get_state(s->ctx)) != PA_CONTEXT_READY) {
245         if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED)
246             return AVERROR_EXTERNAL;
247         pa_threaded_mainloop_wait(s->mainloop);
248     }
249     return 0;
250 }
251 
pulse_stream_result(pa_stream * stream,int success,void * userdata)252 static void pulse_stream_result(pa_stream *stream, int success, void *userdata)
253 {
254     PulseData *s = userdata;
255 
256     if (stream != s->stream)
257         return;
258 
259     s->last_result = success ? 0 : AVERROR_EXTERNAL;
260     pa_threaded_mainloop_signal(s->mainloop, 0);
261 }
262 
pulse_finish_stream_operation(PulseData * s,pa_operation * op,const char * name)263 static int pulse_finish_stream_operation(PulseData *s, pa_operation *op, const char *name)
264 {
265     if (!op) {
266         pa_threaded_mainloop_unlock(s->mainloop);
267         av_log(s, AV_LOG_ERROR, "%s failed.\n", name);
268         return AVERROR_EXTERNAL;
269     }
270     s->last_result = 2;
271     while (s->last_result == 2)
272         pa_threaded_mainloop_wait(s->mainloop);
273     pa_operation_unref(op);
274     pa_threaded_mainloop_unlock(s->mainloop);
275     if (s->last_result != 0)
276         av_log(s, AV_LOG_ERROR, "%s failed.\n", name);
277     return s->last_result;
278 }
279 
pulse_set_pause(PulseData * s,int pause)280 static int pulse_set_pause(PulseData *s, int pause)
281 {
282     pa_operation *op;
283     pa_threaded_mainloop_lock(s->mainloop);
284     op = pa_stream_cork(s->stream, pause, pulse_stream_result, s);
285     return pulse_finish_stream_operation(s, op, "pa_stream_cork");
286 }
287 
pulse_flash_stream(PulseData * s)288 static int pulse_flash_stream(PulseData *s)
289 {
290     pa_operation *op;
291     pa_threaded_mainloop_lock(s->mainloop);
292     op = pa_stream_flush(s->stream, pulse_stream_result, s);
293     return pulse_finish_stream_operation(s, op, "pa_stream_flush");
294 }
295 
pulse_context_result(pa_context * ctx,int success,void * userdata)296 static void pulse_context_result(pa_context *ctx, int success, void *userdata)
297 {
298     PulseData *s = userdata;
299 
300     if (s->ctx != ctx)
301         return;
302 
303     s->last_result = success ? 0 : AVERROR_EXTERNAL;
304     pa_threaded_mainloop_signal(s->mainloop, 0);
305 }
306 
pulse_finish_context_operation(PulseData * s,pa_operation * op,const char * name)307 static int pulse_finish_context_operation(PulseData *s, pa_operation *op, const char *name)
308 {
309     if (!op) {
310         pa_threaded_mainloop_unlock(s->mainloop);
311         av_log(s, AV_LOG_ERROR, "%s failed.\n", name);
312         return AVERROR_EXTERNAL;
313     }
314     s->last_result = 2;
315     while (s->last_result == 2)
316         pa_threaded_mainloop_wait(s->mainloop);
317     pa_operation_unref(op);
318     pa_threaded_mainloop_unlock(s->mainloop);
319     if (s->last_result != 0)
320         av_log(s, AV_LOG_ERROR, "%s failed.\n", name);
321     return s->last_result;
322 }
323 
pulse_set_mute(PulseData * s)324 static int pulse_set_mute(PulseData *s)
325 {
326     pa_operation *op;
327     pa_threaded_mainloop_lock(s->mainloop);
328     op = pa_context_set_sink_input_mute(s->ctx, pa_stream_get_index(s->stream),
329                                         s->mute, pulse_context_result, s);
330     return pulse_finish_context_operation(s, op, "pa_context_set_sink_input_mute");
331 }
332 
pulse_set_volume(PulseData * s,double volume)333 static int pulse_set_volume(PulseData *s, double volume)
334 {
335     pa_operation *op;
336     pa_cvolume cvol;
337     pa_volume_t vol;
338     const pa_sample_spec *ss = pa_stream_get_sample_spec(s->stream);
339 
340     vol = pa_sw_volume_multiply(lrint(volume * PA_VOLUME_NORM), s->base_volume);
341     pa_cvolume_set(&cvol, ss->channels, PA_VOLUME_NORM);
342     pa_sw_cvolume_multiply_scalar(&cvol, &cvol, vol);
343     pa_threaded_mainloop_lock(s->mainloop);
344     op = pa_context_set_sink_input_volume(s->ctx, pa_stream_get_index(s->stream),
345                                           &cvol, pulse_context_result, s);
346     return pulse_finish_context_operation(s, op, "pa_context_set_sink_input_volume");
347 }
348 
pulse_subscribe_events(PulseData * s)349 static int pulse_subscribe_events(PulseData *s)
350 {
351     pa_operation *op;
352 
353     pa_threaded_mainloop_lock(s->mainloop);
354     op = pa_context_subscribe(s->ctx, PA_SUBSCRIPTION_MASK_SINK_INPUT, pulse_context_result, s);
355     return pulse_finish_context_operation(s, op, "pa_context_subscribe");
356 }
357 
pulse_map_channels_to_pulse(const AVChannelLayout * channel_layout,pa_channel_map * channel_map)358 static void pulse_map_channels_to_pulse(const AVChannelLayout *channel_layout, pa_channel_map *channel_map)
359 {
360     channel_map->channels = 0;
361     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_FRONT_LEFT) >= 0)
362         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_LEFT;
363     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_FRONT_RIGHT) >= 0)
364         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_RIGHT;
365     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_FRONT_CENTER) >= 0)
366         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_CENTER;
367     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_LOW_FREQUENCY) >= 0)
368         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_LFE;
369     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_BACK_LEFT) >= 0)
370         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_REAR_LEFT;
371     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_BACK_RIGHT) >= 0)
372         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_REAR_RIGHT;
373     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_FRONT_LEFT_OF_CENTER) >= 0)
374         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER;
375     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_FRONT_RIGHT_OF_CENTER) >= 0)
376         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
377     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_BACK_CENTER) >= 0)
378         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_REAR_CENTER;
379     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_SIDE_LEFT) >= 0)
380         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_SIDE_LEFT;
381     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_SIDE_RIGHT) >= 0)
382         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_SIDE_RIGHT;
383     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_TOP_CENTER) >= 0)
384         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_CENTER;
385     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_TOP_FRONT_LEFT) >= 0)
386         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_FRONT_LEFT;
387     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0)
388         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_FRONT_CENTER;
389     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_TOP_FRONT_RIGHT) >= 0)
390         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_FRONT_RIGHT;
391     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_TOP_BACK_LEFT) >= 0)
392         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_REAR_LEFT;
393     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_TOP_BACK_CENTER) >= 0)
394         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_REAR_CENTER;
395     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_TOP_BACK_RIGHT) >= 0)
396         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
397     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_STEREO_LEFT) >= 0)
398         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_LEFT;
399     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_STEREO_RIGHT) >= 0)
400         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_RIGHT;
401     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_WIDE_LEFT) >= 0)
402         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_AUX0;
403     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_WIDE_RIGHT) >= 0)
404         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_AUX1;
405     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_SURROUND_DIRECT_LEFT) >= 0)
406         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_AUX2;
407     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_SURROUND_DIRECT_RIGHT) >= 0)
408         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_AUX3;
409     if (av_channel_layout_index_from_channel(channel_layout, AV_CHAN_LOW_FREQUENCY_2) >= 0)
410         channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_LFE;
411 }
412 
pulse_write_trailer(AVFormatContext * h)413 static av_cold int pulse_write_trailer(AVFormatContext *h)
414 {
415     PulseData *s = h->priv_data;
416 
417     if (s->mainloop) {
418         pa_threaded_mainloop_lock(s->mainloop);
419         if (s->stream) {
420             pa_stream_disconnect(s->stream);
421             pa_stream_set_state_callback(s->stream, NULL, NULL);
422             pa_stream_set_write_callback(s->stream, NULL, NULL);
423             pa_stream_set_overflow_callback(s->stream, NULL, NULL);
424             pa_stream_set_underflow_callback(s->stream, NULL, NULL);
425             pa_stream_unref(s->stream);
426             s->stream = NULL;
427         }
428         if (s->ctx) {
429             pa_context_disconnect(s->ctx);
430             pa_context_set_state_callback(s->ctx, NULL, NULL);
431             pa_context_set_subscribe_callback(s->ctx, NULL, NULL);
432             pa_context_unref(s->ctx);
433             s->ctx = NULL;
434         }
435         pa_threaded_mainloop_unlock(s->mainloop);
436         pa_threaded_mainloop_stop(s->mainloop);
437         pa_threaded_mainloop_free(s->mainloop);
438         s->mainloop = NULL;
439     }
440 
441     return 0;
442 }
443 
pulse_write_header(AVFormatContext * h)444 static av_cold int pulse_write_header(AVFormatContext *h)
445 {
446     PulseData *s = h->priv_data;
447     AVStream *st = NULL;
448     int ret;
449     pa_sample_spec sample_spec;
450     pa_buffer_attr buffer_attributes = { -1, -1, -1, -1, -1 };
451     pa_channel_map channel_map;
452     pa_mainloop_api *mainloop_api;
453     const char *stream_name = s->stream_name;
454     static const pa_stream_flags_t stream_flags = PA_STREAM_INTERPOLATE_TIMING |
455                                                   PA_STREAM_AUTO_TIMING_UPDATE |
456                                                   PA_STREAM_NOT_MONOTONIC;
457 
458     if (h->nb_streams != 1 || h->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
459         av_log(s, AV_LOG_ERROR, "Only a single audio stream is supported.\n");
460         return AVERROR(EINVAL);
461     }
462     st = h->streams[0];
463 
464     if (!stream_name) {
465         if (h->url[0])
466             stream_name = h->url;
467         else
468             stream_name = "Playback";
469     }
470     s->nonblocking = (h->flags & AVFMT_FLAG_NONBLOCK);
471 
472     if (s->buffer_duration) {
473         int64_t bytes = s->buffer_duration;
474         bytes *= st->codecpar->ch_layout.nb_channels * st->codecpar->sample_rate *
475                  av_get_bytes_per_sample(st->codecpar->format);
476         bytes /= 1000;
477         buffer_attributes.tlength = FFMAX(s->buffer_size, av_clip64(bytes, 0, UINT32_MAX - 1));
478         av_log(s, AV_LOG_DEBUG,
479                "Buffer duration: %ums recalculated into %"PRId64" bytes buffer.\n",
480                s->buffer_duration, bytes);
481         av_log(s, AV_LOG_DEBUG, "Real buffer length is %u bytes\n", buffer_attributes.tlength);
482     } else if (s->buffer_size)
483         buffer_attributes.tlength = s->buffer_size;
484     if (s->prebuf)
485         buffer_attributes.prebuf = s->prebuf;
486     if (s->minreq)
487         buffer_attributes.minreq = s->minreq;
488 
489     sample_spec.format = ff_codec_id_to_pulse_format(st->codecpar->codec_id);
490     sample_spec.rate = st->codecpar->sample_rate;
491     sample_spec.channels = st->codecpar->ch_layout.nb_channels;
492     if (!pa_sample_spec_valid(&sample_spec)) {
493         av_log(s, AV_LOG_ERROR, "Invalid sample spec.\n");
494         return AVERROR(EINVAL);
495     }
496 
497     if (sample_spec.channels == 1) {
498         channel_map.channels = 1;
499         channel_map.map[0] = PA_CHANNEL_POSITION_MONO;
500     } else if (st->codecpar->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
501         if (!av_channel_layout_check(&st->codecpar->ch_layout))
502             return AVERROR(EINVAL);
503         pulse_map_channels_to_pulse(&st->codecpar->ch_layout, &channel_map);
504         /* Unknown channel is present in channel_layout, let PulseAudio use its default. */
505         if (channel_map.channels != sample_spec.channels) {
506             av_log(s, AV_LOG_WARNING, "Unknown channel. Using defaul channel map.\n");
507             channel_map.channels = 0;
508         }
509     } else
510         channel_map.channels = 0;
511 
512     if (!channel_map.channels)
513         av_log(s, AV_LOG_WARNING, "Using PulseAudio's default channel map.\n");
514     else if (!pa_channel_map_valid(&channel_map)) {
515         av_log(s, AV_LOG_ERROR, "Invalid channel map.\n");
516         return AVERROR(EINVAL);
517     }
518 
519     /* start main loop */
520     s->mainloop = pa_threaded_mainloop_new();
521     if (!s->mainloop) {
522         av_log(s, AV_LOG_ERROR, "Cannot create threaded mainloop.\n");
523         return AVERROR(ENOMEM);
524     }
525     if ((ret = pa_threaded_mainloop_start(s->mainloop)) < 0) {
526         av_log(s, AV_LOG_ERROR, "Cannot start threaded mainloop: %s.\n", pa_strerror(ret));
527         pa_threaded_mainloop_free(s->mainloop);
528         s->mainloop = NULL;
529         return AVERROR_EXTERNAL;
530     }
531 
532     pa_threaded_mainloop_lock(s->mainloop);
533 
534     mainloop_api = pa_threaded_mainloop_get_api(s->mainloop);
535     if (!mainloop_api) {
536         av_log(s, AV_LOG_ERROR, "Cannot get mainloop API.\n");
537         ret = AVERROR_EXTERNAL;
538         goto fail;
539     }
540 
541     s->ctx = pa_context_new(mainloop_api, s->name);
542     if (!s->ctx) {
543         av_log(s, AV_LOG_ERROR, "Cannot create context.\n");
544         ret = AVERROR(ENOMEM);
545         goto fail;
546     }
547     pa_context_set_state_callback(s->ctx, pulse_context_state, s);
548     pa_context_set_subscribe_callback(s->ctx, pulse_event, h);
549 
550     if ((ret = pa_context_connect(s->ctx, s->server, 0, NULL)) < 0) {
551         av_log(s, AV_LOG_ERROR, "Cannot connect context: %s.\n", pa_strerror(ret));
552         ret = AVERROR_EXTERNAL;
553         goto fail;
554     }
555 
556     if ((ret = pulse_context_wait(s)) < 0) {
557         av_log(s, AV_LOG_ERROR, "Context failed.\n");
558         goto fail;
559     }
560 
561     s->stream = pa_stream_new(s->ctx, stream_name, &sample_spec,
562                               channel_map.channels ? &channel_map : NULL);
563 
564     if ((ret = pulse_update_sink_info(h)) < 0) {
565         av_log(s, AV_LOG_ERROR, "Updating sink info failed.\n");
566         goto fail;
567     }
568 
569     if (!s->stream) {
570         av_log(s, AV_LOG_ERROR, "Cannot create stream.\n");
571         ret = AVERROR(ENOMEM);
572         goto fail;
573     }
574     pa_stream_set_state_callback(s->stream, pulse_stream_state, s);
575     pa_stream_set_write_callback(s->stream, pulse_stream_writable, h);
576     pa_stream_set_overflow_callback(s->stream, pulse_overflow, h);
577     pa_stream_set_underflow_callback(s->stream, pulse_underflow, h);
578 
579     if ((ret = pa_stream_connect_playback(s->stream, s->device, &buffer_attributes,
580                                           stream_flags, NULL, NULL)) < 0) {
581         av_log(s, AV_LOG_ERROR, "pa_stream_connect_playback failed: %s.\n", pa_strerror(ret));
582         ret = AVERROR_EXTERNAL;
583         goto fail;
584     }
585 
586     if ((ret = pulse_stream_wait(s)) < 0) {
587         av_log(s, AV_LOG_ERROR, "Stream failed.\n");
588         goto fail;
589     }
590 
591     /* read back buffer attributes for future use */
592     buffer_attributes = *pa_stream_get_buffer_attr(s->stream);
593     s->buffer_size = buffer_attributes.tlength;
594     s->prebuf = buffer_attributes.prebuf;
595     s->minreq = buffer_attributes.minreq;
596     av_log(s, AV_LOG_DEBUG, "Real buffer attributes: size: %d, prebuf: %d, minreq: %d\n",
597            s->buffer_size, s->prebuf, s->minreq);
598 
599     pa_threaded_mainloop_unlock(s->mainloop);
600 
601     if ((ret = pulse_subscribe_events(s)) < 0) {
602         av_log(s, AV_LOG_ERROR, "Event subscription failed.\n");
603         /* a bit ugly but the simplest to lock here*/
604         pa_threaded_mainloop_lock(s->mainloop);
605         goto fail;
606     }
607 
608     /* force control messages */
609     s->mute = -1;
610     s->last_volume = PA_VOLUME_INVALID;
611     pa_threaded_mainloop_lock(s->mainloop);
612     if ((ret = pulse_update_sink_input_info(h)) < 0) {
613         av_log(s, AV_LOG_ERROR, "Updating sink input info failed.\n");
614         goto fail;
615     }
616     pa_threaded_mainloop_unlock(s->mainloop);
617 
618     avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
619 
620     return 0;
621   fail:
622     pa_threaded_mainloop_unlock(s->mainloop);
623     pulse_write_trailer(h);
624     return ret;
625 }
626 
pulse_write_packet(AVFormatContext * h,AVPacket * pkt)627 static int pulse_write_packet(AVFormatContext *h, AVPacket *pkt)
628 {
629     PulseData *s = h->priv_data;
630     int ret;
631     int64_t writable_size;
632 
633     if (!pkt)
634         return pulse_flash_stream(s);
635 
636     if (pkt->dts != AV_NOPTS_VALUE)
637         s->timestamp = pkt->dts;
638 
639     if (pkt->duration) {
640         s->timestamp += pkt->duration;
641     } else {
642         AVStream *st = h->streams[0];
643         AVRational r = { 1, st->codecpar->sample_rate };
644         int64_t samples = pkt->size / (av_get_bytes_per_sample(st->codecpar->format) * st->codecpar->ch_layout.nb_channels);
645         s->timestamp += av_rescale_q(samples, r, st->time_base);
646     }
647 
648     pa_threaded_mainloop_lock(s->mainloop);
649     if (!PA_STREAM_IS_GOOD(pa_stream_get_state(s->stream))) {
650         av_log(s, AV_LOG_ERROR, "PulseAudio stream is in invalid state.\n");
651         goto fail;
652     }
653     while (pa_stream_writable_size(s->stream) < s->minreq) {
654         if (s->nonblocking) {
655             pa_threaded_mainloop_unlock(s->mainloop);
656             return AVERROR(EAGAIN);
657         } else
658             pa_threaded_mainloop_wait(s->mainloop);
659     }
660 
661     if ((ret = pa_stream_write(s->stream, pkt->data, pkt->size, NULL, 0, PA_SEEK_RELATIVE)) < 0) {
662         av_log(s, AV_LOG_ERROR, "pa_stream_write failed: %s\n", pa_strerror(ret));
663         goto fail;
664     }
665     if ((writable_size = pa_stream_writable_size(s->stream)) >= s->minreq)
666         avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_BUFFER_WRITABLE, &writable_size, sizeof(writable_size));
667 
668     pa_threaded_mainloop_unlock(s->mainloop);
669 
670     return 0;
671   fail:
672     pa_threaded_mainloop_unlock(s->mainloop);
673     return AVERROR_EXTERNAL;
674 }
675 
pulse_write_frame(AVFormatContext * h,int stream_index,AVFrame ** frame,unsigned flags)676 static int pulse_write_frame(AVFormatContext *h, int stream_index,
677                              AVFrame **frame, unsigned flags)
678 {
679     AVPacket pkt;
680 
681     /* Planar formats are not supported yet. */
682     if (flags & AV_WRITE_UNCODED_FRAME_QUERY)
683         return av_sample_fmt_is_planar(h->streams[stream_index]->codecpar->format) ?
684                AVERROR(EINVAL) : 0;
685 
686     pkt.data     = (*frame)->data[0];
687     pkt.size     = (*frame)->nb_samples * av_get_bytes_per_sample((*frame)->format) * (*frame)->ch_layout.nb_channels;
688     pkt.dts      = (*frame)->pkt_dts;
689     pkt.duration = (*frame)->pkt_duration;
690     return pulse_write_packet(h, &pkt);
691 }
692 
693 
pulse_get_output_timestamp(AVFormatContext * h,int stream,int64_t * dts,int64_t * wall)694 static void pulse_get_output_timestamp(AVFormatContext *h, int stream, int64_t *dts, int64_t *wall)
695 {
696     PulseData *s = h->priv_data;
697     pa_usec_t latency;
698     int neg;
699     pa_threaded_mainloop_lock(s->mainloop);
700     pa_stream_get_latency(s->stream, &latency, &neg);
701     pa_threaded_mainloop_unlock(s->mainloop);
702     if (wall)
703         *wall = av_gettime();
704     if (dts)
705         *dts = s->timestamp - (neg ? -latency : latency);
706 }
707 
pulse_get_device_list(AVFormatContext * h,AVDeviceInfoList * device_list)708 static int pulse_get_device_list(AVFormatContext *h, AVDeviceInfoList *device_list)
709 {
710     PulseData *s = h->priv_data;
711     return ff_pulse_audio_get_devices(device_list, s->server, 1);
712 }
713 
pulse_control_message(AVFormatContext * h,int type,void * data,size_t data_size)714 static int pulse_control_message(AVFormatContext *h, int type,
715                                  void *data, size_t data_size)
716 {
717     PulseData *s = h->priv_data;
718     int ret;
719 
720     switch(type) {
721     case AV_APP_TO_DEV_PAUSE:
722         return pulse_set_pause(s, 1);
723     case AV_APP_TO_DEV_PLAY:
724         return pulse_set_pause(s, 0);
725     case AV_APP_TO_DEV_TOGGLE_PAUSE:
726         return pulse_set_pause(s, !pa_stream_is_corked(s->stream));
727     case AV_APP_TO_DEV_MUTE:
728         if (!s->mute) {
729             s->mute = 1;
730             return pulse_set_mute(s);
731         }
732         return 0;
733     case AV_APP_TO_DEV_UNMUTE:
734         if (s->mute) {
735             s->mute = 0;
736             return pulse_set_mute(s);
737         }
738         return 0;
739     case AV_APP_TO_DEV_TOGGLE_MUTE:
740         s->mute = !s->mute;
741         return pulse_set_mute(s);
742     case AV_APP_TO_DEV_SET_VOLUME:
743         return pulse_set_volume(s, *(double *)data);
744     case AV_APP_TO_DEV_GET_VOLUME:
745         s->last_volume = PA_VOLUME_INVALID;
746         pa_threaded_mainloop_lock(s->mainloop);
747         ret = pulse_update_sink_input_info(h);
748         pa_threaded_mainloop_unlock(s->mainloop);
749         return ret;
750     case AV_APP_TO_DEV_GET_MUTE:
751         s->mute = -1;
752         pa_threaded_mainloop_lock(s->mainloop);
753         ret = pulse_update_sink_input_info(h);
754         pa_threaded_mainloop_unlock(s->mainloop);
755         return ret;
756     default:
757         break;
758     }
759     return AVERROR(ENOSYS);
760 }
761 
762 #define OFFSET(a) offsetof(PulseData, a)
763 #define E AV_OPT_FLAG_ENCODING_PARAM
764 static const AVOption options[] = {
765     { "server",          "set PulseAudio server",            OFFSET(server),          AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
766     { "name",            "set application name",             OFFSET(name),            AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT},  0, 0, E },
767     { "stream_name",     "set stream description",           OFFSET(stream_name),     AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
768     { "device",          "set device name",                  OFFSET(device),          AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
769     { "buffer_size",     "set buffer size in bytes",         OFFSET(buffer_size),     AV_OPT_TYPE_INT,    {.i64 = 0}, 0, INT_MAX, E },
770     { "buffer_duration", "set buffer duration in millisecs", OFFSET(buffer_duration), AV_OPT_TYPE_INT,    {.i64 = 0}, 0, INT_MAX, E },
771     { "prebuf",          "set pre-buffering size",           OFFSET(prebuf),          AV_OPT_TYPE_INT,    {.i64 = 0}, 0, INT_MAX, E },
772     { "minreq",          "set minimum request size",         OFFSET(minreq),          AV_OPT_TYPE_INT,    {.i64 = 0}, 0, INT_MAX, E },
773     { NULL }
774 };
775 
776 static const AVClass pulse_muxer_class = {
777     .class_name     = "PulseAudio outdev",
778     .item_name      = av_default_item_name,
779     .option         = options,
780     .version        = LIBAVUTIL_VERSION_INT,
781     .category       = AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT,
782 };
783 
784 const AVOutputFormat ff_pulse_muxer = {
785     .name                 = "pulse",
786     .long_name            = NULL_IF_CONFIG_SMALL("Pulse audio output"),
787     .priv_data_size       = sizeof(PulseData),
788     .audio_codec          = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE),
789     .video_codec          = AV_CODEC_ID_NONE,
790     .write_header         = pulse_write_header,
791     .write_packet         = pulse_write_packet,
792     .write_uncoded_frame  = pulse_write_frame,
793     .write_trailer        = pulse_write_trailer,
794     .get_output_timestamp = pulse_get_output_timestamp,
795     .get_device_list      = pulse_get_device_list,
796     .control_message      = pulse_control_message,
797     .flags                = AVFMT_NOFILE | AVFMT_ALLOW_FLUSH,
798     .priv_class           = &pulse_muxer_class,
799 };
800