FFmpeg
pulse_audio_dec.c
Go to the documentation of this file.
1 /*
2  * Pulseaudio input
3  * Copyright (c) 2011 Luca Barbato <lu_zero@gentoo.org>
4  * Copyright 2004-2006 Lennart Poettering
5  * Copyright (c) 2014 Michael Niedermayer <michaelni@gmx.at>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include <pulse/rtclock.h>
25 #include <pulse/error.h>
26 
27 #include "libavutil/internal.h"
28 #include "libavutil/opt.h"
29 #include "libavutil/time.h"
30 
31 #include "libavformat/avformat.h"
32 #include "libavformat/internal.h"
33 #include "pulse_audio_common.h"
34 #include "timefilter.h"
35 
36 #define DEFAULT_CODEC_ID AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE)
37 
38 typedef struct PulseData {
39  AVClass *class;
40  char *server;
41  char *name;
42  char *stream_name;
44  int channels;
47 
48  pa_threaded_mainloop *mainloop;
49  pa_context *context;
50  pa_stream *stream;
51 
54  int wallclock;
55 } PulseData;
56 
57 
58 #define CHECK_SUCCESS_GOTO(rerror, expression, label) \
59  do { \
60  if (!(expression)) { \
61  rerror = AVERROR_EXTERNAL; \
62  goto label; \
63  } \
64  } while (0)
65 
66 #define CHECK_DEAD_GOTO(p, rerror, label) \
67  do { \
68  if (!(p)->context || !PA_CONTEXT_IS_GOOD(pa_context_get_state((p)->context)) || \
69  !(p)->stream || !PA_STREAM_IS_GOOD(pa_stream_get_state((p)->stream))) { \
70  rerror = AVERROR_EXTERNAL; \
71  goto label; \
72  } \
73  } while (0)
74 
75 static void context_state_cb(pa_context *c, void *userdata) {
76  PulseData *p = userdata;
77 
78  switch (pa_context_get_state(c)) {
79  case PA_CONTEXT_READY:
80  case PA_CONTEXT_TERMINATED:
81  case PA_CONTEXT_FAILED:
82  pa_threaded_mainloop_signal(p->mainloop, 0);
83  break;
84  }
85 }
86 
87 static void stream_state_cb(pa_stream *s, void * userdata) {
88  PulseData *p = userdata;
89 
90  switch (pa_stream_get_state(s)) {
91  case PA_STREAM_READY:
92  case PA_STREAM_FAILED:
93  case PA_STREAM_TERMINATED:
94  pa_threaded_mainloop_signal(p->mainloop, 0);
95  break;
96  }
97 }
98 
99 static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
100  PulseData *p = userdata;
101 
102  pa_threaded_mainloop_signal(p->mainloop, 0);
103 }
104 
105 static void stream_latency_update_cb(pa_stream *s, void *userdata) {
106  PulseData *p = userdata;
107 
108  pa_threaded_mainloop_signal(p->mainloop, 0);
109 }
110 
112 {
113  PulseData *pd = s->priv_data;
114 
115  if (pd->mainloop)
116  pa_threaded_mainloop_stop(pd->mainloop);
117 
118  if (pd->stream)
119  pa_stream_unref(pd->stream);
120  pd->stream = NULL;
121 
122  if (pd->context) {
123  pa_context_disconnect(pd->context);
124  pa_context_unref(pd->context);
125  }
126  pd->context = NULL;
127 
128  if (pd->mainloop)
129  pa_threaded_mainloop_free(pd->mainloop);
130  pd->mainloop = NULL;
131 
133  pd->timefilter = NULL;
134 
135  return 0;
136 }
137 
139 {
140  PulseData *pd = s->priv_data;
141  AVStream *st;
142  char *device = NULL;
143  int ret;
144  enum AVCodecID codec_id =
146  const pa_sample_spec ss = { ff_codec_id_to_pulse_format(codec_id),
147  pd->sample_rate,
148  pd->channels };
149 
150  pa_buffer_attr attr = { -1 };
151  pa_channel_map cmap;
152 
153  pa_channel_map_init_extend(&cmap, pd->channels, PA_CHANNEL_MAP_WAVEEX);
154 
155  st = avformat_new_stream(s, NULL);
156 
157  if (!st) {
158  av_log(s, AV_LOG_ERROR, "Cannot add stream\n");
159  return AVERROR(ENOMEM);
160  }
161 
162  attr.fragsize = pd->fragment_size;
163 
164  if (s->url[0] != '\0' && strcmp(s->url, "default"))
165  device = s->url;
166 
167  if (!(pd->mainloop = pa_threaded_mainloop_new())) {
168  pulse_close(s);
169  return AVERROR_EXTERNAL;
170  }
171 
172  if (!(pd->context = pa_context_new(pa_threaded_mainloop_get_api(pd->mainloop), pd->name))) {
173  pulse_close(s);
174  return AVERROR_EXTERNAL;
175  }
176 
177  pa_context_set_state_callback(pd->context, context_state_cb, pd);
178 
179  if (pa_context_connect(pd->context, pd->server, 0, NULL) < 0) {
180  pulse_close(s);
181  return AVERROR(pa_context_errno(pd->context));
182  }
183 
184  pa_threaded_mainloop_lock(pd->mainloop);
185 
186  if (pa_threaded_mainloop_start(pd->mainloop) < 0) {
187  ret = -1;
188  goto unlock_and_fail;
189  }
190 
191  for (;;) {
192  pa_context_state_t state;
193 
194  state = pa_context_get_state(pd->context);
195 
196  if (state == PA_CONTEXT_READY)
197  break;
198 
199  if (!PA_CONTEXT_IS_GOOD(state)) {
200  ret = AVERROR(pa_context_errno(pd->context));
201  goto unlock_and_fail;
202  }
203 
204  /* Wait until the context is ready */
205  pa_threaded_mainloop_wait(pd->mainloop);
206  }
207 
208  if (!(pd->stream = pa_stream_new(pd->context, pd->stream_name, &ss, &cmap))) {
209  ret = AVERROR(pa_context_errno(pd->context));
210  goto unlock_and_fail;
211  }
212 
213  pa_stream_set_state_callback(pd->stream, stream_state_cb, pd);
214  pa_stream_set_read_callback(pd->stream, stream_request_cb, pd);
215  pa_stream_set_write_callback(pd->stream, stream_request_cb, pd);
216  pa_stream_set_latency_update_callback(pd->stream, stream_latency_update_cb, pd);
217 
218  ret = pa_stream_connect_record(pd->stream, device, &attr,
219  PA_STREAM_INTERPOLATE_TIMING
220  |PA_STREAM_ADJUST_LATENCY
221  |PA_STREAM_AUTO_TIMING_UPDATE);
222 
223  if (ret < 0) {
224  ret = AVERROR(pa_context_errno(pd->context));
225  goto unlock_and_fail;
226  }
227 
228  for (;;) {
229  pa_stream_state_t state;
230 
231  state = pa_stream_get_state(pd->stream);
232 
233  if (state == PA_STREAM_READY)
234  break;
235 
236  if (!PA_STREAM_IS_GOOD(state)) {
237  ret = AVERROR(pa_context_errno(pd->context));
238  goto unlock_and_fail;
239  }
240 
241  /* Wait until the stream is ready */
242  pa_threaded_mainloop_wait(pd->mainloop);
243  }
244 
245  pa_threaded_mainloop_unlock(pd->mainloop);
246 
247  /* take real parameters */
249  st->codecpar->codec_id = codec_id;
250  st->codecpar->sample_rate = pd->sample_rate;
251  st->codecpar->channels = pd->channels;
252  avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
253 
254  pd->timefilter = ff_timefilter_new(1000000.0 / pd->sample_rate,
255  1000, 1.5E-6);
256 
257  if (!pd->timefilter) {
258  pulse_close(s);
259  return AVERROR(ENOMEM);
260  }
261 
262  return 0;
263 
264 unlock_and_fail:
265  pa_threaded_mainloop_unlock(pd->mainloop);
266 
267  pulse_close(s);
268  return ret;
269 }
270 
272 {
273  PulseData *pd = s->priv_data;
274  int ret;
275  size_t read_length;
276  const void *read_data = NULL;
277  int64_t dts;
278  pa_usec_t latency;
279  int negative;
280 
281  pa_threaded_mainloop_lock(pd->mainloop);
282 
283  CHECK_DEAD_GOTO(pd, ret, unlock_and_fail);
284 
285  while (!read_data) {
286  int r;
287 
288  r = pa_stream_peek(pd->stream, &read_data, &read_length);
289  CHECK_SUCCESS_GOTO(ret, r == 0, unlock_and_fail);
290 
291  if (read_length <= 0) {
292  pa_threaded_mainloop_wait(pd->mainloop);
293  CHECK_DEAD_GOTO(pd, ret, unlock_and_fail);
294  } else if (!read_data) {
295  /* There's a hole in the stream, skip it. We could generate
296  * silence, but that wouldn't work for compressed streams. */
297  r = pa_stream_drop(pd->stream);
298  CHECK_SUCCESS_GOTO(ret, r == 0, unlock_and_fail);
299  }
300  }
301 
302  if (av_new_packet(pkt, read_length) < 0) {
303  ret = AVERROR(ENOMEM);
304  goto unlock_and_fail;
305  }
306 
307  dts = av_gettime();
308  pa_operation_unref(pa_stream_update_timing_info(pd->stream, NULL, NULL));
309 
310  if (pa_stream_get_latency(pd->stream, &latency, &negative) >= 0) {
311  enum AVCodecID codec_id =
313  int frame_size = ((av_get_bits_per_sample(codec_id) >> 3) * pd->channels);
314  int frame_duration = read_length / frame_size;
315 
316 
317  if (negative) {
318  dts += latency;
319  } else
320  dts -= latency;
321  if (pd->wallclock)
322  pkt->pts = ff_timefilter_update(pd->timefilter, dts, pd->last_period);
323 
324  pd->last_period = frame_duration;
325  } else {
326  av_log(s, AV_LOG_WARNING, "pa_stream_get_latency() failed\n");
327  }
328 
329  memcpy(pkt->data, read_data, read_length);
330  pa_stream_drop(pd->stream);
331 
332  pa_threaded_mainloop_unlock(pd->mainloop);
333  return 0;
334 
335 unlock_and_fail:
336  pa_threaded_mainloop_unlock(pd->mainloop);
337  return ret;
338 }
339 
341 {
342  PulseData *s = h->priv_data;
343  return ff_pulse_audio_get_devices(device_list, s->server, 0);
344 }
345 
346 #define OFFSET(a) offsetof(PulseData, a)
347 #define D AV_OPT_FLAG_DECODING_PARAM
348 
349 static const AVOption options[] = {
350  { "server", "set PulseAudio server", OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D },
351  { "name", "set application name", OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, D },
352  { "stream_name", "set stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D },
353  { "sample_rate", "set sample rate in Hz", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 1, INT_MAX, D },
354  { "channels", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, D },
355  { "frame_size", "set number of bytes per frame", OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, D },
356  { "fragment_size", "set buffering size, affects latency and cpu usage", OFFSET(fragment_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D },
357  { "wallclock", "set the initial pts using the current time", OFFSET(wallclock), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, D },
358  { NULL },
359 };
360 
361 static const AVClass pulse_demuxer_class = {
362  .class_name = "Pulse indev",
363  .item_name = av_default_item_name,
364  .option = options,
365  .version = LIBAVUTIL_VERSION_INT,
367 };
368 
370  .name = "pulse",
371  .long_name = NULL_IF_CONFIG_SMALL("Pulse audio input"),
372  .priv_data_size = sizeof(PulseData),
376  .get_device_list = pulse_get_device_list,
377  .flags = AVFMT_NOFILE,
378  .priv_class = &pulse_demuxer_class,
379 };
#define NULL
Definition: coverity.c:32
AVOption.
Definition: opt.h:246
void ff_timefilter_destroy(TimeFilter *self)
Free all resources associated with the filter.
Definition: timefilter.c:62
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
static int read_data(void *opaque, uint8_t *buf, int buf_size)
Definition: dashdec.c:1788
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4926
#define D
channels
Definition: aptx.c:30
#define CHECK_DEAD_GOTO(p, rerror, label)
enum AVCodecID codec_id
Definition: qsv.c:77
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3968
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
static av_cold int pulse_close(AVFormatContext *s)
static AVPacket pkt
AVInputFormat ff_pulse_demuxer
char * stream_name
const char * device
static const AVClass pulse_demuxer_class
Format I/O context.
Definition: avformat.h:1358
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
Opaque type representing a time filter state.
Definition: timefilter.c:30
#define av_cold
Definition: attributes.h:82
AVOptions.
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4499
uint8_t * data
Definition: avcodec.h:1480
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
#define CHECK_SUCCESS_GOTO(rerror, expression, label)
#define av_log(a,...)
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:86
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:1528
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
char * url
input or output URL.
Definition: avformat.h:1454
const char * r
Definition: vf_curves.c:114
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3964
GLsizei GLsizei * length
Definition: opengl_enc.c:114
common internal API header
#define LIBAVFORMAT_IDENT
Definition: version.h:46
pa_stream * stream
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:261
#define OFFSET(a)
enum AVCodecID audio_codec_id
Forced audio codec_id.
Definition: avformat.h:1550
#define s(width, name)
Definition: cbs_vp9.c:257
pa_sample_format_t av_cold ff_codec_id_to_pulse_format(enum AVCodecID codec_id)
static const AVOption options[]
TimeFilter * timefilter
char * server
static void stream_request_cb(pa_stream *s, size_t length, void *userdata)
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:530
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
Stream structure.
Definition: avformat.h:881
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
TimeFilter * ff_timefilter_new(double time_base, double period, double bandwidth)
Create a new Delay Locked Loop time filter.
Definition: timefilter.c:46
static void stream_state_cb(pa_stream *s, void *userdata)
pa_context * context
static av_cold int pulse_read_header(AVFormatContext *s)
Describe the class of an AVClass context structure.
Definition: log.h:67
int ff_pulse_audio_get_devices(AVDeviceInfoList *devices, const char *server, int output)
static void context_state_cb(pa_context *c, void *userdata)
List of devices.
Definition: avdevice.h:460
#define flags(name, subs,...)
Definition: cbs_av1.c:561
int sample_rate
Audio only.
Definition: avcodec.h:4078
Main libavformat public API header.
double ff_timefilter_update(TimeFilter *self, double system_time, double period)
Update the filter.
Definition: timefilter.c:72
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
static void stream_latency_update_cb(pa_stream *s, void *userdata)
void * priv_data
Format private data.
Definition: avformat.h:1386
static struct @316 state
static int pulse_get_device_list(AVFormatContext *h, AVDeviceInfoList *device_list)
int channels
Audio only.
Definition: avcodec.h:4074
pa_threaded_mainloop * mainloop
#define DEFAULT_CODEC_ID
static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt)
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:654
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1028
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
This structure stores compressed data.
Definition: avcodec.h:1457
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1473
const char * name
Definition: opengl_enc.c:102