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 =
145  s->audio_codec_id == AV_CODEC_ID_NONE ? DEFAULT_CODEC_ID : s->audio_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 =
312  s->audio_codec_id == AV_CODEC_ID_NONE ? DEFAULT_CODEC_ID : s->audio_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)
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 demuxer",
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 };
PulseData::context
pa_context * context
Definition: pulse_audio_dec.c:49
options
static const AVOption options[]
Definition: pulse_audio_dec.c:349
TimeFilter
Opaque type representing a time filter state.
Definition: timefilter.c:30
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
LIBAVFORMAT_IDENT
#define LIBAVFORMAT_IDENT
Definition: version.h:46
read_data
static int read_data(void *opaque, uint8_t *buf, int buf_size)
Definition: dashdec.c:1742
r
const char * r
Definition: vf_curves.c:114
AVERROR
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
opt.h
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4480
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3953
codec_id
enum AVCodecID codec_id
Definition: qsv.c:72
PulseData::mainloop
pa_threaded_mainloop * mainloop
Definition: pulse_audio_dec.c:48
pulse_get_device_list
static int pulse_get_device_list(AVFormatContext *h, AVDeviceInfoList *device_list)
Definition: pulse_audio_dec.c:340
PulseData::frame_size
int frame_size
Definition: pulse_audio_dec.c:45
stream_latency_update_cb
static void stream_latency_update_cb(pa_stream *s, void *userdata)
Definition: pulse_audio_dec.c:105
name
const char * name
Definition: avisynth_c.h:867
AVPacket::data
uint8_t * data
Definition: avcodec.h:1477
AVOption
AVOption.
Definition: opt.h:246
ff_codec_id_to_pulse_format
pa_sample_format_t av_cold ff_codec_id_to_pulse_format(enum AVCodecID codec_id)
Definition: pulse_audio_common.c:29
channels
channels
Definition: aptx.c:30
PulseData::channels
int channels
Definition: pulse_audio_dec.c:44
sample_rate
sample_rate
Definition: ffmpeg_filter.c:191
PulseData
Definition: pulse_audio_dec.c:38
AVCodecParameters::channels
int channels
Audio only.
Definition: avcodec.h:4063
PulseData::stream
pa_stream * stream
Definition: pulse_audio_dec.c:50
PulseData::name
char * name
Definition: pulse_audio_dec.c:41
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:261
ff_timefilter_new
TimeFilter * ff_timefilter_new(double time_base, double period, double bandwidth)
Create a new Delay Locked Loop time filter.
Definition: timefilter.c:46
stream_request_cb
static void stream_request_cb(pa_stream *s, size_t length, void *userdata)
Definition: pulse_audio_dec.c:99
AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT
@ AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT
Definition: log.h:44
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
state
static struct @313 state
AVInputFormat
Definition: avformat.h:640
av_cold
#define av_cold
Definition: attributes.h:84
s
#define s(width, name)
Definition: cbs_vp9.c:257
av_new_packet
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
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:645
frame_size
int frame_size
Definition: mxfenc.c:2215
ff_pulse_audio_get_devices
int ff_pulse_audio_get_devices(AVDeviceInfoList *devices, const char *server, int output)
Definition: pulse_audio_common.c:197
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
PulseData::wallclock
int wallclock
Definition: pulse_audio_dec.c:54
PulseData::sample_rate
int sample_rate
Definition: pulse_audio_dec.c:43
ff_pulse_demuxer
AVInputFormat ff_pulse_demuxer
Definition: pulse_audio_dec.c:369
PulseData::stream_name
char * stream_name
Definition: pulse_audio_dec.c:42
AVFormatContext
Format I/O context.
Definition: avformat.h:1342
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1017
pulse_close
static av_cold int pulse_close(AVFormatContext *s)
Definition: pulse_audio_dec.c:111
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:530
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
timefilter.h
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
time.h
c
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
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: avcodec.h:4067
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
pulse_audio_common.h
PulseData::timefilter
TimeFilter * timefilter
Definition: pulse_audio_dec.c:52
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:1550
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
PulseData::server
char * server
Definition: pulse_audio_dec.c:40
avpriv_set_pts_info
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:4910
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
CHECK_SUCCESS_GOTO
#define CHECK_SUCCESS_GOTO(rerror, expression, label)
Definition: pulse_audio_dec.c:58
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
CHECK_DEAD_GOTO
#define CHECK_DEAD_GOTO(p, rerror, label)
Definition: pulse_audio_dec.c:66
pulse_read_packet
static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: pulse_audio_dec.c:271
pulse_read_header
static av_cold int pulse_read_header(AVFormatContext *s)
Definition: pulse_audio_dec.c:138
ff_timefilter_destroy
void ff_timefilter_destroy(TimeFilter *self)
Free all resources associated with the filter.
Definition: timefilter.c:62
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: avcodec.h:216
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1470
internal.h
ff_timefilter_update
double ff_timefilter_update(TimeFilter *self, double system_time, double period)
Update the filter.
Definition: timefilter.c:72
ret
ret
Definition: filter_design.txt:187
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
AVStream
Stream structure.
Definition: avformat.h:870
AVClass::class_name
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
AVDeviceInfoList
List of devices.
Definition: avdevice.h:460
avformat.h
D
#define D
Definition: pulse_audio_dec.c:347
PulseData::fragment_size
int fragment_size
Definition: pulse_audio_dec.c:46
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
PulseData::last_period
int last_period
Definition: pulse_audio_dec.c:53
av_gettime
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
context_state_cb
static void context_state_cb(pa_context *c, void *userdata)
Definition: pulse_audio_dec.c:75
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3957
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
DEFAULT_CODEC_ID
#define DEFAULT_CODEC_ID
Definition: pulse_audio_dec.c:36
stream_state_cb
static void stream_state_cb(pa_stream *s, void *userdata)
Definition: pulse_audio_dec.c:87
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
length
const char int length
Definition: avisynth_c.h:860
h
h
Definition: vp9dsp_template.c:2038
pulse_demuxer_class
static const AVClass pulse_demuxer_class
Definition: pulse_audio_dec.c:361
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:227
OFFSET
#define OFFSET(a)
Definition: pulse_audio_dec.c:346