Libav
|
00001 /* 00002 * Linux audio play and grab interface 00003 * Copyright (c) 2000, 2001 Fabrice Bellard 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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 "libavcodec/avcodec.h" 00041 #include "libavformat/avformat.h" 00042 00043 #define AUDIO_BLOCK_SIZE 4096 00044 00045 typedef struct { 00046 int fd; 00047 int sample_rate; 00048 int channels; 00049 int frame_size; /* in bytes ! */ 00050 enum CodecID codec_id; 00051 unsigned int flip_left : 1; 00052 uint8_t buffer[AUDIO_BLOCK_SIZE]; 00053 int buffer_ptr; 00054 } AudioData; 00055 00056 static int audio_open(AVFormatContext *s1, int is_output, const char *audio_device) 00057 { 00058 AudioData *s = s1->priv_data; 00059 int audio_fd; 00060 int tmp, err; 00061 char *flip = getenv("AUDIO_FLIP_LEFT"); 00062 00063 if (is_output) 00064 audio_fd = open(audio_device, O_WRONLY); 00065 else 00066 audio_fd = open(audio_device, O_RDONLY); 00067 if (audio_fd < 0) { 00068 av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, strerror(errno)); 00069 return AVERROR(EIO); 00070 } 00071 00072 if (flip && *flip == '1') { 00073 s->flip_left = 1; 00074 } 00075 00076 /* non blocking mode */ 00077 if (!is_output) 00078 fcntl(audio_fd, F_SETFL, O_NONBLOCK); 00079 00080 s->frame_size = AUDIO_BLOCK_SIZE; 00081 #if 0 00082 tmp = (NB_FRAGMENTS << 16) | FRAGMENT_BITS; 00083 err = ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &tmp); 00084 if (err < 0) { 00085 perror("SNDCTL_DSP_SETFRAGMENT"); 00086 } 00087 #endif 00088 00089 /* select format : favour native format */ 00090 err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp); 00091 00092 #if HAVE_BIGENDIAN 00093 if (tmp & AFMT_S16_BE) { 00094 tmp = AFMT_S16_BE; 00095 } else if (tmp & AFMT_S16_LE) { 00096 tmp = AFMT_S16_LE; 00097 } else { 00098 tmp = 0; 00099 } 00100 #else 00101 if (tmp & AFMT_S16_LE) { 00102 tmp = AFMT_S16_LE; 00103 } else if (tmp & AFMT_S16_BE) { 00104 tmp = AFMT_S16_BE; 00105 } else { 00106 tmp = 0; 00107 } 00108 #endif 00109 00110 switch(tmp) { 00111 case AFMT_S16_LE: 00112 s->codec_id = CODEC_ID_PCM_S16LE; 00113 break; 00114 case AFMT_S16_BE: 00115 s->codec_id = CODEC_ID_PCM_S16BE; 00116 break; 00117 default: 00118 av_log(s1, AV_LOG_ERROR, "Soundcard does not support 16 bit sample format\n"); 00119 close(audio_fd); 00120 return AVERROR(EIO); 00121 } 00122 err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp); 00123 if (err < 0) { 00124 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SETFMT: %s\n", strerror(errno)); 00125 goto fail; 00126 } 00127 00128 tmp = (s->channels == 2); 00129 err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp); 00130 if (err < 0) { 00131 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_STEREO: %s\n", strerror(errno)); 00132 goto fail; 00133 } 00134 00135 tmp = s->sample_rate; 00136 err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp); 00137 if (err < 0) { 00138 av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SPEED: %s\n", strerror(errno)); 00139 goto fail; 00140 } 00141 s->sample_rate = tmp; /* store real sample rate */ 00142 s->fd = audio_fd; 00143 00144 return 0; 00145 fail: 00146 close(audio_fd); 00147 return AVERROR(EIO); 00148 } 00149 00150 static int audio_close(AudioData *s) 00151 { 00152 close(s->fd); 00153 return 0; 00154 } 00155 00156 /* sound output support */ 00157 static int audio_write_header(AVFormatContext *s1) 00158 { 00159 AudioData *s = s1->priv_data; 00160 AVStream *st; 00161 int ret; 00162 00163 st = s1->streams[0]; 00164 s->sample_rate = st->codec->sample_rate; 00165 s->channels = st->codec->channels; 00166 ret = audio_open(s1, 1, s1->filename); 00167 if (ret < 0) { 00168 return AVERROR(EIO); 00169 } else { 00170 return 0; 00171 } 00172 } 00173 00174 static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) 00175 { 00176 AudioData *s = s1->priv_data; 00177 int len, ret; 00178 int size= pkt->size; 00179 uint8_t *buf= pkt->data; 00180 00181 while (size > 0) { 00182 len = AUDIO_BLOCK_SIZE - s->buffer_ptr; 00183 if (len > size) 00184 len = 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 (ap->sample_rate <= 0 || ap->channels <= 0) 00220 return -1; 00221 00222 st = av_new_stream(s1, 0); 00223 if (!st) { 00224 return AVERROR(ENOMEM); 00225 } 00226 s->sample_rate = ap->sample_rate; 00227 s->channels = ap->channels; 00228 00229 ret = audio_open(s1, 0, s1->filename); 00230 if (ret < 0) { 00231 return AVERROR(EIO); 00232 } 00233 00234 /* take real parameters */ 00235 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00236 st->codec->codec_id = s->codec_id; 00237 st->codec->sample_rate = s->sample_rate; 00238 st->codec->channels = s->channels; 00239 00240 av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ 00241 return 0; 00242 } 00243 00244 static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) 00245 { 00246 AudioData *s = s1->priv_data; 00247 int ret, bdelay; 00248 int64_t cur_time; 00249 struct audio_buf_info abufi; 00250 00251 if ((ret=av_new_packet(pkt, s->frame_size)) < 0) 00252 return ret; 00253 00254 ret = read(s->fd, pkt->data, pkt->size); 00255 if (ret <= 0){ 00256 av_free_packet(pkt); 00257 pkt->size = 0; 00258 if (ret<0) return AVERROR(errno); 00259 else return AVERROR_EOF; 00260 } 00261 pkt->size = ret; 00262 00263 /* compute pts of the start of the packet */ 00264 cur_time = av_gettime(); 00265 bdelay = ret; 00266 if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) { 00267 bdelay += abufi.bytes; 00268 } 00269 /* subtract time represented by the number of bytes in the audio fifo */ 00270 cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels); 00271 00272 /* convert to wanted units */ 00273 pkt->pts = cur_time; 00274 00275 if (s->flip_left && s->channels == 2) { 00276 int i; 00277 short *p = (short *) pkt->data; 00278 00279 for (i = 0; i < ret; i += 4) { 00280 *p = ~*p; 00281 p += 2; 00282 } 00283 } 00284 return 0; 00285 } 00286 00287 static int audio_read_close(AVFormatContext *s1) 00288 { 00289 AudioData *s = s1->priv_data; 00290 00291 audio_close(s); 00292 return 0; 00293 } 00294 00295 #if CONFIG_OSS_INDEV 00296 AVInputFormat oss_demuxer = { 00297 "oss", 00298 NULL_IF_CONFIG_SMALL("Open Sound System capture"), 00299 sizeof(AudioData), 00300 NULL, 00301 audio_read_header, 00302 audio_read_packet, 00303 audio_read_close, 00304 .flags = AVFMT_NOFILE, 00305 }; 00306 #endif 00307 00308 #if CONFIG_OSS_OUTDEV 00309 AVOutputFormat oss_muxer = { 00310 "oss", 00311 NULL_IF_CONFIG_SMALL("Open Sound System playback"), 00312 "", 00313 "", 00314 sizeof(AudioData), 00315 /* XXX: we make the assumption that the soundcard accepts this format */ 00316 /* XXX: find better solution with "preinit" method, needed also in 00317 other formats */ 00318 #if HAVE_BIGENDIAN 00319 CODEC_ID_PCM_S16BE, 00320 #else 00321 CODEC_ID_PCM_S16LE, 00322 #endif 00323 CODEC_ID_NONE, 00324 audio_write_header, 00325 audio_write_packet, 00326 audio_write_trailer, 00327 .flags = AVFMT_NOFILE, 00328 }; 00329 #endif