Aidan Richmond: > Format is still used by modders of these old games. > --- > libavformat/Makefile | 1 + > libavformat/allformats.c | 1 + > libavformat/westwood_audenc.c | 120 > ++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 122 insertions(+) > create mode 100644 libavformat/westwood_audenc.c > > diff --git a/libavformat/Makefile b/libavformat/Makefile > index bc1ddfa81c..85b5d8e7eb 100644 > --- a/libavformat/Makefile > +++ b/libavformat/Makefile > @@ -581,6 +581,7 @@ OBJS-$(CONFIG_WEBP_MUXER) += webpenc.o > OBJS-$(CONFIG_WEBVTT_DEMUXER) += webvttdec.o subtitles.o > OBJS-$(CONFIG_WEBVTT_MUXER) += webvttenc.o > OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood_aud.o > +OBJS-$(CONFIG_WSAUD_MUXER) += westwood_audenc.o > OBJS-$(CONFIG_WSD_DEMUXER) += wsddec.o rawdec.o > OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood_vqa.o > OBJS-$(CONFIG_WTV_DEMUXER) += wtvdec.o wtv_common.o \ > diff --git a/libavformat/allformats.c b/libavformat/allformats.c > index fa093c7ac2..fe70a1e9a2 100644 > --- a/libavformat/allformats.c > +++ b/libavformat/allformats.c > @@ -478,6 +478,7 @@ extern AVOutputFormat ff_webp_muxer; > extern AVInputFormat ff_webvtt_demuxer; > extern AVOutputFormat ff_webvtt_muxer; > extern AVInputFormat ff_wsaud_demuxer; > +extern AVOutputFormat ff_wsaud_muxer; > extern AVInputFormat ff_wsd_demuxer; > extern AVInputFormat ff_wsvqa_demuxer; > extern AVInputFormat ff_wtv_demuxer; > diff --git a/libavformat/westwood_audenc.c b/libavformat/westwood_audenc.c > new file mode 100644 > index 0000000000..49310a47c8 > --- /dev/null > +++ b/libavformat/westwood_audenc.c > @@ -0,0 +1,120 @@ > +/* > + * Copyright (c) 2021 Aidan Richmond > + * > + * 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 > + */ > + > +/** > + * @file > + * Westwood Studios AUD file muxer > + * by Aidan Richmond (aidan...@hotmail.co.uk) > + * > + * This muxer supports IMA ADPCM packed in westwoods format. > + * > + * @see http://xhp.xwis.net/documents/aud3.txt > + */ > + > +#include "avformat.h" > +#include "internal.h" > + > +#define AUD_CHUNK_SIGNATURE 0x0000DEAF > + > +typedef struct AUDMuxContext { > + int uncomp_size; > + int size; > +} AUDMuxContext; > + > +static int wsaud_write_header(AVFormatContext *ctx) > +{ > + AVStream *s = ctx->streams[0];
We typically use st for AVStream (and s is (for some reason used for AVFormatContext). > + AVIOContext *pb = ctx->pb; > + AUDMuxContext *a = ctx->priv_data; > + unsigned char flags = 0; > + > + if (s->codecpar->codec_id != AV_CODEC_ID_ADPCM_IMA_WS) { > + AVCodec *codec = > avcodec_find_decoder(ctx->streams[0]->codecpar->codec_id); Use avcodec_get_name() directly. Furthermore use > + av_log(s, AV_LOG_ERROR, "%s codec not supported for Westwood AUD.\n", > + codec ? codec->name : "NONE"); > + return -1; > + } > + > + if (ctx->nb_streams != 1) { > + av_log(s, AV_LOG_ERROR, "AUD files have exactly one stream\n"); > + return AVERROR(EINVAL); > + } > + > + a->uncomp_size = 0; > + a->size = 0; > + > + /* Flag if we have stereo data. */ > + if (s->codecpar->channels == 2) > + flags |= 1; > + > + /* This flags that the file contains 16 bit samples rather than 8 bit > + since the encoder only encodes 16 bit samples this should be set. */ > + flags |= 2; You presume that libavformat is only used in conjunction with the current libavcodec version. But the packets might come from another encoder or a future version of libavcodec. I presume the information about the bitness is contained in codecpar->bits_per_raw_sample or so. > + > + avio_wl16(pb, s->codecpar->sample_rate); > + /* We don't know the file size yet, so just skip forward 8 bytes */ > + avio_seek(pb, 8, SEEK_CUR); Then just zero this field. > + avio_w8(pb, flags); > + /* 99 indicates the ADPCM format. Other formats not supported. */ > + avio_w8(pb, 99); > + > + return 0; > +} > + > +static int wsaud_write_packet(AVFormatContext *ctx, AVPacket *pkt) > +{ > + AVIOContext *pb = ctx->pb; > + AUDMuxContext *a = ctx->priv_data; > + > + /* Assumes ADPCM since this muxer doesn't support SND1 or PCM format. */ > + avio_wl16(pb, pkt->size); > + avio_wl16(pb, pkt->size * 4); You need to check that this indeed fits into an uint16_t. > + avio_wl32(pb, AUD_CHUNK_SIGNATURE); > + avio_write(pb, pkt->data, pkt->size); > + a->size += pkt->size + 8; > + a->uncomp_size += pkt->size * 4; > + > + return 0; > +} > + > +static int wsaud_write_trailer(AVFormatContext *ctx) > +{ > + AVIOContext *pb = ctx->pb; > + AUDMuxContext *a = ctx->priv_data; > + > + avio_seek(pb, 2, SEEK_SET); Don't just seek, check whether the file is seekable first. Otherwise you will write junk at the end of the output. > + avio_wl32(pb, a->size); > + avio_wl32(pb, a->uncomp_size); > + > + return 0; > +} > + > +AVOutputFormat ff_wsaud_muxer = { > + .name = "wsaud", > + .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios audio"), > + .extensions = "aud", > + .priv_data_size = sizeof(AUDMuxContext), > + .audio_codec = AV_CODEC_ID_ADPCM_IMA_WS, > + .video_codec = AV_CODEC_ID_NONE, > + .flags = AVFMT_TS_NONSTRICT, > + .write_header = wsaud_write_header, > + .write_packet = wsaud_write_packet, > + .write_trailer = wsaud_write_trailer, > +}; > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".