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;
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 = av_rescale(s->buffer_duration,
478  1000);
479  buffer_attributes.tlength = FFMAX(s->buffer_size, av_clip64(bytes, 0, UINT32_MAX - 1));
481  "Buffer duration: %ums recalculated into %"PRId64" bytes buffer.\n",
482  s->buffer_duration, bytes);
483  av_log(s, AV_LOG_DEBUG, "Real buffer length is %u bytes\n", buffer_attributes.tlength);
484  } else if (s->buffer_size)
485  buffer_attributes.tlength = s->buffer_size;
486  if (s->prebuf)
487  buffer_attributes.prebuf = s->prebuf;
488  if (s->minreq)
489  buffer_attributes.minreq = s->minreq;
490 
491  sample_spec.format = ff_codec_id_to_pulse_format(st->codecpar->codec_id);
492  sample_spec.rate = st->codecpar->sample_rate;
493  sample_spec.channels = st->codecpar->ch_layout.nb_channels;
494  if (!pa_sample_spec_valid(&sample_spec)) {
495  av_log(s, AV_LOG_ERROR, "Invalid sample spec.\n");
496  return AVERROR(EINVAL);
497  }
498 
499  if (sample_spec.channels == 1) {
500  channel_map.channels = 1;
501  channel_map.map[0] = PA_CHANNEL_POSITION_MONO;
502  } else if (st->codecpar->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
504  return AVERROR(EINVAL);
506  /* Unknown channel is present in channel_layout, let PulseAudio use its default. */
507  if (channel_map.channels != sample_spec.channels) {
508  av_log(s, AV_LOG_WARNING, "Unknown channel. Using default channel map.\n");
509  channel_map.channels = 0;
510  }
511  } else
512  channel_map.channels = 0;
513 
514  if (!channel_map.channels)
515  av_log(s, AV_LOG_WARNING, "Using PulseAudio's default channel map.\n");
516  else if (!pa_channel_map_valid(&channel_map)) {
517  av_log(s, AV_LOG_ERROR, "Invalid channel map.\n");
518  return AVERROR(EINVAL);
519  }
520 
521  /* start main loop */
522  s->mainloop = pa_threaded_mainloop_new();
523  if (!s->mainloop) {
524  av_log(s, AV_LOG_ERROR, "Cannot create threaded mainloop.\n");
525  return AVERROR(ENOMEM);
526  }
527  if ((ret = pa_threaded_mainloop_start(s->mainloop)) < 0) {
528  av_log(s, AV_LOG_ERROR, "Cannot start threaded mainloop: %s.\n", pa_strerror(ret));
529  pa_threaded_mainloop_free(s->mainloop);
530  s->mainloop = NULL;
531  return AVERROR_EXTERNAL;
532  }
533 
534  pa_threaded_mainloop_lock(s->mainloop);
535 
536  mainloop_api = pa_threaded_mainloop_get_api(s->mainloop);
537  if (!mainloop_api) {
538  av_log(s, AV_LOG_ERROR, "Cannot get mainloop API.\n");
540  goto fail;
541  }
542 
543  s->ctx = pa_context_new(mainloop_api, s->name);
544  if (!s->ctx) {
545  av_log(s, AV_LOG_ERROR, "Cannot create context.\n");
546  ret = AVERROR(ENOMEM);
547  goto fail;
548  }
549  pa_context_set_state_callback(s->ctx, pulse_context_state, s);
550  pa_context_set_subscribe_callback(s->ctx, pulse_event, h);
551 
552  if ((ret = pa_context_connect(s->ctx, s->server, 0, NULL)) < 0) {
553  av_log(s, AV_LOG_ERROR, "Cannot connect context: %s.\n", pa_strerror(ret));
555  goto fail;
556  }
557 
558  if ((ret = pulse_context_wait(s)) < 0) {
559  av_log(s, AV_LOG_ERROR, "Context failed.\n");
560  goto fail;
561  }
562 
563  s->stream = pa_stream_new(s->ctx, stream_name, &sample_spec,
564  channel_map.channels ? &channel_map : NULL);
565 
566  if ((ret = pulse_update_sink_info(h)) < 0) {
567  av_log(s, AV_LOG_ERROR, "Updating sink info failed.\n");
568  goto fail;
569  }
570 
571  if (!s->stream) {
572  av_log(s, AV_LOG_ERROR, "Cannot create stream.\n");
573  ret = AVERROR(ENOMEM);
574  goto fail;
575  }
576  pa_stream_set_state_callback(s->stream, pulse_stream_state, s);
577  pa_stream_set_write_callback(s->stream, pulse_stream_writable, h);
578  pa_stream_set_overflow_callback(s->stream, pulse_overflow, h);
579  pa_stream_set_underflow_callback(s->stream, pulse_underflow, h);
580 
581  if ((ret = pa_stream_connect_playback(s->stream, s->device, &buffer_attributes,
582  stream_flags, NULL, NULL)) < 0) {
583  av_log(s, AV_LOG_ERROR, "pa_stream_connect_playback failed: %s.\n", pa_strerror(ret));
585  goto fail;
586  }
587 
588  if ((ret = pulse_stream_wait(s)) < 0) {
589  av_log(s, AV_LOG_ERROR, "Stream failed.\n");
590  goto fail;
591  }
592 
593  /* read back buffer attributes for future use */
594  buffer_attributes = *pa_stream_get_buffer_attr(s->stream);
595  s->buffer_size = buffer_attributes.tlength;
596  s->prebuf = buffer_attributes.prebuf;
597  s->minreq = buffer_attributes.minreq;
598  av_log(s, AV_LOG_DEBUG, "Real buffer attributes: size: %d, prebuf: %d, minreq: %d\n",
599  s->buffer_size, s->prebuf, s->minreq);
600 
601  pa_threaded_mainloop_unlock(s->mainloop);
602 
603  if ((ret = pulse_subscribe_events(s)) < 0) {
604  av_log(s, AV_LOG_ERROR, "Event subscription failed.\n");
605  /* a bit ugly but the simplest to lock here*/
606  pa_threaded_mainloop_lock(s->mainloop);
607  goto fail;
608  }
609 
610  /* force control messages */
611  s->mute = -1;
612  s->last_volume = PA_VOLUME_INVALID;
613  pa_threaded_mainloop_lock(s->mainloop);
614  if ((ret = pulse_update_sink_input_info(h)) < 0) {
615  av_log(s, AV_LOG_ERROR, "Updating sink input info failed.\n");
616  goto fail;
617  }
618  pa_threaded_mainloop_unlock(s->mainloop);
619 
620  avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
621 
622  return 0;
623  fail:
624  pa_threaded_mainloop_unlock(s->mainloop);
626  return ret;
627 }
628 
630 {
631  PulseData *s = h->priv_data;
632  int ret;
633  int64_t writable_size;
634 
635  if (!pkt)
636  return pulse_flash_stream(s);
637 
638  if (pkt->dts != AV_NOPTS_VALUE)
639  s->timestamp = pkt->dts;
640 
641  if (pkt->duration) {
642  s->timestamp += pkt->duration;
643  } else {
644  AVStream *st = h->streams[0];
645  AVRational r = { 1, st->codecpar->sample_rate };
647  s->timestamp += av_rescale_q(samples, r, st->time_base);
648  }
649 
650  pa_threaded_mainloop_lock(s->mainloop);
651  if (!PA_STREAM_IS_GOOD(pa_stream_get_state(s->stream))) {
652  av_log(s, AV_LOG_ERROR, "PulseAudio stream is in invalid state.\n");
653  goto fail;
654  }
655  while (pa_stream_writable_size(s->stream) < s->minreq) {
656  if (s->nonblocking) {
657  pa_threaded_mainloop_unlock(s->mainloop);
658  return AVERROR(EAGAIN);
659  } else
660  pa_threaded_mainloop_wait(s->mainloop);
661  }
662 
663  if ((ret = pa_stream_write(s->stream, pkt->data, pkt->size, NULL, 0, PA_SEEK_RELATIVE)) < 0) {
664  av_log(s, AV_LOG_ERROR, "pa_stream_write failed: %s\n", pa_strerror(ret));
665  goto fail;
666  }
667  if ((writable_size = pa_stream_writable_size(s->stream)) >= s->minreq)
668  avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_BUFFER_WRITABLE, &writable_size, sizeof(writable_size));
669 
670  pa_threaded_mainloop_unlock(s->mainloop);
671 
672  return 0;
673  fail:
674  pa_threaded_mainloop_unlock(s->mainloop);
675  return AVERROR_EXTERNAL;
676 }
677 
678 static int pulse_write_frame(AVFormatContext *h, int stream_index,
679  AVFrame **frame, unsigned flags)
680 {
681  AVPacket pkt;
682 
683  /* Planar formats are not supported yet. */
685  return av_sample_fmt_is_planar(h->streams[stream_index]->codecpar->format) ?
686  AVERROR(EINVAL) : 0;
687 
688  pkt.data = (*frame)->data[0];
689  pkt.size = (*frame)->nb_samples * av_get_bytes_per_sample((*frame)->format) * (*frame)->ch_layout.nb_channels;
690  pkt.dts = (*frame)->pkt_dts;
691  pkt.duration = (*frame)->duration;
692  return pulse_write_packet(h, &pkt);
693 }
694 
695 
696 static void pulse_get_output_timestamp(AVFormatContext *h, int stream, int64_t *dts, int64_t *wall)
697 {
698  PulseData *s = h->priv_data;
699  pa_usec_t latency;
700  int neg;
701  pa_threaded_mainloop_lock(s->mainloop);
702  pa_stream_get_latency(s->stream, &latency, &neg);
703  pa_threaded_mainloop_unlock(s->mainloop);
704  if (wall)
705  *wall = av_gettime();
706  if (dts)
707  *dts = s->timestamp - (neg ? -latency : latency);
708 }
709 
711 {
712  PulseData *s = h->priv_data;
713  return ff_pulse_audio_get_devices(device_list, s->server, 1);
714 }
715 
717  void *data, size_t data_size)
718 {
719  PulseData *s = h->priv_data;
720  int ret;
721 
722  switch(type) {
723  case AV_APP_TO_DEV_PAUSE:
724  return pulse_set_pause(s, 1);
725  case AV_APP_TO_DEV_PLAY:
726  return pulse_set_pause(s, 0);
728  return pulse_set_pause(s, !pa_stream_is_corked(s->stream));
729  case AV_APP_TO_DEV_MUTE:
730  if (!s->mute) {
731  s->mute = 1;
732  return pulse_set_mute(s);
733  }
734  return 0;
736  if (s->mute) {
737  s->mute = 0;
738  return pulse_set_mute(s);
739  }
740  return 0;
742  s->mute = !s->mute;
743  return pulse_set_mute(s);
745  return pulse_set_volume(s, *(double *)data);
747  s->last_volume = PA_VOLUME_INVALID;
748  pa_threaded_mainloop_lock(s->mainloop);
750  pa_threaded_mainloop_unlock(s->mainloop);
751  return ret;
753  s->mute = -1;
754  pa_threaded_mainloop_lock(s->mainloop);
756  pa_threaded_mainloop_unlock(s->mainloop);
757  return ret;
758  default:
759  break;
760  }
761  return AVERROR(ENOSYS);
762 }
763 
764 #define OFFSET(a) offsetof(PulseData, a)
765 #define E AV_OPT_FLAG_ENCODING_PARAM
766 static const AVOption options[] = {
767  { "server", "set PulseAudio server", OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
768  { "name", "set application name", OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, E },
769  { "stream_name", "set stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
770  { "device", "set device name", OFFSET(device), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
771  { "buffer_size", "set buffer size in bytes", OFFSET(buffer_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
772  { "buffer_duration", "set buffer duration in millisecs", OFFSET(buffer_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
773  { "prebuf", "set pre-buffering size", OFFSET(prebuf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
774  { "minreq", "set minimum request size", OFFSET(minreq), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
775  { NULL }
776 };
777 
778 static const AVClass pulse_muxer_class = {
779  .class_name = "PulseAudio outdev",
780  .item_name = av_default_item_name,
781  .option = options,
782  .version = LIBAVUTIL_VERSION_INT,
784 };
785 
787  .p.name = "pulse",
788  .p.long_name = NULL_IF_CONFIG_SMALL("Pulse audio output"),
789  .priv_data_size = sizeof(PulseData),
791  .p.video_codec = AV_CODEC_ID_NONE,
792  .write_header = pulse_write_header,
793  .write_packet = pulse_write_packet,
794  .write_uncoded_frame = pulse_write_frame,
795  .write_trailer = pulse_write_trailer,
796  .get_output_timestamp = pulse_get_output_timestamp,
797  .get_device_list = pulse_get_device_list,
798  .control_message = pulse_control_message,
799 #if FF_API_ALLOW_FLUSH
800  .p.flags = AVFMT_NOFILE | AVFMT_ALLOW_FLUSH,
801 #else
802  .p.flags = AVFMT_NOFILE,
803 #endif
804  .p.priv_class = &pulse_muxer_class,
805  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
806 };
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:334
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:215
pulse_write_packet
static int pulse_write_packet(AVFormatContext *h, AVPacket *pkt)
Definition: pulse_audio_enc.c:629
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:678
AVOutputFormat::name
const char * name
Definition: avformat.h:510
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
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:50
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
int64_t
long long int64_t
Definition: coverity.c:34
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:778
E
#define E
Definition: pulse_audio_enc.c:765
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
AVPacket::data
uint8_t * data
Definition: packet.h:539
AVOption
AVOption.
Definition: opt.h:429
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:149
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:34
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:557
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:322
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:327
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:65
state
static struct @464 state
PulseData::nonblocking
int nonblocking
Definition: pulse_audio_enc.c:52
PulseData
Definition: pulse_audio_dec.c:40
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: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:867
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:335
AV_CHAN_TOP_BACK_RIGHT
@ AV_CHAN_TOP_BACK_RIGHT
Definition: channel_layout.h:67
fail
#define fail()
Definition: checkasm.h:188
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:77
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:103
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:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
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:119
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:230
ctx
AVFormatContext * ctx
Definition: movenc.c:49
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:696
channel_map
static const uint8_t channel_map[8][8]
Definition: atrac3plusdec.c:52
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
AVFormatContext
Format I/O context.
Definition: avformat.h:1300
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:771
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
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:787
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:786
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:61
pulse_flash_stream
static int pulse_flash_stream(PulseData *s)
Definition: pulse_audio_enc.c:289
double
double
Definition: af_crystalizer.c:132
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:180
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:184
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:716
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:540
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:94
FF_OFMT_FLAG_ALLOW_FLUSH
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
Definition: mux.h:38
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:317
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:468
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:538
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:256
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_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
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:1454
version.h
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:748
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:80
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
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:781
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:764
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:711
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
Underlying C type is int.
Definition: opt.h:259
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:239
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
av_gettime
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
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:92
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:516
pulse_get_device_list
static int pulse_get_device_list(AVFormatContext *h, AVDeviceInfoList *device_list)
Definition: pulse_audio_enc.c:710
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:482
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:2070
AV_CHAN_FRONT_LEFT
@ AV_CHAN_FRONT_LEFT
Definition: channel_layout.h:50
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:276
options
static const AVOption options[]
Definition: pulse_audio_enc.c:766
AV_DEV_TO_APP_BUFFER_UNDERFLOW
@ AV_DEV_TO_APP_BUFFER_UNDERFLOW
Definition: avdevice.h:267
mux.h