It is found in some 8svx files (e.g. ones created by SoX).
Currently the decoder reuses the 8svx functions because we already have
handling of a single large planar packet for the compressed 8svx codecs.
---
libavcodec/8svx.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
libavcodec/Makefile | 1 +
libavcodec/allcodecs.c | 1 +
libavcodec/avcodec.h | 1 +
libavcodec/version.h | 2 +-
libavformat/iff.c | 2 +-
6 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c
index a7b9c86..3e3eae6 100644
--- a/libavcodec/8svx.c
+++ b/libavcodec/8svx.c
@@ -73,6 +73,15 @@ static void delta_decode(uint8_t *dst, const uint8_t *src,
int src_size,
*state = val;
}
+static void raw_decode(uint8_t *dst, const int8_t *src, int src_size,
+ int channels)
+{
+ while (src_size--) {
+ *dst = *src++ + 128;
+ dst += channels;
+ }
+}
+
/** decode a frame */
static int eightsvx_decode_frame(AVCodecContext *avctx, void *data, int
*data_size,
AVPacket *avpkt)
@@ -81,12 +90,14 @@ static int eightsvx_decode_frame(AVCodecContext *avctx,
void *data, int *data_si
int buf_size;
uint8_t *out_data = data;
int out_data_size;
+ int is_compr = (avctx->codec_id != CODEC_ID_PCM_S8_PLANAR);
/* for the first packet, copy data to buffer */
if (avpkt->data) {
- int chan_size = (avpkt->size / avctx->channels) - 2;
+ int hdr_size = is_compr ? 2 : 0;
+ int chan_size = (avpkt->size - hdr_size * avctx->channels) /
avctx->channels;
- if (avpkt->size < 2) {
+ if (avpkt->size < hdr_size * avctx->channels) {
av_log(avctx, AV_LOG_ERROR, "packet size is too small\n");
return AVERROR(EINVAL);
}
@@ -95,9 +106,11 @@ static int eightsvx_decode_frame(AVCodecContext *avctx,
void *data, int *data_si
return AVERROR(EINVAL);
}
+ if (is_compr) {
esc->fib_acc[0] = avpkt->data[1] + 128;
if (avctx->channels == 2)
esc->fib_acc[1] = avpkt->data[2+chan_size+1] + 128;
+ }
esc->data_idx = 0;
esc->data_size = chan_size;
@@ -109,9 +122,9 @@ static int eightsvx_decode_frame(AVCodecContext *avctx,
void *data, int *data_si
return AVERROR(ENOMEM);
}
}
- memcpy(esc->data[0], &avpkt->data[2], chan_size);
+ memcpy(esc->data[0], &avpkt->data[hdr_size], chan_size);
if (avctx->channels == 2)
- memcpy(esc->data[1], &avpkt->data[2+chan_size+2], chan_size);
+ memcpy(esc->data[1], &avpkt->data[2*hdr_size+chan_size],
chan_size);
}
if (!esc->data[0]) {
av_log(avctx, AV_LOG_ERROR, "unexpected empty packet\n");
@@ -124,18 +137,26 @@ static int eightsvx_decode_frame(AVCodecContext *avctx,
void *data, int *data_si
*data_size = 0;
return avpkt->size;
}
- out_data_size = buf_size * 2 * avctx->channels;
+ out_data_size = buf_size * (is_compr + 1) * avctx->channels;
if (*data_size < out_data_size) {
av_log(avctx, AV_LOG_ERROR, "Provided buffer with size %d is too
small.\n",
*data_size);
return AVERROR(EINVAL);
}
+ if (is_compr) {
delta_decode(out_data, &esc->data[0][esc->data_idx], buf_size,
&esc->fib_acc[0], esc->table, avctx->channels);
if (avctx->channels == 2) {
delta_decode(&out_data[1], &esc->data[1][esc->data_idx], buf_size,
&esc->fib_acc[1], esc->table, avctx->channels);
}
+ } else {
+ int ch;
+ for (ch = 0; ch < avctx->channels; ch++) {
+ raw_decode((int8_t *)&out_data[ch], &esc->data[ch][esc->data_idx],
+ buf_size, avctx->channels);
+ }
+ }
esc->data_idx += buf_size;
*data_size = out_data_size;
@@ -159,6 +180,8 @@ static av_cold int eightsvx_decode_init(AVCodecContext
*avctx)
case CODEC_ID_8SVX_EXP:
esc->table = exponential;
break;
+ case CODEC_ID_PCM_S8_PLANAR:
+ break;
default:
return -1;
}
@@ -199,3 +222,15 @@ AVCodec ff_eightsvx_exp_decoder = {
.capabilities = CODEC_CAP_DELAY,
.long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"),
};
+
+AVCodec ff_pcm_s8_planar_decoder = {
+ .name = "pcm_s8_planar",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_PCM_S8_PLANAR,
+ .priv_data_size = sizeof(EightSvxContext),
+ .init = eightsvx_decode_init,
+ .close = eightsvx_decode_close,
+ .decode = eightsvx_decode_frame,
+ .capabilities = CODEC_CAP_DELAY,
+ .long_name = NULL_IF_CONFIG_SMALL("PCM signed 8-bit planar"),
+};
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 421072e..1127357 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -451,6 +451,7 @@ OBJS-$(CONFIG_PCM_MULAW_DECODER) += pcm.o
OBJS-$(CONFIG_PCM_MULAW_ENCODER) += pcm.o
OBJS-$(CONFIG_PCM_S8_DECODER) += pcm.o
OBJS-$(CONFIG_PCM_S8_ENCODER) += pcm.o
+OBJS-$(CONFIG_PCM_S8_PLANAR_DECODER) += 8svx.o
OBJS-$(CONFIG_PCM_S16BE_DECODER) += pcm.o
OBJS-$(CONFIG_PCM_S16BE_ENCODER) += pcm.o
OBJS-$(CONFIG_PCM_S16LE_DECODER) += pcm.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 23d2252..288e782 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -297,6 +297,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (PCM_LXF, pcm_lxf);
REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw);
REGISTER_ENCDEC (PCM_S8, pcm_s8);
+ REGISTER_DECODER (PCM_S8_PLANAR, pcm_s8_planar);
REGISTER_ENCDEC (PCM_S16BE, pcm_s16be);
REGISTER_ENCDEC (PCM_S16LE, pcm_s16le);
REGISTER_DECODER (PCM_S16LE_PLANAR, pcm_s16le_planar);
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 649bce4..7ae47b3 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -245,6 +245,7 @@ enum CodecID {
CODEC_ID_PCM_BLURAY,
CODEC_ID_PCM_LXF,
CODEC_ID_S302M,
+ CODEC_ID_PCM_S8_PLANAR,
/* various ADPCM codecs */
CODEC_ID_ADPCM_IMA_QT= 0x11000,
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 65cc559..3fc418e 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -21,7 +21,7 @@
#define AVCODEC_VERSION_H
#define LIBAVCODEC_VERSION_MAJOR 53
-#define LIBAVCODEC_VERSION_MINOR 15
+#define LIBAVCODEC_VERSION_MINOR 16
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
diff --git a/libavformat/iff.c b/libavformat/iff.c
index 5e8f168..e621373 100644
--- a/libavformat/iff.c
+++ b/libavformat/iff.c
@@ -220,7 +220,7 @@ static int iff_read_header(AVFormatContext *s,
switch(compression) {
case COMP_NONE:
- st->codec->codec_id = CODEC_ID_PCM_S8;
+ st->codec->codec_id = CODEC_ID_PCM_S8_PLANAR;
break;
case COMP_FIB:
st->codec->codec_id = CODEC_ID_8SVX_FIB;
--
1.7.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel