FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavdevice
alsa-audio-dec.c
Go to the documentation of this file.
1
/*
2
* ALSA input and output
3
* Copyright (c) 2007 Luca Abeni ( lucabe72 email it )
4
* Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr )
5
*
6
* This file is part of FFmpeg.
7
*
8
* FFmpeg is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2.1 of the License, or (at your option) any later version.
12
*
13
* FFmpeg is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
17
*
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with FFmpeg; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
*/
22
23
/**
24
* @file
25
* ALSA input and output: input
26
* @author Luca Abeni ( lucabe72 email it )
27
* @author Benoit Fouet ( benoit fouet free fr )
28
* @author Nicolas George ( nicolas george normalesup org )
29
*
30
* This avdevice decoder allows to capture audio from an ALSA (Advanced
31
* Linux Sound Architecture) device.
32
*
33
* The filename parameter is the name of an ALSA PCM device capable of
34
* capture, for example "default" or "plughw:1"; see the ALSA documentation
35
* for naming conventions. The empty string is equivalent to "default".
36
*
37
* The capture period is set to the lower value available for the device,
38
* which gives a low latency suitable for real-time capture.
39
*
40
* The PTS are an Unix time in microsecond.
41
*
42
* Due to a bug in the ALSA library
43
* (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4308), this
44
* decoder does not work with certain ALSA plugins, especially the dsnoop
45
* plugin.
46
*/
47
48
#include <alsa/asoundlib.h>
49
#include "
libavformat/internal.h
"
50
#include "
libavutil/opt.h
"
51
#include "
libavutil/mathematics.h
"
52
53
#include "
avdevice.h
"
54
#include "
alsa-audio.h
"
55
56
static
av_cold
int
audio_read_header
(
AVFormatContext
*
s1
)
57
{
58
AlsaData
*s = s1->
priv_data
;
59
AVStream
*st;
60
int
ret;
61
enum
AVCodecID
codec_id
;
62
63
st =
avformat_new_stream
(s1,
NULL
);
64
if
(!st) {
65
av_log
(s1,
AV_LOG_ERROR
,
"Cannot add stream\n"
);
66
67
return
AVERROR
(ENOMEM);
68
}
69
codec_id = s1->
audio_codec_id
;
70
71
ret =
ff_alsa_open
(s1, SND_PCM_STREAM_CAPTURE, &s->
sample_rate
, s->
channels
,
72
&codec_id);
73
if
(ret < 0) {
74
return
AVERROR
(EIO);
75
}
76
77
/* take real parameters */
78
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
79
st->
codec
->
codec_id
=
codec_id
;
80
st->
codec
->
sample_rate
= s->
sample_rate
;
81
st->
codec
->
channels
= s->
channels
;
82
avpriv_set_pts_info
(st, 64, 1, 1000000);
/* 64 bits pts in us */
83
/* microseconds instead of seconds, MHz instead of Hz */
84
s->
timefilter
=
ff_timefilter_new
(1000000.0 / s->
sample_rate
,
85
s->
period_size
, 1.5E-6);
86
if
(!s->
timefilter
)
87
goto
fail;
88
89
return
0;
90
91
fail:
92
snd_pcm_close(s->
h
);
93
return
AVERROR
(EIO);
94
}
95
96
static
int
audio_read_packet
(
AVFormatContext
*
s1
,
AVPacket
*
pkt
)
97
{
98
AlsaData
*s = s1->
priv_data
;
99
int
res;
100
int64_t dts;
101
snd_pcm_sframes_t delay = 0;
102
103
if
(
av_new_packet
(pkt, s->
period_size
* s->
frame_size
) < 0) {
104
return
AVERROR
(EIO);
105
}
106
107
while
((res = snd_pcm_readi(s->
h
, pkt->
data
, s->
period_size
)) < 0) {
108
if
(res == -EAGAIN) {
109
av_free_packet
(pkt);
110
111
return
AVERROR
(EAGAIN);
112
}
113
if
(
ff_alsa_xrun_recover
(s1, res) < 0) {
114
av_log
(s1,
AV_LOG_ERROR
,
"ALSA read error: %s\n"
,
115
snd_strerror(res));
116
av_free_packet
(pkt);
117
118
return
AVERROR
(EIO);
119
}
120
ff_timefilter_reset
(s->
timefilter
);
121
}
122
123
dts =
av_gettime
();
124
snd_pcm_delay(s->
h
, &delay);
125
dts -=
av_rescale
(delay + res, 1000000, s->
sample_rate
);
126
pkt->
pts
=
ff_timefilter_update
(s->
timefilter
, dts, s->
last_period
);
127
s->
last_period
= res;
128
129
pkt->
size
= res * s->
frame_size
;
130
131
return
0;
132
}
133
134
static
const
AVOption
options
[] = {
135
{
"sample_rate"
,
""
, offsetof(
AlsaData
,
sample_rate
),
AV_OPT_TYPE_INT
, {.i64 = 48000}, 1, INT_MAX,
AV_OPT_FLAG_DECODING_PARAM
},
136
{
"channels"
,
""
, offsetof(
AlsaData
, channels),
AV_OPT_TYPE_INT
, {.i64 = 2}, 1, INT_MAX,
AV_OPT_FLAG_DECODING_PARAM
},
137
{
NULL
},
138
};
139
140
static
const
AVClass
alsa_demuxer_class
= {
141
.
class_name
=
"ALSA demuxer"
,
142
.item_name =
av_default_item_name
,
143
.option =
options
,
144
.version =
LIBAVUTIL_VERSION_INT
,
145
};
146
147
AVInputFormat
ff_alsa_demuxer
= {
148
.
name
=
"alsa"
,
149
.long_name =
NULL_IF_CONFIG_SMALL
(
"ALSA audio input"
),
150
.priv_data_size =
sizeof
(
AlsaData
),
151
.
read_header
=
audio_read_header
,
152
.
read_packet
=
audio_read_packet
,
153
.
read_close
=
ff_alsa_close
,
154
.
flags
=
AVFMT_NOFILE
,
155
.priv_class = &alsa_demuxer_class,
156
};
Generated on Sat May 25 2013 03:58:43 for FFmpeg by
1.8.2