Luca Abeni <[EMAIL PROTECTED]> added the comment:
Alsa support: demuxer
______________________________________________________
FFmpeg issue tracker <[EMAIL PROTECTED]>
<https://roundup.mplayerhq.hu/roundup/ffmpeg/issue247>
______________________________________________________
#include "avformat.h"
#include <alsa/asoundlib.h>
#include "alsa-audio.h"
static int audio_read_close(AVFormatContext *s1)
{
AlsaData *s = s1->priv_data;
ff_alsa_close(s);
return 0;
}
static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap)
{
AlsaData *s = s1->priv_data;
AVStream *st;
int ret;
if (ap->sample_rate <= 0 || ap->channels <= 0) {
av_log(s1, AV_LOG_ERROR, "Bad sample rate %d or channels number %d\n",
ap->sample_rate, ap->channels);
return AVERROR(EIO);
}
st = av_new_stream(s1, 0);
if (st == NULL) {
av_log(s1, AV_LOG_ERROR, "Cannot add stream\n");
return AVERROR(ENOMEM);
}
s->sample_rate = ap->sample_rate;
s->channels = ap->channels;
if (ff_alsa_supported_codec_id(ap->audio_codec_id)) {
s->codec_id = ap->audio_codec_id;
} else {
s->codec_id = DEFAULT_CODEC_ID;
}
ret = ff_alsa_open(s1, SND_PCM_STREAM_CAPTURE);
if (ret < 0) {
av_free(st);
return AVERROR(EIO);
}
/* take real parameters */
st->codec->codec_type = CODEC_TYPE_AUDIO;
st->codec->codec_id = s->codec_id;
st->codec->sample_rate = s->sample_rate;
st->codec->channels = s->channels;
av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
return 0;
}
static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
{
AlsaData *s = s1->priv_data;
int res;
if (av_new_packet(pkt, s->frame_size) < 0) {
return AVERROR(EIO);
}
while ((res = snd_pcm_readi(s->h, pkt->data, pkt->size / (av_get_bits_per_sample(s->codec_id) / 8 * s->channels))) < 0) {
if (res == -EAGAIN) {
pkt->size = 0;
av_free_packet(pkt);
return AVERROR(EAGAIN);
}
if (ff_alsa_xrun_recover(s1, res) < 0) {
av_log(s1, AV_LOG_ERROR, "Alsa read error: %s\n",
snd_strerror(res));
av_free_packet(pkt);
return AVERROR(EIO);
}
}
pkt->size = res * (av_get_bits_per_sample(s->codec_id) / 8 * s->channels);
pkt->pts = av_gettime(); /* FIXME: We might need something better... */
return 0;
}
AVInputFormat alsa_demuxer = {
"alsa",
"Alsa audio input",
sizeof(AlsaData),
NULL,
audio_read_header,
audio_read_packet,
audio_read_close,
.flags = AVFMT_NOFILE,
};