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 
00037 #include "libavutil/log.h"
00038 #include "libavutil/opt.h"
00039 #include "libavutil/time.h"
00040 #include "libavcodec/avcodec.h"
00041 #include "avdevice.h"
00042 #include "libavformat/internal.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 AVCodecID 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 
00084     
00085     err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp);
00086 
00087 #if HAVE_BIGENDIAN
00088     if (tmp & AFMT_S16_BE) {
00089         tmp = AFMT_S16_BE;
00090     } else if (tmp & AFMT_S16_LE) {
00091         tmp = AFMT_S16_LE;
00092     } else {
00093         tmp = 0;
00094     }
00095 #else
00096     if (tmp & AFMT_S16_LE) {
00097         tmp = AFMT_S16_LE;
00098     } else if (tmp & AFMT_S16_BE) {
00099         tmp = AFMT_S16_BE;
00100     } else {
00101         tmp = 0;
00102     }
00103 #endif
00104 
00105     switch(tmp) {
00106     case AFMT_S16_LE:
00107         s->codec_id = AV_CODEC_ID_PCM_S16LE;
00108         break;
00109     case AFMT_S16_BE:
00110         s->codec_id = AV_CODEC_ID_PCM_S16BE;
00111         break;
00112     default:
00113         av_log(s1, AV_LOG_ERROR, "Soundcard does not support 16 bit sample format\n");
00114         close(audio_fd);
00115         return AVERROR(EIO);
00116     }
00117     err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp);
00118     if (err < 0) {
00119         av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SETFMT: %s\n", strerror(errno));
00120         goto fail;
00121     }
00122 
00123     tmp = (s->channels == 2);
00124     err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
00125     if (err < 0) {
00126         av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_STEREO: %s\n", strerror(errno));
00127         goto fail;
00128     }
00129 
00130     tmp = s->sample_rate;
00131     err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp);
00132     if (err < 0) {
00133         av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SPEED: %s\n", strerror(errno));
00134         goto fail;
00135     }
00136     s->sample_rate = tmp; 
00137     s->fd = audio_fd;
00138 
00139     return 0;
00140  fail:
00141     close(audio_fd);
00142     return AVERROR(EIO);
00143 }
00144 
00145 static int audio_close(AudioData *s)
00146 {
00147     close(s->fd);
00148     return 0;
00149 }
00150 
00151 
00152 static int audio_write_header(AVFormatContext *s1)
00153 {
00154     AudioData *s = s1->priv_data;
00155     AVStream *st;
00156     int ret;
00157 
00158     st = s1->streams[0];
00159     s->sample_rate = st->codec->sample_rate;
00160     s->channels = st->codec->channels;
00161     ret = audio_open(s1, 1, s1->filename);
00162     if (ret < 0) {
00163         return AVERROR(EIO);
00164     } else {
00165         return 0;
00166     }
00167 }
00168 
00169 static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt)
00170 {
00171     AudioData *s = s1->priv_data;
00172     int len, ret;
00173     int size= pkt->size;
00174     uint8_t *buf= pkt->data;
00175 
00176     while (size > 0) {
00177         len = FFMIN(AUDIO_BLOCK_SIZE - s->buffer_ptr, size);
00178         memcpy(s->buffer + s->buffer_ptr, buf, len);
00179         s->buffer_ptr += len;
00180         if (s->buffer_ptr >= AUDIO_BLOCK_SIZE) {
00181             for(;;) {
00182                 ret = write(s->fd, s->buffer, AUDIO_BLOCK_SIZE);
00183                 if (ret > 0)
00184                     break;
00185                 if (ret < 0 && (errno != EAGAIN && errno != EINTR))
00186                     return AVERROR(EIO);
00187             }
00188             s->buffer_ptr = 0;
00189         }
00190         buf += len;
00191         size -= len;
00192     }
00193     return 0;
00194 }
00195 
00196 static int audio_write_trailer(AVFormatContext *s1)
00197 {
00198     AudioData *s = s1->priv_data;
00199 
00200     audio_close(s);
00201     return 0;
00202 }
00203 
00204 
00205 
00206 static int audio_read_header(AVFormatContext *s1)
00207 {
00208     AudioData *s = s1->priv_data;
00209     AVStream *st;
00210     int ret;
00211 
00212     st = avformat_new_stream(s1, NULL);
00213     if (!st) {
00214         return AVERROR(ENOMEM);
00215     }
00216 
00217     ret = audio_open(s1, 0, s1->filename);
00218     if (ret < 0) {
00219         return AVERROR(EIO);
00220     }
00221 
00222     
00223     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00224     st->codec->codec_id = s->codec_id;
00225     st->codec->sample_rate = s->sample_rate;
00226     st->codec->channels = s->channels;
00227 
00228     avpriv_set_pts_info(st, 64, 1, 1000000);  
00229     return 0;
00230 }
00231 
00232 static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
00233 {
00234     AudioData *s = s1->priv_data;
00235     int ret, bdelay;
00236     int64_t cur_time;
00237     struct audio_buf_info abufi;
00238 
00239     if ((ret=av_new_packet(pkt, s->frame_size)) < 0)
00240         return ret;
00241 
00242     ret = read(s->fd, pkt->data, pkt->size);
00243     if (ret <= 0){
00244         av_free_packet(pkt);
00245         pkt->size = 0;
00246         if (ret<0)  return AVERROR(errno);
00247         else        return AVERROR_EOF;
00248     }
00249     pkt->size = ret;
00250 
00251     
00252     cur_time = av_gettime();
00253     bdelay = ret;
00254     if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) {
00255         bdelay += abufi.bytes;
00256     }
00257     
00258     cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels);
00259 
00260     
00261     pkt->pts = cur_time;
00262 
00263     if (s->flip_left && s->channels == 2) {
00264         int i;
00265         short *p = (short *) pkt->data;
00266 
00267         for (i = 0; i < ret; i += 4) {
00268             *p = ~*p;
00269             p += 2;
00270         }
00271     }
00272     return 0;
00273 }
00274 
00275 static int audio_read_close(AVFormatContext *s1)
00276 {
00277     AudioData *s = s1->priv_data;
00278 
00279     audio_close(s);
00280     return 0;
00281 }
00282 
00283 #if CONFIG_OSS_INDEV
00284 static const AVOption options[] = {
00285     { "sample_rate", "", offsetof(AudioData, sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
00286     { "channels",    "", offsetof(AudioData, channels),    AV_OPT_TYPE_INT, {.i64 = 2},     1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
00287     { NULL },
00288 };
00289 
00290 static const AVClass oss_demuxer_class = {
00291     .class_name     = "OSS demuxer",
00292     .item_name      = av_default_item_name,
00293     .option         = options,
00294     .version        = LIBAVUTIL_VERSION_INT,
00295 };
00296 
00297 AVInputFormat ff_oss_demuxer = {
00298     .name           = "oss",
00299     .long_name      = NULL_IF_CONFIG_SMALL("OSS (Open Sound System) capture"),
00300     .priv_data_size = sizeof(AudioData),
00301     .read_header    = audio_read_header,
00302     .read_packet    = audio_read_packet,
00303     .read_close     = audio_read_close,
00304     .flags          = AVFMT_NOFILE,
00305     .priv_class     = &oss_demuxer_class,
00306 };
00307 #endif
00308 
00309 #if CONFIG_OSS_OUTDEV
00310 AVOutputFormat ff_oss_muxer = {
00311     .name           = "oss",
00312     .long_name      = NULL_IF_CONFIG_SMALL("OSS (Open Sound System) playback"),
00313     .priv_data_size = sizeof(AudioData),
00314     
00315     
00316 
00317     .audio_codec    = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE),
00318     .video_codec    = AV_CODEC_ID_NONE,
00319     .write_header   = audio_write_header,
00320     .write_packet   = audio_write_packet,
00321     .write_trailer  = audio_write_trailer,
00322     .flags          = AVFMT_NOFILE,
00323 };
00324 #endif