* [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer
@ 2023-01-29 12:00 Paul B Mahol
2023-01-31 17:11 ` Paul B Mahol
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Paul B Mahol @ 2023-01-29 12:00 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 17 bytes --]
Patches attached
[-- Attachment #2: 0001-avcodec-add-WavArc-decoder.patch --]
[-- Type: text/x-patch, Size: 17172 bytes --]
From 5516601630ae83098e2a3d27823f21e86bc0e60d Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Sat, 21 Jan 2023 19:25:41 +0100
Subject: [PATCH 1/2] avcodec: add WavArc decoder
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
libavcodec/Makefile | 1 +
libavcodec/allcodecs.c | 1 +
libavcodec/codec_desc.c | 7 +
libavcodec/codec_id.h | 1 +
libavcodec/wavarc.c | 460 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 470 insertions(+)
create mode 100644 libavcodec/wavarc.c
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index f0ffd0b961..e936c19f33 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -777,6 +777,7 @@ OBJS-$(CONFIG_VP9_V4L2M2M_DECODER) += v4l2_m2m_dec.o
OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o
OBJS-$(CONFIG_VQC_DECODER) += vqcdec.o
OBJS-$(CONFIG_WADY_DPCM_DECODER) += dpcm.o
+OBJS-$(CONFIG_WAVARC_DECODER) += wavarc.o
OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o wavpackdata.o dsd.o
OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackdata.o wavpackenc.o
OBJS-$(CONFIG_WBMP_DECODER) += wbmpdec.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index f30047e17a..0d6998786c 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -538,6 +538,7 @@ extern const FFCodec ff_twinvq_decoder;
extern const FFCodec ff_vmdaudio_decoder;
extern const FFCodec ff_vorbis_encoder;
extern const FFCodec ff_vorbis_decoder;
+extern const FFCodec ff_wavarc_decoder;
extern const FFCodec ff_wavpack_encoder;
extern const FFCodec ff_wavpack_decoder;
extern const FFCodec ff_wmalossless_decoder;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 50f9794e10..6ecdf1002b 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3346,6 +3346,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("FTR Voice"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_WAVARC,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "wavarc",
+ .long_name = NULL_IF_CONFIG_SMALL("Waveform Archiver"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
+ },
/* subtitle codecs */
{
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index cdf7eb79c3..ba3b432387 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -535,6 +535,7 @@ enum AVCodecID {
AV_CODEC_ID_MISC4,
AV_CODEC_ID_APAC,
AV_CODEC_ID_FTR,
+ AV_CODEC_ID_WAVARC,
/* subtitle codecs */
AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs.
diff --git a/libavcodec/wavarc.c b/libavcodec/wavarc.c
new file mode 100644
index 0000000000..898c3c2055
--- /dev/null
+++ b/libavcodec/wavarc.c
@@ -0,0 +1,460 @@
+/*
+ * WavArc audio decoder
+ * Copyright (c) 2023 Paul B Mahol
+ *
+ * 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 "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "codec_internal.h"
+#include "decode.h"
+#include "get_bits.h"
+#include "bytestream.h"
+#include "mathops.h"
+#include "unary.h"
+
+typedef struct WavArcContext {
+ GetBitContext gb;
+
+ int shift;
+ int nb_samples;
+ int offset;
+
+ int eof;
+ int skip;
+ uint8_t *bitstream;
+ int64_t max_framesize;
+ int bitstream_size;
+ int bitstream_index;
+
+ int pred[2][70];
+ int filter[2][70];
+ int samples[2][640];
+} WavArcContext;
+
+static av_cold int wavarc_init(AVCodecContext *avctx)
+{
+ WavArcContext *s = avctx->priv_data;
+
+ if (avctx->extradata_size < 44)
+ return AVERROR_INVALIDDATA;
+ if (AV_RL32(avctx->extradata + 16) != MKTAG('R','I','F','F'))
+ return AVERROR_INVALIDDATA;
+ if (AV_RL32(avctx->extradata + 24) != MKTAG('W','A','V','E'))
+ return AVERROR_INVALIDDATA;
+ if (AV_RL32(avctx->extradata + 28) != MKTAG('f','m','t',' '))
+ return AVERROR_INVALIDDATA;
+ if (AV_RL16(avctx->extradata + 38) != 1 &&
+ AV_RL16(avctx->extradata + 38) != 2)
+ return AVERROR_INVALIDDATA;
+
+ av_channel_layout_uninit(&avctx->ch_layout);
+ av_channel_layout_default(&avctx->ch_layout, AV_RL16(avctx->extradata + 38));
+ avctx->sample_rate = AV_RL32(avctx->extradata + 40);
+
+ switch (avctx->extradata[36]) {
+ case 0: avctx->sample_fmt = AV_SAMPLE_FMT_U8P; break;
+ case 1: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break;
+ }
+
+ s->shift = 0;
+ switch (avctx->codec_tag) {
+ case MKTAG('1','D','I','F'):
+ s->nb_samples = 256;
+ s->offset = 4;
+ break;
+ case MKTAG('2','S','L','P'):
+ case MKTAG('3','N','L','P'):
+ case MKTAG('4','A','L','P'):
+ s->nb_samples = 570;
+ s->offset = 70;
+ break;
+ default:
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->max_framesize = s->nb_samples * 16;
+ s->bitstream = av_calloc(s->max_framesize, sizeof(*s->bitstream));
+ if (!s->bitstream)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static unsigned get_urice(GetBitContext *gb, int k)
+{
+ unsigned x = get_unary(gb, 1, get_bits_left(gb));
+ unsigned y = get_bits_long(gb, k);
+ unsigned z = (x << k) | y;
+
+ return z;
+}
+
+static int get_srice(GetBitContext *gb, int k)
+{
+ unsigned z = get_urice(gb, k);
+
+ return (z & 1) ? ~((int)(z >> 1)) : z >> 1;
+}
+
+static void do_stereo(WavArcContext *s, int ch, int correlated, int len)
+{
+ const int nb_samples = s->nb_samples;
+ const int shift = s->shift;
+
+ if (ch == 0) {
+ if (correlated) {
+ for (int n = 0; n < len; n++) {
+ s->samples[0][n] = s->samples[0][nb_samples + n] >> shift;
+ s->samples[1][n] = s->pred[1][n] >> shift;
+ }
+ } else {
+ for (int n = 0; n < len; n++) {
+ s->samples[0][n] = s->samples[0][nb_samples + n] >> shift;
+ s->samples[1][n] = s->pred[0][n] >> shift;
+ }
+ }
+ } else {
+ if (correlated) {
+ for (int n = 0; n < nb_samples; n++)
+ s->samples[1][n + len] += s->samples[0][n + len];
+ }
+ for (int n = 0; n < len; n++) {
+ s->pred[0][n] = s->samples[1][nb_samples + n];
+ s->pred[1][n] = s->pred[0][n] - s->samples[0][nb_samples + n];
+ }
+ }
+}
+
+static int decode_1dif(AVCodecContext *avctx,
+ WavArcContext *s, GetBitContext *gb)
+{
+ int ch, finished, fill, correlated;
+
+ ch = 0;
+ finished = 0;
+ while (!finished) {
+ int *samples = s->samples[ch];
+ int k, block_type;
+
+ if (get_bits_left(gb) <= 0)
+ return AVERROR_INVALIDDATA;
+
+ block_type = get_urice(gb, 1);
+ if (block_type < 4 && block_type >= 0) {
+ k = 1 + (avctx->sample_fmt == AV_SAMPLE_FMT_S16P);
+ k = get_urice(gb, k) + 1;
+ }
+
+ switch (block_type) {
+ case 8:
+ s->eof = 1;
+ return AVERROR_EOF;
+ case 7:
+ s->nb_samples = get_bits(gb, 8);
+ continue;
+ case 6:
+ s->shift = get_urice(gb, 2);
+ continue;
+ case 5:
+ if (avctx->sample_fmt == AV_SAMPLE_FMT_U8P) {
+ fill = (int8_t)get_bits(gb, 8);
+ fill -= 0x80;
+ } else {
+ fill = (int16_t)get_bits(gb, 16);
+ fill -= 0x8000;
+ }
+
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 4] = fill;
+ finished = 1;
+ break;
+ case 4:
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 4] = 0;
+ finished = 1;
+ break;
+ case 3:
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 4] = get_srice(gb, k) + (samples[n + 3] - samples[n + 2]) * 3 +
+ samples[n + 1];
+ finished = 1;
+ break;
+ case 2:
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 4] = get_srice(gb, k) + (samples[n + 3] * 2 - samples[n + 2]);
+ finished = 1;
+ break;
+ case 1:
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 4] = get_srice(gb, k) + samples[n + 3];
+ finished = 1;
+ break;
+ case 0:
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 4] = get_srice(gb, k);
+ finished = 1;
+ break;
+ default:
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (finished == 1 && avctx->ch_layout.nb_channels == 2) {
+ if (ch == 0)
+ correlated = get_bits1(gb);
+ finished = ch != 0;
+ do_stereo(s, ch, correlated, 4);
+ ch = 1;
+ }
+ }
+
+ if (avctx->ch_layout.nb_channels == 1) {
+ for (int n = 0; n < 4; n++)
+ s->samples[0][n] = s->samples[0][s->nb_samples + n] >> s->shift;
+ }
+
+ return 0;
+}
+
+static int decode_2slp(AVCodecContext *avctx,
+ WavArcContext *s, GetBitContext *gb)
+{
+ int ch, finished, fill, correlated, order;
+
+ ch = 0;
+ finished = 0;
+ while (!finished) {
+ int *samples = s->samples[ch];
+ int k, block_type;
+
+ if (get_bits_left(gb) <= 0)
+ return AVERROR_INVALIDDATA;
+
+ block_type = get_urice(gb, 1);
+ if (block_type < 5 && block_type >= 0) {
+ k = 1 + (avctx->sample_fmt == AV_SAMPLE_FMT_S16P);
+ k = get_urice(gb, k) + 1;
+ }
+
+ switch (block_type) {
+ case 9:
+ s->eof = 1;
+ return AVERROR_EOF;
+ case 8:
+ s->nb_samples = get_urice(gb, 8);
+ continue;
+ case 7:
+ s->shift = get_urice(gb, 2);
+ continue;
+ case 6:
+ if (avctx->sample_fmt == AV_SAMPLE_FMT_U8P) {
+ fill = (int8_t)get_bits(gb, 8);
+ fill -= 0x80;
+ } else {
+ fill = (int16_t)get_bits(gb, 16);
+ fill -= 0x8000;
+ }
+
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 70] = fill;
+ finished = 1;
+ break;
+ case 5:
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 70] = 0;
+ finished = 1;
+ break;
+ case 4:
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 70] = get_srice(gb, k) + (samples[n + 69] - samples[n + 68]) * 3 +
+ samples[n + 67];
+ finished = 1;
+ break;
+ case 3:
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 70] = get_srice(gb, k) + (samples[n + 69] * 2 - samples[n + 68]);
+ finished = 1;
+ break;
+ case 2:
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 70] = get_srice(gb, k);
+ finished = 1;
+ break;
+ case 1:
+ for (int n = 0; n < s->nb_samples; n++)
+ samples[n + 70] = get_srice(gb, k) + samples[n + 69];
+ finished = 1;
+ break;
+ case 0:
+ order = get_urice(gb, 2);
+ for (int o = 0; o < order; o++)
+ s->filter[ch][o] = get_srice(gb, 2);
+ for (int n = 0; n < s->nb_samples; n++) {
+ int sum = 15;
+
+ for (int o = 0; o < order; o++)
+ sum += s->filter[ch][o] * samples[n + 70 - o - 1];
+
+ samples[n + 70] = get_srice(gb, k) + (sum >> 4);
+ }
+ finished = 1;
+ break;
+ default:
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (finished == 1 && avctx->ch_layout.nb_channels == 2) {
+ if (ch == 0)
+ correlated = get_bits1(gb);
+ finished = ch != 0;
+ do_stereo(s, ch, correlated, 70);
+ ch = 1;
+ }
+ }
+
+ if (avctx->ch_layout.nb_channels == 1) {
+ for (int n = 0; n < 70; n++)
+ s->samples[0][n] = s->samples[0][s->nb_samples + n] >> s->shift;
+ }
+
+ return 0;
+}
+
+static int wavarc_decode(AVCodecContext *avctx, AVFrame *frame,
+ int *got_frame_ptr, AVPacket *pkt)
+{
+ WavArcContext *s = avctx->priv_data;
+ GetBitContext *gb = &s->gb;
+ int buf_size, input_buf_size;
+ const uint8_t *buf;
+ int ret, n;
+
+ if ((!pkt->size && !s->bitstream_size) || s->nb_samples == 0 || s->eof) {
+ *got_frame_ptr = 0;
+ return pkt->size;
+ }
+
+ buf_size = FFMIN(pkt->size, s->max_framesize - s->bitstream_size);
+ input_buf_size = buf_size;
+ if (s->bitstream_index + s->bitstream_size + buf_size + AV_INPUT_BUFFER_PADDING_SIZE > s->max_framesize) {
+ memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);
+ s->bitstream_index = 0;
+ }
+ if (pkt->data)
+ memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], pkt->data, buf_size);
+ buf = &s->bitstream[s->bitstream_index];
+ buf_size += s->bitstream_size;
+ s->bitstream_size = buf_size;
+ if (buf_size < s->max_framesize && pkt->data) {
+ *got_frame_ptr = 0;
+ return input_buf_size;
+ }
+
+ if ((ret = init_get_bits8(gb, buf, buf_size)) < 0)
+ return ret;
+ skip_bits(gb, s->skip);
+
+ switch (avctx->codec_tag) {
+ case MKTAG('1','D','I','F'):
+ ret = decode_1dif(avctx, s, gb);
+ break;
+ case MKTAG('2','S','L','P'):
+ case MKTAG('3','N','L','P'):
+ case MKTAG('4','A','L','P'):
+ ret = decode_2slp(avctx, s, gb);
+ break;
+ default:
+ ret = AVERROR_INVALIDDATA;
+ }
+
+ if (ret < 0)
+ goto fail;
+
+ s->skip = get_bits_count(gb) - 8 * (get_bits_count(gb) / 8);
+ n = get_bits_count(gb) / 8;
+
+ if (n > buf_size) {
+fail:
+ s->bitstream_size = 0;
+ s->bitstream_index = 0;
+ return ret;
+ }
+
+ frame->nb_samples = s->nb_samples;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ switch (avctx->sample_fmt) {
+ case AV_SAMPLE_FMT_U8P:
+ for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
+ uint8_t *dst = (uint8_t *)frame->extended_data[ch];
+ const int *src = s->samples[ch] + s->offset;
+
+ for (int n = 0; n < frame->nb_samples; n++)
+ dst[n] = src[n] * (1 << s->shift);
+ }
+ break;
+ case AV_SAMPLE_FMT_S16P:
+ for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
+ int16_t *dst = (int16_t *)frame->extended_data[ch];
+ const int *src = s->samples[ch] + s->offset;
+
+ for (int n = 0; n < frame->nb_samples; n++)
+ dst[n] = src[n] * (1 << s->shift);
+ }
+ break;
+ }
+
+ *got_frame_ptr = 1;
+
+ if (s->bitstream_size) {
+ s->bitstream_index += n;
+ s->bitstream_size -= n;
+ return input_buf_size;
+ }
+
+ return n;
+}
+
+static av_cold int wavarc_close(AVCodecContext *avctx)
+{
+ WavArcContext *s = avctx->priv_data;
+
+ av_freep(&s->bitstream);
+ s->bitstream_size = 0;
+
+ return 0;
+}
+
+const FFCodec ff_wavarc_decoder = {
+ .p.name = "wavarc",
+ CODEC_LONG_NAME("Waveform Archiver"),
+ .p.type = AVMEDIA_TYPE_AUDIO,
+ .p.id = AV_CODEC_ID_WAVARC,
+ .priv_data_size = sizeof(WavArcContext),
+ .init = wavarc_init,
+ FF_CODEC_DECODE_CB(wavarc_decode),
+ .close = wavarc_close,
+ .p.capabilities = AV_CODEC_CAP_DR1 |
+ AV_CODEC_CAP_SUBFRAMES |
+ AV_CODEC_CAP_DELAY,
+ .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
+ AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_NONE },
+};
--
2.39.1
[-- Attachment #3: 0002-avformat-add-WavArc-demuxer.patch --]
[-- Type: text/x-patch, Size: 5889 bytes --]
From b54f2ba1e206bff2ef5d9e8882cbdce4a5fbccc4 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Sat, 21 Jan 2023 19:17:38 +0100
Subject: [PATCH 2/2] avformat: add WavArc demuxer
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
libavformat/Makefile | 1 +
libavformat/allformats.c | 1 +
libavformat/wavarc.c | 127 +++++++++++++++++++++++++++++++++++++++
3 files changed, 129 insertions(+)
create mode 100644 libavformat/wavarc.c
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 2d11bcd7a3..9052b023a7 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -598,6 +598,7 @@ OBJS-$(CONFIG_VQF_DEMUXER) += vqf.o
OBJS-$(CONFIG_W64_DEMUXER) += wavdec.o w64.o pcm.o
OBJS-$(CONFIG_W64_MUXER) += wavenc.o w64.o
OBJS-$(CONFIG_WADY_DEMUXER) += wady.o pcm.o
+OBJS-$(CONFIG_WAVARC_DEMUXER) += wavarc.o rawdec.o
OBJS-$(CONFIG_WAV_DEMUXER) += wavdec.o pcm.o
OBJS-$(CONFIG_WAV_MUXER) += wavenc.o
OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index bf8afe2078..7c01c7f098 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -480,6 +480,7 @@ extern const AVInputFormat ff_vqf_demuxer;
extern const AVInputFormat ff_w64_demuxer;
extern const AVOutputFormat ff_w64_muxer;
extern const AVInputFormat ff_wady_demuxer;
+extern const AVInputFormat ff_wavarc_demuxer;
extern const AVInputFormat ff_wav_demuxer;
extern const AVOutputFormat ff_wav_muxer;
extern const AVInputFormat ff_wc3_demuxer;
diff --git a/libavformat/wavarc.c b/libavformat/wavarc.c
new file mode 100644
index 0000000000..a475c85f8e
--- /dev/null
+++ b/libavformat/wavarc.c
@@ -0,0 +1,127 @@
+/*
+ * WavArc demuxer
+ * Copyright (c) 2023 Paul B Mahol
+ *
+ * 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 "libavutil/channel_layout.h"
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "demux.h"
+#include "internal.h"
+#include "rawdec.h"
+
+static int wavarc_probe(const AVProbeData *p)
+{
+ int len = p->buf[0];
+ uint32_t id;
+
+ if (len == 0 || len + 6 >= p->buf_size)
+ return 0;
+
+ if (p->buf[len + 1] != 0)
+ return 0;
+
+ id = AV_RL32(p->buf + len + 2);
+ if (id != MKTAG('1','D','I','F') &&
+ id != MKTAG('2','S','L','P') &&
+ id != MKTAG('3','N','L','P') &&
+ id != MKTAG('4','A','L','P') &&
+ id != MKTAG('5','E','L','P'))
+ return 0;
+
+ return AVPROBE_SCORE_MAX / 3 * 2;
+}
+
+static int wavarc_read_header(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ AVCodecParameters *par;
+ int filename_len, fmt_len, ret;
+ uint8_t data[36];
+ AVStream *st;
+ uint32_t id;
+
+ filename_len = avio_r8(pb);
+ if (filename_len == 0)
+ return AVERROR_INVALIDDATA;
+ avio_skip(pb, filename_len);
+ if (avio_r8(pb))
+ return AVERROR_INVALIDDATA;
+ id = avio_rl32(pb);
+ if (avio_read(pb, data, sizeof(data)) != sizeof(data))
+ return AVERROR(EIO);
+ fmt_len = AV_RL32(data + 32);
+ if (fmt_len < 12)
+ return AVERROR_INVALIDDATA;
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ par = st->codecpar;
+
+ ret = ff_alloc_extradata(par, fmt_len + sizeof(data));
+ if (ret < 0)
+ return ret;
+ memcpy(par->extradata, data, sizeof(data));
+ avio_read(pb, par->extradata + sizeof(data), fmt_len);
+
+ par->codec_type = AVMEDIA_TYPE_AUDIO;
+ par->codec_id = AV_CODEC_ID_WAVARC;
+ par->codec_tag = id;
+
+ do {
+ id = avio_rl32(pb);
+ if (id != MKTAG('d','a','t','a'))
+ avio_skip(pb, avio_rl32(pb));
+ } while (id != MKTAG('d','a','t','a'));
+ avio_skip(pb, 4);
+
+ if (AV_RL32(par->extradata + 16) != MKTAG('R','I','F','F'))
+ return AVERROR_INVALIDDATA;
+ if (AV_RL32(par->extradata + 24) != MKTAG('W','A','V','E'))
+ return AVERROR_INVALIDDATA;
+ if (AV_RL32(par->extradata + 28) != MKTAG('f','m','t',' '))
+ return AVERROR_INVALIDDATA;
+
+ av_channel_layout_uninit(&par->ch_layout);
+ av_channel_layout_default(&par->ch_layout, AV_RL16(par->extradata + 38));
+ par->sample_rate = AV_RL32(par->extradata + 40);
+ avpriv_set_pts_info(st, 64, 1, par->sample_rate);
+ st->start_time = 0;
+
+ switch (par->extradata[36]) {
+ case 0: par->format = AV_SAMPLE_FMT_U8P; break;
+ case 1: par->format = AV_SAMPLE_FMT_S16P; break;
+ }
+
+ return 0;
+}
+
+const AVInputFormat ff_wavarc_demuxer = {
+ .name = "wavarc",
+ .long_name = NULL_IF_CONFIG_SMALL("Waveform Archiver"),
+ .read_probe = wavarc_probe,
+ .read_packet = ff_raw_read_partial_packet,
+ .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK | AVFMT_NOTIMESTAMPS,
+ .read_header = wavarc_read_header,
+ .extensions = "wa",
+ .raw_codec_id = AV_CODEC_ID_WAVARC,
+ .priv_data_size = sizeof(FFRawDemuxerContext),
+ .priv_class = &ff_raw_demuxer_class,
+};
--
2.39.1
[-- Attachment #4: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer
2023-01-29 12:00 [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer Paul B Mahol
@ 2023-01-31 17:11 ` Paul B Mahol
2023-01-31 20:06 ` Anton Khirnov
2023-02-01 9:36 ` Tomas Härdin
2023-02-01 13:54 ` Andreas Rheinhardt
2 siblings, 1 reply; 8+ messages in thread
From: Paul B Mahol @ 2023-01-31 17:11 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On 1/29/23, Paul B Mahol <onemda@gmail.com> wrote:
> Patches attached
>
will apply soon
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer
2023-01-31 17:11 ` Paul B Mahol
@ 2023-01-31 20:06 ` Anton Khirnov
0 siblings, 0 replies; 8+ messages in thread
From: Anton Khirnov @ 2023-01-31 20:06 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Quoting Paul B Mahol (2023-01-31 18:11:10)
> On 1/29/23, Paul B Mahol <onemda@gmail.com> wrote:
> > Patches attached
> >
>
> will apply soon
needs FATE tests
--
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer
2023-01-29 12:00 [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer Paul B Mahol
2023-01-31 17:11 ` Paul B Mahol
@ 2023-02-01 9:36 ` Tomas Härdin
2023-02-01 9:42 ` Nicolas George
2023-02-01 10:53 ` Paul B Mahol
2023-02-01 13:54 ` Andreas Rheinhardt
2 siblings, 2 replies; 8+ messages in thread
From: Tomas Härdin @ 2023-02-01 9:36 UTC (permalink / raw)
To: FFmpeg development discussions and patches
> + if (avctx->extradata_size < 44)
> + return AVERROR_INVALIDDATA;
> + if (AV_RL32(avctx->extradata + 16) != MKTAG('R','I','F','F'))
> + return AVERROR_INVALIDDATA;
> + if (AV_RL32(avctx->extradata + 24) != MKTAG('W','A','V','E'))
> + return AVERROR_INVALIDDATA;
> + if (AV_RL32(avctx->extradata + 28) != MKTAG('f','m','t',' '))
> + return AVERROR_INVALIDDATA;
> + if (AV_RL16(avctx->extradata + 38) != 1 &&
> + AV_RL16(avctx->extradata + 38) != 2)
> + return AVERROR_INVALIDDATA;
What in tarnation
> + av_channel_layout_default(&avctx->ch_layout, AV_RL16(avctx-
> >extradata + 38));
> + avctx->sample_rate = AV_RL32(avctx->extradata + 40);
>
This belongs in the demuxer. In fact it appears the decoder duplicates
code from the demuxer. Why? Some samples would help.
/Tomas
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer
2023-02-01 9:36 ` Tomas Härdin
@ 2023-02-01 9:42 ` Nicolas George
2023-02-02 16:59 ` Tomas Härdin
2023-02-01 10:53 ` Paul B Mahol
1 sibling, 1 reply; 8+ messages in thread
From: Nicolas George @ 2023-02-01 9:42 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Tomas Härdin (12023-02-01):
> This belongs in the demuxer. In fact it appears the decoder duplicates
> code from the demuxer. Why?
Because sharing code between demuxer and decoder is extremely annoying,
because somebody decided the libraries must be separate even though all
the technical reasons for it have less annoying solutions.
Regards,
--
Nicolas George
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer
2023-02-01 9:36 ` Tomas Härdin
2023-02-01 9:42 ` Nicolas George
@ 2023-02-01 10:53 ` Paul B Mahol
1 sibling, 0 replies; 8+ messages in thread
From: Paul B Mahol @ 2023-02-01 10:53 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On 2/1/23, Tomas Härdin <git@haerdin.se> wrote:
>> + if (avctx->extradata_size < 44)
>> + return AVERROR_INVALIDDATA;
>> + if (AV_RL32(avctx->extradata + 16) != MKTAG('R','I','F','F'))
>> + return AVERROR_INVALIDDATA;
>> + if (AV_RL32(avctx->extradata + 24) != MKTAG('W','A','V','E'))
>> + return AVERROR_INVALIDDATA;
>> + if (AV_RL32(avctx->extradata + 28) != MKTAG('f','m','t',' '))
>> + return AVERROR_INVALIDDATA;
>> + if (AV_RL16(avctx->extradata + 38) != 1 &&
>> + AV_RL16(avctx->extradata + 38) != 2)
>> + return AVERROR_INVALIDDATA;
>
> What in tarnation
>
>> + av_channel_layout_default(&avctx->ch_layout, AV_RL16(avctx-
>> >extradata + 38));
>> + avctx->sample_rate = AV_RL32(avctx->extradata + 40);
>>
>
> This belongs in the demuxer. In fact it appears the decoder duplicates
Decoder needs extradata as relevant information is not provided in
bitstream of packets.
> code from the demuxer. Why? Some samples would help.
Anybody is free to create samples.
>
> /Tomas
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer
2023-01-29 12:00 [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer Paul B Mahol
2023-01-31 17:11 ` Paul B Mahol
2023-02-01 9:36 ` Tomas Härdin
@ 2023-02-01 13:54 ` Andreas Rheinhardt
2 siblings, 0 replies; 8+ messages in thread
From: Andreas Rheinhardt @ 2023-02-01 13:54 UTC (permalink / raw)
To: ffmpeg-devel
Paul B Mahol:
> + if (AV_RL32(par->extradata + 28) != MKTAG('f','m','t',' '))
> + return AVERROR_INVALIDDATA;
> +
> + av_channel_layout_uninit(&par->ch_layout);
You do not need this; the channel layout of a freshly allocated stream
is always blank.
> + av_channel_layout_default(&par->ch_layout, AV_RL16(par->extradata + 38));
> + par->sample_rate = AV_RL32(par->extradata + 40);
> + avpriv_set_pts_info(st, 64, 1, par->sample_rate)
- Andreas
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer
2023-02-01 9:42 ` Nicolas George
@ 2023-02-02 16:59 ` Tomas Härdin
0 siblings, 0 replies; 8+ messages in thread
From: Tomas Härdin @ 2023-02-02 16:59 UTC (permalink / raw)
To: FFmpeg development discussions and patches
ons 2023-02-01 klockan 10:42 +0100 skrev Nicolas George:
> Tomas Härdin (12023-02-01):
> > This belongs in the demuxer. In fact it appears the decoder
> > duplicates
> > code from the demuxer. Why?
>
> Because sharing code between demuxer and decoder is extremely
> annoying,
> because somebody decided the libraries must be separate even though
> all
> the technical reasons for it have less annoying solutions.
Carrying information like sample rate from demuxer to decoder happens
all the time..
/Tomas
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-02-02 16:59 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-29 12:00 [FFmpeg-devel] [PATCH] Waveform Archiver decoder and demuxer Paul B Mahol
2023-01-31 17:11 ` Paul B Mahol
2023-01-31 20:06 ` Anton Khirnov
2023-02-01 9:36 ` Tomas Härdin
2023-02-01 9:42 ` Nicolas George
2023-02-02 16:59 ` Tomas Härdin
2023-02-01 10:53 ` Paul B Mahol
2023-02-01 13:54 ` Andreas Rheinhardt
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git