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/demux.h"
33 #include "libavformat/internal.h"
34 #include "libavformat/version.h"
35 #include "pulse_audio_common.h"
36 #include "timefilter.h"
37 
38 #define DEFAULT_CODEC_ID AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE)
39 
40 typedef struct PulseData {
41  AVClass *class;
42  char *server;
43  char *name;
44  char *stream_name;
46  int channels;
49 
50  pa_threaded_mainloop *mainloop;
51  pa_context *context;
52  pa_stream *stream;
53  size_t pa_frame_size;
54 
57  int wallclock;
58 } PulseData;
59 
60 
61 #define CHECK_SUCCESS_GOTO(rerror, expression, label) \
62  do { \
63  if (!(expression)) { \
64  rerror = AVERROR_EXTERNAL; \
65  goto label; \
66  } \
67  } while (0)
68 
69 #define CHECK_DEAD_GOTO(p, rerror, label) \
70  do { \
71  if (!(p)->context || !PA_CONTEXT_IS_GOOD(pa_context_get_state((p)->context)) || \
72  !(p)->stream || !PA_STREAM_IS_GOOD(pa_stream_get_state((p)->stream))) { \
73  rerror = AVERROR_EXTERNAL; \
74  goto label; \
75  } \
76  } while (0)
77 
78 static void context_state_cb(pa_context *c, void *userdata) {
79  PulseData *p = userdata;
80 
81  switch (pa_context_get_state(c)) {
82  case PA_CONTEXT_READY:
83  case PA_CONTEXT_TERMINATED:
84  case PA_CONTEXT_FAILED:
85  pa_threaded_mainloop_signal(p->mainloop, 0);
86  break;
87  }
88 }
89 
90 static void stream_state_cb(pa_stream *s, void * userdata) {
91  PulseData *p = userdata;
92 
93  switch (pa_stream_get_state(s)) {
94  case PA_STREAM_READY:
95  case PA_STREAM_FAILED:
96  case PA_STREAM_TERMINATED:
97  pa_threaded_mainloop_signal(p->mainloop, 0);
98  break;
99  }
100 }
101 
102 static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
103  PulseData *p = userdata;
104 
105  pa_threaded_mainloop_signal(p->mainloop, 0);
106 }
107 
108 static void stream_latency_update_cb(pa_stream *s, void *userdata) {
109  PulseData *p = userdata;
110 
111  pa_threaded_mainloop_signal(p->mainloop, 0);
112 }
113 
115 {
116  PulseData *pd = s->priv_data;
117 
118  if (pd->mainloop)
119  pa_threaded_mainloop_stop(pd->mainloop);
120 
121  if (pd->stream)
122  pa_stream_unref(pd->stream);
123  pd->stream = NULL;
124 
125  if (pd->context) {
126  pa_context_disconnect(pd->context);
127  pa_context_unref(pd->context);
128  }
129  pd->context = NULL;
130 
131  if (pd->mainloop)
132  pa_threaded_mainloop_free(pd->mainloop);
133  pd->mainloop = NULL;
134 
136  pd->timefilter = NULL;
137 
138  return 0;
139 }
140 
142 {
143  PulseData *pd = s->priv_data;
144  AVStream *st;
145  char *device = NULL;
146  int ret;
147  enum AVCodecID codec_id =
148  s->audio_codec_id == AV_CODEC_ID_NONE ? DEFAULT_CODEC_ID : s->audio_codec_id;
149  const pa_sample_spec ss = { ff_codec_id_to_pulse_format(codec_id),
150  pd->sample_rate,
151  pd->channels };
152 
153  pa_buffer_attr attr = { -1 };
154  pa_channel_map cmap;
155  const pa_buffer_attr *queried_attr;
156 
157  pa_channel_map_init_extend(&cmap, pd->channels, PA_CHANNEL_MAP_WAVEEX);
158 
159  if (!pa_sample_spec_valid(&ss)) {
160  av_log(s, AV_LOG_ERROR, "Invalid sample spec.\n");
161  return AVERROR(EINVAL);
162  }
163 
164  st = avformat_new_stream(s, NULL);
165 
166  if (!st) {
167  av_log(s, AV_LOG_ERROR, "Cannot add stream\n");
168  return AVERROR(ENOMEM);
169  }
170 
171  if (pd->fragment_size == -1) {
172  // 50 ms fragments/latency by default seem good enough
173  attr.fragsize = pa_frame_size(&ss) * (pd->sample_rate / 20);
174  } else {
175  attr.fragsize = pd->fragment_size;
176  }
177 
178  if (s->url[0] != '\0' && strcmp(s->url, "default"))
179  device = s->url;
180 
181  if (!(pd->mainloop = pa_threaded_mainloop_new())) {
182  pulse_close(s);
183  return AVERROR_EXTERNAL;
184  }
185 
186  if (!(pd->context = pa_context_new(pa_threaded_mainloop_get_api(pd->mainloop), pd->name))) {
187  pulse_close(s);
188  return AVERROR_EXTERNAL;
189  }
190 
191  pa_context_set_state_callback(pd->context, context_state_cb, pd);
192 
193  if (pa_context_connect(pd->context, pd->server, 0, NULL) < 0) {
194  pulse_close(s);
195  return AVERROR(pa_context_errno(pd->context));
196  }
197 
198  pa_threaded_mainloop_lock(pd->mainloop);
199 
200  if (pa_threaded_mainloop_start(pd->mainloop) < 0) {
201  ret = -1;
202  goto unlock_and_fail;
203  }
204 
205  for (;;) {
206  pa_context_state_t state;
207 
208  state = pa_context_get_state(pd->context);
209 
210  if (state == PA_CONTEXT_READY)
211  break;
212 
213  if (!PA_CONTEXT_IS_GOOD(state)) {
214  ret = AVERROR(pa_context_errno(pd->context));
215  goto unlock_and_fail;
216  }
217 
218  /* Wait until the context is ready */
219  pa_threaded_mainloop_wait(pd->mainloop);
220  }
221 
222  if (!(pd->stream = pa_stream_new(pd->context, pd->stream_name, &ss, &cmap))) {
223  ret = AVERROR(pa_context_errno(pd->context));
224  goto unlock_and_fail;
225  }
226 
227  pa_stream_set_state_callback(pd->stream, stream_state_cb, pd);
228  pa_stream_set_read_callback(pd->stream, stream_request_cb, pd);
229  pa_stream_set_write_callback(pd->stream, stream_request_cb, pd);
230  pa_stream_set_latency_update_callback(pd->stream, stream_latency_update_cb, pd);
231 
232  ret = pa_stream_connect_record(pd->stream, device, &attr,
233  PA_STREAM_INTERPOLATE_TIMING
234  |PA_STREAM_ADJUST_LATENCY
235  |PA_STREAM_AUTO_TIMING_UPDATE);
236 
237  if (ret < 0) {
238  ret = AVERROR(pa_context_errno(pd->context));
239  goto unlock_and_fail;
240  }
241 
242  for (;;) {
243  pa_stream_state_t state;
244 
245  state = pa_stream_get_state(pd->stream);
246 
247  if (state == PA_STREAM_READY)
248  break;
249 
250  if (!PA_STREAM_IS_GOOD(state)) {
251  ret = AVERROR(pa_context_errno(pd->context));
252  goto unlock_and_fail;
253  }
254 
255  /* Wait until the stream is ready */
256  pa_threaded_mainloop_wait(pd->mainloop);
257  }
258 
259  /* Query actual fragment size */
260  queried_attr = pa_stream_get_buffer_attr(pd->stream);
261  if (!queried_attr || queried_attr->fragsize > INT_MAX/100) {
263  goto unlock_and_fail;
264  }
265  pd->fragment_size = queried_attr->fragsize;
266  pd->pa_frame_size = pa_frame_size(&ss);
267 
268  pa_threaded_mainloop_unlock(pd->mainloop);
269 
270  /* take real parameters */
272  st->codecpar->codec_id = codec_id;
273  st->codecpar->sample_rate = pd->sample_rate;
275  avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
276 
277  pd->timefilter = ff_timefilter_new(1000000.0 / pd->sample_rate,
278  pd->fragment_size / pd->pa_frame_size, 1.5E-6);
279 
280  if (!pd->timefilter) {
281  pulse_close(s);
282  return AVERROR(ENOMEM);
283  }
284 
285  return 0;
286 
287 unlock_and_fail:
288  pa_threaded_mainloop_unlock(pd->mainloop);
289 
290  pulse_close(s);
291  return ret;
292 }
293 
295 {
296  PulseData *pd = s->priv_data;
297  int ret;
298  size_t read_length;
299  const void *read_data = NULL;
300  int64_t dts;
301  pa_usec_t latency;
302  int negative;
303  ptrdiff_t pos = 0;
304 
305  pa_threaded_mainloop_lock(pd->mainloop);
306 
307  CHECK_DEAD_GOTO(pd, ret, unlock_and_fail);
308 
309  while (pos < pd->fragment_size) {
310  int r;
311 
312  r = pa_stream_peek(pd->stream, &read_data, &read_length);
313  CHECK_SUCCESS_GOTO(ret, r == 0, unlock_and_fail);
314 
315  if (read_length <= 0) {
316  pa_threaded_mainloop_wait(pd->mainloop);
317  CHECK_DEAD_GOTO(pd, ret, unlock_and_fail);
318  } else if (!read_data) {
319  /* There's a hole in the stream, skip it. We could generate
320  * silence, but that wouldn't work for compressed streams. */
321  r = pa_stream_drop(pd->stream);
322  CHECK_SUCCESS_GOTO(ret, r == 0, unlock_and_fail);
323  } else {
324  if (!pos) {
325  if (av_new_packet(pkt, pd->fragment_size) < 0) {
326  ret = AVERROR(ENOMEM);
327  goto unlock_and_fail;
328  }
329 
330  dts = av_gettime();
331  pa_operation_unref(pa_stream_update_timing_info(pd->stream, NULL, NULL));
332 
333  if (pa_stream_get_latency(pd->stream, &latency, &negative) >= 0) {
334  if (negative) {
335  dts += latency;
336  } else
337  dts -= latency;
338  } else {
339  av_log(s, AV_LOG_WARNING, "pa_stream_get_latency() failed\n");
340  }
341  }
342  if (pkt->size - pos < read_length) {
343  if (pos)
344  break;
345  pa_stream_drop(pd->stream);
346  /* Oversized fragment??? */
348  goto unlock_and_fail;
349  }
350  memcpy(pkt->data + pos, read_data, read_length);
351  pos += read_length;
352  pa_stream_drop(pd->stream);
353  }
354  }
355 
356  pa_threaded_mainloop_unlock(pd->mainloop);
357 
359 
360  if (pd->wallclock)
362  pd->last_period = pkt->size / pd->pa_frame_size;
363 
364  return 0;
365 
366 unlock_and_fail:
368  pa_threaded_mainloop_unlock(pd->mainloop);
369  return ret;
370 }
371 
373 {
374  PulseData *s = h->priv_data;
375  return ff_pulse_audio_get_devices(device_list, s->server, 0);
376 }
377 
378 #define OFFSET(a) offsetof(PulseData, a)
379 #define D AV_OPT_FLAG_DECODING_PARAM
380 #define DEPR AV_OPT_FLAG_DEPRECATED
381 
382 static const AVOption options[] = {
383  { "server", "set PulseAudio server", OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D },
384  { "name", "set application name", OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, D },
385  { "stream_name", "set stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D },
386  { "sample_rate", "set sample rate in Hz", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 1, INT_MAX, D },
387  { "channels", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, D },
388  { "frame_size", "set number of bytes per frame", OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, D | DEPR },
389  { "fragment_size", "set buffering size, affects latency and cpu usage", OFFSET(fragment_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D },
390  { "wallclock", "set the initial pts using the current time", OFFSET(wallclock), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, D },
391  { NULL },
392 };
393 
394 static const AVClass pulse_demuxer_class = {
395  .class_name = "Pulse indev",
396  .item_name = av_default_item_name,
397  .option = options,
398  .version = LIBAVUTIL_VERSION_INT,
400 };
401 
403  .p.name = "pulse",
404  .p.long_name = NULL_IF_CONFIG_SMALL("Pulse audio input"),
405  .p.flags = AVFMT_NOFILE,
406  .p.priv_class = &pulse_demuxer_class,
407  .priv_data_size = sizeof(PulseData),
411  .get_device_list = pulse_get_device_list,
412 };
DEPR
#define DEPR
Definition: pulse_audio_dec.c:380
PulseData::context
pa_context * context
Definition: pulse_audio_dec.c:51
options
static const AVOption options[]
Definition: pulse_audio_dec.c:382
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:434
TimeFilter
Opaque type representing a time filter state.
Definition: timefilter.c:34
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
LIBAVFORMAT_IDENT
#define LIBAVFORMAT_IDENT
Definition: version.h:45
read_data
static int read_data(void *opaque, uint8_t *buf, int buf_size)
Definition: dashdec.c:1845
r
const char * r
Definition: vf_curves.c:127
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
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:53
PulseData::mainloop
pa_threaded_mainloop * mainloop
Definition: pulse_audio_dec.c:50
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
pulse_get_device_list
static int pulse_get_device_list(AVFormatContext *h, AVDeviceInfoList *device_list)
Definition: pulse_audio_dec.c:372
av_cold
#define av_cold
Definition: attributes.h:119
int64_t
long long int64_t
Definition: coverity.c:34
PulseData::frame_size
int frame_size
Definition: pulse_audio_dec.c:47
stream_latency_update_cb
static void stream_latency_update_cb(pa_stream *s, void *userdata)
Definition: pulse_audio_dec.c:108
AVPacket::data
uint8_t * data
Definition: packet.h:603
AVOption
AVOption.
Definition: opt.h:428
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
server
FFmpeg hosted at Telepoint in bulgaria ns2 avcodec org Replica Name server(provided by an ffmpeg developer, hosted at Hetzner in germany) ns3.avcodec.org Replica Name server(provided by an ffmpeg developer
PulseData::channels
int channels
Definition: pulse_audio_dec.c:46
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
PulseData
Definition: pulse_audio_dec.c:40
PulseData::stream
pa_stream * stream
Definition: pulse_audio_dec.c:52
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:829
PulseData::name
char * name
Definition: pulse_audio_dec.c:43
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: packet.c:113
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
state
static struct @602 state
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
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:50
stream_request_cb
static void stream_request_cb(pa_stream *s, size_t length, void *userdata)
Definition: pulse_audio_dec.c:102
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:210
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
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: packet.c:98
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:570
frame_size
int frame_size
Definition: mxfenc.c:2489
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:201
PulseData::wallclock
int wallclock
Definition: pulse_audio_dec.c:57
PulseData::sample_rate
int sample_rate
Definition: pulse_audio_dec.c:45
channels
channels
Definition: aptx.h:31
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
PulseData::stream_name
char * stream_name
Definition: pulse_audio_dec.c:44
if
if(ret)
Definition: filter_design.txt:179
AVFormatContext
Format I/O context.
Definition: avformat.h:1333
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:789
pulse_close
static av_cold int pulse_close(AVFormatContext *s)
Definition: pulse_audio_dec.c:114
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
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:242
options
Definition: swscale.c:50
time.h
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition: codec_par.h:207
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
The number of audio samples per second.
Definition: codec_par.h:213
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
pulse_audio_common.h
PulseData::timefilter
TimeFilter * timefilter
Definition: pulse_audio_dec.c:55
AVPacket::size
int size
Definition: packet.h:604
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:88
PulseData::server
char * server
Definition: pulse_audio_dec.c:42
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:488
ff_pulse_demuxer
const FFInputFormat ff_pulse_demuxer
Definition: pulse_audio_dec.c:402
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:70
CHECK_SUCCESS_GOTO
#define CHECK_SUCCESS_GOTO(rerror, expression, label)
Definition: pulse_audio_dec.c:61
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
CHECK_DEAD_GOTO
#define CHECK_DEAD_GOTO(p, rerror, label)
Definition: pulse_audio_dec.c:69
read_header
static int read_header(FFV1Context *f, RangeCoder *c)
Definition: ffv1dec.c:574
pulse_read_packet
static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: pulse_audio_dec.c:294
pulse_read_header
static av_cold int pulse_read_header(AVFormatContext *s)
Definition: pulse_audio_dec.c:141
ff_timefilter_destroy
void ff_timefilter_destroy(TimeFilter *self)
Free all resources associated with the filter.
Definition: timefilter.c:66
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:48
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:596
internal.h
s
uint8_t s
Definition: llvidencdsp.c:39
ff_timefilter_update
double ff_timefilter_update(TimeFilter *self, double system_time, double period)
Update the filter.
Definition: timefilter.c:76
demux.h
version.h
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:766
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:81
AVDeviceInfoList
List of devices.
Definition: avdevice.h:343
pos
unsigned int pos
Definition: spdifenc.c:431
avformat.h
D
#define D
Definition: pulse_audio_dec.c:379
PulseData::fragment_size
int fragment_size
Definition: pulse_audio_dec.c:48
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:258
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
PulseData::last_period
int last_period
Definition: pulse_audio_dec.c:56
av_gettime
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:40
PulseData::pa_frame_size
size_t pa_frame_size
Definition: pulse_audio_dec.c:53
context_state_cb
static void context_state_cb(pa_context *c, void *userdata)
Definition: pulse_audio_dec.c:78
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:57
AVPacket
This structure stores compressed data.
Definition: packet.h:580
DEFAULT_CODEC_ID
#define DEFAULT_CODEC_ID
Definition: pulse_audio_dec.c:38
stream_state_cb
static void stream_state_cb(pa_stream *s, void *userdata)
Definition: pulse_audio_dec.c:90
FFInputFormat
Definition: demux.h:66
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2070
pulse_demuxer_class
static const AVClass pulse_demuxer_class
Definition: pulse_audio_dec.c:394
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:275
OFFSET
#define OFFSET(a)
Definition: pulse_audio_dec.c:378