diff mbox series

[FFmpeg-devel] Waveform Archiver decoder and demuxer

Message ID CAPYw7P4xq5H_h+8tftJOs+nQxufRjiRs2oZxZzU5E4KsSsyPkA@mail.gmail.com
State New
Headers show
Series [FFmpeg-devel] Waveform Archiver decoder and demuxer | expand

Checks

Context Check Description
andriy/make_x86 fail Make failed

Commit Message

Paul B Mahol Jan. 29, 2023, noon UTC
Patches attached

Comments

Paul B Mahol Jan. 31, 2023, 5:11 p.m. UTC | #1
On 1/29/23, Paul B Mahol <onemda@gmail.com> wrote:
> Patches attached
>

will apply soon
Anton Khirnov Jan. 31, 2023, 8:06 p.m. UTC | #2
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
Tomas Härdin Feb. 1, 2023, 9:36 a.m. UTC | #3
> +    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
Nicolas George Feb. 1, 2023, 9:42 a.m. UTC | #4
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,
Paul B Mahol Feb. 1, 2023, 10:53 a.m. UTC | #5
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".
>
Andreas Rheinhardt Feb. 1, 2023, 1:54 p.m. UTC | #6
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
Tomas Härdin Feb. 2, 2023, 4:59 p.m. UTC | #7
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
diff mbox series

Patch

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