00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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 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 };