diff --git a/libavdevice/pulse.c b/libavdevice/pulse.c index 94bb32ff5e..56ae323856 100644 --- a/libavdevice/pulse.c +++ b/libavdevice/pulse.c @@ -41,11 +41,11 @@ typedef struct PulseData { AVClass *class; char *server; char *name; - char *dev; char *stream_name; int sample_rate; int channels; int frame_size; + int fragment_size; pa_simple *s; int64_t pts; } PulseData; @@ -72,6 +72,7 @@ static av_cold int pulse_read_header(AVFormatContext *s, { PulseData *pd = s->priv_data; AVStream *st; + char *device = NULL; int ret; enum CodecID codec_id = s->audio_codec_id == CODEC_ID_NONE ? DEFAULT_CODEC_ID : s->audio_codec_id; @@ -88,12 +89,16 @@ static av_cold int pulse_read_header(AVFormatContext *s, return AVERROR(ENOMEM); } - attr.fragsize = pd->frame_size * 4; + attr.fragsize = pd->fragment_size; + + if (strcmp(s->filename, "default")) + device = s->filename; pd->s = pa_simple_new(pd->server, pd->name, PA_STREAM_RECORD, - pd->dev, pd->stream_name, &ss, + device, pd->stream_name, &ss, NULL, &attr, &ret); + if (!pd->s) { av_log(s, AV_LOG_ERROR, "pa_simple_new failed: %s\n", pa_strerror(ret)); @@ -106,6 +111,8 @@ static av_cold int pulse_read_header(AVFormatContext *s, st->codec->channels = pd->channels; av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ + pd->pts = AV_NOPTS_VALUE; + return 0; } @@ -113,7 +120,7 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) { PulseData *pd = s->priv_data; int res; - pa_usec_t latency, cur; + pa_usec_t latency; uint64_t frame_duration = (pd->frame_size*1000000LL)/(pd->sample_rate * pd->channels); @@ -121,8 +128,6 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(ENOMEM); } - cur = pa_rtclock_now(); - if ((pa_simple_read(pd->s, pkt->data, pkt->size, &res)) < 0) { av_log(s, AV_LOG_ERROR, "pa_simple_read failed: %s\n", pa_strerror(res)); @@ -136,16 +141,12 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EIO); } - if (!pd->pts) { - pd->pts -= latency; + if (pd->pts == AV_NOPTS_VALUE) { + pd->pts = -latency; } pd->pts += frame_duration; - av_log(s, AV_LOG_DEBUG, "%"PRId64" time %"PRId64"," - " latency %"PRId64", %"PRId64"\n", - av_gettime(), cur, latency, pd->pts); - pkt->pts = pd->pts; return 0; @@ -162,13 +163,20 @@ static av_cold int pulse_close(AVFormatContext *s) #define D AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { - { "server", "pulse server name", 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 }, - { "dev", "device to use", OFFSET(dev), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D }, - { "stream_name", "stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D }, - { "sample_rate", "", 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 }, + { "server", "pulse server name", + 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 }, + { "stream_name", "stream description", + OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D }, + { "sample_rate", "", + 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 }, };