Commit c2553a55 authored by Michael Niedermayer's avatar Michael Niedermayer

Merge remote-tracking branch 'luzero/pulse'

* luzero/pulse:
  pulse: set the device from the avformat filename

Conflicts:
	libavdevice/pulse.c
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 4ffed61b 94619d5e
...@@ -41,11 +41,11 @@ typedef struct PulseData { ...@@ -41,11 +41,11 @@ typedef struct PulseData {
AVClass *class; AVClass *class;
char *server; char *server;
char *name; char *name;
char *dev;
char *stream_name; char *stream_name;
int sample_rate; int sample_rate;
int channels; int channels;
int frame_size; int frame_size;
int fragment_size;
pa_simple *s; pa_simple *s;
int64_t pts; int64_t pts;
} PulseData; } PulseData;
...@@ -72,6 +72,7 @@ static av_cold int pulse_read_header(AVFormatContext *s, ...@@ -72,6 +72,7 @@ static av_cold int pulse_read_header(AVFormatContext *s,
{ {
PulseData *pd = s->priv_data; PulseData *pd = s->priv_data;
AVStream *st; AVStream *st;
char *device = NULL;
int ret; int ret;
enum CodecID codec_id = enum CodecID codec_id =
s->audio_codec_id == CODEC_ID_NONE ? DEFAULT_CODEC_ID : s->audio_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, ...@@ -88,12 +89,16 @@ static av_cold int pulse_read_header(AVFormatContext *s,
return AVERROR(ENOMEM); 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, pd->s = pa_simple_new(pd->server, pd->name,
PA_STREAM_RECORD, PA_STREAM_RECORD,
pd->dev, pd->stream_name, &ss, device, pd->stream_name, &ss,
NULL, &attr, &ret); NULL, &attr, &ret);
if (!pd->s) { if (!pd->s) {
av_log(s, AV_LOG_ERROR, "pa_simple_new failed: %s\n", av_log(s, AV_LOG_ERROR, "pa_simple_new failed: %s\n",
pa_strerror(ret)); pa_strerror(ret));
...@@ -106,6 +111,8 @@ static av_cold int pulse_read_header(AVFormatContext *s, ...@@ -106,6 +111,8 @@ static av_cold int pulse_read_header(AVFormatContext *s,
st->codec->channels = pd->channels; st->codec->channels = pd->channels;
av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
pd->pts = AV_NOPTS_VALUE;
return 0; return 0;
} }
...@@ -113,7 +120,7 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -113,7 +120,7 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt)
{ {
PulseData *pd = s->priv_data; PulseData *pd = s->priv_data;
int res; int res;
pa_usec_t latency, cur; 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);
...@@ -121,8 +128,6 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -121,8 +128,6 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
cur = pa_rtclock_now();
if ((pa_simple_read(pd->s, pkt->data, pkt->size, &res)) < 0) { if ((pa_simple_read(pd->s, pkt->data, pkt->size, &res)) < 0) {
av_log(s, AV_LOG_ERROR, "pa_simple_read failed: %s\n", av_log(s, AV_LOG_ERROR, "pa_simple_read failed: %s\n",
pa_strerror(res)); pa_strerror(res));
...@@ -136,16 +141,12 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -136,16 +141,12 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(EIO); return AVERROR(EIO);
} }
if (!pd->pts) { if (pd->pts == AV_NOPTS_VALUE) {
pd->pts -= latency; pd->pts = -latency;
} }
pd->pts += frame_duration; 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; pkt->pts = pd->pts;
return 0; return 0;
...@@ -162,13 +163,20 @@ static av_cold int pulse_close(AVFormatContext *s) ...@@ -162,13 +163,20 @@ 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", OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D }, { "server", "pulse server name",
{ "name", "application name", OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, D }, OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D },
{ "dev", "device to use", OFFSET(dev), AV_OPT_TYPE_STRING, {.str = NULL}, 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", "", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, D }, { "stream_name", "stream description",
{ "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", "", OFFSET(frame_size), AV_OPT_TYPE_INT, {.dbl = 1024}, 1, INT_MAX, 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 }, { NULL },
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment