FFmpeg
pulse_audio_enc.c
Go to the documentation of this file.
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"
29 #include "libavutil/frame.h"
30 #include "libavutil/internal.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/time.h"
33 #include "libavutil/log.h"
34 #include "libavutil/attributes.h"
35 #include "pulse_audio_common.h"
36 
37 typedef struct PulseData {
38  AVClass *class;
39  const char *server;
40  const char *name;
41  const char *stream_name;
42  const char *device;
43  int64_t timestamp;
44  int buffer_size; /**< Buffer size in bytes */
45  int buffer_duration; /**< Buffer size in ms, recalculated to buffer_size */
46  int prebuf;
47  int minreq;
49  pa_threaded_mainloop *mainloop;
50  pa_context *ctx;
51  pa_stream *stream;
53  int mute;
54  pa_volume_t base_volume;
55  pa_volume_t last_volume;
56 } PulseData;
57 
58 static void pulse_audio_sink_device_cb(pa_context *ctx, const pa_sink_info *dev,
59  int eol, void *userdata)
60 {
61  PulseData *s = userdata;
62 
63  if (s->ctx != ctx)
64  return;
65 
66  if (eol) {
67  pa_threaded_mainloop_signal(s->mainloop, 0);
68  } else {
69  if (dev->flags & PA_SINK_FLAT_VOLUME)
70  s->base_volume = dev->base_volume;
71  else
72  s->base_volume = PA_VOLUME_NORM;
73  av_log(s, AV_LOG_DEBUG, "base volume: %u\n", s->base_volume);
74  }
75 }
76 
77 /* Mainloop must be locked before calling this function as it uses pa_threaded_mainloop_wait. */
79 {
80  PulseData *s = h->priv_data;
81  pa_operation *op;
82  if (!(op = pa_context_get_sink_info_by_name(s->ctx, s->device,
84  av_log(s, AV_LOG_ERROR, "pa_context_get_sink_info_by_name failed.\n");
85  return AVERROR_EXTERNAL;
86  }
87  while (pa_operation_get_state(op) == PA_OPERATION_RUNNING)
88  pa_threaded_mainloop_wait(s->mainloop);
89  pa_operation_unref(op);
90  return 0;
91 }
92 
93 static void pulse_audio_sink_input_cb(pa_context *ctx, const pa_sink_input_info *i,
94  int eol, void *userdata)
95 {
96  AVFormatContext *h = userdata;
97  PulseData *s = h->priv_data;
98 
99  if (s->ctx != ctx)
100  return;
101 
102  if (!eol) {
103  double val;
104  pa_volume_t vol = pa_cvolume_avg(&i->volume);
105  if (s->mute < 0 || (s->mute && !i->mute) || (!s->mute && i->mute)) {
106  s->mute = i->mute;
108  }
109 
110  vol = pa_sw_volume_divide(vol, s->base_volume);
111  if (s->last_volume != vol) {
112  val = (double)vol / PA_VOLUME_NORM;
114  s->last_volume = vol;
115  }
116  }
117 }
118 
119 /* This function creates new loop so may be called from PA callbacks.
120  Mainloop must be locked before calling this function as it operates on streams. */
122 {
123  PulseData *s = h->priv_data;
124  pa_operation *op;
125  enum pa_operation_state op_state;
126  pa_mainloop *ml = NULL;
127  pa_context *ctx = NULL;
128  int ret = 0;
129 
130  if ((ret = ff_pulse_audio_connect_context(&ml, &ctx, s->server, "Update sink input information")) < 0)
131  return ret;
132 
133  if (!(op = pa_context_get_sink_input_info(ctx, pa_stream_get_index(s->stream),
136  goto fail;
137  }
138 
139  while ((op_state = pa_operation_get_state(op)) == PA_OPERATION_RUNNING)
140  pa_mainloop_iterate(ml, 1, NULL);
141  pa_operation_unref(op);
142  if (op_state != PA_OPERATION_DONE) {
144  goto fail;
145  }
146 
147  fail:
149  if (ret)
150  av_log(s, AV_LOG_ERROR, "pa_context_get_sink_input_info failed.\n");
151  return ret;
152 }
153 
154 static void pulse_event(pa_context *ctx, pa_subscription_event_type_t t,
155  uint32_t idx, void *userdata)
156 {
157  AVFormatContext *h = userdata;
158  PulseData *s = h->priv_data;
159 
160  if (s->ctx != ctx)
161  return;
162 
163  if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) {
164  if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_CHANGE)
165  // Calling from mainloop callback. No need to lock mainloop.
167  }
168 }
169 
170 static void pulse_stream_writable(pa_stream *stream, size_t nbytes, void *userdata)
171 {
172  AVFormatContext *h = userdata;
173  PulseData *s = h->priv_data;
174  int64_t val = nbytes;
175 
176  if (stream != s->stream)
177  return;
178 
180  pa_threaded_mainloop_signal(s->mainloop, 0);
181 }
182 
183 static void pulse_overflow(pa_stream *stream, void *userdata)
184 {
185  AVFormatContext *h = userdata;
187 }
188 
189 static void pulse_underflow(pa_stream *stream, void *userdata)
190 {
191  AVFormatContext *h = userdata;
193 }
194 
195 static void pulse_stream_state(pa_stream *stream, void *userdata)
196 {
197  PulseData *s = userdata;
198 
199  if (stream != s->stream)
200  return;
201 
202  switch (pa_stream_get_state(s->stream)) {
203  case PA_STREAM_READY:
204  case PA_STREAM_FAILED:
205  case PA_STREAM_TERMINATED:
206  pa_threaded_mainloop_signal(s->mainloop, 0);
207  default:
208  break;
209  }
210 }
211 
213 {
214  pa_stream_state_t state;
215 
216  while ((state = pa_stream_get_state(s->stream)) != PA_STREAM_READY) {
217  if (state == PA_STREAM_FAILED || state == PA_STREAM_TERMINATED)
218  return AVERROR_EXTERNAL;
219  pa_threaded_mainloop_wait(s->mainloop);
220  }
221  return 0;
222 }
223 
224 static void pulse_context_state(pa_context *ctx, void *userdata)
225 {
226  PulseData *s = userdata;
227 
228  if (s->ctx != ctx)
229  return;
230 
231  switch (pa_context_get_state(ctx)) {
232  case PA_CONTEXT_READY:
233  case PA_CONTEXT_FAILED:
234  case PA_CONTEXT_TERMINATED:
235  pa_threaded_mainloop_signal(s->mainloop, 0);
236  default:
237  break;
238  }
239 }
240 
242 {
243  pa_context_state_t state;
244 
245  while ((state = pa_context_get_state(s->ctx)) != PA_CONTEXT_READY) {
246  if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED)
247  return AVERROR_EXTERNAL;
248  pa_threaded_mainloop_wait(s->mainloop);
249  }
250  return 0;
251 }
252 
253 static void pulse_stream_result(pa_stream *stream, int success, void *userdata)
254 {
255  PulseData *s = userdata;
256 
257  if (stream != s->stream)
258  return;
259 
260  s->last_result = success ? 0 : AVERROR_EXTERNAL;
261  pa_threaded_mainloop_signal(s->mainloop, 0);
262 }
263 
264 static int pulse_finish_stream_operation(PulseData *s, pa_operation *op, const char *name)
265 {
266  if (!op) {
267  pa_threaded_mainloop_unlock(s->mainloop);
268  av_log(s, AV_LOG_ERROR, "%s failed.\n", name);
269  return AVERROR_EXTERNAL;
270  }
271  s->last_result = 2;
272  while (s->last_result == 2)
273  pa_threaded_mainloop_wait(s->mainloop);
274  pa_operation_unref(op);
275  pa_threaded_mainloop_unlock(s->mainloop);
276  if (s->last_result != 0)
277  av_log(s, AV_LOG_ERROR, "%s failed.\n", name);
278  return s->last_result;
279 }
280 
281 static int pulse_set_pause(PulseData *s, int pause)
282 {
283  pa_operation *op;
284  pa_threaded_mainloop_lock(s->mainloop);
285  op = pa_stream_cork(s->stream, pause, pulse_stream_result, s);
286  return pulse_finish_stream_operation(s, op, "pa_stream_cork");
287 }
288 
290 {
291  pa_operation *op;
292  pa_threaded_mainloop_lock(s->mainloop);
293  op = pa_stream_flush(s->stream, pulse_stream_result, s);
294  return pulse_finish_stream_operation(s, op, "pa_stream_flush");
295 }
296 
297 static void pulse_context_result(pa_context *ctx, int success, void *userdata)
298 {
299  PulseData *s = userdata;
300 
301  if (s->ctx != ctx)
302  return;
303 
304  s->last_result = success ? 0 : AVERROR_EXTERNAL;
305  pa_threaded_mainloop_signal(s->mainloop, 0);
306 }
307 
308 static int pulse_finish_context_operation(PulseData *s, pa_operation *op, const char *name)
309 {
310  if (!op) {
311  pa_threaded_mainloop_unlock(s->mainloop);
312  av_log(s, AV_LOG_ERROR, "%s failed.\n", name);
313  return AVERROR_EXTERNAL;
314  }
315  s->last_result = 2;
316  while (s->last_result == 2)
317  pa_threaded_mainloop_wait(s->mainloop);
318  pa_operation_unref(op);
319  pa_threaded_mainloop_unlock(s->mainloop);
320  if (s->last_result != 0)
321  av_log(s, AV_LOG_ERROR, "%s failed.\n", name);
322  return s->last_result;
323 }
324 
326 {
327  pa_operation *op;
328  pa_threaded_mainloop_lock(s->mainloop);
329  op = pa_context_set_sink_input_mute(s->ctx, pa_stream_get_index(s->stream),
330  s->mute, pulse_context_result, s);
331  return pulse_finish_context_operation(s, op, "pa_context_set_sink_input_mute");
332 }
333 
334 static int pulse_set_volume(PulseData *s, double volume)
335 {
336  pa_operation *op;
337  pa_cvolume cvol;
338  pa_volume_t vol;
339  const pa_sample_spec *ss = pa_stream_get_sample_spec(s->stream);
340 
341  vol = pa_sw_volume_multiply(lrint(volume * PA_VOLUME_NORM), s->base_volume);
342  pa_cvolume_set(&cvol, ss->channels, PA_VOLUME_NORM);
343  pa_sw_cvolume_multiply_scalar(&cvol, &cvol, vol);
344  pa_threaded_mainloop_lock(s->mainloop);
345  op = pa_context_set_sink_input_volume(s->ctx, pa_stream_get_index(s->stream),
346  &cvol, pulse_context_result, s);
347  return pulse_finish_context_operation(s, op, "pa_context_set_sink_input_volume");
348 }
349 
351 {
352  pa_operation *op;
353 
354  pa_threaded_mainloop_lock(s->mainloop);
355  op = pa_context_subscribe(s->ctx, PA_SUBSCRIPTION_MASK_SINK_INPUT, pulse_context_result, s);
356  return pulse_finish_context_operation(s, op, "pa_context_subscribe");
357 }
358 
359 static void pulse_map_channels_to_pulse(const AVChannelLayout *channel_layout, pa_channel_map *channel_map)
360 {
361  channel_map->channels = 0;
363  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_LEFT;
365  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_RIGHT;
367  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_CENTER;
369  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_LFE;
371  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_REAR_LEFT;
373  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_REAR_RIGHT;
375  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER;
377  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
379  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_REAR_CENTER;
381  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_SIDE_LEFT;
383  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_SIDE_RIGHT;
385  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_CENTER;
387  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_FRONT_LEFT;
389  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_FRONT_CENTER;
391  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_FRONT_RIGHT;
393  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_REAR_LEFT;
395  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_REAR_CENTER;
397  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
399  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_LEFT;
401  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_FRONT_RIGHT;
403  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_AUX0;
405  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_AUX1;
407  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_AUX2;
409  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_AUX3;
411  channel_map->map[channel_map->channels++] = PA_CHANNEL_POSITION_LFE;
412 }
413 
415 {
416  PulseData *s = h->priv_data;
417 
418  if (s->mainloop) {
419  pa_threaded_mainloop_lock(s->mainloop);
420  if (s->stream) {
421  pa_stream_disconnect(s->stream);
422  pa_stream_set_state_callback(s->stream, NULL, NULL);
423  pa_stream_set_write_callback(s->stream, NULL, NULL);
424  pa_stream_set_overflow_callback(s->stream, NULL, NULL);
425  pa_stream_set_underflow_callback(s->stream, NULL, NULL);
426  pa_stream_unref(s->stream);
427  s->stream = NULL;
428  }
429  if (s->ctx) {
430  pa_context_disconnect(s->ctx);
431  pa_context_set_state_callback(s->ctx, NULL, NULL);
432  pa_context_set_subscribe_callback(s->ctx, NULL, NULL);
433  pa_context_unref(s->ctx);
434  s->ctx = NULL;
435  }
436  pa_threaded_mainloop_unlock(s->mainloop);
437  pa_threaded_mainloop_stop(s->mainloop);
438  pa_threaded_mainloop_free(s->mainloop);
439  s->mainloop = NULL;
440  }
441 
442  return 0;
443 }
444 
446 {
447  PulseData *s = h->priv_data;
448  AVStream *st = NULL;
449  int ret;
450  pa_sample_spec sample_spec;
451  pa_buffer_attr buffer_attributes = { -1, -1, -1, -1, -1 };
452  pa_channel_map channel_map;
453  pa_mainloop_api *mainloop_api;
454  const char *stream_name = s->stream_name;
455  static const pa_stream_flags_t stream_flags = PA_STREAM_INTERPOLATE_TIMING |
456  PA_STREAM_AUTO_TIMING_UPDATE |
457  PA_STREAM_NOT_MONOTONIC;
458 
459  if (h->nb_streams != 1 || h->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
460  av_log(s, AV_LOG_ERROR, "Only a single audio stream is supported.\n");
461  return AVERROR(EINVAL);
462  }
463  st = h->streams[0];
464 
465  if (!stream_name) {
466  if (h->url[0])
467  stream_name = h->url;
468  else
469  stream_name = "Playback";
470  }
471  s->nonblocking = (h->flags & AVFMT_FLAG_NONBLOCK);
472 
473  if (s->buffer_duration) {
474  int64_t bytes = s->buffer_duration;
475  bytes *= st->codecpar->ch_layout.nb_channels * st->codecpar->sample_rate *
477  bytes /= 1000;
478  buffer_attributes.tlength = FFMAX(s->buffer_size, av_clip64(bytes, 0, UINT32_MAX - 1));
480  "Buffer duration: %ums recalculated into %"PRId64" bytes buffer.\n",
481  s->buffer_duration, bytes);
482  av_log(s, AV_LOG_DEBUG, "Real buffer length is %u bytes\n", buffer_attributes.tlength);
483  } else if (s->buffer_size)
484  buffer_attributes.tlength = s->buffer_size;
485  if (s->prebuf)
486  buffer_attributes.prebuf = s->prebuf;
487  if (s->minreq)
488  buffer_attributes.minreq = s->minreq;
489 
490  sample_spec.format = ff_codec_id_to_pulse_format(st->codecpar->codec_id);
491  sample_spec.rate = st->codecpar->sample_rate;
492  sample_spec.channels = st->codecpar->ch_layout.nb_channels;
493  if (!pa_sample_spec_valid(&sample_spec)) {
494  av_log(s, AV_LOG_ERROR, "Invalid sample spec.\n");
495  return AVERROR(EINVAL);
496  }
497 
498  if (sample_spec.channels == 1) {
499  channel_map.channels = 1;
500  channel_map.map[0] = PA_CHANNEL_POSITION_MONO;
501  } else if (st->codecpar->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
503  return AVERROR(EINVAL);
505  /* Unknown channel is present in channel_layout, let PulseAudio use its default. */
506  if (channel_map.channels != sample_spec.channels) {
507  av_log(s, AV_LOG_WARNING, "Unknown channel. Using defaul channel map.\n");
508  channel_map.channels = 0;
509  }
510  } else
511  channel_map.channels = 0;
512 
513  if (!channel_map.channels)
514  av_log(s, AV_LOG_WARNING, "Using PulseAudio's default channel map.\n");
515  else if (!pa_channel_map_valid(&channel_map)) {
516  av_log(s, AV_LOG_ERROR, "Invalid channel map.\n");
517  return AVERROR(EINVAL);
518  }
519 
520  /* start main loop */
521  s->mainloop = pa_threaded_mainloop_new();
522  if (!s->mainloop) {
523  av_log(s, AV_LOG_ERROR, "Cannot create threaded mainloop.\n");
524  return AVERROR(ENOMEM);
525  }
526  if ((ret = pa_threaded_mainloop_start(s->mainloop)) < 0) {
527  av_log(s, AV_LOG_ERROR, "Cannot start threaded mainloop: %s.\n", pa_strerror(ret));
528  pa_threaded_mainloop_free(s->mainloop);
529  s->mainloop = NULL;
530  return AVERROR_EXTERNAL;
531  }
532 
533  pa_threaded_mainloop_lock(s->mainloop);
534 
535  mainloop_api = pa_threaded_mainloop_get_api(s->mainloop);
536  if (!mainloop_api) {
537  av_log(s, AV_LOG_ERROR, "Cannot get mainloop API.\n");
539  goto fail;
540  }
541 
542  s->ctx = pa_context_new(mainloop_api, s->name);
543  if (!s->ctx) {
544  av_log(s, AV_LOG_ERROR, "Cannot create context.\n");
545  ret = AVERROR(ENOMEM);
546  goto fail;
547  }
548  pa_context_set_state_callback(s->ctx, pulse_context_state, s);
549  pa_context_set_subscribe_callback(s->ctx, pulse_event, h);
550 
551  if ((ret = pa_context_connect(s->ctx, s->server, 0, NULL)) < 0) {
552  av_log(s, AV_LOG_ERROR, "Cannot connect context: %s.\n", pa_strerror(ret));
554  goto fail;
555  }
556 
557  if ((ret = pulse_context_wait(s)) < 0) {
558  av_log(s, AV_LOG_ERROR, "Context failed.\n");
559  goto fail;
560  }
561 
562  s->stream = pa_stream_new(s->ctx, stream_name, &sample_spec,
563  channel_map.channels ? &channel_map : NULL);
564 
565  if ((ret = pulse_update_sink_info(h)) < 0) {
566  av_log(s, AV_LOG_ERROR, "Updating sink info failed.\n");
567  goto fail;
568  }
569 
570  if (!s->stream) {
571  av_log(s, AV_LOG_ERROR, "Cannot create stream.\n");
572  ret = AVERROR(ENOMEM);
573  goto fail;
574  }
575  pa_stream_set_state_callback(s->stream, pulse_stream_state, s);
576  pa_stream_set_write_callback(s->stream, pulse_stream_writable, h);
577  pa_stream_set_overflow_callback(s->stream, pulse_overflow, h);
578  pa_stream_set_underflow_callback(s->stream, pulse_underflow, h);
579 
580  if ((ret = pa_stream_connect_playback(s->stream, s->device, &buffer_attributes,
581  stream_flags, NULL, NULL)) < 0) {
582  av_log(s, AV_LOG_ERROR, "pa_stream_connect_playback failed: %s.\n", pa_strerror(ret));
584  goto fail;
585  }
586 
587  if ((ret = pulse_stream_wait(s)) < 0) {
588  av_log(s, AV_LOG_ERROR, "Stream failed.\n");
589  goto fail;
590  }
591 
592  /* read back buffer attributes for future use */
593  buffer_attributes = *pa_stream_get_buffer_attr(s->stream);
594  s->buffer_size = buffer_attributes.tlength;
595  s->prebuf = buffer_attributes.prebuf;
596  s->minreq = buffer_attributes.minreq;
597  av_log(s, AV_LOG_DEBUG, "Real buffer attributes: size: %d, prebuf: %d, minreq: %d\n",
598  s->buffer_size, s->prebuf, s->minreq);
599 
600  pa_threaded_mainloop_unlock(s->mainloop);
601 
602  if ((ret = pulse_subscribe_events(s)) < 0) {
603  av_log(s, AV_LOG_ERROR, "Event subscription failed.\n");
604  /* a bit ugly but the simplest to lock here*/
605  pa_threaded_mainloop_lock(s->mainloop);
606  goto fail;
607  }
608 
609  /* force control messages */
610  s->mute = -1;
611  s->last_volume = PA_VOLUME_INVALID;
612  pa_threaded_mainloop_lock(s->mainloop);
613  if ((ret = pulse_update_sink_input_info(h)) < 0) {
614  av_log(s, AV_LOG_ERROR, "Updating sink input info failed.\n");
615  goto fail;
616  }
617  pa_threaded_mainloop_unlock(s->mainloop);
618 
619  avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
620 
621  return 0;
622  fail:
623  pa_threaded_mainloop_unlock(s->mainloop);
625  return ret;
626 }
627 
629 {
630  PulseData *s = h->priv_data;
631  int ret;
632  int64_t writable_size;
633 
634  if (!pkt)
635  return pulse_flash_stream(s);
636 
637  if (pkt->dts != AV_NOPTS_VALUE)
638  s->timestamp = pkt->dts;
639 
640  if (pkt->duration) {
641  s->timestamp += pkt->duration;
642  } else {
643  AVStream *st = h->streams[0];
644  AVRational r = { 1, st->codecpar->sample_rate };
646  s->timestamp += av_rescale_q(samples, r, st->time_base);
647  }
648 
649  pa_threaded_mainloop_lock(s->mainloop);
650  if (!PA_STREAM_IS_GOOD(pa_stream_get_state(s->stream))) {
651  av_log(s, AV_LOG_ERROR, "PulseAudio stream is in invalid state.\n");
652  goto fail;
653  }
654  while (pa_stream_writable_size(s->stream) < s->minreq) {
655  if (s->nonblocking) {
656  pa_threaded_mainloop_unlock(s->mainloop);
657  return AVERROR(EAGAIN);
658  } else
659  pa_threaded_mainloop_wait(s->mainloop);
660  }
661 
662  if ((ret = pa_stream_write(s->stream, pkt->data, pkt->size, NULL, 0, PA_SEEK_RELATIVE)) < 0) {
663  av_log(s, AV_LOG_ERROR, "pa_stream_write failed: %s\n", pa_strerror(ret));
664  goto fail;
665  }
666  if ((writable_size = pa_stream_writable_size(s->stream)) >= s->minreq)
667  avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_BUFFER_WRITABLE, &writable_size, sizeof(writable_size));
668 
669  pa_threaded_mainloop_unlock(s->mainloop);
670 
671  return 0;
672  fail:
673  pa_threaded_mainloop_unlock(s->mainloop);
674  return AVERROR_EXTERNAL;
675 }
676 
677 static int pulse_write_frame(AVFormatContext *h, int stream_index,
678  AVFrame **frame, unsigned flags)
679 {
680  AVPacket pkt;
681 
682  /* Planar formats are not supported yet. */
684  return av_sample_fmt_is_planar(h->streams[stream_index]->codecpar->format) ?
685  AVERROR(EINVAL) : 0;
686 
687  pkt.data = (*frame)->data[0];
688  pkt.size = (*frame)->nb_samples * av_get_bytes_per_sample((*frame)->format) * (*frame)->ch_layout.nb_channels;
689  pkt.dts = (*frame)->pkt_dts;
690 #if FF_API_PKT_DURATION
692  if ((*frame)->pkt_duration)
693  pkt.duration = (*frame)->pkt_duration;
694  else
696 #endif
697  pkt.duration = (*frame)->duration;
698  return pulse_write_packet(h, &pkt);
699 }
700 
701 
702 static void pulse_get_output_timestamp(AVFormatContext *h, int stream, int64_t *dts, int64_t *wall)
703 {
704  PulseData *s = h->priv_data;
705  pa_usec_t latency;
706  int neg;
707  pa_threaded_mainloop_lock(s->mainloop);
708  pa_stream_get_latency(s->stream, &latency, &neg);
709  pa_threaded_mainloop_unlock(s->mainloop);
710  if (wall)
711  *wall = av_gettime();
712  if (dts)
713  *dts = s->timestamp - (neg ? -latency : latency);
714 }
715 
717 {
718  PulseData *s = h->priv_data;
719  return ff_pulse_audio_get_devices(device_list, s->server, 1);
720 }
721 
723  void *data, size_t data_size)
724 {
725  PulseData *s = h->priv_data;
726  int ret;
727 
728  switch(type) {
729  case AV_APP_TO_DEV_PAUSE:
730  return pulse_set_pause(s, 1);
731  case AV_APP_TO_DEV_PLAY:
732  return pulse_set_pause(s, 0);
734  return pulse_set_pause(s, !pa_stream_is_corked(s->stream));
735  case AV_APP_TO_DEV_MUTE:
736  if (!s->mute) {
737  s->mute = 1;
738  return pulse_set_mute(s);
739  }
740  return 0;
742  if (s->mute) {
743  s->mute = 0;
744  return pulse_set_mute(s);
745  }
746  return 0;
748  s->mute = !s->mute;
749  return pulse_set_mute(s);
751  return pulse_set_volume(s, *(double *)data);
753  s->last_volume = PA_VOLUME_INVALID;
754  pa_threaded_mainloop_lock(s->mainloop);
756  pa_threaded_mainloop_unlock(s->mainloop);
757  return ret;
759  s->mute = -1;
760  pa_threaded_mainloop_lock(s->mainloop);
762  pa_threaded_mainloop_unlock(s->mainloop);
763  return ret;
764  default:
765  break;
766  }
767  return AVERROR(ENOSYS);
768 }
769 
770 #define OFFSET(a) offsetof(PulseData, a)
771 #define E AV_OPT_FLAG_ENCODING_PARAM
772 static const AVOption options[] = {
773  { "server", "set PulseAudio server", OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
774  { "name", "set application name", OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, E },
775  { "stream_name", "set stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
776  { "device", "set device name", OFFSET(device), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
777  { "buffer_size", "set buffer size in bytes", OFFSET(buffer_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
778  { "buffer_duration", "set buffer duration in millisecs", OFFSET(buffer_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
779  { "prebuf", "set pre-buffering size", OFFSET(prebuf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
780  { "minreq", "set minimum request size", OFFSET(minreq), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
781  { NULL }
782 };
783 
784 static const AVClass pulse_muxer_class = {
785  .class_name = "PulseAudio outdev",
786  .item_name = av_default_item_name,
787  .option = options,
788  .version = LIBAVUTIL_VERSION_INT,
790 };
791 
793  .p.name = "pulse",
794  .p.long_name = NULL_IF_CONFIG_SMALL("Pulse audio output"),
795  .priv_data_size = sizeof(PulseData),
797  .p.video_codec = AV_CODEC_ID_NONE,
798  .write_header = pulse_write_header,
799  .write_packet = pulse_write_packet,
800  .write_uncoded_frame = pulse_write_frame,
801  .write_trailer = pulse_write_trailer,
802  .get_output_timestamp = pulse_get_output_timestamp,
803  .get_device_list = pulse_get_device_list,
804  .control_message = pulse_control_message,
805 #if FF_API_ALLOW_FLUSH
806  .p.flags = AVFMT_NOFILE | AVFMT_ALLOW_FLUSH,
807 #else
808  .p.flags = AVFMT_NOFILE,
809 #endif
810  .p.priv_class = &pulse_muxer_class,
811  .flags_internal = FF_FMT_ALLOW_FLUSH,
812 };
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:330
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
pulse_finish_stream_operation
static int pulse_finish_stream_operation(PulseData *s, pa_operation *op, const char *name)
Definition: pulse_audio_enc.c:264
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
pulse_write_packet
static int pulse_write_packet(AVFormatContext *h, AVPacket *pkt)
Definition: pulse_audio_enc.c:628
pulse_map_channels_to_pulse
static void pulse_map_channels_to_pulse(const AVChannelLayout *channel_layout, pa_channel_map *channel_map)
Definition: pulse_audio_enc.c:359
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
AV_APP_TO_DEV_MUTE
@ AV_APP_TO_DEV_MUTE
Mute control messages.
Definition: avdevice.h:185
pulse_write_frame
static int pulse_write_frame(AVFormatContext *h, int stream_index, AVFrame **frame, unsigned flags)
Definition: pulse_audio_enc.c:677
AVOutputFormat::name
const char * name
Definition: avformat.h:511
r
const char * r
Definition: vf_curves.c:126
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
pulse_context_wait
static int pulse_context_wait(PulseData *s)
Definition: pulse_audio_enc.c:241
PulseData::mainloop
pa_threaded_mainloop * mainloop
Definition: pulse_audio_dec.c:49
AV_APP_TO_DEV_SET_VOLUME
@ AV_APP_TO_DEV_SET_VOLUME
Volume control message.
Definition: avdevice.h:174
AV_DEV_TO_APP_BUFFER_OVERFLOW
@ AV_DEV_TO_APP_BUFFER_OVERFLOW
Buffer fullness status messages.
Definition: avdevice.h:266
PulseData::server
const char * server
Definition: pulse_audio_enc.c:39
pulse_write_header
static av_cold int pulse_write_header(AVFormatContext *h)
Definition: pulse_audio_enc.c:445
pulse_set_pause
static int pulse_set_pause(PulseData *s, int pause)
Definition: pulse_audio_enc.c:281
AV_CHAN_WIDE_LEFT
@ AV_CHAN_WIDE_LEFT
Definition: channel_layout.h:72
pulse_underflow
static void pulse_underflow(pa_stream *stream, void *userdata)
Definition: pulse_audio_enc.c:189
pulse_muxer_class
static const AVClass pulse_muxer_class
Definition: pulse_audio_enc.c:784
E
#define E
Definition: pulse_audio_enc.c:771
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
AVPacket::data
uint8_t * data
Definition: packet.h:491
AVOption
AVOption.
Definition: opt.h:251
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
data
const char data[16]
Definition: mxf.c:148
avdevice_dev_to_app_control_message
int avdevice_dev_to_app_control_message(struct AVFormatContext *s, enum AVDevToAppMessageType type, void *data, size_t data_size)
Send control message from device to application.
Definition: avdevice.c:32
AV_APP_TO_DEV_PAUSE
@ AV_APP_TO_DEV_PAUSE
Request pause/play.
Definition: avdevice.h:161
pulse_context_result
static void pulse_context_result(pa_context *ctx, int success, void *userdata)
Definition: pulse_audio_enc.c:297
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:509
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:312
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
pulse_overflow
static void pulse_overflow(pa_stream *stream, void *userdata)
Definition: pulse_audio_enc.c:183
AV_APP_TO_DEV_GET_MUTE
@ AV_APP_TO_DEV_GET_MUTE
Definition: avdevice.h:198
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:317
AV_DEV_TO_APP_MUTE_STATE_CHANGED
@ AV_DEV_TO_APP_MUTE_STATE_CHANGED
Mute state change message.
Definition: avdevice.h:290
pulse_stream_wait
static int pulse_stream_wait(PulseData *s)
Definition: pulse_audio_enc.c:212
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:36
PulseData::nonblocking
int nonblocking
Definition: pulse_audio_enc.c:52
PulseData
Definition: pulse_audio_dec.c:39
AV_CHAN_SURROUND_DIRECT_LEFT
@ AV_CHAN_SURROUND_DIRECT_LEFT
Definition: channel_layout.h:74
PulseData::last_volume
pa_volume_t last_volume
Definition: pulse_audio_enc.c:55
PulseData::stream
pa_stream * stream
Definition: pulse_audio_dec.c:51
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:761
FF_FMT_ALLOW_FLUSH
#define FF_FMT_ALLOW_FLUSH
Definition: mux.h:30
PulseData::timestamp
int64_t timestamp
Definition: pulse_audio_enc.c:43
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:331
AV_CHAN_TOP_BACK_RIGHT
@ AV_CHAN_TOP_BACK_RIGHT
Definition: channel_layout.h:67
fail
#define fail()
Definition: checkasm.h:138
PulseData::base_volume
pa_volume_t base_volume
Definition: pulse_audio_enc.c:54
val
static double val(void *priv, double ch)
Definition: aeval.c:78
pulse_update_sink_input_info
static int pulse_update_sink_input_info(AVFormatContext *h)
Definition: pulse_audio_enc.c:121
type
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 type
Definition: writing_filters.txt:86
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
av_clip64
#define av_clip64
Definition: common.h:99
AV_CHAN_STEREO_RIGHT
@ AV_CHAN_STEREO_RIGHT
See above.
Definition: channel_layout.h:71
AV_APP_TO_DEV_UNMUTE
@ AV_APP_TO_DEV_UNMUTE
Definition: avdevice.h:186
lrint
#define lrint
Definition: tablegen.h:53
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
pulse_stream_state
static void pulse_stream_state(pa_stream *stream, void *userdata)
Definition: pulse_audio_enc.c:195
av_cold
#define av_cold
Definition: attributes.h:90
AV_APP_TO_DEV_TOGGLE_PAUSE
@ AV_APP_TO_DEV_TOGGLE_PAUSE
Definition: avdevice.h:163
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_NE
#define AV_NE(be, le)
Definition: macros.h:33
pulse_set_volume
static int pulse_set_volume(PulseData *s, double volume)
Definition: pulse_audio_enc.c:334
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
op
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:76
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:112
AV_CHAN_SIDE_RIGHT
@ AV_CHAN_SIDE_RIGHT
Definition: channel_layout.h:60
av_sample_fmt_is_planar
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition: samplefmt.c:114
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
pulse_get_output_timestamp
static void pulse_get_output_timestamp(AVFormatContext *h, int stream, int64_t *dts, int64_t *wall)
Definition: pulse_audio_enc.c:702
channel_map
static const uint8_t channel_map[8][8]
Definition: atrac3plusdec.c:51
pulse_update_sink_info
static int pulse_update_sink_info(AVFormatContext *h)
Definition: pulse_audio_enc.c:78
PulseData::stream_name
const char * stream_name
Definition: pulse_audio_enc.c:41
frame
static AVFrame * frame
Definition: demux_decode.c:54
AVFormatContext
Format I/O context.
Definition: avformat.h:1115
internal.h
pulse_event
static void pulse_event(pa_context *ctx, pa_subscription_event_type_t t, uint32_t idx, void *userdata)
Definition: pulse_audio_enc.c:154
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:864
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:880
NULL
#define NULL
Definition: coverity.c:32
AV_APP_TO_DEV_GET_VOLUME
@ AV_APP_TO_DEV_GET_VOLUME
Get volume/mute messages.
Definition: avdevice.h:197
PulseData::mute
int mute
Definition: pulse_audio_enc.c:53
ff_pulse_muxer
const FFOutputFormat ff_pulse_muxer
Definition: pulse_audio_enc.c:792
PulseData::ctx
pa_context * ctx
Definition: pulse_audio_enc.c:50
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_CHAN_TOP_BACK_CENTER
@ AV_CHAN_TOP_BACK_CENTER
Definition: channel_layout.h:66
pulse_audio_sink_device_cb
static void pulse_audio_sink_device_cb(pa_context *ctx, const pa_sink_info *dev, int eol, void *userdata)
Definition: pulse_audio_enc.c:58
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
FFOutputFormat
Definition: mux.h:32
pulse_flash_stream
static int pulse_flash_stream(PulseData *s)
Definition: pulse_audio_enc.c:289
double
double
Definition: af_crystalizer.c:131
time.h
AV_CHAN_TOP_CENTER
@ AV_CHAN_TOP_CENTER
Definition: channel_layout.h:61
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:206
pulse_stream_result
static void pulse_stream_result(pa_stream *stream, int success, void *userdata)
Definition: pulse_audio_enc.c:253
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:171
AV_CHAN_FRONT_RIGHT_OF_CENTER
@ AV_CHAN_FRONT_RIGHT_OF_CENTER
Definition: channel_layout.h:57
AV_CHAN_FRONT_RIGHT
@ AV_CHAN_FRONT_RIGHT
Definition: channel_layout.h:51
AV_CHAN_FRONT_CENTER
@ AV_CHAN_FRONT_CENTER
Definition: channel_layout.h:52
pulse_audio_common.h
pulse_control_message
static int pulse_control_message(AVFormatContext *h, int type, void *data, size_t data_size)
Definition: pulse_audio_enc.c:722
pulse_audio_sink_input_cb
static void pulse_audio_sink_input_cb(pa_context *ctx, const pa_sink_input_info *i, int eol, void *userdata)
Definition: pulse_audio_enc.c:93
AVPacket::size
int size
Definition: packet.h:492
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:106
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:307
AV_APP_TO_DEV_PLAY
@ AV_APP_TO_DEV_PLAY
Definition: avdevice.h:162
pulse_stream_writable
static void pulse_stream_writable(pa_stream *stream, size_t nbytes, void *userdata)
Definition: pulse_audio_enc.c:170
AV_CHAN_LOW_FREQUENCY
@ AV_CHAN_LOW_FREQUENCY
Definition: channel_layout.h:53
AV_CHAN_BACK_RIGHT
@ AV_CHAN_BACK_RIGHT
Definition: channel_layout.h:55
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
ff_pulse_audio_disconnect_context
void ff_pulse_audio_disconnect_context(pa_mainloop **pa_ml, pa_context **pa_ctx)
Definition: pulse_audio_common.c:77
AV_CHAN_SIDE_LEFT
@ AV_CHAN_SIDE_LEFT
Definition: channel_layout.h:59
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:469
frame.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:490
pulse_context_state
static void pulse_context_state(pa_context *ctx, void *userdata)
Definition: pulse_audio_enc.c:224
AV_APP_TO_DEV_TOGGLE_MUTE
@ AV_APP_TO_DEV_TOGGLE_MUTE
Definition: avdevice.h:187
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
AV_CHAN_TOP_FRONT_RIGHT
@ AV_CHAN_TOP_FRONT_RIGHT
Definition: channel_layout.h:64
PulseData::prebuf
int prebuf
Definition: pulse_audio_enc.c:46
attributes.h
AV_CHAN_FRONT_LEFT_OF_CENTER
@ AV_CHAN_FRONT_LEFT_OF_CENTER
Definition: channel_layout.h:56
ff_pulse_audio_connect_context
int ff_pulse_audio_connect_context(pa_mainloop **pa_ml, pa_context **pa_ctx, const char *server, const char *description)
Definition: pulse_audio_common.c:93
log.h
AV_CHAN_SURROUND_DIRECT_RIGHT
@ AV_CHAN_SURROUND_DIRECT_RIGHT
Definition: channel_layout.h:75
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
PulseData::buffer_size
int buffer_size
Buffer size in bytes.
Definition: pulse_audio_enc.c:44
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
av_get_bytes_per_sample
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:108
internal.h
AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT
@ AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT
Definition: log.h:42
AV_CHAN_STEREO_LEFT
@ AV_CHAN_STEREO_LEFT
Stereo downmix.
Definition: channel_layout.h:69
AVFMT_FLAG_NONBLOCK
#define AVFMT_FLAG_NONBLOCK
Do not block when reading packets from input.
Definition: avformat.h:1236
version.h
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:841
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:71
PulseData::name
const char * name
Definition: pulse_audio_enc.c:40
AVDeviceInfoList
List of devices.
Definition: avdevice.h:343
av_channel_layout_check
int av_channel_layout_check(const AVChannelLayout *channel_layout)
Check whether a channel layout is valid, i.e.
Definition: channel_layout.c:916
avformat.h
PulseData::buffer_duration
int buffer_duration
Buffer size in ms, recalculated to buffer_size.
Definition: pulse_audio_enc.c:45
AV_CHAN_BACK_CENTER
@ AV_CHAN_BACK_CENTER
Definition: channel_layout.h:58
channel_layout.h
OFFSET
#define OFFSET(a)
Definition: pulse_audio_enc.c:770
AV_CHAN_LOW_FREQUENCY_2
@ AV_CHAN_LOW_FREQUENCY_2
Definition: channel_layout.h:76
AV_CHAN_TOP_BACK_LEFT
@ AV_CHAN_TOP_BACK_LEFT
Definition: channel_layout.h:65
av_channel_layout_index_from_channel
int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, enum AVChannel channel)
Get the index of a given channel in a channel layout.
Definition: channel_layout.c:846
pulse_write_trailer
static av_cold int pulse_write_trailer(AVFormatContext *h)
Definition: pulse_audio_enc.c:414
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
pulse_subscribe_events
static int pulse_subscribe_events(PulseData *s)
Definition: pulse_audio_enc.c:350
AV_WRITE_UNCODED_FRAME_QUERY
@ AV_WRITE_UNCODED_FRAME_QUERY
Query whether the feature is possible on this stream.
Definition: mux.h:210
AV_CHAN_BACK_LEFT
@ AV_CHAN_BACK_LEFT
Definition: channel_layout.h:54
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
pulse_set_mute
static int pulse_set_mute(PulseData *s)
Definition: pulse_audio_enc.c:325
state
static struct @362 state
av_gettime
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
PulseData::minreq
int minreq
Definition: pulse_audio_enc.c:47
AV_CHAN_TOP_FRONT_CENTER
@ AV_CHAN_TOP_FRONT_CENTER
Definition: channel_layout.h:63
pulse_finish_context_operation
static int pulse_finish_context_operation(PulseData *s, pa_operation *op, const char *name)
Definition: pulse_audio_enc.c:308
AV_CHAN_WIDE_RIGHT
@ AV_CHAN_WIDE_RIGHT
Definition: channel_layout.h:73
AVCodecParameters::format
int format
Definition: codec_par.h:79
AV_DEV_TO_APP_VOLUME_LEVEL_CHANGED
@ AV_DEV_TO_APP_VOLUME_LEVEL_CHANGED
Volume level change message.
Definition: avdevice.h:299
AV_DEV_TO_APP_BUFFER_WRITABLE
@ AV_DEV_TO_APP_BUFFER_WRITABLE
Definition: avdevice.h:281
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:468
pulse_get_device_list
static int pulse_get_device_list(AVFormatContext *h, AVDeviceInfoList *device_list)
Definition: pulse_audio_enc.c:716
AV_CHAN_TOP_FRONT_LEFT
@ AV_CHAN_TOP_FRONT_LEFT
Definition: channel_layout.h:62
PulseData::device
const char * device
Definition: pulse_audio_enc.c:42
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
PulseData::last_result
int last_result
Definition: pulse_audio_enc.c:48
h
h
Definition: vp9dsp_template.c:2038
AV_CHAN_FRONT_LEFT
@ AV_CHAN_FRONT_LEFT
Definition: channel_layout.h:50
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
options
static const AVOption options[]
Definition: pulse_audio_enc.c:772
AV_DEV_TO_APP_BUFFER_UNDERFLOW
@ AV_DEV_TO_APP_BUFFER_UNDERFLOW
Definition: avdevice.h:267
mux.h