Commit | Line | Data |
---|---|---|
2ba45a60 DM |
1 | /* |
2 | * JACK Audio Connection Kit input device | |
3 | * Copyright (c) 2009 Samalyse | |
4 | * Author: Olivier Guilyardi <olivier samalyse com> | |
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 | #include "config.h" | |
24 | #include <semaphore.h> | |
25 | #include <jack/jack.h> | |
26 | ||
27 | #include "libavutil/log.h" | |
28 | #include "libavutil/fifo.h" | |
29 | #include "libavutil/opt.h" | |
30 | #include "libavutil/time.h" | |
31 | #include "libavcodec/avcodec.h" | |
32 | #include "libavformat/avformat.h" | |
33 | #include "libavformat/internal.h" | |
34 | #include "timefilter.h" | |
35 | #include "avdevice.h" | |
36 | ||
37 | /** | |
38 | * Size of the internal FIFO buffers as a number of audio packets | |
39 | */ | |
40 | #define FIFO_PACKETS_NUM 16 | |
41 | ||
42 | typedef struct JackData { | |
43 | AVClass *class; | |
44 | jack_client_t * client; | |
45 | int activated; | |
46 | sem_t packet_count; | |
47 | jack_nframes_t sample_rate; | |
48 | jack_nframes_t buffer_size; | |
49 | jack_port_t ** ports; | |
50 | int nports; | |
51 | TimeFilter * timefilter; | |
52 | AVFifoBuffer * new_pkts; | |
53 | AVFifoBuffer * filled_pkts; | |
54 | int pkt_xrun; | |
55 | int jack_xrun; | |
56 | } JackData; | |
57 | ||
58 | static int process_callback(jack_nframes_t nframes, void *arg) | |
59 | { | |
60 | /* Warning: this function runs in realtime. One mustn't allocate memory here | |
61 | * or do any other thing that could block. */ | |
62 | ||
63 | int i, j; | |
64 | JackData *self = arg; | |
65 | float * buffer; | |
66 | jack_nframes_t latency, cycle_delay; | |
67 | AVPacket pkt; | |
68 | float *pkt_data; | |
69 | double cycle_time; | |
70 | ||
71 | if (!self->client) | |
72 | return 0; | |
73 | ||
74 | /* The approximate delay since the hardware interrupt as a number of frames */ | |
75 | cycle_delay = jack_frames_since_cycle_start(self->client); | |
76 | ||
77 | /* Retrieve filtered cycle time */ | |
78 | cycle_time = ff_timefilter_update(self->timefilter, | |
79 | av_gettime() / 1000000.0 - (double) cycle_delay / self->sample_rate, | |
80 | self->buffer_size); | |
81 | ||
82 | /* Check if an empty packet is available, and if there's enough space to send it back once filled */ | |
83 | if ((av_fifo_size(self->new_pkts) < sizeof(pkt)) || (av_fifo_space(self->filled_pkts) < sizeof(pkt))) { | |
84 | self->pkt_xrun = 1; | |
85 | return 0; | |
86 | } | |
87 | ||
88 | /* Retrieve empty (but allocated) packet */ | |
89 | av_fifo_generic_read(self->new_pkts, &pkt, sizeof(pkt), NULL); | |
90 | ||
91 | pkt_data = (float *) pkt.data; | |
92 | latency = 0; | |
93 | ||
94 | /* Copy and interleave audio data from the JACK buffer into the packet */ | |
95 | for (i = 0; i < self->nports; i++) { | |
96 | #if HAVE_JACK_PORT_GET_LATENCY_RANGE | |
97 | jack_latency_range_t range; | |
98 | jack_port_get_latency_range(self->ports[i], JackCaptureLatency, &range); | |
99 | latency += range.max; | |
100 | #else | |
101 | latency += jack_port_get_total_latency(self->client, self->ports[i]); | |
102 | #endif | |
103 | buffer = jack_port_get_buffer(self->ports[i], self->buffer_size); | |
104 | for (j = 0; j < self->buffer_size; j++) | |
105 | pkt_data[j * self->nports + i] = buffer[j]; | |
106 | } | |
107 | ||
108 | /* Timestamp the packet with the cycle start time minus the average latency */ | |
109 | pkt.pts = (cycle_time - (double) latency / (self->nports * self->sample_rate)) * 1000000.0; | |
110 | ||
111 | /* Send the now filled packet back, and increase packet counter */ | |
112 | av_fifo_generic_write(self->filled_pkts, &pkt, sizeof(pkt), NULL); | |
113 | sem_post(&self->packet_count); | |
114 | ||
115 | return 0; | |
116 | } | |
117 | ||
118 | static void shutdown_callback(void *arg) | |
119 | { | |
120 | JackData *self = arg; | |
121 | self->client = NULL; | |
122 | } | |
123 | ||
124 | static int xrun_callback(void *arg) | |
125 | { | |
126 | JackData *self = arg; | |
127 | self->jack_xrun = 1; | |
128 | ff_timefilter_reset(self->timefilter); | |
129 | return 0; | |
130 | } | |
131 | ||
132 | static int supply_new_packets(JackData *self, AVFormatContext *context) | |
133 | { | |
134 | AVPacket pkt; | |
135 | int test, pkt_size = self->buffer_size * self->nports * sizeof(float); | |
136 | ||
137 | /* Supply the process callback with new empty packets, by filling the new | |
138 | * packets FIFO buffer with as many packets as possible. process_callback() | |
139 | * can't do this by itself, because it can't allocate memory in realtime. */ | |
140 | while (av_fifo_space(self->new_pkts) >= sizeof(pkt)) { | |
141 | if ((test = av_new_packet(&pkt, pkt_size)) < 0) { | |
142 | av_log(context, AV_LOG_ERROR, "Could not create packet of size %d\n", pkt_size); | |
143 | return test; | |
144 | } | |
145 | av_fifo_generic_write(self->new_pkts, &pkt, sizeof(pkt), NULL); | |
146 | } | |
147 | return 0; | |
148 | } | |
149 | ||
150 | static int start_jack(AVFormatContext *context) | |
151 | { | |
152 | JackData *self = context->priv_data; | |
153 | jack_status_t status; | |
154 | int i, test; | |
155 | ||
156 | /* Register as a JACK client, using the context filename as client name. */ | |
157 | self->client = jack_client_open(context->filename, JackNullOption, &status); | |
158 | if (!self->client) { | |
159 | av_log(context, AV_LOG_ERROR, "Unable to register as a JACK client\n"); | |
160 | return AVERROR(EIO); | |
161 | } | |
162 | ||
163 | sem_init(&self->packet_count, 0, 0); | |
164 | ||
165 | self->sample_rate = jack_get_sample_rate(self->client); | |
166 | self->ports = av_malloc_array(self->nports, sizeof(*self->ports)); | |
167 | self->buffer_size = jack_get_buffer_size(self->client); | |
168 | ||
169 | /* Register JACK ports */ | |
170 | for (i = 0; i < self->nports; i++) { | |
171 | char str[16]; | |
172 | snprintf(str, sizeof(str), "input_%d", i + 1); | |
173 | self->ports[i] = jack_port_register(self->client, str, | |
174 | JACK_DEFAULT_AUDIO_TYPE, | |
175 | JackPortIsInput, 0); | |
176 | if (!self->ports[i]) { | |
177 | av_log(context, AV_LOG_ERROR, "Unable to register port %s:%s\n", | |
178 | context->filename, str); | |
179 | jack_client_close(self->client); | |
180 | return AVERROR(EIO); | |
181 | } | |
182 | } | |
183 | ||
184 | /* Register JACK callbacks */ | |
185 | jack_set_process_callback(self->client, process_callback, self); | |
186 | jack_on_shutdown(self->client, shutdown_callback, self); | |
187 | jack_set_xrun_callback(self->client, xrun_callback, self); | |
188 | ||
189 | /* Create time filter */ | |
190 | self->timefilter = ff_timefilter_new (1.0 / self->sample_rate, self->buffer_size, 1.5); | |
191 | if (!self->timefilter) { | |
192 | jack_client_close(self->client); | |
193 | return AVERROR(ENOMEM); | |
194 | } | |
195 | ||
196 | /* Create FIFO buffers */ | |
197 | self->filled_pkts = av_fifo_alloc_array(FIFO_PACKETS_NUM, sizeof(AVPacket)); | |
198 | /* New packets FIFO with one extra packet for safety against underruns */ | |
199 | self->new_pkts = av_fifo_alloc_array((FIFO_PACKETS_NUM + 1), sizeof(AVPacket)); | |
200 | if ((test = supply_new_packets(self, context))) { | |
201 | jack_client_close(self->client); | |
202 | return test; | |
203 | } | |
204 | ||
205 | return 0; | |
206 | ||
207 | } | |
208 | ||
209 | static void free_pkt_fifo(AVFifoBuffer **fifo) | |
210 | { | |
211 | AVPacket pkt; | |
212 | while (av_fifo_size(*fifo)) { | |
213 | av_fifo_generic_read(*fifo, &pkt, sizeof(pkt), NULL); | |
214 | av_free_packet(&pkt); | |
215 | } | |
216 | av_fifo_freep(fifo); | |
217 | } | |
218 | ||
219 | static void stop_jack(JackData *self) | |
220 | { | |
221 | if (self->client) { | |
222 | if (self->activated) | |
223 | jack_deactivate(self->client); | |
224 | jack_client_close(self->client); | |
225 | } | |
226 | sem_destroy(&self->packet_count); | |
227 | free_pkt_fifo(&self->new_pkts); | |
228 | free_pkt_fifo(&self->filled_pkts); | |
229 | av_freep(&self->ports); | |
230 | ff_timefilter_destroy(self->timefilter); | |
231 | } | |
232 | ||
233 | static int audio_read_header(AVFormatContext *context) | |
234 | { | |
235 | JackData *self = context->priv_data; | |
236 | AVStream *stream; | |
237 | int test; | |
238 | ||
239 | if ((test = start_jack(context))) | |
240 | return test; | |
241 | ||
242 | stream = avformat_new_stream(context, NULL); | |
243 | if (!stream) { | |
244 | stop_jack(self); | |
245 | return AVERROR(ENOMEM); | |
246 | } | |
247 | ||
248 | stream->codec->codec_type = AVMEDIA_TYPE_AUDIO; | |
249 | #if HAVE_BIGENDIAN | |
250 | stream->codec->codec_id = AV_CODEC_ID_PCM_F32BE; | |
251 | #else | |
252 | stream->codec->codec_id = AV_CODEC_ID_PCM_F32LE; | |
253 | #endif | |
254 | stream->codec->sample_rate = self->sample_rate; | |
255 | stream->codec->channels = self->nports; | |
256 | ||
257 | avpriv_set_pts_info(stream, 64, 1, 1000000); /* 64 bits pts in us */ | |
258 | return 0; | |
259 | } | |
260 | ||
261 | static int audio_read_packet(AVFormatContext *context, AVPacket *pkt) | |
262 | { | |
263 | JackData *self = context->priv_data; | |
264 | struct timespec timeout = {0, 0}; | |
265 | int test; | |
266 | ||
267 | /* Activate the JACK client on first packet read. Activating the JACK client | |
268 | * means that process_callback() starts to get called at regular interval. | |
269 | * If we activate it in audio_read_header(), we're actually reading audio data | |
270 | * from the device before instructed to, and that may result in an overrun. */ | |
271 | if (!self->activated) { | |
272 | if (!jack_activate(self->client)) { | |
273 | self->activated = 1; | |
274 | av_log(context, AV_LOG_INFO, | |
275 | "JACK client registered and activated (rate=%dHz, buffer_size=%d frames)\n", | |
276 | self->sample_rate, self->buffer_size); | |
277 | } else { | |
278 | av_log(context, AV_LOG_ERROR, "Unable to activate JACK client\n"); | |
279 | return AVERROR(EIO); | |
280 | } | |
281 | } | |
282 | ||
283 | /* Wait for a packet coming back from process_callback(), if one isn't available yet */ | |
284 | timeout.tv_sec = av_gettime() / 1000000 + 2; | |
285 | if (sem_timedwait(&self->packet_count, &timeout)) { | |
286 | if (errno == ETIMEDOUT) { | |
287 | av_log(context, AV_LOG_ERROR, | |
288 | "Input error: timed out when waiting for JACK process callback output\n"); | |
289 | } else { | |
290 | av_log(context, AV_LOG_ERROR, "Error while waiting for audio packet: %s\n", | |
291 | strerror(errno)); | |
292 | } | |
293 | if (!self->client) | |
294 | av_log(context, AV_LOG_ERROR, "Input error: JACK server is gone\n"); | |
295 | ||
296 | return AVERROR(EIO); | |
297 | } | |
298 | ||
299 | if (self->pkt_xrun) { | |
300 | av_log(context, AV_LOG_WARNING, "Audio packet xrun\n"); | |
301 | self->pkt_xrun = 0; | |
302 | } | |
303 | ||
304 | if (self->jack_xrun) { | |
305 | av_log(context, AV_LOG_WARNING, "JACK xrun\n"); | |
306 | self->jack_xrun = 0; | |
307 | } | |
308 | ||
309 | /* Retrieve the packet filled with audio data by process_callback() */ | |
310 | av_fifo_generic_read(self->filled_pkts, pkt, sizeof(*pkt), NULL); | |
311 | ||
312 | if ((test = supply_new_packets(self, context))) | |
313 | return test; | |
314 | ||
315 | return 0; | |
316 | } | |
317 | ||
318 | static int audio_read_close(AVFormatContext *context) | |
319 | { | |
320 | JackData *self = context->priv_data; | |
321 | stop_jack(self); | |
322 | return 0; | |
323 | } | |
324 | ||
325 | #define OFFSET(x) offsetof(JackData, x) | |
326 | static const AVOption options[] = { | |
327 | { "channels", "Number of audio channels.", OFFSET(nports), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, | |
328 | { NULL }, | |
329 | }; | |
330 | ||
331 | static const AVClass jack_indev_class = { | |
332 | .class_name = "JACK indev", | |
333 | .item_name = av_default_item_name, | |
334 | .option = options, | |
335 | .version = LIBAVUTIL_VERSION_INT, | |
336 | .category = AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, | |
337 | }; | |
338 | ||
339 | AVInputFormat ff_jack_demuxer = { | |
340 | .name = "jack", | |
341 | .long_name = NULL_IF_CONFIG_SMALL("JACK Audio Connection Kit"), | |
342 | .priv_data_size = sizeof(JackData), | |
343 | .read_header = audio_read_header, | |
344 | .read_packet = audio_read_packet, | |
345 | .read_close = audio_read_close, | |
346 | .flags = AVFMT_NOFILE, | |
347 | .priv_class = &jack_indev_class, | |
348 | }; |