mirror of https://github.com/FFmpeg/FFmpeg.git
The libavformat API is not suitable for exporting output devices as muxers. Some practical problems are e.g. lack of timing/synchronization mechanisms or interaction with output-specific features.pull/272/head
parent
eb3c1a94ad
commit
8e7e042d41
12 changed files with 22 additions and 419 deletions
@ -1,33 +0,0 @@ |
|||||||
@chapter Output Devices |
|
||||||
@c man begin OUTPUT DEVICES |
|
||||||
|
|
||||||
Output devices are configured elements in Libav which allow to write |
|
||||||
multimedia data to an output device attached to your system. |
|
||||||
|
|
||||||
When you configure your Libav build, all the supported output devices |
|
||||||
are enabled by default. You can list all available ones using the |
|
||||||
configure option "--list-outdevs". |
|
||||||
|
|
||||||
You can disable all the output devices using the configure option |
|
||||||
"--disable-outdevs", and selectively enable an output device using the |
|
||||||
option "--enable-outdev=@var{OUTDEV}", or you can disable a particular |
|
||||||
input device using the option "--disable-outdev=@var{OUTDEV}". |
|
||||||
|
|
||||||
The option "-formats" of the av* tools will display the list of |
|
||||||
enabled output devices (amongst the muxers). |
|
||||||
|
|
||||||
A description of the currently available output devices follows. |
|
||||||
|
|
||||||
@section alsa |
|
||||||
|
|
||||||
ALSA (Advanced Linux Sound Architecture) output device. |
|
||||||
|
|
||||||
@section oss |
|
||||||
|
|
||||||
OSS (Open Sound System) output device. |
|
||||||
|
|
||||||
@section sndio |
|
||||||
|
|
||||||
sndio audio output device. |
|
||||||
|
|
||||||
@c man end OUTPUT DEVICES |
|
@ -1,117 +0,0 @@ |
|||||||
/*
|
|
||||||
* ALSA input and output |
|
||||||
* Copyright (c) 2007 Luca Abeni ( lucabe72 email it ) |
|
||||||
* Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr ) |
|
||||||
* |
|
||||||
* This file is part of Libav. |
|
||||||
* |
|
||||||
* Libav is free software; you can redistribute it and/or |
|
||||||
* modify it under the terms of the GNU Lesser General Public |
|
||||||
* License as published by the Free Software Foundation; either |
|
||||||
* version 2.1 of the License, or (at your option) any later version. |
|
||||||
* |
|
||||||
* Libav is distributed in the hope that it will be useful, |
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||||
* Lesser General Public License for more details. |
|
||||||
* |
|
||||||
* You should have received a copy of the GNU Lesser General Public |
|
||||||
* License along with Libav; if not, write to the Free Software |
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
||||||
*/ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @file |
|
||||||
* ALSA input and output: output |
|
||||||
* @author Luca Abeni ( lucabe72 email it ) |
|
||||||
* @author Benoit Fouet ( benoit fouet free fr ) |
|
||||||
* |
|
||||||
* This avdevice encoder allows to play audio to an ALSA (Advanced Linux |
|
||||||
* Sound Architecture) device. |
|
||||||
* |
|
||||||
* The filename parameter is the name of an ALSA PCM device capable of |
|
||||||
* capture, for example "default" or "plughw:1"; see the ALSA documentation |
|
||||||
* for naming conventions. The empty string is equivalent to "default". |
|
||||||
* |
|
||||||
* The playback period is set to the lower value available for the device, |
|
||||||
* which gives a low latency suitable for real-time playback. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <alsa/asoundlib.h> |
|
||||||
|
|
||||||
#include "libavutil/internal.h" |
|
||||||
|
|
||||||
#include "libavformat/avformat.h" |
|
||||||
|
|
||||||
#include "alsa.h" |
|
||||||
|
|
||||||
static av_cold int audio_write_header(AVFormatContext *s1) |
|
||||||
{ |
|
||||||
AlsaData *s = s1->priv_data; |
|
||||||
AVStream *st; |
|
||||||
unsigned int sample_rate; |
|
||||||
enum AVCodecID codec_id; |
|
||||||
int res; |
|
||||||
|
|
||||||
st = s1->streams[0]; |
|
||||||
sample_rate = st->codecpar->sample_rate; |
|
||||||
codec_id = st->codecpar->codec_id; |
|
||||||
res = ff_alsa_open(s1, SND_PCM_STREAM_PLAYBACK, &sample_rate, |
|
||||||
st->codecpar->channels, &codec_id); |
|
||||||
if (sample_rate != st->codecpar->sample_rate) { |
|
||||||
av_log(s1, AV_LOG_ERROR, |
|
||||||
"sample rate %d not available, nearest is %d\n", |
|
||||||
st->codecpar->sample_rate, sample_rate); |
|
||||||
goto fail; |
|
||||||
} |
|
||||||
|
|
||||||
return res; |
|
||||||
|
|
||||||
fail: |
|
||||||
snd_pcm_close(s->h); |
|
||||||
return AVERROR(EIO); |
|
||||||
} |
|
||||||
|
|
||||||
static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) |
|
||||||
{ |
|
||||||
AlsaData *s = s1->priv_data; |
|
||||||
int res; |
|
||||||
int size = pkt->size; |
|
||||||
uint8_t *buf = pkt->data; |
|
||||||
|
|
||||||
size /= s->frame_size; |
|
||||||
if (s->reorder_func) { |
|
||||||
if (size > s->reorder_buf_size) |
|
||||||
if (ff_alsa_extend_reorder_buf(s, size)) |
|
||||||
return AVERROR(ENOMEM); |
|
||||||
s->reorder_func(buf, s->reorder_buf, size); |
|
||||||
buf = s->reorder_buf; |
|
||||||
} |
|
||||||
while ((res = snd_pcm_writei(s->h, buf, size)) < 0) { |
|
||||||
if (res == -EAGAIN) { |
|
||||||
|
|
||||||
return AVERROR(EAGAIN); |
|
||||||
} |
|
||||||
|
|
||||||
if (ff_alsa_xrun_recover(s1, res) < 0) { |
|
||||||
av_log(s1, AV_LOG_ERROR, "ALSA write error: %s\n", |
|
||||||
snd_strerror(res)); |
|
||||||
|
|
||||||
return AVERROR(EIO); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
AVOutputFormat ff_alsa_muxer = { |
|
||||||
.name = "alsa", |
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("ALSA audio output"), |
|
||||||
.priv_data_size = sizeof(AlsaData), |
|
||||||
.audio_codec = DEFAULT_CODEC_ID, |
|
||||||
.video_codec = AV_CODEC_ID_NONE, |
|
||||||
.write_header = audio_write_header, |
|
||||||
.write_packet = audio_write_packet, |
|
||||||
.write_trailer = ff_alsa_close, |
|
||||||
.flags = AVFMT_NOFILE, |
|
||||||
}; |
|
@ -1,108 +0,0 @@ |
|||||||
/*
|
|
||||||
* Linux audio grab interface |
|
||||||
* Copyright (c) 2000, 2001 Fabrice Bellard |
|
||||||
* |
|
||||||
* This file is part of Libav. |
|
||||||
* |
|
||||||
* Libav is free software; you can redistribute it and/or |
|
||||||
* modify it under the terms of the GNU Lesser General Public |
|
||||||
* License as published by the Free Software Foundation; either |
|
||||||
* version 2.1 of the License, or (at your option) any later version. |
|
||||||
* |
|
||||||
* Libav is distributed in the hope that it will be useful, |
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||||
* Lesser General Public License for more details. |
|
||||||
* |
|
||||||
* You should have received a copy of the GNU Lesser General Public |
|
||||||
* License along with Libav; if not, write to the Free Software |
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
||||||
*/ |
|
||||||
|
|
||||||
#include "config.h" |
|
||||||
|
|
||||||
#if HAVE_SOUNDCARD_H |
|
||||||
#include <soundcard.h> |
|
||||||
#else |
|
||||||
#include <sys/soundcard.h> |
|
||||||
#endif |
|
||||||
|
|
||||||
#include <unistd.h> |
|
||||||
#include <fcntl.h> |
|
||||||
#include <sys/ioctl.h> |
|
||||||
|
|
||||||
#include "libavutil/internal.h" |
|
||||||
|
|
||||||
#include "libavcodec/avcodec.h" |
|
||||||
|
|
||||||
#include "libavformat/avformat.h" |
|
||||||
#include "libavformat/internal.h" |
|
||||||
|
|
||||||
#include "oss.h" |
|
||||||
|
|
||||||
static int audio_write_header(AVFormatContext *s1) |
|
||||||
{ |
|
||||||
OSSAudioData *s = s1->priv_data; |
|
||||||
AVStream *st; |
|
||||||
int ret; |
|
||||||
|
|
||||||
st = s1->streams[0]; |
|
||||||
s->sample_rate = st->codecpar->sample_rate; |
|
||||||
s->channels = st->codecpar->channels; |
|
||||||
ret = ff_oss_audio_open(s1, 1, s1->filename); |
|
||||||
if (ret < 0) { |
|
||||||
return AVERROR(EIO); |
|
||||||
} else { |
|
||||||
return 0; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) |
|
||||||
{ |
|
||||||
OSSAudioData *s = s1->priv_data; |
|
||||||
int len, ret; |
|
||||||
int size= pkt->size; |
|
||||||
uint8_t *buf= pkt->data; |
|
||||||
|
|
||||||
while (size > 0) { |
|
||||||
len = FFMIN(OSS_AUDIO_BLOCK_SIZE - s->buffer_ptr, size); |
|
||||||
memcpy(s->buffer + s->buffer_ptr, buf, len); |
|
||||||
s->buffer_ptr += len; |
|
||||||
if (s->buffer_ptr >= OSS_AUDIO_BLOCK_SIZE) { |
|
||||||
for(;;) { |
|
||||||
ret = write(s->fd, s->buffer, OSS_AUDIO_BLOCK_SIZE); |
|
||||||
if (ret > 0) |
|
||||||
break; |
|
||||||
if (ret < 0 && (errno != EAGAIN && errno != EINTR)) |
|
||||||
return AVERROR(EIO); |
|
||||||
} |
|
||||||
s->buffer_ptr = 0; |
|
||||||
} |
|
||||||
buf += len; |
|
||||||
size -= len; |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
static int audio_write_trailer(AVFormatContext *s1) |
|
||||||
{ |
|
||||||
OSSAudioData *s = s1->priv_data; |
|
||||||
|
|
||||||
ff_oss_audio_close(s); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
AVOutputFormat ff_oss_muxer = { |
|
||||||
.name = "oss", |
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("OSS (Open Sound System) playback"), |
|
||||||
.priv_data_size = sizeof(OSSAudioData), |
|
||||||
/* XXX: we make the assumption that the soundcard accepts this format */ |
|
||||||
/* XXX: find better solution with "preinit" method, needed also in
|
|
||||||
other formats */ |
|
||||||
.audio_codec = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE), |
|
||||||
.video_codec = AV_CODEC_ID_NONE, |
|
||||||
.write_header = audio_write_header, |
|
||||||
.write_packet = audio_write_packet, |
|
||||||
.write_trailer = audio_write_trailer, |
|
||||||
.flags = AVFMT_NOFILE, |
|
||||||
}; |
|
@ -1,95 +0,0 @@ |
|||||||
/*
|
|
||||||
* sndio play and grab interface |
|
||||||
* Copyright (c) 2010 Jacob Meuser |
|
||||||
* |
|
||||||
* This file is part of Libav. |
|
||||||
* |
|
||||||
* Libav is free software; you can redistribute it and/or |
|
||||||
* modify it under the terms of the GNU Lesser General Public |
|
||||||
* License as published by the Free Software Foundation; either |
|
||||||
* version 2.1 of the License, or (at your option) any later version. |
|
||||||
* |
|
||||||
* Libav is distributed in the hope that it will be useful, |
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||||
* Lesser General Public License for more details. |
|
||||||
* |
|
||||||
* You should have received a copy of the GNU Lesser General Public |
|
||||||
* License along with Libav; if not, write to the Free Software |
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <stdint.h> |
|
||||||
#include <sndio.h> |
|
||||||
|
|
||||||
#include "libavutil/internal.h" |
|
||||||
|
|
||||||
#include "libavformat/avformat.h" |
|
||||||
|
|
||||||
#include "libavdevice/sndio.h" |
|
||||||
|
|
||||||
static av_cold int audio_write_header(AVFormatContext *s1) |
|
||||||
{ |
|
||||||
SndioData *s = s1->priv_data; |
|
||||||
AVStream *st; |
|
||||||
int ret; |
|
||||||
|
|
||||||
st = s1->streams[0]; |
|
||||||
s->sample_rate = st->codecpar->sample_rate; |
|
||||||
s->channels = st->codecpar->channels; |
|
||||||
|
|
||||||
ret = ff_sndio_open(s1, 1, s1->filename); |
|
||||||
|
|
||||||
return ret; |
|
||||||
} |
|
||||||
|
|
||||||
static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) |
|
||||||
{ |
|
||||||
SndioData *s = s1->priv_data; |
|
||||||
uint8_t *buf= pkt->data; |
|
||||||
int size = pkt->size; |
|
||||||
int len, ret; |
|
||||||
|
|
||||||
while (size > 0) { |
|
||||||
len = FFMIN(s->buffer_size - s->buffer_offset, size); |
|
||||||
memcpy(s->buffer + s->buffer_offset, buf, len); |
|
||||||
buf += len; |
|
||||||
size -= len; |
|
||||||
s->buffer_offset += len; |
|
||||||
if (s->buffer_offset >= s->buffer_size) { |
|
||||||
ret = sio_write(s->hdl, s->buffer, s->buffer_size); |
|
||||||
if (ret == 0 || sio_eof(s->hdl)) |
|
||||||
return AVERROR(EIO); |
|
||||||
s->softpos += ret; |
|
||||||
s->buffer_offset = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
static int audio_write_trailer(AVFormatContext *s1) |
|
||||||
{ |
|
||||||
SndioData *s = s1->priv_data; |
|
||||||
|
|
||||||
sio_write(s->hdl, s->buffer, s->buffer_offset); |
|
||||||
|
|
||||||
ff_sndio_close(s); |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
AVOutputFormat ff_sndio_muxer = { |
|
||||||
.name = "sndio", |
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("sndio audio playback"), |
|
||||||
.priv_data_size = sizeof(SndioData), |
|
||||||
/* XXX: we make the assumption that the soundcard accepts this format */ |
|
||||||
/* XXX: find better solution with "preinit" method, needed also in
|
|
||||||
other formats */ |
|
||||||
.audio_codec = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE), |
|
||||||
.video_codec = AV_CODEC_ID_NONE, |
|
||||||
.write_header = audio_write_header, |
|
||||||
.write_packet = audio_write_packet, |
|
||||||
.write_trailer = audio_write_trailer, |
|
||||||
.flags = AVFMT_NOFILE, |
|
||||||
}; |
|
Loading…
Reference in new issue