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#include <unistd.h> 34#include <fcntl.h> 35#include <sys/ioctl.h> 36#include <sys/time.h> 37#include <sys/select.h> 38 39#include "libavutil/log.h" 40#include "libavcodec/avcodec.h" 41#include "libavformat/avformat.h" 42 43#define AUDIO_BLOCK_SIZE 4096 44 45typedef struct { 46 int fd; 47 int sample_rate; 48 int channels; 49 int frame_size; /* in bytes ! */ 50 enum CodecID codec_id; 51 unsigned int flip_left : 1; 52 uint8_t buffer[AUDIO_BLOCK_SIZE]; 53 int buffer_ptr; 54} AudioData; 55 56static int audio_open(AVFormatContext *s1, int is_output, const char *audio_device) 57{ 58 AudioData *s = s1->priv_data; 59 int audio_fd; 60 int tmp, err; 61 char *flip = getenv("AUDIO_FLIP_LEFT"); 62 63 if (is_output) 64 audio_fd = open(audio_device, O_WRONLY); 65 else 66 audio_fd = open(audio_device, O_RDONLY); 67 if (audio_fd < 0) { 68 av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, strerror(errno)); 69 return AVERROR(EIO); 70 } 71 72 if (flip && *flip == '1') { 73 s->flip_left = 1; 74 } 75 76 /* non blocking mode */ 77 if (!is_output) 78 fcntl(audio_fd, F_SETFL, O_NONBLOCK); 79 80 s->frame_size = AUDIO_BLOCK_SIZE; 81#if 0 82 tmp = (NB_FRAGMENTS << 16) | FRAGMENT_BITS; 83 err = ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &tmp); 84 if (err < 0) { 85 perror("SNDCTL_DSP_SETFRAGMENT"); 86 } 87#endif 88 89 /* select format : favour native format */ 90 err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp); 91 92#if HAVE_BIGENDIAN 93 if (tmp & AFMT_S16_BE) { 94 tmp = AFMT_S16_BE; 95 } else if (tmp & AFMT_S16_LE) { 96 tmp = AFMT_S16_LE; 97 } else { 98 tmp = 0; 99 } 100#else 101 if (tmp & AFMT_S16_LE) { 102 tmp = AFMT_S16_LE; 103 } else if (tmp & AFMT_S16_BE) { 104 tmp = AFMT_S16_BE; 105 } else { 106 tmp = 0; 107 } 108#endif 109 110 switch(tmp) { 111 case AFMT_S16_LE: 112 s->codec_id = CODEC_ID_PCM_S16LE; 113 break; 114 case AFMT_S16_BE: 115 s->codec_id = CODEC_ID_PCM_S16BE; 116 break; 117 default: 118 av_log(s1, AV_LOG_ERROR, "Soundcard does not support 16 bit sample format\n"); 119 close(audio_fd); 120 return AVERROR(EIO); 121 } 122 err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp); 123 if (err < 0) { 124 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SETFMT: %s\n", strerror(errno)); 125 goto fail; 126 } 127 128 tmp = (s->channels == 2); 129 err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp); 130 if (err < 0) { 131 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_STEREO: %s\n", strerror(errno)); 132 goto fail; 133 } 134 135 tmp = s->sample_rate; 136 err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp); 137 if (err < 0) { 138 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SPEED: %s\n", strerror(errno)); 139 goto fail; 140 } 141 s->sample_rate = tmp; /* store real sample rate */ 142 s->fd = audio_fd; 143 144 return 0; 145 fail: 146 close(audio_fd); 147 return AVERROR(EIO); 148} 149 150static int audio_close(AudioData *s) 151{ 152 close(s->fd); 153 return 0; 154} 155 156/* sound output support */ 157static int audio_write_header(AVFormatContext *s1) 158{ 159 AudioData *s = s1->priv_data; 160 AVStream *st; 161 int ret; 162 163 st = s1->streams[0]; 164 s->sample_rate = st->codec->sample_rate; 165 s->channels = st->codec->channels; 166 ret = audio_open(s1, 1, s1->filename); 167 if (ret < 0) { 168 return AVERROR(EIO); 169 } else { 170 return 0; 171 } 172} 173 174static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) 175{ 176 AudioData *s = s1->priv_data; 177 int len, ret; 178 int size= pkt->size; 179 uint8_t *buf= pkt->data; 180 181 while (size > 0) { 182 len = AUDIO_BLOCK_SIZE - s->buffer_ptr; 183 if (len > size) 184 len = size; 185 memcpy(s->buffer + s->buffer_ptr, buf, len); 186 s->buffer_ptr += len; 187 if (s->buffer_ptr >= AUDIO_BLOCK_SIZE) { 188 for(;;) { 189 ret = write(s->fd, s->buffer, AUDIO_BLOCK_SIZE); 190 if (ret > 0) 191 break; 192 if (ret < 0 && (errno != EAGAIN && errno != EINTR)) 193 return AVERROR(EIO); 194 } 195 s->buffer_ptr = 0; 196 } 197 buf += len; 198 size -= len; 199 } 200 return 0; 201} 202 203static int audio_write_trailer(AVFormatContext *s1) 204{ 205 AudioData *s = s1->priv_data; 206 207 audio_close(s); 208 return 0; 209} 210 211/* grab support */ 212 213static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap) 214{ 215 AudioData *s = s1->priv_data; 216 AVStream *st; 217 int ret; 218 219 if (ap->sample_rate <= 0 || ap->channels <= 0) 220 return -1; 221 222 st = av_new_stream(s1, 0); 223 if (!st) { 224 return AVERROR(ENOMEM); 225 } 226 s->sample_rate = ap->sample_rate; 227 s->channels = ap->channels; 228 229 ret = audio_open(s1, 0, s1->filename); 230 if (ret < 0) { 231 return AVERROR(EIO); 232 } 233 234 /* take real parameters */ 235 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 236 st->codec->codec_id = s->codec_id; 237 st->codec->sample_rate = s->sample_rate; 238 st->codec->channels = s->channels; 239 240 av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ 241 return 0; 242} 243 244static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) 245{ 246 AudioData *s = s1->priv_data; 247 int ret, bdelay; 248 int64_t cur_time; 249 struct audio_buf_info abufi; 250 251 if ((ret=av_new_packet(pkt, s->frame_size)) < 0) 252 return ret; 253 254 ret = read(s->fd, pkt->data, pkt->size); 255 if (ret <= 0){ 256 av_free_packet(pkt); 257 pkt->size = 0; 258 if (ret<0) return AVERROR(errno); 259 else return AVERROR_EOF; 260 } 261 pkt->size = ret; 262 263 /* compute pts of the start of the packet */ 264 cur_time = av_gettime(); 265 bdelay = ret; 266 if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) { 267 bdelay += abufi.bytes; 268 } 269 /* subtract time represented by the number of bytes in the audio fifo */ 270 cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels); 271 272 /* convert to wanted units */ 273 pkt->pts = cur_time; 274 275 if (s->flip_left && s->channels == 2) { 276 int i; 277 short *p = (short *) pkt->data; 278 279 for (i = 0; i < ret; i += 4) { 280 *p = ~*p; 281 p += 2; 282 } 283 } 284 return 0; 285} 286 287static int audio_read_close(AVFormatContext *s1) 288{ 289 AudioData *s = s1->priv_data; 290 291 audio_close(s); 292 return 0; 293} 294 295#if CONFIG_OSS_INDEV 296AVInputFormat oss_demuxer = { 297 "oss", 298 NULL_IF_CONFIG_SMALL("Open Sound System capture"), 299 sizeof(AudioData), 300 NULL, 301 audio_read_header, 302 audio_read_packet, 303 audio_read_close, 304 .flags = AVFMT_NOFILE, 305}; 306#endif 307 308#if CONFIG_OSS_OUTDEV 309AVOutputFormat oss_muxer = { 310 "oss", 311 NULL_IF_CONFIG_SMALL("Open Sound System playback"), 312 "", 313 "", 314 sizeof(AudioData), 315 /* XXX: we make the assumption that the soundcard accepts this format */ 316 /* XXX: find better solution with "preinit" method, needed also in 317 other formats */ 318#if HAVE_BIGENDIAN 319 CODEC_ID_PCM_S16BE, 320#else 321 CODEC_ID_PCM_S16LE, 322#endif 323 CODEC_ID_NONE, 324 audio_write_header, 325 audio_write_packet, 326 audio_write_trailer, 327 .flags = AVFMT_NOFILE, 328}; 329#endif 330