aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/wavarc.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2023-02-07 16:54:54 +0100
committerPaul B Mahol <onemda@gmail.com>2023-02-07 17:13:11 +0100
commitdf4ab69cfa4583c5cd48ed57f4349c773673233a (patch)
tree16f2cd97a05b58b9b3ec87efa5e85aa20bdbec2c /libavcodec/wavarc.c
parent0c7af7b95484167c89ec0cb1bd6a862ecaf70e36 (diff)
downloadffmpeg-df4ab69cfa4583c5cd48ed57f4349c773673233a.tar.gz
avcodec/wavarc: add support for 0CPY
Diffstat (limited to 'libavcodec/wavarc.c')
-rw-r--r--libavcodec/wavarc.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/libavcodec/wavarc.c b/libavcodec/wavarc.c
index 6e0e66dcd8..2d6a58ffb0 100644
--- a/libavcodec/wavarc.c
+++ b/libavcodec/wavarc.c
@@ -35,6 +35,8 @@ typedef struct WavArcContext {
int shift;
int nb_samples;
int offset;
+ int align;
+ int add;
int eof;
int skip;
@@ -68,22 +70,32 @@ static av_cold int wavarc_init(AVCodecContext *avctx)
av_channel_layout_default(&avctx->ch_layout, AV_RL16(avctx->extradata + 38));
avctx->sample_rate = AV_RL32(avctx->extradata + 40);
+ s->align = avctx->ch_layout.nb_channels;
+
switch (AV_RL16(avctx->extradata + 50)) {
case 8: avctx->sample_fmt = AV_SAMPLE_FMT_U8P; break;
- case 16: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break;
+ case 16: s->align *= 2;
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break;
}
s->shift = 0;
switch (avctx->codec_tag) {
+ case MKTAG('0','C','P','Y'):
+ s->nb_samples = 640;
+ s->offset = 0;
+ s->add = 0;
+ break;
case MKTAG('1','D','I','F'):
s->nb_samples = 256;
s->offset = 4;
+ s->add = 0x80;
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;
+ s->add = 0x80;
break;
default:
return AVERROR_INVALIDDATA;
@@ -142,6 +154,19 @@ static void do_stereo(WavArcContext *s, int ch, int correlated, int len)
}
}
+static int decode_0cpy(AVCodecContext *avctx,
+ WavArcContext *s, GetBitContext *gb)
+{
+ int bits = s->align * 8;
+ s->nb_samples = FFMIN(640, get_bits_left(gb) / bits);
+
+ for (int n = 0; n < s->nb_samples; n++) {
+ for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++)
+ s->samples[ch][n] = get_bits(gb, bits);
+ }
+ return 0;
+}
+
static int decode_1dif(AVCodecContext *avctx,
WavArcContext *s, GetBitContext *gb)
{
@@ -375,6 +400,9 @@ static int wavarc_decode(AVCodecContext *avctx, AVFrame *frame,
skip_bits(gb, s->skip);
switch (avctx->codec_tag) {
+ case MKTAG('0','C','P','Y'):
+ ret = decode_0cpy(avctx, s, gb);
+ break;
case MKTAG('1','D','I','F'):
ret = decode_1dif(avctx, s, gb);
break;
@@ -413,7 +441,7 @@ fail:
const int *src = s->samples[ch] + s->offset;
for (int n = 0; n < frame->nb_samples; n++)
- dst[n] = src[n] * (1 << s->shift) + 0x80U;
+ dst[n] = src[n] * (1 << s->shift) + s->add;
}
break;
case AV_SAMPLE_FMT_S16P: