Libav 0.7.1
|
00001 /* 00002 * Linux audio play and grab interface 00003 * Copyright (c) 2000, 2001 Fabrice Bellard 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "config.h" 00023 #include <stdlib.h> 00024 #include <stdio.h> 00025 #include <stdint.h> 00026 #include <string.h> 00027 #include <errno.h> 00028 #if HAVE_SOUNDCARD_H 00029 #include <soundcard.h> 00030 #else 00031 #include <sys/soundcard.h> 00032 #endif 00033 #include <unistd.h> 00034 #include <fcntl.h> 00035 #include <sys/ioctl.h> 00036 #include <sys/time.h> 00037 #include <sys/select.h> 00038 00039 #include "libavutil/log.h" 00040 #include "libavutil/opt.h" 00041 #include "libavcodec/avcodec.h" 00042 #include "libavformat/avformat.h" 00043 00044 #define AUDIO_BLOCK_SIZE 4096 00045 00046 typedef struct { 00047 AVClass *class; 00048 int fd; 00049 int sample_rate; 00050 int channels; 00051 int frame_size; /* in bytes ! */ 00052 enum CodecID codec_id; 00053 unsigned int flip_left : 1; 00054 uint8_t buffer[AUDIO_BLOCK_SIZE]; 00055 int buffer_ptr; 00056 } AudioData; 00057 00058 static int audio_open(AVFormatContext *s1, int is_output, const char *audio_device) 00059 { 00060 AudioData *s = s1->priv_data; 00061 int audio_fd; 00062 int tmp, err; 00063 char *flip = getenv("AUDIO_FLIP_LEFT"); 00064 00065 if (is_output) 00066 audio_fd = open(audio_device, O_WRONLY); 00067 else 00068 audio_fd = open(audio_device, O_RDONLY); 00069 if (audio_fd < 0) { 00070 av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, strerror(errno)); 00071 return AVERROR(EIO); 00072 } 00073 00074 if (flip && *flip == '1') { 00075 s->flip_left = 1; 00076 } 00077 00078 /* non blocking mode */ 00079 if (!is_output) 00080 fcntl(audio_fd, F_SETFL, O_NONBLOCK); 00081 00082 s->frame_size = AUDIO_BLOCK_SIZE; 00083 #if 0 00084 tmp = (NB_FRAGMENTS << 16) | FRAGMENT_BITS; 00085 err = ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &tmp); 00086 if (err < 0) { 00087 perror("SNDCTL_DSP_SETFRAGMENT"); 00088 } 00089 #endif 00090 00091 /* select format : favour native format */ 00092 err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp); 00093 00094 #if HAVE_BIGENDIAN 00095 if (tmp & AFMT_S16_BE) { 00096 tmp = AFMT_S16_BE; 00097 } else if (tmp & AFMT_S16_LE) { 00098 tmp = AFMT_S16_LE; 00099 } else { 00100 tmp = 0; 00101 } 00102 #else 00103 if (tmp & AFMT_S16_LE) { 00104 tmp = AFMT_S16_LE; 00105 } else if (tmp & AFMT_S16_BE) { 00106 tmp = AFMT_S16_BE; 00107 } else { 00108 tmp = 0; 00109 } 00110 #endif 00111 00112 switch(tmp) { 00113 case AFMT_S16_LE: 00114 s->codec_id = CODEC_ID_PCM_S16LE; 00115 break; 00116 case AFMT_S16_BE: 00117 s->codec_id = CODEC_ID_PCM_S16BE; 00118 break; 00119 default: 00120 av_log(s1, AV_LOG_ERROR, "Soundcard does not support 16 bit sample format\n"); 00121 close(audio_fd); 00122 return AVERROR(EIO); 00123 } 00124 err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp); 00125 if (err < 0) { 00126 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SETFMT: %s\n", strerror(errno)); 00127 goto fail; 00128 } 00129 00130 tmp = (s->channels == 2); 00131 err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp); 00132 if (err < 0) { 00133 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_STEREO: %s\n", strerror(errno)); 00134 goto fail; 00135 } 00136 00137 tmp = s->sample_rate; 00138 err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp); 00139 if (err < 0) { 00140 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SPEED: %s\n", strerror(errno)); 00141 goto fail; 00142 } 00143 s->sample_rate = tmp; /* store real sample rate */ 00144 s->fd = audio_fd; 00145 00146 return 0; 00147 fail: 00148 close(audio_fd); 00149 return AVERROR(EIO); 00150 } 00151 00152 static int audio_close(AudioData *s) 00153 { 00154 close(s->fd); 00155 return 0; 00156 } 00157 00158 /* sound output support */ 00159 static int audio_write_header(AVFormatContext *s1) 00160 { 00161 AudioData *s = s1->priv_data; 00162 AVStream *st; 00163 int ret; 00164 00165 st = s1->streams[0]; 00166 s->sample_rate = st->codec->sample_rate; 00167 s->channels = st->codec->channels; 00168 ret = audio_open(s1, 1, s1->filename); 00169 if (ret < 0) { 00170 return AVERROR(EIO); 00171 } else { 00172 return 0; 00173 } 00174 } 00175 00176 static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) 00177 { 00178 AudioData *s = s1->priv_data; 00179 int len, ret; 00180 int size= pkt->size; 00181 uint8_t *buf= pkt->data; 00182 00183 while (size > 0) { 00184 len = FFMIN(AUDIO_BLOCK_SIZE - s->buffer_ptr, size); 00185 memcpy(s->buffer + s->buffer_ptr, buf, len); 00186 s->buffer_ptr += len; 00187 if (s->buffer_ptr >= AUDIO_BLOCK_SIZE) { 00188 for(;;) { 00189 ret = write(s->fd, s->buffer, AUDIO_BLOCK_SIZE); 00190 if (ret > 0) 00191 break; 00192 if (ret < 0 && (errno != EAGAIN && errno != EINTR)) 00193 return AVERROR(EIO); 00194 } 00195 s->buffer_ptr = 0; 00196 } 00197 buf += len; 00198 size -= len; 00199 } 00200 return 0; 00201 } 00202 00203 static int audio_write_trailer(AVFormatContext *s1) 00204 { 00205 AudioData *s = s1->priv_data; 00206 00207 audio_close(s); 00208 return 0; 00209 } 00210 00211 /* grab support */ 00212 00213 static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap) 00214 { 00215 AudioData *s = s1->priv_data; 00216 AVStream *st; 00217 int ret; 00218 00219 #if FF_API_FORMAT_PARAMETERS 00220 if (ap->sample_rate > 0) 00221 s->sample_rate = ap->sample_rate; 00222 if (ap->channels > 0) 00223 s->channels = ap->channels; 00224 #endif 00225 00226 st = av_new_stream(s1, 0); 00227 if (!st) { 00228 return AVERROR(ENOMEM); 00229 } 00230 00231 ret = audio_open(s1, 0, s1->filename); 00232 if (ret < 0) { 00233 return AVERROR(EIO); 00234 } 00235 00236 /* take real parameters */ 00237 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00238 st->codec->codec_id = s->codec_id; 00239 st->codec->sample_rate = s->sample_rate; 00240 st->codec->channels = s->channels; 00241 00242 av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ 00243 return 0; 00244 } 00245 00246 static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) 00247 { 00248 AudioData *s = s1->priv_data; 00249 int ret, bdelay; 00250 int64_t cur_time; 00251 struct audio_buf_info abufi; 00252 00253 if ((ret=av_new_packet(pkt, s->frame_size)) < 0) 00254 return ret; 00255 00256 ret = read(s->fd, pkt->data, pkt->size); 00257 if (ret <= 0){ 00258 av_free_packet(pkt); 00259 pkt->size = 0; 00260 if (ret<0) return AVERROR(errno); 00261 else return AVERROR_EOF; 00262 } 00263 pkt->size = ret; 00264 00265 /* compute pts of the start of the packet */ 00266 cur_time = av_gettime(); 00267 bdelay = ret; 00268 if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) { 00269 bdelay += abufi.bytes; 00270 } 00271 /* subtract time represented by the number of bytes in the audio fifo */ 00272 cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels); 00273 00274 /* convert to wanted units */ 00275 pkt->pts = cur_time; 00276 00277 if (s->flip_left && s->channels == 2) { 00278 int i; 00279 short *p = (short *) pkt->data; 00280 00281 for (i = 0; i < ret; i += 4) { 00282 *p = ~*p; 00283 p += 2; 00284 } 00285 } 00286 return 0; 00287 } 00288 00289 static int audio_read_close(AVFormatContext *s1) 00290 { 00291 AudioData *s = s1->priv_data; 00292 00293 audio_close(s); 00294 return 0; 00295 } 00296 00297 #if CONFIG_OSS_INDEV 00298 static const AVOption options[] = { 00299 { "sample_rate", "", offsetof(AudioData, sample_rate), FF_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, 00300 { "channels", "", offsetof(AudioData, channels), FF_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, 00301 { NULL }, 00302 }; 00303 00304 static const AVClass oss_demuxer_class = { 00305 .class_name = "OSS demuxer", 00306 .item_name = av_default_item_name, 00307 .option = options, 00308 .version = LIBAVUTIL_VERSION_INT, 00309 }; 00310 00311 AVInputFormat ff_oss_demuxer = { 00312 "oss", 00313 NULL_IF_CONFIG_SMALL("Open Sound System capture"), 00314 sizeof(AudioData), 00315 NULL, 00316 audio_read_header, 00317 audio_read_packet, 00318 audio_read_close, 00319 .flags = AVFMT_NOFILE, 00320 .priv_class = &oss_demuxer_class, 00321 }; 00322 #endif 00323 00324 #if CONFIG_OSS_OUTDEV 00325 AVOutputFormat ff_oss_muxer = { 00326 "oss", 00327 NULL_IF_CONFIG_SMALL("Open Sound System playback"), 00328 "", 00329 "", 00330 sizeof(AudioData), 00331 /* XXX: we make the assumption that the soundcard accepts this format */ 00332 /* XXX: find better solution with "preinit" method, needed also in 00333 other formats */ 00334 AV_NE(CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE), 00335 CODEC_ID_NONE, 00336 audio_write_header, 00337 audio_write_packet, 00338 audio_write_trailer, 00339 .flags = AVFMT_NOFILE, 00340 }; 00341 #endif