summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/indevs.texi83
-rw-r--r--libavdevice/pulse.c37
-rw-r--r--libavformat/iv8.c71
3 files changed, 144 insertions, 47 deletions
diff --git a/doc/indevs.texi b/doc/indevs.texi
index 63a543057e..a456deffbe 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -390,6 +390,89 @@ ffmpeg -f oss -i /dev/dsp /tmp/oss.wav
For more information about OSS see:
@url{http://manuals.opensound.com/usersguide/dsp.html}
+@section pulse
+
+pulseaudio input device.
+
+To enable this input device during configuration you need libpulse-simple
+installed in your system.
+
+The filename to provide to the input device is a source device or the
+string "default"
+
+To list the pulse source devices and their properties you can invoke
+the command @file{pactl list sources}.
+
+@example
+avconv -f pulse -i default /tmp/pulse.wav
+@end example
+
+@subsection @var{server} AVOption
+
+The syntax is:
+@example
+-server @var{server name}
+@end example
+
+Connects to a specific server.
+
+@subsection @var{name} AVOption
+
+The syntax is:
+@example
+-name @var{application name}
+@end example
+
+Specify the application name pulse will use when showing active clients,
+by default it is "libav"
+
+@subsection @var{stream_name} AVOption
+
+The syntax is:
+@example
+-stream_name @var{stream name}
+@end example
+
+Specify the stream name pulse will use when showing active streams,
+by default it is "record"
+
+@subsection @var{sample_rate} AVOption
+
+The syntax is:
+@example
+-sample_rate @var{samplerate}
+@end example
+
+Specify the samplerate in Hz, by default 48kHz is used.
+
+@subsection @var{channels} AVOption
+
+The syntax is:
+@example
+-channels @var{N}
+@end example
+
+Specify the channels in use, by default 2 (stereo) is set.
+
+@subsection @var{frame_size} AVOption
+
+The syntax is:
+@example
+-frame_size @var{bytes}
+@end example
+
+Specify the number of byte per frame, by default it is set to 1024.
+
+@subsection @var{fragment_size} AVOption
+
+The syntax is:
+@example
+-fragment_size @var{bytes}
+@end example
+
+Specify the minimal buffering fragment in pulseaudio, it will affect the
+audio latency. By default it is unset.
+
@section sndio
sndio input device.
diff --git a/libavdevice/pulse.c b/libavdevice/pulse.c
index 56ae323856..79da7a6bfb 100644
--- a/libavdevice/pulse.c
+++ b/libavdevice/pulse.c
@@ -21,11 +21,9 @@
/**
* @file
- * Pulseaudio input
+ * PulseAudio input using the simple API.
* @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>
@@ -95,9 +93,9 @@ static av_cold int pulse_read_header(AVFormatContext *s,
device = s->filename;
pd->s = pa_simple_new(pd->server, pd->name,
- PA_STREAM_RECORD,
- device, pd->stream_name, &ss,
- NULL, &attr, &ret);
+ PA_STREAM_RECORD,
+ device, pd->stream_name, &ss,
+ NULL, &attr, &ret);
if (!pd->s) {
av_log(s, AV_LOG_ERROR, "pa_simple_new failed: %s\n",
@@ -122,7 +120,7 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt)
int res;
pa_usec_t latency;
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) {
return AVERROR(ENOMEM);
@@ -145,10 +143,10 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt)
pd->pts = -latency;
}
- pd->pts += frame_duration;
-
pkt->pts = pd->pts;
+ pd->pts += frame_duration;
+
return 0;
}
@@ -163,20 +161,13 @@ 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 },
- { "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 },
+ { "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", "sample rate in Hz", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, D },
+ { "channels", "number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, D },
+ { "frame_size", "number of bytes per frame", 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 },
};
diff --git a/libavformat/iv8.c b/libavformat/iv8.c
index 03593982bf..1db4c0325a 100644
--- a/libavformat/iv8.c
+++ b/libavformat/iv8.c
@@ -55,33 +55,56 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
- int ret, size, pts, type;
-retry:
- type= avio_rb16(s->pb); // 257 or 258
- size= avio_rb16(s->pb);
-
- avio_rb16(s->pb); //some flags, 0x80 indicates end of frame
- avio_rb16(s->pb); //packet number
- pts=avio_rb32(s->pb);
- avio_rb32(s->pb); //6A 13 E3 88
-
- size -= 12;
- if(size<1)
- return -1;
-
- if(type==258){
- avio_skip(s->pb, size);
- goto retry;
+ int ret, size, pts, type, flags;
+ int first_pkt = 0;
+ int frame_complete = 0;
+
+ while (!frame_complete) {
+
+ type = avio_rb16(s->pb); // 257 or 258
+ size = avio_rb16(s->pb);
+ flags = avio_rb16(s->pb); //some flags, 0x80 indicates end of frame
+ avio_rb16(s->pb); //packet number
+ pts = avio_rb32(s->pb);
+ avio_rb32(s->pb); //6A 13 E3 88
+
+ frame_complete = flags & 0x80;
+
+ size -= 12;
+ if (size < 1)
+ return -1;
+
+ if (type == 258) {
+ avio_skip(s->pb, size);
+ frame_complete = 0;
+ continue;
+ }
+
+ if (!first_pkt) {
+ ret = av_get_packet(s->pb, pkt, size);
+ if (ret < 0)
+ return ret;
+ first_pkt = 1;
+ pkt->pts = pts;
+ pkt->pos -= 16;
+ } else {
+ ret = av_append_packet(s->pb, pkt, size);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "failed to grow packet\n");
+ av_free_packet(pkt);
+ return ret;
+ }
+ }
+ if (ret < size) {
+ av_log(s, AV_LOG_ERROR, "Truncated packet! Read %d of %d bytes\n",
+ ret, size);
+ pkt->flags |= AV_PKT_FLAG_CORRUPT;
+ break;
+ }
}
-
- ret= av_get_packet(s->pb, pkt, size);
-
- pkt->pts= pts;
- pkt->pos-=16;
-
pkt->stream_index = 0;
- return ret;
+ return 0;
}
AVInputFormat ff_iv8_demuxer = {