From: Paul B Mahol <onemda@gmail.com> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: [FFmpeg-devel] [PATCH] add WADY demuxer and decoder Date: Sat, 21 Jan 2023 14:44:26 +0100 Message-ID: <CAPYw7P7otkW-9jgOLwx4CjHtb7Z3xDmDrwpc8YN49CWOrrohYQ@mail.gmail.com> (raw) [-- Attachment #1: Type: text/plain, Size: 23 bytes --] Hi, Patches attached. [-- Attachment #2: 0001-avcodec-add-WADY-DPCM-decoder.patch --] [-- Type: text/x-patch, Size: 6490 bytes --] From 5f4f4a77e19fe12bc44ab32021cc3690610d03b9 Mon Sep 17 00:00:00 2001 From: Paul B Mahol <onemda@gmail.com> Date: Sat, 21 Jan 2023 12:21:44 +0100 Subject: [PATCH 1/3] avcodec: add WADY DPCM 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/dpcm.c | 45 +++++++++++++++++++++++++++++++++++++++-- libavcodec/utils.c | 1 + 6 files changed, 54 insertions(+), 2 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 651d302442..2ad4400a81 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -774,6 +774,7 @@ OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o 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_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 b009848a44..46aaa89e99 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -628,6 +628,7 @@ extern const FFCodec ff_roq_dpcm_decoder; extern const FFCodec ff_sdx2_dpcm_decoder; extern const FFCodec ff_sol_dpcm_decoder; extern const FFCodec ff_xan_dpcm_decoder; +extern const FFCodec ff_wady_dpcm_decoder; /* ADPCM codecs */ extern const FFCodec ff_adpcm_4xm_decoder; diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 24a0433dba..2272232ed6 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2619,6 +2619,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("DPCM Xilam DERF"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_WADY_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "wady_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM Marble WADY"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, /* audio codecs */ { diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h index f436a2b624..5ec3fd4b30 100644 --- a/libavcodec/codec_id.h +++ b/libavcodec/codec_id.h @@ -430,6 +430,7 @@ enum AVCodecID { AV_CODEC_ID_SDX2_DPCM, AV_CODEC_ID_GREMLIN_DPCM, AV_CODEC_ID_DERF_DPCM, + AV_CODEC_ID_WADY_DPCM, /* audio codecs */ AV_CODEC_ID_MP2 = 0x15000, diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 2425f84eb9..2420647bc0 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -45,7 +45,8 @@ typedef struct DPCMContext { int16_t array[256]; - int sample[2]; ///< previous sample (for SOL_DPCM) + int sample[2]; ///< previous sample (for SOL_DPCM and WADY_DPCM) + int scale; ///< scale for WADY_DPCM const int8_t *sol_table; ///< delta table for SOL_DPCM } DPCMContext; @@ -126,6 +127,24 @@ static const int16_t sol_table_16[128] = { 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 }; +static const int16_t wady_table[128] = { + 0, 2, 4, 6, 8, 10, 12, 15, + 18, 21, 24, 28, 32, 36, 40, 44, + 49, 54, 59, 64, 70, 76, 82, 88, + 95, 102, 109, 116, 124, 132, 140, 148, + 160, 170, 180, 190, 200, 210, 220, 230, + 240, 255, 270, 285, 300, 320, 340, 360, + 380, 400, 425, 450, 475, 500, 525, 550, + 580, 610, 650, 700, 750, 800, 900, 1000, + -0, -2, -4, -6, -8, -10, -12, -15, + -18, -21, -24, -28, -32, -36, -40, -44, + -49, -54, -59, -64, -70, -76, -82, -88, + -95, -102,-109,-116,-124,-132,-140,-148, + -160,-170,-180,-190,-200,-210,-220,-230, + -240,-255,-270,-285,-300,-320,-340,-360, + -380,-400,-425,-450,-475,-500,-525,-550, + -580,-610,-650,-700,-750,-800,-900,-1000, +}; static av_cold int dpcm_decode_init(AVCodecContext *avctx) { @@ -139,7 +158,7 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) s->sample[0] = s->sample[1] = 0; - switch(avctx->codec->id) { + switch (avctx->codec->id) { case AV_CODEC_ID_ROQ_DPCM: /* initialize square table */ @@ -193,6 +212,10 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) } break; + case AV_CODEC_ID_WADY_DPCM: + s->scale = (avctx->extradata && avctx->extradata_size > 0) ? avctx->extradata[0] : 1; + break; + default: break; } @@ -239,6 +262,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, else out = buf_size; break; + case AV_CODEC_ID_WADY_DPCM: case AV_CODEC_ID_DERF_DPCM: case AV_CODEC_ID_GREMLIN_DPCM: case AV_CODEC_ID_SDX2_DPCM: @@ -401,6 +425,22 @@ static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, } } break; + + case AV_CODEC_ID_WADY_DPCM: { + int idx = 0; + + while (output_samples < samples_end) { + const uint8_t n = bytestream2_get_byteu(&gb); + + if (n & 0x80) + s->sample[idx] = sign_extend((n & 0x7f) << 9, 16); + else + s->sample[idx] += s->scale * wady_table[n & 0x7f]; + *output_samples++ = av_clip_int16(s->sample[idx]); + idx ^= stereo; + } + } + break; } *got_frame_ptr = 1; @@ -427,3 +467,4 @@ DPCM_DECODER(AV_CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ"); DPCM_DECODER(AV_CODEC_ID_SDX2_DPCM, sdx2_dpcm, "DPCM Squareroot-Delta-Exact"); DPCM_DECODER(AV_CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol"); DPCM_DECODER(AV_CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan"); +DPCM_DECODER(AV_CODEC_ID_WADY_DPCM, wady_dpcm, "DPCM Marble WADY"); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 2b63a498b9..27ab92c9ce 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -515,6 +515,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id) case AV_CODEC_ID_PCM_U8: case AV_CODEC_ID_SDX2_DPCM: case AV_CODEC_ID_DERF_DPCM: + case AV_CODEC_ID_WADY_DPCM: return 8; case AV_CODEC_ID_PCM_S16BE: case AV_CODEC_ID_PCM_S16BE_PLANAR: -- 2.39.1 [-- Attachment #3: 0002-avformat-add-WADY-demuxer.patch --] [-- Type: text/x-patch, Size: 4497 bytes --] From a539077d32f8b94f0a4d505f2cb7f2938d5b28e0 Mon Sep 17 00:00:00 2001 From: Paul B Mahol <onemda@gmail.com> Date: Sat, 21 Jan 2023 12:05:30 +0100 Subject: [PATCH 2/3] avformat: add WADY demuxer Signed-off-by: Paul B Mahol <onemda@gmail.com> --- libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/wady.c | 87 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 libavformat/wady.c diff --git a/libavformat/Makefile b/libavformat/Makefile index fa71ec12f7..2d11bcd7a3 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -597,6 +597,7 @@ OBJS-$(CONFIG_VPLAYER_DEMUXER) += vplayerdec.o subtitles.o 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_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 62262ae935..bf8afe2078 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -479,6 +479,7 @@ extern const AVInputFormat ff_vplayer_demuxer; 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_wav_demuxer; extern const AVOutputFormat ff_wav_muxer; extern const AVInputFormat ff_wc3_demuxer; diff --git a/libavformat/wady.c b/libavformat/wady.c new file mode 100644 index 0000000000..bd9b64f514 --- /dev/null +++ b/libavformat/wady.c @@ -0,0 +1,87 @@ +/* + * WADY 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 "pcm.h" + +static int wady_probe(const AVProbeData *p) +{ + if (AV_RL32(p->buf) != MKTAG('W','A','D','Y')) + return 0; + if (p->buf[4] != 0 || p->buf[5] == 0 || + AV_RL16(p->buf+6) == 0 || + AV_RL32(p->buf+8) == 0) + return 0; + + return AVPROBE_SCORE_MAX / 3 * 2; +} + +static int wady_read_header(AVFormatContext *s) +{ + AVIOContext *pb = s->pb; + AVCodecParameters *par; + int channels, ret; + AVStream *st; + + avio_skip(pb, 4); + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + avio_skip(pb, 1); + par = st->codecpar; + par->codec_type = AVMEDIA_TYPE_AUDIO; + par->codec_id = AV_CODEC_ID_WADY_DPCM; + par->format = AV_SAMPLE_FMT_S16; + if ((ret = ff_get_extradata(s, par, pb, 1)) < 0) + return ret; + channels = avio_rl16(pb); + if (channels == 0) + return AVERROR_INVALIDDATA; + av_channel_layout_default(&par->ch_layout, channels); + par->sample_rate = avio_rl32(pb); + if (par->sample_rate <= 0) + return AVERROR_INVALIDDATA; + avio_skip(pb, 4); + st->duration = avio_rl32(pb); + par->block_align = channels; + avpriv_set_pts_info(st, 64, 1, par->sample_rate); + + avio_seek(pb, 0x30, SEEK_SET); + + return 0; +} + +const AVInputFormat ff_wady_demuxer = { + .name = "wady", + .long_name = NULL_IF_CONFIG_SMALL("Marble WADY"), + .read_probe = wady_probe, + .read_header = wady_read_header, + .read_packet = ff_pcm_read_packet, + .read_seek = ff_pcm_read_seek, + .flags = AVFMT_GENERIC_INDEX, + .extensions = "way", +}; -- 2.39.1 [-- Attachment #4: 0003-avcodec-dpcm-add-.flush.patch --] [-- Type: text/x-patch, Size: 1368 bytes --] From 02f05b5d81597bacc28b9b400f4aa262856a7a2e Mon Sep 17 00:00:00 2001 From: Paul B Mahol <onemda@gmail.com> Date: Sat, 21 Jan 2023 14:07:48 +0100 Subject: [PATCH 3/3] avcodec/dpcm: add .flush Otherwise after seek, DC offset for audio samples might be big. Signed-off-by: Paul B Mahol <onemda@gmail.com> --- libavcodec/dpcm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 2420647bc0..86cb9134f8 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -448,6 +448,13 @@ static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, return avpkt->size; } +static void dpcm_flush(AVCodecContext *avctx) +{ + DPCMContext *s = avctx->priv_data; + + s->sample[0] = s->sample[1] = 0; +} + #define DPCM_DECODER(id_, name_, long_name_) \ const FFCodec ff_ ## name_ ## _decoder = { \ .p.name = #name_, \ @@ -457,6 +464,7 @@ const FFCodec ff_ ## name_ ## _decoder = { \ .p.capabilities = AV_CODEC_CAP_DR1, \ .priv_data_size = sizeof(DPCMContext), \ .init = dpcm_decode_init, \ + .flush = dpcm_flush, \ FF_CODEC_DECODE_CB(dpcm_decode_frame), \ } -- 2.39.1 [-- Attachment #5: 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".
next reply other threads:[~2023-01-21 13:44 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-01-21 13:44 Paul B Mahol [this message] 2023-01-24 10:14 ` Paul B Mahol
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=CAPYw7P7otkW-9jgOLwx4CjHtb7Z3xDmDrwpc8YN49CWOrrohYQ@mail.gmail.com \ --to=onemda@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
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