00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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 "avdevice.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;
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
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
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;
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
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
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
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);
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
00266 cur_time = av_gettime();
00267 bdelay = ret;
00268 if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) {
00269 bdelay += abufi.bytes;
00270 }
00271
00272 cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels);
00273
00274
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
00332
00333
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