diff --git a/doc/general.texi b/doc/general.texi
index 05f7bcd9fc..e3874430a4 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -545,6 +545,7 @@ library:
 @item raw VC-1                  @tab X @tab X
 @item raw PCM A-law             @tab X @tab X
 @item raw PCM mu-law            @tab X @tab X
+@item raw PCM Archimedes VIDC   @tab X @tab X
 @item raw PCM signed 8 bit      @tab X @tab X
 @item raw PCM signed 16 bit big-endian  @tab X @tab X
 @item raw PCM signed 16 bit little-endian  @tab X @tab X
@@ -1146,6 +1147,7 @@ following image formats are supported:
     @tab encoding supported through external library libopus
 @item PCM A-law              @tab  X  @tab  X
 @item PCM mu-law             @tab  X  @tab  X
+@item PCM Archimedes VIDC    @tab  X  @tab  X
 @item PCM signed 8-bit planar  @tab  X  @tab  X
 @item PCM signed 16-bit big-endian planar  @tab  X  @tab  X
 @item PCM signed 16-bit little-endian planar  @tab  X  @tab  X
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index ce766aa466..b12d9ffccd 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -794,6 +794,8 @@ OBJS-$(CONFIG_PCM_U32BE_DECODER)          += pcm.o
 OBJS-$(CONFIG_PCM_U32BE_ENCODER)          += pcm.o
 OBJS-$(CONFIG_PCM_U32LE_DECODER)          += pcm.o
 OBJS-$(CONFIG_PCM_U32LE_ENCODER)          += pcm.o
+OBJS-$(CONFIG_PCM_VIDC_DECODER)           += pcm.o
+OBJS-$(CONFIG_PCM_VIDC_ENCODER)           += pcm.o
 OBJS-$(CONFIG_PCM_ZORK_DECODER)           += pcm.o
 
 OBJS-$(CONFIG_ADPCM_4XM_DECODER)          += adpcm.o adpcm_data.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index c0b4d56d0d..1b8144a2b7 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -552,6 +552,8 @@ extern AVCodec ff_pcm_u32be_encoder;
 extern AVCodec ff_pcm_u32be_decoder;
 extern AVCodec ff_pcm_u32le_encoder;
 extern AVCodec ff_pcm_u32le_decoder;
+extern AVCodec ff_pcm_vidc_encoder;
+extern AVCodec ff_pcm_vidc_decoder;
 extern AVCodec ff_pcm_zork_decoder;
 
 /* DPCM codecs */
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 705a3ce4f3..7ffef768dc 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -491,6 +491,7 @@ enum AVCodecID {
     AV_CODEC_ID_PCM_S64BE,
     AV_CODEC_ID_PCM_F16LE,
     AV_CODEC_ID_PCM_F24LE,
+    AV_CODEC_ID_PCM_VIDC,
 
     /* various ADPCM codecs */
     AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 67a30542d1..1a159f7e13 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -1936,6 +1936,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("PCM 24.0 floating point little-endian"),
         .props     = AV_CODEC_PROP_LOSSLESS,
     },
+    {
+        .id        = AV_CODEC_ID_PCM_VIDC,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "pcm_vidc",
+        .long_name = NULL_IF_CONFIG_SMALL("PCM Archimedes VIDC"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
 
     /* various ADPCM codecs */
     {
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c
index 8c326c6829..ffcbccc77d 100644
--- a/libavcodec/pcm.c
+++ b/libavcodec/pcm.c
@@ -42,6 +42,9 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx)
     case AV_CODEC_ID_PCM_MULAW:
         pcm_ulaw_tableinit();
         break;
+    case AV_CODEC_ID_PCM_VIDC:
+        pcm_vidc_tableinit();
+        break;
     default:
         break;
     }
@@ -216,6 +219,12 @@ static int pcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
             *dst++ = linear_to_ulaw[(v + 32768) >> 2];
         }
         break;
+    case AV_CODEC_ID_PCM_VIDC:
+        for (; n > 0; n--) {
+            v      = *samples++;
+            *dst++ = linear_to_vidc[(v + 32768) >> 2];
+        }
+        break;
     default:
         return -1;
     }
@@ -249,6 +258,10 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx)
         for (i = 0; i < 256; i++)
             s->table[i] = ulaw2linear(i);
         break;
+    case AV_CODEC_ID_PCM_VIDC:
+        for (i = 0; i < 256; i++)
+            s->table[i] = vidc2linear(i);
+        break;
     case AV_CODEC_ID_PCM_F16LE:
     case AV_CODEC_ID_PCM_F24LE:
         s->scale = 1. / (1 << (avctx->bits_per_coded_sample - 1));
@@ -485,6 +498,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
         break;
     case AV_CODEC_ID_PCM_ALAW:
     case AV_CODEC_ID_PCM_MULAW:
+    case AV_CODEC_ID_PCM_VIDC:
         for (; n > 0; n--) {
             AV_WN16A(samples, s->table[*src++]);
             samples += 2;
@@ -612,3 +626,4 @@ PCM_CODEC  (PCM_U32LE,        AV_SAMPLE_FMT_S32, pcm_u32le,        "PCM unsigned
 PCM_DECODER(PCM_ZORK,         AV_SAMPLE_FMT_U8,  pcm_zork,         "PCM Zork");
 PCM_CODEC  (PCM_S64BE,        AV_SAMPLE_FMT_S64, pcm_s64be,        "PCM signed 64-bit big-endian");
 PCM_CODEC  (PCM_S64LE,        AV_SAMPLE_FMT_S64, pcm_s64le,        "PCM signed 64-bit little-endian");
+PCM_CODEC  (PCM_VIDC,         AV_SAMPLE_FMT_S16, pcm_vidc,         "PCM Archimedes VIDC");
diff --git a/libavcodec/pcm_tablegen.c b/libavcodec/pcm_tablegen.c
index bf8e7fb707..473a47f6d9 100644
--- a/libavcodec/pcm_tablegen.c
+++ b/libavcodec/pcm_tablegen.c
@@ -29,11 +29,13 @@ int main(void)
 {
     pcm_alaw_tableinit();
     pcm_ulaw_tableinit();
+    pcm_vidc_tableinit();
 
     write_fileheader();
 
     WRITE_ARRAY("static const", uint8_t, linear_to_alaw);
     WRITE_ARRAY("static const", uint8_t, linear_to_ulaw);
+    WRITE_ARRAY("static const", uint8_t, linear_to_vidc);
 
     return 0;
 }
diff --git a/libavcodec/pcm_tablegen.h b/libavcodec/pcm_tablegen.h
index 7ce147f768..d8763abc40 100644
--- a/libavcodec/pcm_tablegen.h
+++ b/libavcodec/pcm_tablegen.h
@@ -36,6 +36,12 @@
 
 #define         BIAS            (0x84)      /* Bias for linear code. */
 
+#define         VIDC_SIGN_BIT    (1)
+#define         VIDC_QUANT_MASK  (0x1E)
+#define         VIDC_QUANT_SHIFT (1)
+#define         VIDC_SEG_SHIFT   (5)
+#define         VIDC_SEG_MASK    (0xE0)
+
 /* alaw2linear() - Convert an A-law value to 16-bit linear PCM */
 static av_cold int alaw2linear(unsigned char a_val)
 {
@@ -69,14 +75,30 @@ static av_cold int ulaw2linear(unsigned char u_val)
         return (u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS);
 }
 
+static av_cold int vidc2linear(unsigned char u_val)
+{
+        int t;
+
+        /*
+         * Extract and bias the quantization bits. Then
+         * shift up by the segment number and subtract out the bias.
+         */
+        t = (((u_val & VIDC_QUANT_MASK) >> VIDC_QUANT_SHIFT) << 3) + BIAS;
+        t <<= ((unsigned)u_val & VIDC_SEG_MASK) >> VIDC_SEG_SHIFT;
+
+        return (u_val & VIDC_SIGN_BIT) ? (BIAS - t) : (t - BIAS);
+}
+
 #if CONFIG_HARDCODED_TABLES
 #define pcm_alaw_tableinit()
 #define pcm_ulaw_tableinit()
+#define pcm_vidc_tableinit()
 #include "libavcodec/pcm_tables.h"
 #else
 /* 16384 entries per table */
 static uint8_t linear_to_alaw[16384];
 static uint8_t linear_to_ulaw[16384];
+static uint8_t linear_to_vidc[16384];
 
 static av_cold void build_xlaw_table(uint8_t *linear_to_xlaw,
                              int (*xlaw2linear)(unsigned char),
@@ -111,6 +133,11 @@ static void pcm_ulaw_tableinit(void)
 {
     build_xlaw_table(linear_to_ulaw, ulaw2linear, 0xff);
 }
+
+static void pcm_vidc_tableinit(void)
+{
+    build_xlaw_table(linear_to_vidc, vidc2linear, 0xff);
+}
 #endif /* CONFIG_HARDCODED_TABLES */
 
 #endif /* AVCODEC_PCM_TABLEGEN_H */
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 285bfdbc63..1661d48b90 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -1438,6 +1438,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
     case AV_CODEC_ID_DSD_MSBF_PLANAR:
     case AV_CODEC_ID_PCM_ALAW:
     case AV_CODEC_ID_PCM_MULAW:
+    case AV_CODEC_ID_PCM_VIDC:
     case AV_CODEC_ID_PCM_S8:
     case AV_CODEC_ID_PCM_S8_PLANAR:
     case AV_CODEC_ID_PCM_U8:
diff --git a/libavformat/Makefile b/libavformat/Makefile
index e0222535c1..e23889e28e 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -411,6 +411,8 @@ OBJS-$(CONFIG_PCM_U32LE_DEMUXER)         += pcmdec.o pcm.o
 OBJS-$(CONFIG_PCM_U32LE_MUXER)           += pcmenc.o rawenc.o
 OBJS-$(CONFIG_PCM_U8_DEMUXER)            += pcmdec.o pcm.o
 OBJS-$(CONFIG_PCM_U8_MUXER)              += pcmenc.o rawenc.o
+OBJS-$(CONFIG_PCM_VIDC_DEMUXER)          += pcmdec.o pcm.o
+OBJS-$(CONFIG_PCM_VIDC_MUXER)            += pcmenc.o rawenc.o
 OBJS-$(CONFIG_PJS_DEMUXER)               += pjsdec.o subtitles.o
 OBJS-$(CONFIG_PMP_DEMUXER)               += pmpdec.o
 OBJS-$(CONFIG_PVA_DEMUXER)               += pva.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 5c32ee6dff..bcdbb5e777 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -289,6 +289,8 @@ extern AVInputFormat  ff_pcm_alaw_demuxer;
 extern AVOutputFormat ff_pcm_alaw_muxer;
 extern AVInputFormat  ff_pcm_mulaw_demuxer;
 extern AVOutputFormat ff_pcm_mulaw_muxer;
+extern AVInputFormat  ff_pcm_vidc_demuxer;
+extern AVOutputFormat ff_pcm_vidc_muxer;
 extern AVInputFormat  ff_pcm_f64be_demuxer;
 extern AVOutputFormat ff_pcm_f64be_muxer;
 extern AVInputFormat  ff_pcm_f64le_demuxer;
diff --git a/libavformat/pcmdec.c b/libavformat/pcmdec.c
index d0ceea6fa9..bd2a0384f8 100644
--- a/libavformat/pcmdec.c
+++ b/libavformat/pcmdec.c
@@ -177,6 +177,9 @@ PCMDEF(alaw, "PCM A-law",
 PCMDEF(mulaw, "PCM mu-law",
        "ul", AV_CODEC_ID_PCM_MULAW)
 
+PCMDEF(vidc, "PCM Archimedes VIDC",
+       NULL, AV_CODEC_ID_PCM_VIDC)
+
 static const AVOption sln_options[] = {
     { "sample_rate", "", offsetof(PCMAudioDemuxerContext, sample_rate), AV_OPT_TYPE_INT, {.i64 = 8000}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
     { "channels",    "", offsetof(PCMAudioDemuxerContext, channels),    AV_OPT_TYPE_INT, {.i64 = 1}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
diff --git a/libavformat/pcmenc.c b/libavformat/pcmenc.c
index 3e4f308057..1760b3bef7 100644
--- a/libavformat/pcmenc.c
+++ b/libavformat/pcmenc.c
@@ -92,3 +92,6 @@ PCMDEF(alaw, "PCM A-law",
 
 PCMDEF(mulaw, "PCM mu-law",
        "ul", AV_CODEC_ID_PCM_MULAW)
+
+PCMDEF(vidc, "PCM Archimedes VIDC",
+       NULL, AV_CODEC_ID_PCM_VIDC)
