Libav 0.7.1
|
00001 /* 00002 * sndio play and grab interface 00003 * Copyright (c) 2010 Jacob Meuser 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include <stdint.h> 00023 #include <sndio.h> 00024 00025 #include "libavformat/avformat.h" 00026 00027 #include "sndio_common.h" 00028 00029 static av_cold int audio_write_header(AVFormatContext *s1) 00030 { 00031 SndioData *s = s1->priv_data; 00032 AVStream *st; 00033 int ret; 00034 00035 st = s1->streams[0]; 00036 s->sample_rate = st->codec->sample_rate; 00037 s->channels = st->codec->channels; 00038 00039 ret = ff_sndio_open(s1, 1, s1->filename); 00040 00041 return ret; 00042 } 00043 00044 static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) 00045 { 00046 SndioData *s = s1->priv_data; 00047 uint8_t *buf= pkt->data; 00048 int size = pkt->size; 00049 int len, ret; 00050 00051 while (size > 0) { 00052 len = FFMIN(s->buffer_size - s->buffer_offset, size); 00053 memcpy(s->buffer + s->buffer_offset, buf, len); 00054 buf += len; 00055 size -= len; 00056 s->buffer_offset += len; 00057 if (s->buffer_offset >= s->buffer_size) { 00058 ret = sio_write(s->hdl, s->buffer, s->buffer_size); 00059 if (ret == 0 || sio_eof(s->hdl)) 00060 return AVERROR(EIO); 00061 s->softpos += ret; 00062 s->buffer_offset = 0; 00063 } 00064 } 00065 00066 return 0; 00067 } 00068 00069 static int audio_write_trailer(AVFormatContext *s1) 00070 { 00071 SndioData *s = s1->priv_data; 00072 00073 sio_write(s->hdl, s->buffer, s->buffer_offset); 00074 00075 ff_sndio_close(s); 00076 00077 return 0; 00078 } 00079 00080 AVOutputFormat ff_sndio_muxer = { 00081 .name = "sndio", 00082 .long_name = NULL_IF_CONFIG_SMALL("sndio audio playback"), 00083 .priv_data_size = sizeof(SndioData), 00084 /* XXX: we make the assumption that the soundcard accepts this format */ 00085 /* XXX: find better solution with "preinit" method, needed also in 00086 other formats */ 00087 .audio_codec = AV_NE(CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE), 00088 .video_codec = CODEC_ID_NONE, 00089 .write_header = audio_write_header, 00090 .write_packet = audio_write_packet, 00091 .write_trailer = audio_write_trailer, 00092 .flags = AVFMT_NOFILE, 00093 };