Message ID | 20200410031015.24404-2-zane@zanevaniperen.com |
---|---|
State | Superseded |
Headers | show |
Series | [FFmpeg-devel,1/2] avcodec: add adpcm_ima_ssi encoder | expand |
Context | Check | Description |
---|---|---|
andriy/ffmpeg-patchwork | success | Make fate finished |
On 4/10/2020 12:10 AM, Zane van Iperen wrote: > Signed-off-by: Zane van Iperen <zane@zanevaniperen.com> > --- > Changelog | 1 + > libavformat/Makefile | 1 + > libavformat/allformats.c | 1 + > libavformat/kvag.c | 78 +++++++++++++++++++++++++++++++++++++++- > libavformat/version.h | 2 +- > 5 files changed, 81 insertions(+), 2 deletions(-) > > diff --git a/Changelog b/Changelog > index b4fff44329..b2de88484b 100644 > --- a/Changelog > +++ b/Changelog > @@ -57,6 +57,7 @@ version <next>: > - overlay_cuda filter > - switch from AvxSynth to AviSynth+ on Linux > - Simon & Schuster Interactive ADPCM encoder > +- Real War KVAG muxer > > > version 4.2: > diff --git a/libavformat/Makefile b/libavformat/Makefile > index 8fd0d43721..ff920c4373 100644 > --- a/libavformat/Makefile > +++ b/libavformat/Makefile > @@ -285,6 +285,7 @@ OBJS-$(CONFIG_JACOSUB_MUXER) += jacosubenc.o rawenc.o > OBJS-$(CONFIG_JV_DEMUXER) += jvdec.o > OBJS-$(CONFIG_KUX_DEMUXER) += flvdec.o > OBJS-$(CONFIG_KVAG_DEMUXER) += kvag.o > +OBJS-$(CONFIG_KVAG_MUXER) += kvag.o > OBJS-$(CONFIG_LATM_MUXER) += latmenc.o rawenc.o > OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o > OBJS-$(CONFIG_LOAS_DEMUXER) += loasdec.o rawdec.o > diff --git a/libavformat/allformats.c b/libavformat/allformats.c > index 39d2c352f5..e12b50375c 100644 > --- a/libavformat/allformats.c > +++ b/libavformat/allformats.c > @@ -220,6 +220,7 @@ extern AVOutputFormat ff_jacosub_muxer; > extern AVInputFormat ff_jv_demuxer; > extern AVInputFormat ff_kux_demuxer; > extern AVInputFormat ff_kvag_demuxer; > +extern AVOutputFormat ff_kvag_muxer; > extern AVOutputFormat ff_latm_muxer; > extern AVInputFormat ff_lmlm4_demuxer; > extern AVInputFormat ff_loas_demuxer; > diff --git a/libavformat/kvag.c b/libavformat/kvag.c > index 71b0eb4118..d337d1cd4f 100644 > --- a/libavformat/kvag.c > +++ b/libavformat/kvag.c > @@ -1,5 +1,5 @@ > /* > - * Simon & Schuster Interactive VAG demuxer > + * Simon & Schuster Interactive VAG (de)muxer > * > * Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.com) > * > @@ -34,6 +34,7 @@ typedef struct KVAGHeader { > uint16_t stereo; > } KVAGHeader; > > +#if CONFIG_KVAG_DEMUXER > static int kvag_probe(const AVProbeData *p) > { > if (AV_RL32(p->buf) != KVAG_TAG) > @@ -115,3 +116,78 @@ AVInputFormat ff_kvag_demuxer = { > .read_header = kvag_read_header, > .read_packet = kvag_read_packet > }; > +#endif > + > +#if CONFIG_KVAG_MUXER > +static int kvag_write_header(AVFormatContext *s) > +{ > + AVCodecParameters *par; > + uint8_t buf[KVAG_HEADER_SIZE]; > + > + if (s->nb_streams != 1) { > + av_log(s, AV_LOG_ERROR, "KVAG files have exactly one stream\n"); > + return AVERROR(EINVAL); > + } > + > + par = s->streams[0]->codecpar; > + > + if (par->codec_id != AV_CODEC_ID_ADPCM_IMA_SSI) { > + AVCodec *codec = avcodec_find_encoder(par->codec_id); avcodec_get_name(par->codec_id); > + av_log(s, AV_LOG_ERROR, "%s codec not supported\n", > + codec ? codec->name : "NONE"); With the above change codec will never be NULL, so you can remove this check. > + return AVERROR(EINVAL); > + } > + > + if (par->channels > 2) { > + av_log(s, AV_LOG_ERROR, "KVAG files only support up to 2 channels\n"); > + return AVERROR(EINVAL); > + } Everything up to this check should be in a separate AVOutputFormat.init() function instead. > + > + AV_WL32(buf + 0, KVAG_TAG); > + AV_WL32(buf + 4, 0); /* Data size, we fix this up later. */ > + AV_WL32(buf + 8, par->sample_rate); > + AV_WL16(buf + 12, par->channels == 2); > + > + avio_write(s->pb, buf, sizeof(buf)); > + return 0; > +} > + > +static int kvag_write_packet(AVFormatContext *s, AVPacket *pkt) > +{ > + avio_write(s->pb, pkt->data, pkt->size); > + return 0; > +} Use ff_raw_write_packet() instead. > + > +static int kvag_write_trailer(AVFormatContext *s) > +{ > + int64_t file_size, data_size; > + > + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) > + return 0; > + > + file_size = avio_tell(s->pb); > + data_size = file_size - KVAG_HEADER_SIZE; > + if (data_size < UINT32_MAX) { > + avio_seek(s->pb, 4, SEEK_SET); > + avio_wl32(s->pb, (uint32_t)data_size); > + avio_seek(s->pb, file_size, SEEK_SET); > + } else { > + av_log(s, AV_LOG_ERROR, > + "Filesize %"PRId64" invalid for KVAG, output file will be broken\n", > + file_size); This should be a warning. And you should also print a warning in the non seekable case, if not writing the data_size value will result in an invalid file. > + } > + > + return 0; > +} > + > +AVOutputFormat ff_kvag_muxer = { > + .name = "kvag", > + .long_name = NULL_IF_CONFIG_SMALL("Simon & Schuster Interactive VAG"), > + .extensions = "vag", > + .audio_codec = AV_CODEC_ID_ADPCM_IMA_SSI, > + .video_codec = AV_CODEC_ID_NONE, > + .write_header = kvag_write_header, > + .write_packet = kvag_write_packet, > + .write_trailer = kvag_write_trailer > +}; > +#endif > diff --git a/libavformat/version.h b/libavformat/version.h > index 18c2f5fec2..493a0b337f 100644 > --- a/libavformat/version.h > +++ b/libavformat/version.h > @@ -32,7 +32,7 @@ > // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) > // Also please add any ticket numbers that you believe might be affected here > #define LIBAVFORMAT_VERSION_MAJOR 58 > -#define LIBAVFORMAT_VERSION_MINOR 42 > +#define LIBAVFORMAT_VERSION_MINOR 43 > #define LIBAVFORMAT_VERSION_MICRO 100 > > #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ >
diff --git a/Changelog b/Changelog index b4fff44329..b2de88484b 100644 --- a/Changelog +++ b/Changelog @@ -57,6 +57,7 @@ version <next>: - overlay_cuda filter - switch from AvxSynth to AviSynth+ on Linux - Simon & Schuster Interactive ADPCM encoder +- Real War KVAG muxer version 4.2: diff --git a/libavformat/Makefile b/libavformat/Makefile index 8fd0d43721..ff920c4373 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -285,6 +285,7 @@ OBJS-$(CONFIG_JACOSUB_MUXER) += jacosubenc.o rawenc.o OBJS-$(CONFIG_JV_DEMUXER) += jvdec.o OBJS-$(CONFIG_KUX_DEMUXER) += flvdec.o OBJS-$(CONFIG_KVAG_DEMUXER) += kvag.o +OBJS-$(CONFIG_KVAG_MUXER) += kvag.o OBJS-$(CONFIG_LATM_MUXER) += latmenc.o rawenc.o OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o OBJS-$(CONFIG_LOAS_DEMUXER) += loasdec.o rawdec.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 39d2c352f5..e12b50375c 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -220,6 +220,7 @@ extern AVOutputFormat ff_jacosub_muxer; extern AVInputFormat ff_jv_demuxer; extern AVInputFormat ff_kux_demuxer; extern AVInputFormat ff_kvag_demuxer; +extern AVOutputFormat ff_kvag_muxer; extern AVOutputFormat ff_latm_muxer; extern AVInputFormat ff_lmlm4_demuxer; extern AVInputFormat ff_loas_demuxer; diff --git a/libavformat/kvag.c b/libavformat/kvag.c index 71b0eb4118..d337d1cd4f 100644 --- a/libavformat/kvag.c +++ b/libavformat/kvag.c @@ -1,5 +1,5 @@ /* - * Simon & Schuster Interactive VAG demuxer + * Simon & Schuster Interactive VAG (de)muxer * * Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.com) * @@ -34,6 +34,7 @@ typedef struct KVAGHeader { uint16_t stereo; } KVAGHeader; +#if CONFIG_KVAG_DEMUXER static int kvag_probe(const AVProbeData *p) { if (AV_RL32(p->buf) != KVAG_TAG) @@ -115,3 +116,78 @@ AVInputFormat ff_kvag_demuxer = { .read_header = kvag_read_header, .read_packet = kvag_read_packet }; +#endif + +#if CONFIG_KVAG_MUXER +static int kvag_write_header(AVFormatContext *s) +{ + AVCodecParameters *par; + uint8_t buf[KVAG_HEADER_SIZE]; + + if (s->nb_streams != 1) { + av_log(s, AV_LOG_ERROR, "KVAG files have exactly one stream\n"); + return AVERROR(EINVAL); + } + + par = s->streams[0]->codecpar; + + if (par->codec_id != AV_CODEC_ID_ADPCM_IMA_SSI) { + AVCodec *codec = avcodec_find_encoder(par->codec_id); + av_log(s, AV_LOG_ERROR, "%s codec not supported\n", + codec ? codec->name : "NONE"); + return AVERROR(EINVAL); + } + + if (par->channels > 2) { + av_log(s, AV_LOG_ERROR, "KVAG files only support up to 2 channels\n"); + return AVERROR(EINVAL); + } + + AV_WL32(buf + 0, KVAG_TAG); + AV_WL32(buf + 4, 0); /* Data size, we fix this up later. */ + AV_WL32(buf + 8, par->sample_rate); + AV_WL16(buf + 12, par->channels == 2); + + avio_write(s->pb, buf, sizeof(buf)); + return 0; +} + +static int kvag_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + avio_write(s->pb, pkt->data, pkt->size); + return 0; +} + +static int kvag_write_trailer(AVFormatContext *s) +{ + int64_t file_size, data_size; + + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) + return 0; + + file_size = avio_tell(s->pb); + data_size = file_size - KVAG_HEADER_SIZE; + if (data_size < UINT32_MAX) { + avio_seek(s->pb, 4, SEEK_SET); + avio_wl32(s->pb, (uint32_t)data_size); + avio_seek(s->pb, file_size, SEEK_SET); + } else { + av_log(s, AV_LOG_ERROR, + "Filesize %"PRId64" invalid for KVAG, output file will be broken\n", + file_size); + } + + return 0; +} + +AVOutputFormat ff_kvag_muxer = { + .name = "kvag", + .long_name = NULL_IF_CONFIG_SMALL("Simon & Schuster Interactive VAG"), + .extensions = "vag", + .audio_codec = AV_CODEC_ID_ADPCM_IMA_SSI, + .video_codec = AV_CODEC_ID_NONE, + .write_header = kvag_write_header, + .write_packet = kvag_write_packet, + .write_trailer = kvag_write_trailer +}; +#endif diff --git a/libavformat/version.h b/libavformat/version.h index 18c2f5fec2..493a0b337f 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 -#define LIBAVFORMAT_VERSION_MINOR 42 +#define LIBAVFORMAT_VERSION_MINOR 43 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com> --- Changelog | 1 + libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/kvag.c | 78 +++++++++++++++++++++++++++++++++++++++- libavformat/version.h | 2 +- 5 files changed, 81 insertions(+), 2 deletions(-)