Browse code

avcodec: Implement Archimedes VIDC encoder/decoder

Signed-off-by: Cameron Cawley <ccawley2011@gmail.com>

Cameron Cawley authored on 2018/10/13 08:06:39
Showing 15 changed files
... ...
@@ -40,6 +40,7 @@ version <next>:
40 40
 - vibrance filter
41 41
 - decoding S12M timecode in h264
42 42
 - xstack filter
43
+- pcm vidc decoder and encoder
43 44
 
44 45
 
45 46
 version 4.0:
... ...
@@ -545,6 +545,7 @@ library:
545 545
 @item raw VC-1                  @tab X @tab X
546 546
 @item raw PCM A-law             @tab X @tab X
547 547
 @item raw PCM mu-law            @tab X @tab X
548
+@item raw PCM Archimedes VIDC   @tab X @tab X
548 549
 @item raw PCM signed 8 bit      @tab X @tab X
549 550
 @item raw PCM signed 16 bit big-endian  @tab X @tab X
550 551
 @item raw PCM signed 16 bit little-endian  @tab X @tab X
... ...
@@ -1147,6 +1148,7 @@ following image formats are supported:
1147 1147
     @tab encoding supported through external library libopus
1148 1148
 @item PCM A-law              @tab  X  @tab  X
1149 1149
 @item PCM mu-law             @tab  X  @tab  X
1150
+@item PCM Archimedes VIDC    @tab  X  @tab  X
1150 1151
 @item PCM signed 8-bit planar  @tab  X  @tab  X
1151 1152
 @item PCM signed 16-bit big-endian planar  @tab  X  @tab  X
1152 1153
 @item PCM signed 16-bit little-endian planar  @tab  X  @tab  X
... ...
@@ -794,6 +794,8 @@ OBJS-$(CONFIG_PCM_U32BE_DECODER)          += pcm.o
794 794
 OBJS-$(CONFIG_PCM_U32BE_ENCODER)          += pcm.o
795 795
 OBJS-$(CONFIG_PCM_U32LE_DECODER)          += pcm.o
796 796
 OBJS-$(CONFIG_PCM_U32LE_ENCODER)          += pcm.o
797
+OBJS-$(CONFIG_PCM_VIDC_DECODER)           += pcm.o
798
+OBJS-$(CONFIG_PCM_VIDC_ENCODER)           += pcm.o
797 799
 OBJS-$(CONFIG_PCM_ZORK_DECODER)           += pcm.o
798 800
 
799 801
 OBJS-$(CONFIG_ADPCM_4XM_DECODER)          += adpcm.o adpcm_data.o
... ...
@@ -552,6 +552,8 @@ extern AVCodec ff_pcm_u32be_encoder;
552 552
 extern AVCodec ff_pcm_u32be_decoder;
553 553
 extern AVCodec ff_pcm_u32le_encoder;
554 554
 extern AVCodec ff_pcm_u32le_decoder;
555
+extern AVCodec ff_pcm_vidc_encoder;
556
+extern AVCodec ff_pcm_vidc_decoder;
555 557
 extern AVCodec ff_pcm_zork_decoder;
556 558
 
557 559
 /* DPCM codecs */
... ...
@@ -491,6 +491,7 @@ enum AVCodecID {
491 491
     AV_CODEC_ID_PCM_S64BE,
492 492
     AV_CODEC_ID_PCM_F16LE,
493 493
     AV_CODEC_ID_PCM_F24LE,
494
+    AV_CODEC_ID_PCM_VIDC,
494 495
 
495 496
     /* various ADPCM codecs */
496 497
     AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,
... ...
@@ -1936,6 +1936,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
1936 1936
         .long_name = NULL_IF_CONFIG_SMALL("PCM 24.0 floating point little-endian"),
1937 1937
         .props     = AV_CODEC_PROP_LOSSLESS,
1938 1938
     },
1939
+    {
1940
+        .id        = AV_CODEC_ID_PCM_VIDC,
1941
+        .type      = AVMEDIA_TYPE_AUDIO,
1942
+        .name      = "pcm_vidc",
1943
+        .long_name = NULL_IF_CONFIG_SMALL("PCM Archimedes VIDC"),
1944
+        .props     = AV_CODEC_PROP_LOSSY,
1945
+    },
1939 1946
 
1940 1947
     /* various ADPCM codecs */
1941 1948
     {
... ...
@@ -42,6 +42,9 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx)
42 42
     case AV_CODEC_ID_PCM_MULAW:
43 43
         pcm_ulaw_tableinit();
44 44
         break;
45
+    case AV_CODEC_ID_PCM_VIDC:
46
+        pcm_vidc_tableinit();
47
+        break;
45 48
     default:
46 49
         break;
47 50
     }
... ...
@@ -216,6 +219,12 @@ static int pcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
216 216
             *dst++ = linear_to_ulaw[(v + 32768) >> 2];
217 217
         }
218 218
         break;
219
+    case AV_CODEC_ID_PCM_VIDC:
220
+        for (; n > 0; n--) {
221
+            v      = *samples++;
222
+            *dst++ = linear_to_vidc[(v + 32768) >> 2];
223
+        }
224
+        break;
219 225
     default:
220 226
         return -1;
221 227
     }
... ...
@@ -249,6 +258,10 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx)
249 249
         for (i = 0; i < 256; i++)
250 250
             s->table[i] = ulaw2linear(i);
251 251
         break;
252
+    case AV_CODEC_ID_PCM_VIDC:
253
+        for (i = 0; i < 256; i++)
254
+            s->table[i] = vidc2linear(i);
255
+        break;
252 256
     case AV_CODEC_ID_PCM_F16LE:
253 257
     case AV_CODEC_ID_PCM_F24LE:
254 258
         s->scale = 1. / (1 << (avctx->bits_per_coded_sample - 1));
... ...
@@ -485,6 +498,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
485 485
         break;
486 486
     case AV_CODEC_ID_PCM_ALAW:
487 487
     case AV_CODEC_ID_PCM_MULAW:
488
+    case AV_CODEC_ID_PCM_VIDC:
488 489
         for (; n > 0; n--) {
489 490
             AV_WN16A(samples, s->table[*src++]);
490 491
             samples += 2;
... ...
@@ -612,3 +626,4 @@ PCM_CODEC  (PCM_U32LE,        AV_SAMPLE_FMT_S32, pcm_u32le,        "PCM unsigned
612 612
 PCM_DECODER(PCM_ZORK,         AV_SAMPLE_FMT_U8,  pcm_zork,         "PCM Zork");
613 613
 PCM_CODEC  (PCM_S64BE,        AV_SAMPLE_FMT_S64, pcm_s64be,        "PCM signed 64-bit big-endian");
614 614
 PCM_CODEC  (PCM_S64LE,        AV_SAMPLE_FMT_S64, pcm_s64le,        "PCM signed 64-bit little-endian");
615
+PCM_CODEC  (PCM_VIDC,         AV_SAMPLE_FMT_S16, pcm_vidc,         "PCM Archimedes VIDC");
... ...
@@ -29,11 +29,13 @@ int main(void)
29 29
 {
30 30
     pcm_alaw_tableinit();
31 31
     pcm_ulaw_tableinit();
32
+    pcm_vidc_tableinit();
32 33
 
33 34
     write_fileheader();
34 35
 
35 36
     WRITE_ARRAY("static const", uint8_t, linear_to_alaw);
36 37
     WRITE_ARRAY("static const", uint8_t, linear_to_ulaw);
38
+    WRITE_ARRAY("static const", uint8_t, linear_to_vidc);
37 39
 
38 40
     return 0;
39 41
 }
... ...
@@ -36,6 +36,12 @@
36 36
 
37 37
 #define         BIAS            (0x84)      /* Bias for linear code. */
38 38
 
39
+#define         VIDC_SIGN_BIT    (1)
40
+#define         VIDC_QUANT_MASK  (0x1E)
41
+#define         VIDC_QUANT_SHIFT (1)
42
+#define         VIDC_SEG_SHIFT   (5)
43
+#define         VIDC_SEG_MASK    (0xE0)
44
+
39 45
 /* alaw2linear() - Convert an A-law value to 16-bit linear PCM */
40 46
 static av_cold int alaw2linear(unsigned char a_val)
41 47
 {
... ...
@@ -69,14 +75,30 @@ static av_cold int ulaw2linear(unsigned char u_val)
69 69
         return (u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS);
70 70
 }
71 71
 
72
+static av_cold int vidc2linear(unsigned char u_val)
73
+{
74
+        int t;
75
+
76
+        /*
77
+         * Extract and bias the quantization bits. Then
78
+         * shift up by the segment number and subtract out the bias.
79
+         */
80
+        t = (((u_val & VIDC_QUANT_MASK) >> VIDC_QUANT_SHIFT) << 3) + BIAS;
81
+        t <<= ((unsigned)u_val & VIDC_SEG_MASK) >> VIDC_SEG_SHIFT;
82
+
83
+        return (u_val & VIDC_SIGN_BIT) ? (BIAS - t) : (t - BIAS);
84
+}
85
+
72 86
 #if CONFIG_HARDCODED_TABLES
73 87
 #define pcm_alaw_tableinit()
74 88
 #define pcm_ulaw_tableinit()
89
+#define pcm_vidc_tableinit()
75 90
 #include "libavcodec/pcm_tables.h"
76 91
 #else
77 92
 /* 16384 entries per table */
78 93
 static uint8_t linear_to_alaw[16384];
79 94
 static uint8_t linear_to_ulaw[16384];
95
+static uint8_t linear_to_vidc[16384];
80 96
 
81 97
 static av_cold void build_xlaw_table(uint8_t *linear_to_xlaw,
82 98
                              int (*xlaw2linear)(unsigned char),
... ...
@@ -111,6 +133,11 @@ static void pcm_ulaw_tableinit(void)
111 111
 {
112 112
     build_xlaw_table(linear_to_ulaw, ulaw2linear, 0xff);
113 113
 }
114
+
115
+static void pcm_vidc_tableinit(void)
116
+{
117
+    build_xlaw_table(linear_to_vidc, vidc2linear, 0xff);
118
+}
114 119
 #endif /* CONFIG_HARDCODED_TABLES */
115 120
 
116 121
 #endif /* AVCODEC_PCM_TABLEGEN_H */
... ...
@@ -1438,6 +1438,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
1438 1438
     case AV_CODEC_ID_DSD_MSBF_PLANAR:
1439 1439
     case AV_CODEC_ID_PCM_ALAW:
1440 1440
     case AV_CODEC_ID_PCM_MULAW:
1441
+    case AV_CODEC_ID_PCM_VIDC:
1441 1442
     case AV_CODEC_ID_PCM_S8:
1442 1443
     case AV_CODEC_ID_PCM_S8_PLANAR:
1443 1444
     case AV_CODEC_ID_PCM_U8:
... ...
@@ -28,8 +28,8 @@
28 28
 #include "libavutil/version.h"
29 29
 
30 30
 #define LIBAVCODEC_VERSION_MAJOR  58
31
-#define LIBAVCODEC_VERSION_MINOR  33
32
-#define LIBAVCODEC_VERSION_MICRO 102
31
+#define LIBAVCODEC_VERSION_MINOR  34
32
+#define LIBAVCODEC_VERSION_MICRO 100
33 33
 
34 34
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
35 35
                                                LIBAVCODEC_VERSION_MINOR, \
... ...
@@ -411,6 +411,8 @@ OBJS-$(CONFIG_PCM_U32LE_DEMUXER)         += pcmdec.o pcm.o
411 411
 OBJS-$(CONFIG_PCM_U32LE_MUXER)           += pcmenc.o rawenc.o
412 412
 OBJS-$(CONFIG_PCM_U8_DEMUXER)            += pcmdec.o pcm.o
413 413
 OBJS-$(CONFIG_PCM_U8_MUXER)              += pcmenc.o rawenc.o
414
+OBJS-$(CONFIG_PCM_VIDC_DEMUXER)          += pcmdec.o pcm.o
415
+OBJS-$(CONFIG_PCM_VIDC_MUXER)            += pcmenc.o rawenc.o
414 416
 OBJS-$(CONFIG_PJS_DEMUXER)               += pjsdec.o subtitles.o
415 417
 OBJS-$(CONFIG_PMP_DEMUXER)               += pmpdec.o
416 418
 OBJS-$(CONFIG_PVA_DEMUXER)               += pva.o
... ...
@@ -289,6 +289,8 @@ extern AVInputFormat  ff_pcm_alaw_demuxer;
289 289
 extern AVOutputFormat ff_pcm_alaw_muxer;
290 290
 extern AVInputFormat  ff_pcm_mulaw_demuxer;
291 291
 extern AVOutputFormat ff_pcm_mulaw_muxer;
292
+extern AVInputFormat  ff_pcm_vidc_demuxer;
293
+extern AVOutputFormat ff_pcm_vidc_muxer;
292 294
 extern AVInputFormat  ff_pcm_f64be_demuxer;
293 295
 extern AVOutputFormat ff_pcm_f64be_muxer;
294 296
 extern AVInputFormat  ff_pcm_f64le_demuxer;
... ...
@@ -177,6 +177,9 @@ PCMDEF(alaw, "PCM A-law",
177 177
 PCMDEF(mulaw, "PCM mu-law",
178 178
        "ul", AV_CODEC_ID_PCM_MULAW)
179 179
 
180
+PCMDEF(vidc, "PCM Archimedes VIDC",
181
+       NULL, AV_CODEC_ID_PCM_VIDC)
182
+
180 183
 static const AVOption sln_options[] = {
181 184
     { "sample_rate", "", offsetof(PCMAudioDemuxerContext, sample_rate), AV_OPT_TYPE_INT, {.i64 = 8000}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
182 185
     { "channels",    "", offsetof(PCMAudioDemuxerContext, channels),    AV_OPT_TYPE_INT, {.i64 = 1}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
... ...
@@ -92,3 +92,6 @@ PCMDEF(alaw, "PCM A-law",
92 92
 
93 93
 PCMDEF(mulaw, "PCM mu-law",
94 94
        "ul", AV_CODEC_ID_PCM_MULAW)
95
+
96
+PCMDEF(vidc, "PCM Archimedes VIDC",
97
+       NULL, AV_CODEC_ID_PCM_VIDC)