|
|
@ -21,11 +21,9 @@ |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @file |
|
|
|
* @file |
|
|
|
* Pulseaudio input |
|
|
|
* PulseAudio input using the simple API. |
|
|
|
* @author Luca Barbato <lu_zero@gentoo.org> |
|
|
|
* @author Luca Barbato <lu_zero@gentoo.org> |
|
|
|
* |
|
|
|
* |
|
|
|
* This avdevice decoder allows to capture audio from a Pulseaudio device using |
|
|
|
|
|
|
|
* the simple api. |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
#include <pulse/simple.h> |
|
|
|
#include <pulse/simple.h> |
|
|
@ -122,7 +120,7 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) |
|
|
|
int res; |
|
|
|
int res; |
|
|
|
pa_usec_t latency; |
|
|
|
pa_usec_t latency; |
|
|
|
uint64_t frame_duration = |
|
|
|
uint64_t frame_duration = |
|
|
|
(pd->frame_size*1000000LL)/(pd->sample_rate * pd->channels); |
|
|
|
(pd->frame_size*1000000LL) / (pd->sample_rate * pd->channels); |
|
|
|
|
|
|
|
|
|
|
|
if (av_new_packet(pkt, pd->frame_size) < 0) { |
|
|
|
if (av_new_packet(pkt, pd->frame_size) < 0) { |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
@ -145,10 +143,10 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) |
|
|
|
pd->pts = -latency; |
|
|
|
pd->pts = -latency; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pd->pts += frame_duration; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pkt->pts = pd->pts; |
|
|
|
pkt->pts = pd->pts; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pd->pts += frame_duration; |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -163,20 +161,13 @@ static av_cold int pulse_close(AVFormatContext *s) |
|
|
|
#define D AV_OPT_FLAG_DECODING_PARAM |
|
|
|
#define D AV_OPT_FLAG_DECODING_PARAM |
|
|
|
|
|
|
|
|
|
|
|
static const AVOption options[] = { |
|
|
|
static const AVOption options[] = { |
|
|
|
{ "server", "pulse server name", |
|
|
|
{ "server", "pulse server name", OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D }, |
|
|
|
OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D }, |
|
|
|
{ "name", "application name", OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, D }, |
|
|
|
{ "name", "application name", |
|
|
|
{ "stream_name", "stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D }, |
|
|
|
OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, D }, |
|
|
|
{ "sample_rate", "sample rate in Hz", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, D }, |
|
|
|
{ "stream_name", "stream description", |
|
|
|
{ "channels", "number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, D }, |
|
|
|
OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D }, |
|
|
|
{ "frame_size", "number of bytes per frame", OFFSET(frame_size), AV_OPT_TYPE_INT, {.dbl = 1024}, 1, INT_MAX, D }, |
|
|
|
{ "sample_rate", "", |
|
|
|
{ "fragment_size", "buffering size, affects latency and cpu usage", OFFSET(fragment_size), AV_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX, D }, |
|
|
|
OFFSET(sample_rate), AV_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, D }, |
|
|
|
|
|
|
|
{ "channels", "", |
|
|
|
|
|
|
|
OFFSET(channels), AV_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, D }, |
|
|
|
|
|
|
|
{ "frame_size", "", |
|
|
|
|
|
|
|
OFFSET(frame_size), AV_OPT_TYPE_INT, {.dbl = 1024}, 1, INT_MAX, D }, |
|
|
|
|
|
|
|
{ "fragment_size", "buffering size, affects latency and cpu usage", |
|
|
|
|
|
|
|
OFFSET(fragment_size), AV_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX, D }, |
|
|
|
|
|
|
|
{ NULL }, |
|
|
|
{ NULL }, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|