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>
7 * This file is part of FFmpeg.
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.
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.
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
24 #include <pulse/rtclock.h>
25 #include <pulse/error.h>
26 #include "libavformat/avformat.h"
27 #include "libavformat/internal.h"
28 #include "libavutil/opt.h"
29 #include "libavutil/time.h"
30 #include "pulse_audio_common.h"
31 #include "timefilter.h"
33 #define DEFAULT_CODEC_ID AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE)
35 typedef struct PulseData
{
45 pa_threaded_mainloop
*mainloop
;
49 TimeFilter
*timefilter
;
55 #define CHECK_SUCCESS_GOTO(rerror, expression, label) \
57 if (!(expression)) { \
58 rerror = AVERROR_EXTERNAL; \
63 #define CHECK_DEAD_GOTO(p, rerror, label) \
65 if (!(p)->context || !PA_CONTEXT_IS_GOOD(pa_context_get_state((p)->context)) || \
66 !(p)->stream || !PA_STREAM_IS_GOOD(pa_stream_get_state((p)->stream))) { \
67 rerror = AVERROR_EXTERNAL; \
72 static void context_state_cb(pa_context
*c
, void *userdata
) {
73 PulseData
*p
= userdata
;
75 switch (pa_context_get_state(c
)) {
76 case PA_CONTEXT_READY
:
77 case PA_CONTEXT_TERMINATED
:
78 case PA_CONTEXT_FAILED
:
79 pa_threaded_mainloop_signal(p
->mainloop
, 0);
84 static void stream_state_cb(pa_stream
*s
, void * userdata
) {
85 PulseData
*p
= userdata
;
87 switch (pa_stream_get_state(s
)) {
89 case PA_STREAM_FAILED
:
90 case PA_STREAM_TERMINATED
:
91 pa_threaded_mainloop_signal(p
->mainloop
, 0);
96 static void stream_request_cb(pa_stream
*s
, size_t length
, void *userdata
) {
97 PulseData
*p
= userdata
;
99 pa_threaded_mainloop_signal(p
->mainloop
, 0);
102 static void stream_latency_update_cb(pa_stream
*s
, void *userdata
) {
103 PulseData
*p
= userdata
;
105 pa_threaded_mainloop_signal(p
->mainloop
, 0);
108 static av_cold
int pulse_close(AVFormatContext
*s
)
110 PulseData
*pd
= s
->priv_data
;
113 pa_threaded_mainloop_stop(pd
->mainloop
);
116 pa_stream_unref(pd
->stream
);
120 pa_context_disconnect(pd
->context
);
121 pa_context_unref(pd
->context
);
126 pa_threaded_mainloop_free(pd
->mainloop
);
129 ff_timefilter_destroy(pd
->timefilter
);
130 pd
->timefilter
= NULL
;
135 static av_cold
int pulse_read_header(AVFormatContext
*s
)
137 PulseData
*pd
= s
->priv_data
;
141 enum AVCodecID codec_id
=
142 s
->audio_codec_id
== AV_CODEC_ID_NONE
? DEFAULT_CODEC_ID
: s
->audio_codec_id
;
143 const pa_sample_spec ss
= { ff_codec_id_to_pulse_format(codec_id
),
147 pa_buffer_attr attr
= { -1 };
149 st
= avformat_new_stream(s
, NULL
);
152 av_log(s
, AV_LOG_ERROR
, "Cannot add stream\n");
153 return AVERROR(ENOMEM
);
156 attr
.fragsize
= pd
->fragment_size
;
158 if (s
->filename
[0] != '\0' && strcmp(s
->filename
, "default"))
159 device
= s
->filename
;
161 if (!(pd
->mainloop
= pa_threaded_mainloop_new())) {
163 return AVERROR_EXTERNAL
;
166 if (!(pd
->context
= pa_context_new(pa_threaded_mainloop_get_api(pd
->mainloop
), pd
->name
))) {
168 return AVERROR_EXTERNAL
;
171 pa_context_set_state_callback(pd
->context
, context_state_cb
, pd
);
173 if (pa_context_connect(pd
->context
, pd
->server
, 0, NULL
) < 0) {
175 return AVERROR(pa_context_errno(pd
->context
));
178 pa_threaded_mainloop_lock(pd
->mainloop
);
180 if (pa_threaded_mainloop_start(pd
->mainloop
) < 0) {
182 goto unlock_and_fail
;
186 pa_context_state_t state
;
188 state
= pa_context_get_state(pd
->context
);
190 if (state
== PA_CONTEXT_READY
)
193 if (!PA_CONTEXT_IS_GOOD(state
)) {
194 ret
= AVERROR(pa_context_errno(pd
->context
));
195 goto unlock_and_fail
;
198 /* Wait until the context is ready */
199 pa_threaded_mainloop_wait(pd
->mainloop
);
202 if (!(pd
->stream
= pa_stream_new(pd
->context
, pd
->stream_name
, &ss
, NULL
))) {
203 ret
= AVERROR(pa_context_errno(pd
->context
));
204 goto unlock_and_fail
;
207 pa_stream_set_state_callback(pd
->stream
, stream_state_cb
, pd
);
208 pa_stream_set_read_callback(pd
->stream
, stream_request_cb
, pd
);
209 pa_stream_set_write_callback(pd
->stream
, stream_request_cb
, pd
);
210 pa_stream_set_latency_update_callback(pd
->stream
, stream_latency_update_cb
, pd
);
212 ret
= pa_stream_connect_record(pd
->stream
, device
, &attr
,
213 PA_STREAM_INTERPOLATE_TIMING
214 |PA_STREAM_ADJUST_LATENCY
215 |PA_STREAM_AUTO_TIMING_UPDATE
);
218 ret
= AVERROR(pa_context_errno(pd
->context
));
219 goto unlock_and_fail
;
223 pa_stream_state_t state
;
225 state
= pa_stream_get_state(pd
->stream
);
227 if (state
== PA_STREAM_READY
)
230 if (!PA_STREAM_IS_GOOD(state
)) {
231 ret
= AVERROR(pa_context_errno(pd
->context
));
232 goto unlock_and_fail
;
235 /* Wait until the stream is ready */
236 pa_threaded_mainloop_wait(pd
->mainloop
);
239 pa_threaded_mainloop_unlock(pd
->mainloop
);
241 /* take real parameters */
242 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
243 st
->codec
->codec_id
= codec_id
;
244 st
->codec
->sample_rate
= pd
->sample_rate
;
245 st
->codec
->channels
= pd
->channels
;
246 avpriv_set_pts_info(st
, 64, 1, 1000000); /* 64 bits pts in us */
248 pd
->timefilter
= ff_timefilter_new(1000000.0 / pd
->sample_rate
,
251 if (!pd
->timefilter
) {
253 return AVERROR(ENOMEM
);
259 pa_threaded_mainloop_unlock(pd
->mainloop
);
265 static int pulse_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
267 PulseData
*pd
= s
->priv_data
;
270 const void *read_data
= NULL
;
275 pa_threaded_mainloop_lock(pd
->mainloop
);
277 CHECK_DEAD_GOTO(pd
, ret
, unlock_and_fail
);
282 r
= pa_stream_peek(pd
->stream
, &read_data
, &read_length
);
283 CHECK_SUCCESS_GOTO(ret
, r
== 0, unlock_and_fail
);
285 if (read_length
<= 0) {
286 pa_threaded_mainloop_wait(pd
->mainloop
);
287 CHECK_DEAD_GOTO(pd
, ret
, unlock_and_fail
);
288 } else if (!read_data
) {
289 /* There's a hole in the stream, skip it. We could generate
290 * silence, but that wouldn't work for compressed streams. */
291 r
= pa_stream_drop(pd
->stream
);
292 CHECK_SUCCESS_GOTO(ret
, r
== 0, unlock_and_fail
);
296 if (av_new_packet(pkt
, read_length
) < 0) {
297 ret
= AVERROR(ENOMEM
);
298 goto unlock_and_fail
;
302 pa_operation_unref(pa_stream_update_timing_info(pd
->stream
, NULL
, NULL
));
304 if (pa_stream_get_latency(pd
->stream
, &latency
, &negative
) >= 0) {
305 enum AVCodecID codec_id
=
306 s
->audio_codec_id
== AV_CODEC_ID_NONE
? DEFAULT_CODEC_ID
: s
->audio_codec_id
;
307 int frame_size
= ((av_get_bits_per_sample(codec_id
) >> 3) * pd
->channels
);
308 int frame_duration
= read_length
/ frame_size
;
316 pkt
->pts
= ff_timefilter_update(pd
->timefilter
, dts
, pd
->last_period
);
318 pd
->last_period
= frame_duration
;
320 av_log(s
, AV_LOG_WARNING
, "pa_stream_get_latency() failed\n");
323 memcpy(pkt
->data
, read_data
, read_length
);
324 pa_stream_drop(pd
->stream
);
326 pa_threaded_mainloop_unlock(pd
->mainloop
);
330 pa_threaded_mainloop_unlock(pd
->mainloop
);
334 static int pulse_get_device_list(AVFormatContext
*h
, AVDeviceInfoList
*device_list
)
336 PulseData
*s
= h
->priv_data
;
337 return ff_pulse_audio_get_devices(device_list
, s
->server
, 0);
340 #define OFFSET(a) offsetof(PulseData, a)
341 #define D AV_OPT_FLAG_DECODING_PARAM
343 static const AVOption options
[] = {
344 { "server", "set PulseAudio server", OFFSET(server
), AV_OPT_TYPE_STRING
, {.str
= NULL
}, 0, 0, D
},
345 { "name", "set application name", OFFSET(name
), AV_OPT_TYPE_STRING
, {.str
= LIBAVFORMAT_IDENT
}, 0, 0, D
},
346 { "stream_name", "set stream description", OFFSET(stream_name
), AV_OPT_TYPE_STRING
, {.str
= "record"}, 0, 0, D
},
347 { "sample_rate", "set sample rate in Hz", OFFSET(sample_rate
), AV_OPT_TYPE_INT
, {.i64
= 48000}, 1, INT_MAX
, D
},
348 { "channels", "set number of audio channels", OFFSET(channels
), AV_OPT_TYPE_INT
, {.i64
= 2}, 1, INT_MAX
, D
},
349 { "frame_size", "set number of bytes per frame", OFFSET(frame_size
), AV_OPT_TYPE_INT
, {.i64
= 1024}, 1, INT_MAX
, D
},
350 { "fragment_size", "set buffering size, affects latency and cpu usage", OFFSET(fragment_size
), AV_OPT_TYPE_INT
, {.i64
= -1}, -1, INT_MAX
, D
},
351 { "wallclock", "set the initial pts using the current time", OFFSET(wallclock
), AV_OPT_TYPE_INT
, {.i64
= 1}, -1, 1, D
},
355 static const AVClass pulse_demuxer_class
= {
356 .class_name
= "Pulse demuxer",
357 .item_name
= av_default_item_name
,
359 .version
= LIBAVUTIL_VERSION_INT
,
360 .category
= AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT
,
363 AVInputFormat ff_pulse_demuxer
= {
365 .long_name
= NULL_IF_CONFIG_SMALL("Pulse audio input"),
366 .priv_data_size
= sizeof(PulseData
),
367 .read_header
= pulse_read_header
,
368 .read_packet
= pulse_read_packet
,
369 .read_close
= pulse_close
,
370 .get_device_list
= pulse_get_device_list
,
371 .flags
= AVFMT_NOFILE
,
372 .priv_class
= &pulse_demuxer_class
,