Re: [FFmpeg-devel] [PATCH] RK Audio demuxer and decoder

2023-02-15 Thread James Almer

On 2/5/2023 4:17 PM, Paul B Mahol wrote:

On 2/4/23, Paul B Mahol  wrote:

Hi,

Patches attached, decoder is not bit by bit exact yet for lossless
mode because some samples are not properly rounded.



Now lossless mode is bit exact.


[...]


+static av_cold int rka_decode_init(AVCodecContext *avctx)
+{
+RKAContext *s = avctx->priv_data;
+int cmode;
+
+if (avctx->extradata_size < 16)
+return AVERROR_INVALIDDATA;
+
+s->bps = avctx->bits_per_raw_sample = avctx->extradata[13];
+
+switch (s->bps) {
+case 8:
+avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
+break;
+case 16:
+avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+break;
+default:
+return AVERROR_INVALIDDATA;
+}
+
+s->channels = avctx->ch_layout.nb_channels;


You're ignoring the channels reported by the extradata despite flagging 
this decoder as AV_CODEC_CAP_CHANNEL_CONF. It should be the other way 
around, and ignore the user set layout, if any, with


av_channel_layout_uninit(>ch_layout);
s->channels = avctx->ch_layout.nb_channels = avctx->extradata[12];

Because the stream may not necessarily come from the lavf demuxer. 
Extradata presence is required given you check for it above, but the 
avctx fields could be set to whatever if the source is not the lavf rka 
demuxer.



+if (s->channels < 1 || s->channels > 2)
+return AVERROR_INVALIDDATA;
+
+s->align = (s->channels * (avctx->bits_per_raw_sample >> 3));
+s->samples_left = s->total_nb_samples = (AV_RL32(avctx->extradata + 4)) / 
s->align;
+s->frame_samples = 131072 / s->align;
+s->last_nb_samples = s->total_nb_samples % s->frame_samples;
+
+cmode = avctx->extradata[14] & 0xf;
+if ((avctx->extradata[15] & 4) != 0)
+cmode = -cmode;
+
+s->ch[0].cmode = s->ch[1].cmode = cmode;
+s->ch[0].cmode2 = -s->ch[0].cmode;
+s->ch[1].cmode2 = -s->ch[1].cmode;
+av_log(avctx, AV_LOG_DEBUG, "cmode: %d\n", cmode);
+
+return 0;
+}

___
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".


Re: [FFmpeg-devel] [PATCH] RK Audio demuxer and decoder

2023-02-10 Thread Paul B Mahol
will apply
___
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".


[FFmpeg-devel] [PATCH] RK Audio demuxer and decoder

2023-02-05 Thread Paul B Mahol
On 2/4/23, Paul B Mahol  wrote:
> Hi,
>
> Patches attached, decoder is not bit by bit exact yet for lossless
> mode because some samples are not properly rounded.
>

Now lossless mode is bit exact.
From 232125e5bbbd6ac0b8049cc32e5ca61c484d1bd8 Mon Sep 17 00:00:00 2001
From: Paul B Mahol 
Date: Tue, 31 Jan 2023 19:27:09 +0100
Subject: [PATCH 1/2] avformat: add RKA demuxer

Signed-off-by: Paul B Mahol 
---
 libavformat/Makefile |   1 +
 libavformat/allformats.c |   1 +
 libavformat/rka.c| 173 +++
 3 files changed, 175 insertions(+)
 create mode 100644 libavformat/rka.c

diff --git a/libavformat/Makefile b/libavformat/Makefile
index f0408a58b1..cd9c7a36a8 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -482,6 +482,7 @@ OBJS-$(CONFIG_RAWVIDEO_DEMUXER)  += rawvideodec.o
 OBJS-$(CONFIG_RAWVIDEO_MUXER)+= rawenc.o
 OBJS-$(CONFIG_REALTEXT_DEMUXER)  += realtextdec.o subtitles.o
 OBJS-$(CONFIG_REDSPARK_DEMUXER)  += redspark.o
+OBJS-$(CONFIG_RKA_DEMUXER)   += rka.o apetag.o img2.o
 OBJS-$(CONFIG_RL2_DEMUXER)   += rl2.o
 OBJS-$(CONFIG_RM_DEMUXER)+= rmdec.o rm.o rmsipr.o
 OBJS-$(CONFIG_RM_MUXER)  += rmenc.o rm.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 9ca8d2692f..4903bf7f9d 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -380,6 +380,7 @@ extern const AVInputFormat  ff_rawvideo_demuxer;
 extern const AVOutputFormat ff_rawvideo_muxer;
 extern const AVInputFormat  ff_realtext_demuxer;
 extern const AVInputFormat  ff_redspark_demuxer;
+extern const AVInputFormat  ff_rka_demuxer;
 extern const AVInputFormat  ff_rl2_demuxer;
 extern const AVInputFormat  ff_rm_demuxer;
 extern const AVOutputFormat ff_rm_muxer;
diff --git a/libavformat/rka.c b/libavformat/rka.c
new file mode 100644
index 00..c1e64ebcb3
--- /dev/null
+++ b/libavformat/rka.c
@@ -0,0 +1,173 @@
+/*
+ * RKA 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/dict.h"
+#include "libavutil/intreadwrite.h"
+
+#include "apetag.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "demux.h"
+#include "internal.h"
+
+typedef struct RKAContext {
+int total_frames, currentframe;
+int frame_size;
+int last_frame_size;
+} RKAContext;
+
+static int rka_probe(const AVProbeData *p)
+{
+if (AV_RL32(>buf[0]) == MKTAG('R', 'K', 'A', '7') &&
+AV_RL32(>buf[4]) > 0 &&
+AV_RL32(>buf[8]) > 0 &&
+p->buf[12] > 0 &&
+p->buf[12] <= 2 &&
+(p->buf[13] == 8 || p->buf[13] == 16) &&
+p->buf[15] & 2 != 0)
+return AVPROBE_SCORE_EXTENSION + 30;
+return 0;
+}
+
+static int rka_read_header(AVFormatContext *s)
+{
+int64_t nb_samples, size_offset;
+RKAContext *c = s->priv_data;
+int channels, bps, samplerate;
+AVCodecParameters *par;
+int64_t framepos;
+AVStream *st;
+int ret;
+
+st = avformat_new_stream(s, NULL);
+if (!st)
+return AVERROR(ENOMEM);
+
+par = st->codecpar;
+ret = ff_get_extradata(s, par, s->pb, 16);
+if (ret < 0)
+return ret;
+
+nb_samples = AV_RL32(par->extradata + 4);
+samplerate = AV_RL32(par->extradata + 8);
+channels = par->extradata[12];
+if (channels == 0)
+return AVERROR_INVALIDDATA;
+bps = par->extradata[13];
+if (bps == 0)
+return AVERROR_INVALIDDATA;
+size_offset = avio_rl32(s->pb);
+framepos = avio_tell(s->pb);
+c->frame_size = 131072;
+
+avpriv_set_pts_info(st, 64, 1, samplerate);
+st->start_time = 0;
+
+avio_seek(s->pb, size_offset, SEEK_SET);
+c->total_frames = (nb_samples + c->frame_size - 1) / c->frame_size;
+c->last_frame_size = nb_samples % c->frame_size;
+
+for (int i = 0; i < c->total_frames; i++) {
+int r, end = 0;
+int64_t size;
+
+if (avio_feof(s->pb))
+break;
+
+size = avio_rl24(s->pb);
+if (size == 0) {
+end = 1;
+size = size_offset - framepos;
+if (size <= 0)
+break;
+}
+
+if ((r = av_add_index_entry(st, framepos, (i *