* qatar/master:
lavc: remove "legacy" mpegvideo decoder.
iv8: assemble packets to return complete frames
pulse: documentation
pulse: introduce pulseaudio input
remove the zork pcm seek test
Conflicts:
configure
libavdevice/Makefile
libavdevice/alldevices.c
libavdevice/avdevice.h
libavdevice/pulse.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
| ... | ... |
@@ -390,6 +390,89 @@ ffmpeg -f oss -i /dev/dsp /tmp/oss.wav |
| 390 | 390 |
For more information about OSS see: |
| 391 | 391 |
@url{http://manuals.opensound.com/usersguide/dsp.html}
|
| 392 | 392 |
|
| 393 |
+@section pulse |
|
| 394 |
+ |
|
| 395 |
+pulseaudio input device. |
|
| 396 |
+ |
|
| 397 |
+To enable this input device during configuration you need libpulse-simple |
|
| 398 |
+installed in your system. |
|
| 399 |
+ |
|
| 400 |
+The filename to provide to the input device is a source device or the |
|
| 401 |
+string "default" |
|
| 402 |
+ |
|
| 403 |
+To list the pulse source devices and their properties you can invoke |
|
| 404 |
+the command @file{pactl list sources}.
|
|
| 405 |
+ |
|
| 406 |
+@example |
|
| 407 |
+avconv -f pulse -i default /tmp/pulse.wav |
|
| 408 |
+@end example |
|
| 409 |
+ |
|
| 410 |
+@subsection @var{server} AVOption
|
|
| 411 |
+ |
|
| 412 |
+The syntax is: |
|
| 413 |
+@example |
|
| 414 |
+-server @var{server name}
|
|
| 415 |
+@end example |
|
| 416 |
+ |
|
| 417 |
+Connects to a specific server. |
|
| 418 |
+ |
|
| 419 |
+@subsection @var{name} AVOption
|
|
| 420 |
+ |
|
| 421 |
+The syntax is: |
|
| 422 |
+@example |
|
| 423 |
+-name @var{application name}
|
|
| 424 |
+@end example |
|
| 425 |
+ |
|
| 426 |
+Specify the application name pulse will use when showing active clients, |
|
| 427 |
+by default it is "libav" |
|
| 428 |
+ |
|
| 429 |
+@subsection @var{stream_name} AVOption
|
|
| 430 |
+ |
|
| 431 |
+The syntax is: |
|
| 432 |
+@example |
|
| 433 |
+-stream_name @var{stream name}
|
|
| 434 |
+@end example |
|
| 435 |
+ |
|
| 436 |
+Specify the stream name pulse will use when showing active streams, |
|
| 437 |
+by default it is "record" |
|
| 438 |
+ |
|
| 439 |
+@subsection @var{sample_rate} AVOption
|
|
| 440 |
+ |
|
| 441 |
+The syntax is: |
|
| 442 |
+@example |
|
| 443 |
+-sample_rate @var{samplerate}
|
|
| 444 |
+@end example |
|
| 445 |
+ |
|
| 446 |
+Specify the samplerate in Hz, by default 48kHz is used. |
|
| 447 |
+ |
|
| 448 |
+@subsection @var{channels} AVOption
|
|
| 449 |
+ |
|
| 450 |
+The syntax is: |
|
| 451 |
+@example |
|
| 452 |
+-channels @var{N}
|
|
| 453 |
+@end example |
|
| 454 |
+ |
|
| 455 |
+Specify the channels in use, by default 2 (stereo) is set. |
|
| 456 |
+ |
|
| 457 |
+@subsection @var{frame_size} AVOption
|
|
| 458 |
+ |
|
| 459 |
+The syntax is: |
|
| 460 |
+@example |
|
| 461 |
+-frame_size @var{bytes}
|
|
| 462 |
+@end example |
|
| 463 |
+ |
|
| 464 |
+Specify the number of byte per frame, by default it is set to 1024. |
|
| 465 |
+ |
|
| 466 |
+@subsection @var{fragment_size} AVOption
|
|
| 467 |
+ |
|
| 468 |
+The syntax is: |
|
| 469 |
+@example |
|
| 470 |
+-fragment_size @var{bytes}
|
|
| 471 |
+@end example |
|
| 472 |
+ |
|
| 473 |
+Specify the minimal buffering fragment in pulseaudio, it will affect the |
|
| 474 |
+audio latency. By default it is unset. |
|
| 475 |
+ |
|
| 393 | 476 |
@section sndio |
| 394 | 477 |
|
| 395 | 478 |
sndio input device. |
| ... | ... |
@@ -21,11 +21,9 @@ |
| 21 | 21 |
|
| 22 | 22 |
/** |
| 23 | 23 |
* @file |
| 24 |
- * Pulseaudio input |
|
| 24 |
+ * PulseAudio input using the simple API. |
|
| 25 | 25 |
* @author Luca Barbato <lu_zero@gentoo.org> |
| 26 | 26 |
* |
| 27 |
- * This avdevice decoder allows to capture audio from a Pulseaudio device using |
|
| 28 |
- * the simple api. |
|
| 29 | 27 |
*/ |
| 30 | 28 |
|
| 31 | 29 |
#include <pulse/simple.h> |
| ... | ... |
@@ -95,9 +93,9 @@ static av_cold int pulse_read_header(AVFormatContext *s, |
| 95 | 95 |
device = s->filename; |
| 96 | 96 |
|
| 97 | 97 |
pd->s = pa_simple_new(pd->server, pd->name, |
| 98 |
- PA_STREAM_RECORD, |
|
| 99 |
- device, pd->stream_name, &ss, |
|
| 100 |
- NULL, &attr, &ret); |
|
| 98 |
+ PA_STREAM_RECORD, |
|
| 99 |
+ device, pd->stream_name, &ss, |
|
| 100 |
+ NULL, &attr, &ret); |
|
| 101 | 101 |
|
| 102 | 102 |
if (!pd->s) {
|
| 103 | 103 |
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) |
| 122 | 122 |
int res; |
| 123 | 123 |
pa_usec_t latency; |
| 124 | 124 |
uint64_t frame_duration = |
| 125 |
- (pd->frame_size*1000000LL)/(pd->sample_rate * pd->channels); |
|
| 125 |
+ (pd->frame_size*1000000LL) / (pd->sample_rate * pd->channels); |
|
| 126 | 126 |
|
| 127 | 127 |
if (av_new_packet(pkt, pd->frame_size) < 0) {
|
| 128 | 128 |
return AVERROR(ENOMEM); |
| ... | ... |
@@ -145,10 +143,10 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt) |
| 145 | 145 |
pd->pts = -latency; |
| 146 | 146 |
} |
| 147 | 147 |
|
| 148 |
- pd->pts += frame_duration; |
|
| 149 |
- |
|
| 150 | 148 |
pkt->pts = pd->pts; |
| 151 | 149 |
|
| 150 |
+ pd->pts += frame_duration; |
|
| 151 |
+ |
|
| 152 | 152 |
return 0; |
| 153 | 153 |
} |
| 154 | 154 |
|
| ... | ... |
@@ -163,20 +161,13 @@ static av_cold int pulse_close(AVFormatContext *s) |
| 163 | 163 |
#define D AV_OPT_FLAG_DECODING_PARAM |
| 164 | 164 |
|
| 165 | 165 |
static const AVOption options[] = {
|
| 166 |
- { "server", "pulse server name",
|
|
| 167 |
- OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D },
|
|
| 168 |
- { "name", "application name",
|
|
| 169 |
- OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, D },
|
|
| 170 |
- { "stream_name", "stream description",
|
|
| 171 |
- OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D },
|
|
| 172 |
- { "sample_rate", "",
|
|
| 173 |
- OFFSET(sample_rate), AV_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, D },
|
|
| 174 |
- { "channels", "",
|
|
| 175 |
- OFFSET(channels), AV_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, D },
|
|
| 176 |
- { "frame_size", "",
|
|
| 177 |
- OFFSET(frame_size), AV_OPT_TYPE_INT, {.dbl = 1024}, 1, INT_MAX, D },
|
|
| 178 |
- { "fragment_size", "buffering size, affects latency and cpu usage",
|
|
| 179 |
- OFFSET(fragment_size), AV_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX, D },
|
|
| 166 |
+ { "server", "pulse server name", OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D },
|
|
| 167 |
+ { "name", "application name", OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, D },
|
|
| 168 |
+ { "stream_name", "stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D },
|
|
| 169 |
+ { "sample_rate", "sample rate in Hz", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, D },
|
|
| 170 |
+ { "channels", "number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, D },
|
|
| 171 |
+ { "frame_size", "number of bytes per frame", OFFSET(frame_size), AV_OPT_TYPE_INT, {.dbl = 1024}, 1, INT_MAX, D },
|
|
| 172 |
+ { "fragment_size", "buffering size, affects latency and cpu usage", OFFSET(fragment_size), AV_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX, D },
|
|
| 180 | 173 |
{ NULL },
|
| 181 | 174 |
}; |
| 182 | 175 |
|
| ... | ... |
@@ -55,33 +55,56 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap) |
| 55 | 55 |
|
| 56 | 56 |
static int read_packet(AVFormatContext *s, AVPacket *pkt) |
| 57 | 57 |
{
|
| 58 |
- int ret, size, pts, type; |
|
| 59 |
-retry: |
|
| 60 |
- type= avio_rb16(s->pb); // 257 or 258 |
|
| 61 |
- size= avio_rb16(s->pb); |
|
| 62 |
- |
|
| 63 |
- avio_rb16(s->pb); //some flags, 0x80 indicates end of frame |
|
| 64 |
- avio_rb16(s->pb); //packet number |
|
| 65 |
- pts=avio_rb32(s->pb); |
|
| 66 |
- avio_rb32(s->pb); //6A 13 E3 88 |
|
| 67 |
- |
|
| 68 |
- size -= 12; |
|
| 69 |
- if(size<1) |
|
| 70 |
- return -1; |
|
| 71 |
- |
|
| 72 |
- if(type==258){
|
|
| 73 |
- avio_skip(s->pb, size); |
|
| 74 |
- goto retry; |
|
| 58 |
+ int ret, size, pts, type, flags; |
|
| 59 |
+ int first_pkt = 0; |
|
| 60 |
+ int frame_complete = 0; |
|
| 61 |
+ |
|
| 62 |
+ while (!frame_complete) {
|
|
| 63 |
+ |
|
| 64 |
+ type = avio_rb16(s->pb); // 257 or 258 |
|
| 65 |
+ size = avio_rb16(s->pb); |
|
| 66 |
+ flags = avio_rb16(s->pb); //some flags, 0x80 indicates end of frame |
|
| 67 |
+ avio_rb16(s->pb); //packet number |
|
| 68 |
+ pts = avio_rb32(s->pb); |
|
| 69 |
+ avio_rb32(s->pb); //6A 13 E3 88 |
|
| 70 |
+ |
|
| 71 |
+ frame_complete = flags & 0x80; |
|
| 72 |
+ |
|
| 73 |
+ size -= 12; |
|
| 74 |
+ if (size < 1) |
|
| 75 |
+ return -1; |
|
| 76 |
+ |
|
| 77 |
+ if (type == 258) {
|
|
| 78 |
+ avio_skip(s->pb, size); |
|
| 79 |
+ frame_complete = 0; |
|
| 80 |
+ continue; |
|
| 81 |
+ } |
|
| 82 |
+ |
|
| 83 |
+ if (!first_pkt) {
|
|
| 84 |
+ ret = av_get_packet(s->pb, pkt, size); |
|
| 85 |
+ if (ret < 0) |
|
| 86 |
+ return ret; |
|
| 87 |
+ first_pkt = 1; |
|
| 88 |
+ pkt->pts = pts; |
|
| 89 |
+ pkt->pos -= 16; |
|
| 90 |
+ } else {
|
|
| 91 |
+ ret = av_append_packet(s->pb, pkt, size); |
|
| 92 |
+ if (ret < 0) {
|
|
| 93 |
+ av_log(s, AV_LOG_ERROR, "failed to grow packet\n"); |
|
| 94 |
+ av_free_packet(pkt); |
|
| 95 |
+ return ret; |
|
| 96 |
+ } |
|
| 97 |
+ } |
|
| 98 |
+ if (ret < size) {
|
|
| 99 |
+ av_log(s, AV_LOG_ERROR, "Truncated packet! Read %d of %d bytes\n", |
|
| 100 |
+ ret, size); |
|
| 101 |
+ pkt->flags |= AV_PKT_FLAG_CORRUPT; |
|
| 102 |
+ break; |
|
| 103 |
+ } |
|
| 75 | 104 |
} |
| 76 |
- |
|
| 77 |
- ret= av_get_packet(s->pb, pkt, size); |
|
| 78 |
- |
|
| 79 |
- pkt->pts= pts; |
|
| 80 |
- pkt->pos-=16; |
|
| 81 |
- |
|
| 82 | 105 |
pkt->stream_index = 0; |
| 83 | 106 |
|
| 84 |
- return ret; |
|
| 107 |
+ return 0; |
|
| 85 | 108 |
} |
| 86 | 109 |
|
| 87 | 110 |
AVInputFormat ff_iv8_demuxer = {
|