Libav 0.7.1
|
00001 /* 00002 * ALSA input and output 00003 * Copyright (c) 2007 Luca Abeni ( lucabe72 email it ) 00004 * Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr ) 00005 * 00006 * This file is part of Libav. 00007 * 00008 * Libav is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * Libav is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with Libav; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00040 #include <alsa/asoundlib.h> 00041 #include "libavformat/avformat.h" 00042 00043 #include "alsa-audio.h" 00044 00045 static av_cold int audio_write_header(AVFormatContext *s1) 00046 { 00047 AlsaData *s = s1->priv_data; 00048 AVStream *st; 00049 unsigned int sample_rate; 00050 enum CodecID codec_id; 00051 int res; 00052 00053 st = s1->streams[0]; 00054 sample_rate = st->codec->sample_rate; 00055 codec_id = st->codec->codec_id; 00056 res = ff_alsa_open(s1, SND_PCM_STREAM_PLAYBACK, &sample_rate, 00057 st->codec->channels, &codec_id); 00058 if (sample_rate != st->codec->sample_rate) { 00059 av_log(s1, AV_LOG_ERROR, 00060 "sample rate %d not available, nearest is %d\n", 00061 st->codec->sample_rate, sample_rate); 00062 goto fail; 00063 } 00064 00065 return res; 00066 00067 fail: 00068 snd_pcm_close(s->h); 00069 return AVERROR(EIO); 00070 } 00071 00072 static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) 00073 { 00074 AlsaData *s = s1->priv_data; 00075 int res; 00076 int size = pkt->size; 00077 uint8_t *buf = pkt->data; 00078 00079 while((res = snd_pcm_writei(s->h, buf, size / s->frame_size)) < 0) { 00080 if (res == -EAGAIN) { 00081 00082 return AVERROR(EAGAIN); 00083 } 00084 00085 if (ff_alsa_xrun_recover(s1, res) < 0) { 00086 av_log(s1, AV_LOG_ERROR, "ALSA write error: %s\n", 00087 snd_strerror(res)); 00088 00089 return AVERROR(EIO); 00090 } 00091 } 00092 00093 return 0; 00094 } 00095 00096 AVOutputFormat ff_alsa_muxer = { 00097 "alsa", 00098 NULL_IF_CONFIG_SMALL("ALSA audio output"), 00099 "", 00100 "", 00101 sizeof(AlsaData), 00102 DEFAULT_CODEC_ID, 00103 CODEC_ID_NONE, 00104 audio_write_header, 00105 audio_write_packet, 00106 ff_alsa_close, 00107 .flags = AVFMT_NOFILE, 00108 };