avcodec: Implement Archimedes VIDC encoder/decoder
authorCameron Cawley <ccawley2011@gmail.com>
Fri, 12 Oct 2018 23:06:39 +0000 (00:06 +0100)
committerPaul B Mahol <onemda@gmail.com>
Fri, 26 Oct 2018 11:39:25 +0000 (13:39 +0200)
Signed-off-by: Cameron Cawley <ccawley2011@gmail.com>
15 files changed:
Changelog
doc/general.texi
libavcodec/Makefile
libavcodec/allcodecs.c
libavcodec/avcodec.h
libavcodec/codec_desc.c
libavcodec/pcm.c
libavcodec/pcm_tablegen.c
libavcodec/pcm_tablegen.h
libavcodec/utils.c
libavcodec/version.h
libavformat/Makefile
libavformat/allformats.c
libavformat/pcmdec.c
libavformat/pcmenc.c

index 54ff28f..de03830 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -40,6 +40,7 @@ version <next>:
 - vibrance filter
 - decoding S12M timecode in h264
 - xstack filter
+- pcm vidc decoder and encoder
 
 
 version 4.0:
index 4983134..2b015f1 100644 (file)
@@ -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
@@ -1147,6 +1148,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
index a97055e..3e41497 100644 (file)
@@ -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
index c0b4d56..1b8144a 100644 (file)
@@ -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 */
index 705a3ce..7ffef76 100644 (file)
@@ -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,
index 67a3054..1a159f7 100644 (file)
@@ -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 */
     {
index 8c326c6..ffcbccc 100644 (file)
@@ -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");
index bf8e7fb..473a47f 100644 (file)
@@ -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;
 }
index 7ce147f..d8763ab 100644 (file)
 
 #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 */
index 285bfdb..1661d48 100644 (file)
@@ -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:
index 9098882..9180964 100644 (file)
@@ -28,8 +28,8 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR  58
-#define LIBAVCODEC_VERSION_MINOR  33
-#define LIBAVCODEC_VERSION_MICRO 102
+#define LIBAVCODEC_VERSION_MINOR  34
+#define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \
index e99e915..e4d997c 100644 (file)
@@ -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
index 9e41718..498077e 100644 (file)
@@ -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;
index d0ceea6..bd2a038 100644 (file)
@@ -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 },
index 3e4f308..1760b3b 100644 (file)
@@ -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)