FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
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
#include "
libavutil/time.h
"
53
54
#include "
avdevice.h
"
55
#include "
alsa-audio.h
"
56
57
static
av_cold
int
audio_read_header
(
AVFormatContext
*
s1
)
58
{
59
AlsaData
*
s
= s1->
priv_data
;
60
AVStream
*st;
61
int
ret
;
62
enum
AVCodecID
codec_id
;
63
64
st =
avformat_new_stream
(s1,
NULL
);
65
if
(!st) {
66
av_log
(s1,
AV_LOG_ERROR
,
"Cannot add stream\n"
);
67
68
return
AVERROR
(ENOMEM);
69
}
70
codec_id = s1->
audio_codec_id
;
71
72
ret =
ff_alsa_open
(s1, SND_PCM_STREAM_CAPTURE, &s->
sample_rate
, s->
channels
,
73
&codec_id);
74
if
(ret < 0) {
75
return
AVERROR
(EIO);
76
}
77
78
/* take real parameters */
79
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
80
st->
codec
->
codec_id
=
codec_id
;
81
st->
codec
->
sample_rate
= s->
sample_rate
;
82
st->
codec
->
channels
= s->
channels
;
83
st->
codec
->
frame_size
= s->
frame_size
;
84
avpriv_set_pts_info
(st, 64, 1, 1000000);
/* 64 bits pts in us */
85
/* microseconds instead of seconds, MHz instead of Hz */
86
s->
timefilter
=
ff_timefilter_new
(1000000.0 / s->
sample_rate
,
87
s->
period_size
, 1.5E-6);
88
if
(!s->
timefilter
)
89
goto
fail;
90
91
return
0;
92
93
fail:
94
snd_pcm_close(s->
h
);
95
return
AVERROR
(EIO);
96
}
97
98
static
int
audio_read_packet
(
AVFormatContext
*
s1
,
AVPacket
*
pkt
)
99
{
100
AlsaData
*
s
= s1->
priv_data
;
101
int
res;
102
int64_t dts;
103
snd_pcm_sframes_t delay = 0;
104
105
if
(
av_new_packet
(pkt, s->
period_size
* s->
frame_size
) < 0) {
106
return
AVERROR
(EIO);
107
}
108
109
while
((res = snd_pcm_readi(s->
h
, pkt->
data
, s->
period_size
)) < 0) {
110
if
(res == -EAGAIN) {
111
av_free_packet
(pkt);
112
113
return
AVERROR
(EAGAIN);
114
}
115
if
(
ff_alsa_xrun_recover
(s1, res) < 0) {
116
av_log
(s1,
AV_LOG_ERROR
,
"ALSA read error: %s\n"
,
117
snd_strerror(res));
118
av_free_packet
(pkt);
119
120
return
AVERROR
(EIO);
121
}
122
ff_timefilter_reset
(s->
timefilter
);
123
}
124
125
dts =
av_gettime
();
126
snd_pcm_delay(s->
h
, &delay);
127
dts -=
av_rescale
(delay + res, 1000000, s->
sample_rate
);
128
pkt->
pts
=
ff_timefilter_update
(s->
timefilter
, dts, s->
last_period
);
129
s->
last_period
= res;
130
131
pkt->
size
= res * s->
frame_size
;
132
133
return
0;
134
}
135
136
static
int
audio_get_device_list
(
AVFormatContext
*h,
AVDeviceInfoList
*device_list)
137
{
138
return
ff_alsa_get_device_list
(device_list, SND_PCM_STREAM_CAPTURE);
139
}
140
141
static
const
AVOption
options
[] = {
142
{
"sample_rate"
,
""
, offsetof(
AlsaData
,
sample_rate
),
AV_OPT_TYPE_INT
, {.i64 = 48000}, 1, INT_MAX,
AV_OPT_FLAG_DECODING_PARAM
},
143
{
"channels"
,
""
, offsetof(
AlsaData
, channels),
AV_OPT_TYPE_INT
, {.i64 = 2}, 1, INT_MAX,
AV_OPT_FLAG_DECODING_PARAM
},
144
{
NULL
},
145
};
146
147
static
const
AVClass
alsa_demuxer_class
= {
148
.
class_name
=
"ALSA demuxer"
,
149
.item_name =
av_default_item_name
,
150
.option =
options
,
151
.version =
LIBAVUTIL_VERSION_INT
,
152
.category =
AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT
,
153
};
154
155
AVInputFormat
ff_alsa_demuxer
= {
156
.
name
=
"alsa"
,
157
.long_name =
NULL_IF_CONFIG_SMALL
(
"ALSA audio input"
),
158
.priv_data_size =
sizeof
(
AlsaData
),
159
.
read_header
=
audio_read_header
,
160
.
read_packet
=
audio_read_packet
,
161
.
read_close
=
ff_alsa_close
,
162
.
get_device_list
=
audio_get_device_list
,
163
.
flags
=
AVFMT_NOFILE
,
164
.priv_class = &alsa_demuxer_class,
165
};
Generated on Sun Mar 8 2015 02:35:04 for FFmpeg by
1.8.2