diff options
author | Paul B Mahol <onemda@gmail.com> | 2023-02-07 16:54:54 +0100 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2023-02-07 17:13:11 +0100 |
commit | df4ab69cfa4583c5cd48ed57f4349c773673233a (patch) | |
tree | 16f2cd97a05b58b9b3ec87efa5e85aa20bdbec2c /libavcodec/wavarc.c | |
parent | 0c7af7b95484167c89ec0cb1bd6a862ecaf70e36 (diff) | |
download | ffmpeg-df4ab69cfa4583c5cd48ed57f4349c773673233a.tar.gz |
avcodec/wavarc: add support for 0CPY
Diffstat (limited to 'libavcodec/wavarc.c')
-rw-r--r-- | libavcodec/wavarc.c | 32 |
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: |