1/* 2 * Linux audio play and grab interface 3 * Copyright (c) 2000, 2001 Fabrice Bellard 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include "config.h" 23#include <stdlib.h> 24#include <stdio.h> 25#include <stdint.h> 26#include <string.h> 27#include <errno.h> 28#if HAVE_SOUNDCARD_H 29#include <soundcard.h> 30#else 31#include <sys/soundcard.h> 32#endif 33#if HAVE_UNISTD_H 34#include <unistd.h> 35#endif 36#include <fcntl.h> 37#include <sys/ioctl.h> 38 39#include "libavutil/internal.h" 40#include "libavutil/log.h" 41#include "libavutil/opt.h" 42#include "libavutil/time.h" 43#include "libavcodec/avcodec.h" 44#include "avdevice.h" 45#include "libavformat/internal.h" 46 47#define AUDIO_BLOCK_SIZE 4096 48 49typedef struct { 50 AVClass *class; 51 int fd; 52 int sample_rate; 53 int channels; 54 int frame_size; /* in bytes ! */ 55 enum AVCodecID codec_id; 56 unsigned int flip_left : 1; 57 uint8_t buffer[AUDIO_BLOCK_SIZE]; 58 int buffer_ptr; 59} AudioData; 60 61static int audio_open(AVFormatContext *s1, int is_output, const char *audio_device) 62{ 63 AudioData *s = s1->priv_data; 64 int audio_fd; 65 int tmp, err; 66 char *flip = getenv("AUDIO_FLIP_LEFT"); 67 68 if (is_output) 69 audio_fd = avpriv_open(audio_device, O_WRONLY); 70 else 71 audio_fd = avpriv_open(audio_device, O_RDONLY); 72 if (audio_fd < 0) { 73 av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, strerror(errno)); 74 return AVERROR(EIO); 75 } 76 77 if (flip && *flip == '1') { 78 s->flip_left = 1; 79 } 80 81 /* non blocking mode */ 82 if (!is_output) { 83 if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) < 0) { 84 av_log(s1, AV_LOG_WARNING, "%s: Could not enable non block mode (%s)\n", audio_device, strerror(errno)); 85 } 86 } 87 88 s->frame_size = AUDIO_BLOCK_SIZE; 89 90 /* select format : favour native format */ 91 err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp); 92 93#if HAVE_BIGENDIAN 94 if (tmp & AFMT_S16_BE) { 95 tmp = AFMT_S16_BE; 96 } else if (tmp & AFMT_S16_LE) { 97 tmp = AFMT_S16_LE; 98 } else { 99 tmp = 0; 100 } 101#else 102 if (tmp & AFMT_S16_LE) { 103 tmp = AFMT_S16_LE; 104 } else if (tmp & AFMT_S16_BE) { 105 tmp = AFMT_S16_BE; 106 } else { 107 tmp = 0; 108 } 109#endif 110 111 switch(tmp) { 112 case AFMT_S16_LE: 113 s->codec_id = AV_CODEC_ID_PCM_S16LE; 114 break; 115 case AFMT_S16_BE: 116 s->codec_id = AV_CODEC_ID_PCM_S16BE; 117 break; 118 default: 119 av_log(s1, AV_LOG_ERROR, "Soundcard does not support 16 bit sample format\n"); 120 close(audio_fd); 121 return AVERROR(EIO); 122 } 123 err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp); 124 if (err < 0) { 125 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SETFMT: %s\n", strerror(errno)); 126 goto fail; 127 } 128 129 tmp = (s->channels == 2); 130 err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp); 131 if (err < 0) { 132 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_STEREO: %s\n", strerror(errno)); 133 goto fail; 134 } 135 136 tmp = s->sample_rate; 137 err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp); 138 if (err < 0) { 139 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SPEED: %s\n", strerror(errno)); 140 goto fail; 141 } 142 s->sample_rate = tmp; /* store real sample rate */ 143 s->fd = audio_fd; 144 145 return 0; 146 fail: 147 close(audio_fd); 148 return AVERROR(EIO); 149} 150 151static int audio_close(AudioData *s) 152{ 153 close(s->fd); 154 return 0; 155} 156 157/* sound output support */ 158static int audio_write_header(AVFormatContext *s1) 159{ 160 AudioData *s = s1->priv_data; 161 AVStream *st; 162 int ret; 163 164 st = s1->streams[0]; 165 s->sample_rate = st->codec->sample_rate; 166 s->channels = st->codec->channels; 167 ret = audio_open(s1, 1, s1->filename); 168 if (ret < 0) { 169 return AVERROR(EIO); 170 } else { 171 return 0; 172 } 173} 174 175static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) 176{ 177 AudioData *s = s1->priv_data; 178 int len, ret; 179 int size= pkt->size; 180 uint8_t *buf= pkt->data; 181 182 while (size > 0) { 183 len = FFMIN(AUDIO_BLOCK_SIZE - s->buffer_ptr, size); 184 memcpy(s->buffer + s->buffer_ptr, buf, len); 185 s->buffer_ptr += len; 186 if (s->buffer_ptr >= AUDIO_BLOCK_SIZE) { 187 for(;;) { 188 ret = write(s->fd, s->buffer, AUDIO_BLOCK_SIZE); 189 if (ret > 0) 190 break; 191 if (ret < 0 && (errno != EAGAIN && errno != EINTR)) 192 return AVERROR(EIO); 193 } 194 s->buffer_ptr = 0; 195 } 196 buf += len; 197 size -= len; 198 } 199 return 0; 200} 201 202static int audio_write_trailer(AVFormatContext *s1) 203{ 204 AudioData *s = s1->priv_data; 205 206 audio_close(s); 207 return 0; 208} 209 210/* grab support */ 211 212static int audio_read_header(AVFormatContext *s1) 213{ 214 AudioData *s = s1->priv_data; 215 AVStream *st; 216 int ret; 217 218 st = avformat_new_stream(s1, NULL); 219 if (!st) { 220 return AVERROR(ENOMEM); 221 } 222 223 ret = audio_open(s1, 0, s1->filename); 224 if (ret < 0) { 225 return AVERROR(EIO); 226 } 227 228 /* take real parameters */ 229 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 230 st->codec->codec_id = s->codec_id; 231 st->codec->sample_rate = s->sample_rate; 232 st->codec->channels = s->channels; 233 234 avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ 235 return 0; 236} 237 238static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) 239{ 240 AudioData *s = s1->priv_data; 241 int ret, bdelay; 242 int64_t cur_time; 243 struct audio_buf_info abufi; 244 245 if ((ret=av_new_packet(pkt, s->frame_size)) < 0) 246 return ret; 247 248 ret = read(s->fd, pkt->data, pkt->size); 249 if (ret <= 0){ 250 av_free_packet(pkt); 251 pkt->size = 0; 252 if (ret<0) return AVERROR(errno); 253 else return AVERROR_EOF; 254 } 255 pkt->size = ret; 256 257 /* compute pts of the start of the packet */ 258 cur_time = av_gettime(); 259 bdelay = ret; 260 if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) { 261 bdelay += abufi.bytes; 262 } 263 /* subtract time represented by the number of bytes in the audio fifo */ 264 cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels); 265 266 /* convert to wanted units */ 267 pkt->pts = cur_time; 268 269 if (s->flip_left && s->channels == 2) { 270 int i; 271 short *p = (short *) pkt->data; 272 273 for (i = 0; i < ret; i += 4) { 274 *p = ~*p; 275 p += 2; 276 } 277 } 278 return 0; 279} 280 281static int audio_read_close(AVFormatContext *s1) 282{ 283 AudioData *s = s1->priv_data; 284 285 audio_close(s); 286 return 0; 287} 288 289#if CONFIG_OSS_INDEV 290static const AVOption options[] = { 291 { "sample_rate", "", offsetof(AudioData, sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, 292 { "channels", "", offsetof(AudioData, channels), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, 293 { NULL }, 294}; 295 296static const AVClass oss_demuxer_class = { 297 .class_name = "OSS demuxer", 298 .item_name = av_default_item_name, 299 .option = options, 300 .version = LIBAVUTIL_VERSION_INT, 301 .category = AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, 302}; 303 304AVInputFormat ff_oss_demuxer = { 305 .name = "oss", 306 .long_name = NULL_IF_CONFIG_SMALL("OSS (Open Sound System) capture"), 307 .priv_data_size = sizeof(AudioData), 308 .read_header = audio_read_header, 309 .read_packet = audio_read_packet, 310 .read_close = audio_read_close, 311 .flags = AVFMT_NOFILE, 312 .priv_class = &oss_demuxer_class, 313}; 314#endif 315 316#if CONFIG_OSS_OUTDEV 317static const AVClass oss_muxer_class = { 318 .class_name = "OSS muxer", 319 .item_name = av_default_item_name, 320 .version = LIBAVUTIL_VERSION_INT, 321 .category = AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, 322}; 323 324AVOutputFormat ff_oss_muxer = { 325 .name = "oss", 326 .long_name = NULL_IF_CONFIG_SMALL("OSS (Open Sound System) playback"), 327 .priv_data_size = sizeof(AudioData), 328 /* XXX: we make the assumption that the soundcard accepts this format */ 329 /* XXX: find better solution with "preinit" method, needed also in 330 other formats */ 331 .audio_codec = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE), 332 .video_codec = AV_CODEC_ID_NONE, 333 .write_header = audio_write_header, 334 .write_packet = audio_write_packet, 335 .write_trailer = audio_write_trailer, 336 .flags = AVFMT_NOFILE, 337 .priv_class = &oss_muxer_class, 338}; 339#endif 340