annotate ffmpeg/libavdevice/jack_audio.c @ 13:844d341cf643 tip

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