From patchwork Mon Mar 16 01:25:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: nia X-Patchwork-Id: 18218 Delivered-To: andriy.gelman@gmail.com Received: by 2002:a0c:ab15:0:0:0:0:0 with SMTP id h21csp654887qvb; Sun, 15 Mar 2020 18:26:01 -0700 (PDT) X-Google-Smtp-Source: ADFU+vsawkQlEU7rZyV2Kvi0xSqJgFmLkmvbpsLrpLDXXLnAJ1FmnAaGr3Rlex8476S+W6UMXfPy X-Received: by 2002:a05:6402:306f:: with SMTP id bs15mr191350edb.58.1584321961461; Sun, 15 Mar 2020 18:26:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1584321961; cv=none; d=google.com; s=arc-20160816; b=yzQv+EA1aKNcQeO0EntSRFQnj78p4EG40LXvyPLkpgyucnaMy+vvi27LmJ03GOA+tT ddLAsEMEdHXJJXVTmnmZSUt5zrJVulcLc1doxm3AbbjnvjMDx/dJRGKq++9MFoffzyOm qnrzAbtJCLzdrAxhqVuwHgLOIb+LiLm4Y8aIUgKQJkybrFJ/3j6KNapkMzCEdb/A+ick 4+p0OjUkNusnnfG2OuJsfvz/2xSxW0sCNRS8dYJF544ixuQ/9ewR2mpP98OacTCQsG8O SzCLd0KAXLcnEvZmINgl1VlsOe3kme0dbTPlmzsxEJKzD4MQfAd6VknH3Ia7+HLZA8AW 98Nw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:user-agent:content-disposition:mime-version :message-id:to:from:date:delivered-to; bh=0jCQjPLcvXQ/mxbDCh8MhJRxf2l+MgAmHqsOs4S/5wk=; b=S9h54MGLWntY8tNtogiuJTLBF8UTMTlBwSfxZ5S3hSDAbk8stixdzrI3hXL3kKauLl t1P521MyStoaASBcU23h6nrCCkpBrpFR87BjDETjVuqb6+d45nQ8InT6XlvL2EVIITNQ R7UVC9fV01ZgD3iLykO+BqU98Pl8huV9EWg+fDfoamjOMi7qeES2hhp8XwxhDYSRUlr3 Vd975mhKEePcNVAZkpLc6zmk8GulcQEhX/+HJLkzCLzgougZmpFj/gkJtV9xhS1oQzEK Z6YHltmua8RFT+27ZVi8ccpuwAiOLxEAGaSxJOD9qpLnOLiswf7BqMafh/ak6DWISt4l DLCg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id r20si4283805edo.117.2020.03.15.18.26.00; Sun, 15 Mar 2020 18:26:01 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E025168B405; Mon, 16 Mar 2020 03:25:56 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4911368B1E1 for ; Mon, 16 Mar 2020 03:25:49 +0200 (EET) Received: by mail.netbsd.org (Postfix, from userid 1524) id 0DF8784D25; Mon, 16 Mar 2020 01:25:47 +0000 (UTC) Date: Mon, 16 Mar 2020 01:25:47 +0000 From: nia To: ffmpeg-devel@ffmpeg.org Message-ID: <20200316012547.GA19513@homeworld.netbsd.org> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.12.2 (2019-09-21) Subject: [FFmpeg-devel] [PATCH] avdevice: Add support for Solaris/NetBSD audio - sunau X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: lUs1/8G1/WL/ Content-Length: 25277 It's expected this will primarily be used on NetBSD as most Solarish platforms seem to prefer either OSS or PulseAudio now. The OSS support in FFmpeg has some problems on NetBSD due to implementation differences between OSSv4 and NetBSD's OSS emulation layer. Using the relatively well documented native API, cross-referencing with illumos documentation to maintain compatibility, we can get much better results with higher quality recording and playback without the problems caused by non-blocking I/O and reading from the device with the incorrect number of channels. Signed-off-by: Nia Alarie --- configure | 4 ++ doc/general.texi | 1 + doc/indevs.texi | 29 ++++++++ doc/outdevs.texi | 11 ++++ libavdevice/Makefile | 2 + libavdevice/alldevices.c | 2 + libavdevice/sunau.c | 102 +++++++++++++++++++++++++++++ libavdevice/sunau.h | 48 ++++++++++++++ libavdevice/sunau_dec.c | 138 +++++++++++++++++++++++++++++++++++++++ libavdevice/sunau_enc.c | 114 ++++++++++++++++++++++++++++++++ 10 files changed, 451 insertions(+) create mode 100644 libavdevice/sunau.c create mode 100644 libavdevice/sunau.h create mode 100644 libavdevice/sunau_dec.c create mode 100644 libavdevice/sunau_enc.c diff --git a/configure b/configure index 6ceb0c7af4..29a2b38629 100755 --- a/configure +++ b/configure @@ -2129,6 +2129,7 @@ HEADERS_LIST=" sys_resource_h sys_select_h sys_soundcard_h + sys_audioio_h sys_time_h sys_un_h sys_videoio_h @@ -3375,6 +3376,8 @@ opengl_outdev_deps="opengl" opengl_outdev_suggest="sdl2" oss_indev_deps_any="sys_soundcard_h" oss_outdev_deps_any="sys_soundcard_h" +sunau_indev_deps_any="sys_audioio_h" +sunau_outdev_deps_any="sys_audioio_h" pulse_indev_deps="libpulse" pulse_outdev_deps="libpulse" sdl2_outdev_deps="sdl2" @@ -6082,6 +6085,7 @@ check_headers libcrystalhd/libcrystalhd_if.h check_headers malloc.h check_headers net/udplite.h check_headers poll.h +check_headers sys/audioio.h check_headers sys/param.h check_headers sys/resource.h check_headers sys/select.h diff --git a/doc/general.texi b/doc/general.texi index 3684847ac1..2231a1442f 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -1382,6 +1382,7 @@ performance on systems without hardware floating point support). @item OSS @tab X @tab X @item PulseAudio @tab X @tab X @item SDL @tab @tab X +@item Sun Audio @tab @tab X @item Video4Linux2 @tab X @tab X @item VfW capture @tab X @tab @item X11 grabbing @tab X @tab diff --git a/doc/indevs.texi b/doc/indevs.texi index 6f5afaf344..c55dcb6329 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -1285,6 +1285,35 @@ Set the number of channels. Default is 2. @end table +@section sunau + +Solaris/NetBSD audio input device. + +The filename to provide to the input device is the device node +representing the Sun input device, and is usually set to +@file{/dev/audio0}. + +For example to grab from @file{/dev/audio0} using @command{ffmpeg} use the +command: +@example +ffmpeg -f sunau -i /dev/audio0 /tmp/oss.wav +@end example + +@subsection Options + +@table @option + +@item buffer_samples +Set the size of the audio buffer in samples. Default is 32. + +@item sample_rate +Set the sample rate in Hz. Default is 48000. + +@item channels +Set the number of channels. Default is 2. + +@end table + @section video4linux2, v4l2 Video4Linux2 input video device. diff --git a/doc/outdevs.texi b/doc/outdevs.texi index 60606eb6e7..5a327adbb0 100644 --- a/doc/outdevs.texi +++ b/doc/outdevs.texi @@ -395,6 +395,17 @@ ffmpeg -i INPUT -c:v rawvideo -pix_fmt yuv420p -window_size qcif -f sdl "SDL out sndio audio output device. +@section sunau + +Solaris/NetBSD audio output device. + +@subsection Options +@table @option + +@item buffer_samples +Set the size of the audio buffer in samples. Default is 32. +@end table + @section v4l2 Video4Linux2 output device. diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 6ea62b914e..51d703d824 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -43,6 +43,8 @@ OBJS-$(CONFIG_PULSE_OUTDEV) += pulse_audio_enc.o \ OBJS-$(CONFIG_SDL2_OUTDEV) += sdl2.o OBJS-$(CONFIG_SNDIO_INDEV) += sndio_dec.o sndio.o OBJS-$(CONFIG_SNDIO_OUTDEV) += sndio_enc.o sndio.o +OBJS-$(CONFIG_SUNAU_INDEV) += sunau_dec.o sunau.o +OBJS-$(CONFIG_SUNAU_OUTDEV) += sunau_enc.o sunau.o OBJS-$(CONFIG_V4L2_INDEV) += v4l2.o v4l2-common.o timefilter.o OBJS-$(CONFIG_V4L2_OUTDEV) += v4l2enc.o v4l2-common.o OBJS-$(CONFIG_VFWCAP_INDEV) += vfwcap.o diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c index 8633433254..c2fce8a4f3 100644 --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c @@ -49,6 +49,8 @@ extern AVOutputFormat ff_pulse_muxer; extern AVOutputFormat ff_sdl2_muxer; extern AVInputFormat ff_sndio_demuxer; extern AVOutputFormat ff_sndio_muxer; +extern AVInputFormat ff_sunau_demuxer; +extern AVOutputFormat ff_sunau_muxer; extern AVInputFormat ff_v4l2_demuxer; extern AVOutputFormat ff_v4l2_muxer; extern AVInputFormat ff_vfwcap_demuxer; diff --git a/libavdevice/sunau.c b/libavdevice/sunau.c new file mode 100644 index 0000000000..a707388617 --- /dev/null +++ b/libavdevice/sunau.c @@ -0,0 +1,102 @@ +/* + * Solaris/NetBSD play and grab interface + * Copyright (c) 2020 Yorick Hardy + * Copyright (c) 2020 Nia Alarie + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include + +#include +#include +#include +#include + +#include "libavutil/log.h" + +#include "libavcodec/avcodec.h" +#include "avdevice.h" + +#include "sunau.h" + +int ff_sunau_audio_open(AVFormatContext *s1, int is_output, + const char *audio_device) +{ + SunAudioData *s = s1->priv_data; + struct audio_info info; + struct audio_prinfo *prinfo; + int audio_fd, err; + + audio_fd = avpriv_open(audio_device, is_output ? O_WRONLY : O_RDONLY); + if (audio_fd < 0) { + av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, av_err2str(AVERROR(errno))); + return AVERROR(EIO); + } + + AUDIO_INITINFO(&info); + +#ifdef AUMODE_PLAY /* BSD extension */ + info.mode = is_output ? AUMODE_PLAY : AUMODE_RECORD; +#endif + + prinfo = is_output ? &info.play : &info.record; + + prinfo->encoding = AUDIO_ENCODING_LINEAR; + prinfo->precision = 16; + prinfo->sample_rate = s->sample_rate; + prinfo->channels = s->channels; + + if ((err = ioctl(audio_fd, AUDIO_SETINFO, &info)) < 0) { + av_log(s1, AV_LOG_ERROR, "AUDIO_SETINFO: %s\n", av_err2str(AVERROR(errno))); + goto fail; + } + + if ((err = ioctl(audio_fd, AUDIO_GETINFO, &info)) < 0) { + av_log(s1, AV_LOG_ERROR, "AUDIO_GETINFO: %s\n", av_err2str(AVERROR(errno))); + goto fail; + } + + s->fd = audio_fd; +#ifdef HAVE_BIGENDIAN + s->codec_id = AV_CODEC_ID_PCM_S16BE; +#else + s->codec_id = AV_CODEC_ID_PCM_S16LE; +#endif + s->precision = prinfo->precision; + s->sample_rate = prinfo->sample_rate; + s->channels = prinfo->channels; + s->blocksize = s->buffer_samples * prinfo->precision * prinfo->channels; + + if ((s->buffer = malloc(s->blocksize)) == NULL) { + av_log(s1, AV_LOG_ERROR, "malloc: %s\n", av_err2str(AVERROR(errno))); + goto fail; + } + + return 0; + fail: + close(audio_fd); + return AVERROR(EIO); +} + +int ff_sunau_audio_close(SunAudioData *s) +{ + close(s->fd); + return 0; +} diff --git a/libavdevice/sunau.h b/libavdevice/sunau.h new file mode 100644 index 0000000000..27dd8bec68 --- /dev/null +++ b/libavdevice/sunau.h @@ -0,0 +1,48 @@ +/* + * Solaris/NetBSD play and grab interface + * Copyright (c) 2020 Yorick Hardy + * Copyright (c) 2020 Nia Alarie + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVDEVICE_SUNAU_H +#define AVDEVICE_SUNAU_H + +#include "libavcodec/avcodec.h" + +#include "libavformat/avformat.h" + +typedef struct SunAudioData { + AVClass *class; + int fd; + int buffer_samples; + unsigned int sample_rate; + unsigned int channels; + unsigned int precision; + size_t blocksize; + enum AVCodecID codec_id; + uint8_t *buffer; + size_t buffer_ptr; +} SunAudioData; + +int ff_sunau_audio_open(AVFormatContext *s1, int is_output, + const char *audio_device); + +int ff_sunau_audio_close(SunAudioData *s); + +#endif /* AVDEVICE_SUNAU_H */ diff --git a/libavdevice/sunau_dec.c b/libavdevice/sunau_dec.c new file mode 100644 index 0000000000..7157fbc6d6 --- /dev/null +++ b/libavdevice/sunau_dec.c @@ -0,0 +1,138 @@ +/* + * Solaris/NetBSD play and grab interface + * Copyright (c) 2020 Yorick Hardy + * Copyright (c) 2020 Nia Alarie + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include + +#include +#include +#include +#include +#include + +#include "libavutil/internal.h" +#include "libavutil/opt.h" +#include "libavutil/time.h" + +#include "libavcodec/avcodec.h" + +#include "avdevice.h" +#include "libavformat/internal.h" + +#include "sunau.h" + +static int audio_read_header(AVFormatContext *s1) +{ + SunAudioData *s = s1->priv_data; + AVStream *st; + + st = avformat_new_stream(s1, NULL); + if (!st) { + return AVERROR(ENOMEM); + } + + if (ff_sunau_audio_open(s1, 0, s1->url) < 0) { + return AVERROR(EIO); + } + + /* take real parameters */ + st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; + st->codecpar->codec_id = s->codec_id; + st->codecpar->sample_rate = s->sample_rate; + st->codecpar->channels = s->channels; + + avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ + + return 0; +} + +static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) +{ + SunAudioData *s = s1->priv_data; + struct audio_info info; + int ret; + long bdelay; + int64_t cur_time; + + if ((ret = av_new_packet(pkt, s->blocksize)) < 0) + return ret; + + ret = read(s->fd, pkt->data, pkt->size); + if (ret <= 0) { + av_packet_unref(pkt); + pkt->size = 0; + return ret < 0 ? AVERROR(errno) : AVERROR_EOF; + } + + /* compute pts of the start of the packet */ + cur_time = av_gettime(); + bdelay = ret; + +#ifdef AUDIO_GETBUFINFO /* BSD extension */ + if (ioctl(s->fd, AUDIO_GETBUFINFO, &info) == 0) { + bdelay += info.record.seek; + } +#endif + + /* subtract time represented by the number of bytes in the audio fifo */ + cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels * s->precision); + + /* convert to wanted units */ + pkt->pts = cur_time; + + return 0; +} + +static int audio_read_close(AVFormatContext *s1) +{ + SunAudioData *s = s1->priv_data; + + ff_sunau_audio_close(s); + return 0; +} + +static const AVOption options[] = { + { "buffer_samples", "", offsetof(SunAudioData, buffer_samples), AV_OPT_TYPE_INT, {.i64 = 32}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, + { "sample_rate", "", offsetof(SunAudioData, sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 1000, 192000, AV_OPT_FLAG_DECODING_PARAM }, + { "channels", "", offsetof(SunAudioData, channels), AV_OPT_TYPE_INT, {.i64 = 2}, 1, 12, AV_OPT_FLAG_DECODING_PARAM }, + { NULL }, +}; + +static const AVClass sunau_demuxer_class = { + .class_name = "Sun/NetBSD audio demuxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, +}; + +AVInputFormat ff_sunau_demuxer = { + .name = "sunau", + .long_name = NULL_IF_CONFIG_SMALL("Sun/NetBSD audio capture"), + .priv_data_size = sizeof(SunAudioData), + .read_header = audio_read_header, + .read_packet = audio_read_packet, + .read_close = audio_read_close, + .flags = AVFMT_NOFILE, + .priv_class = &sunau_demuxer_class, +}; diff --git a/libavdevice/sunau_enc.c b/libavdevice/sunau_enc.c new file mode 100644 index 0000000000..f71705d9ca --- /dev/null +++ b/libavdevice/sunau_enc.c @@ -0,0 +1,114 @@ +/* + * Solaris/NetBSD play and grab interface + * Copyright (c) 2020 Yorick Hardy + * Copyright (c) 2020 Nia Alarie + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "libavutil/internal.h" + +#include "libavcodec/avcodec.h" + +#include "avdevice.h" +#include "libavformat/internal.h" + +#include "sunau.h" + +static int audio_write_header(AVFormatContext *s1) +{ + SunAudioData *s = s1->priv_data; + AVStream *st; + + st = s1->streams[0]; + s->sample_rate = st->codecpar->sample_rate; + s->channels = st->codecpar->channels; + s->codec_id = st->codecpar->codec_id; + return ff_sunau_audio_open(s1, 1, s1->url) < 0 ? AVERROR(EIO) : 0; +} + +static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) +{ + SunAudioData *s = s1->priv_data; + unsigned int len, size = pkt->size; + uint8_t *buf = pkt->data; + int ret; + + while (size > 0) { + len = FFMIN(s->blocksize - s->buffer_ptr, size); + memcpy(s->buffer + s->buffer_ptr, buf, len); + s->buffer_ptr += len; + if (s->buffer_ptr >= s->blocksize) { + for (;;) { + ret = write(s->fd, s->buffer, s->blocksize); + 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) +{ + SunAudioData *s = s1->priv_data; + + ff_sunau_audio_close(s); + return 0; +} + +static const AVOption options[] = { + { "buffer_samples", "", offsetof(SunAudioData, buffer_samples), AV_OPT_TYPE_INT, {.i64 = 32}, 1, 192000, AV_OPT_FLAG_DECODING_PARAM }, + { NULL }, +}; + +static const AVClass sunau_muxer_class = { + .class_name = "Sun/NetBSD audio muxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, +}; + +AVOutputFormat ff_sunau_muxer = { + .name = "sunau", + .long_name = NULL_IF_CONFIG_SMALL("Sun/NetBSD audio playback"), + .priv_data_size = sizeof(SunAudioData), + /* XXX: we may need to support higher precisions in the future, but + right now this is what the kernel can handle natively */ + /* 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, + .priv_class = &sunau_muxer_class, +};