Browse code

avcodec: add pcm_f16le and pcm_f24le decoder

Signed-off-by: Paul B Mahol <onemda@gmail.com>

Paul B Mahol authored on 2016/09/20 05:26:39
Showing 8 changed files
... ...
@@ -9,6 +9,8 @@ version <next>:
9 9
 - Support for spherical videos
10 10
 - configure now fails if autodetect-libraries are requested but not found
11 11
 - PSD Decoder
12
+- 16.8 floating point pcm decoder
13
+- 24.0 floating point pcm decoder
12 14
 
13 15
 version 3.2:
14 16
 - libopenmpt demuxer
... ...
@@ -658,6 +658,8 @@ OBJS-$(CONFIG_PCM_ALAW_DECODER)           += pcm.o
658 658
 OBJS-$(CONFIG_PCM_ALAW_ENCODER)           += pcm.o
659 659
 OBJS-$(CONFIG_PCM_BLURAY_DECODER)         += pcm-bluray.o
660 660
 OBJS-$(CONFIG_PCM_DVD_DECODER)            += pcm-dvd.o
661
+OBJS-$(CONFIG_PCM_F16LE_DECODER)          += pcm.o
662
+OBJS-$(CONFIG_PCM_F24LE_DECODER)          += pcm.o
661 663
 OBJS-$(CONFIG_PCM_F32BE_DECODER)          += pcm.o
662 664
 OBJS-$(CONFIG_PCM_F32BE_ENCODER)          += pcm.o
663 665
 OBJS-$(CONFIG_PCM_F32LE_DECODER)          += pcm.o
... ...
@@ -477,6 +477,8 @@ void avcodec_register_all(void)
477 477
     REGISTER_ENCDEC (PCM_ALAW,          pcm_alaw);
478 478
     REGISTER_DECODER(PCM_BLURAY,        pcm_bluray);
479 479
     REGISTER_DECODER(PCM_DVD,           pcm_dvd);
480
+    REGISTER_DECODER(PCM_F16LE,         pcm_f16le);
481
+    REGISTER_DECODER(PCM_F24LE,         pcm_f24le);
480 482
     REGISTER_ENCDEC (PCM_F32BE,         pcm_f32be);
481 483
     REGISTER_ENCDEC (PCM_F32LE,         pcm_f32le);
482 484
     REGISTER_ENCDEC (PCM_F64BE,         pcm_f64be);
... ...
@@ -449,6 +449,8 @@ enum AVCodecID {
449 449
 
450 450
     AV_CODEC_ID_PCM_S64LE = 0x10800,
451 451
     AV_CODEC_ID_PCM_S64BE,
452
+    AV_CODEC_ID_PCM_F16LE,
453
+    AV_CODEC_ID_PCM_F24LE,
452 454
 
453 455
     /* various ADPCM codecs */
454 456
     AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,
... ...
@@ -1749,6 +1749,20 @@ static const AVCodecDescriptor codec_descriptors[] = {
1749 1749
         .props     = AV_CODEC_PROP_LOSSLESS,
1750 1750
     },
1751 1751
     {
1752
+        .id        = AV_CODEC_ID_PCM_F16LE,
1753
+        .type      = AVMEDIA_TYPE_AUDIO,
1754
+        .name      = "pcm_f16le",
1755
+        .long_name = NULL_IF_CONFIG_SMALL("PCM 16.8 floating point little-endian"),
1756
+        .props     = AV_CODEC_PROP_LOSSLESS,
1757
+    },
1758
+    {
1759
+        .id        = AV_CODEC_ID_PCM_F24LE,
1760
+        .type      = AVMEDIA_TYPE_AUDIO,
1761
+        .name      = "pcm_f24le",
1762
+        .long_name = NULL_IF_CONFIG_SMALL("PCM 24.0 floating point little-endian"),
1763
+        .props     = AV_CODEC_PROP_LOSSLESS,
1764
+    },
1765
+    {
1752 1766
         .id        = AV_CODEC_ID_PCM_F32BE,
1753 1767
         .type      = AVMEDIA_TYPE_AUDIO,
1754 1768
         .name      = "pcm_f32be",
... ...
@@ -25,6 +25,7 @@
25 25
  */
26 26
 
27 27
 #include "libavutil/attributes.h"
28
+#include "libavutil/float_dsp.h"
28 29
 #include "avcodec.h"
29 30
 #include "bytestream.h"
30 31
 #include "internal.h"
... ...
@@ -225,6 +226,8 @@ static int pcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
225 225
 
226 226
 typedef struct PCMDecode {
227 227
     short   table[256];
228
+    AVFloatDSPContext *fdsp;
229
+    float   scale;
228 230
 } PCMDecode;
229 231
 
230 232
 static av_cold int pcm_decode_init(AVCodecContext *avctx)
... ...
@@ -246,6 +249,13 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx)
246 246
         for (i = 0; i < 256; i++)
247 247
             s->table[i] = ulaw2linear(i);
248 248
         break;
249
+    case AV_CODEC_ID_PCM_F16LE:
250
+    case AV_CODEC_ID_PCM_F24LE:
251
+        s->scale = 1. / (1 << (avctx->bits_per_coded_sample - 1));
252
+        s->fdsp = avpriv_float_dsp_alloc(0);
253
+        if (!s->fdsp)
254
+            return AVERROR(ENOMEM);
255
+        break;
249 256
     default:
250 257
         break;
251 258
     }
... ...
@@ -258,6 +268,15 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx)
258 258
     return 0;
259 259
 }
260 260
 
261
+static av_cold int pcm_decode_close(AVCodecContext *avctx)
262
+{
263
+    PCMDecode *s = avctx->priv_data;
264
+
265
+    av_freep(&s->fdsp);
266
+
267
+    return 0;
268
+}
269
+
261 270
 /**
262 271
  * Read PCM samples macro
263 272
  * @param size   Data size of native machine format
... ...
@@ -400,6 +419,8 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
400 400
         break;
401 401
     case AV_CODEC_ID_PCM_S32LE:
402 402
     case AV_CODEC_ID_PCM_F32LE:
403
+    case AV_CODEC_ID_PCM_F24LE:
404
+    case AV_CODEC_ID_PCM_F16LE:
403 405
         DECODE(32, le32, src, samples, n, 0, 0)
404 406
         break;
405 407
     case AV_CODEC_ID_PCM_S32LE_PLANAR:
... ...
@@ -433,6 +454,8 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
433 433
         break;
434 434
     case AV_CODEC_ID_PCM_F64LE:
435 435
     case AV_CODEC_ID_PCM_F32LE:
436
+    case AV_CODEC_ID_PCM_F24LE:
437
+    case AV_CODEC_ID_PCM_F16LE:
436 438
     case AV_CODEC_ID_PCM_S64LE:
437 439
     case AV_CODEC_ID_PCM_S32LE:
438 440
     case AV_CODEC_ID_PCM_S16LE:
... ...
@@ -495,6 +518,14 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
495 495
         return -1;
496 496
     }
497 497
 
498
+    if (avctx->codec_id == AV_CODEC_ID_PCM_F16LE ||
499
+        avctx->codec_id == AV_CODEC_ID_PCM_F24LE) {
500
+        s->fdsp->vector_fmul_scalar((float *)frame->extended_data[0],
501
+                                    (const float *)frame->extended_data[0],
502
+                                    s->scale, FFALIGN(frame->nb_samples * avctx->channels, 4));
503
+        emms_c();
504
+    }
505
+
498 506
     *got_frame_ptr = 1;
499 507
 
500 508
     return buf_size;
... ...
@@ -530,6 +561,7 @@ AVCodec ff_ ## name_ ## _decoder = {                                        \
530 530
     .id             = AV_CODEC_ID_ ## id_,                                  \
531 531
     .priv_data_size = sizeof(PCMDecode),                                    \
532 532
     .init           = pcm_decode_init,                                      \
533
+    .close          = pcm_decode_close,                                     \
533 534
     .decode         = pcm_decode_frame,                                     \
534 535
     .capabilities   = AV_CODEC_CAP_DR1,                                     \
535 536
     .sample_fmts    = (const enum AVSampleFormat[]){ sample_fmt_,           \
... ...
@@ -549,6 +581,8 @@ AVCodec ff_ ## name_ ## _decoder = {                                        \
549 549
 
550 550
 /* Note: Do not forget to add new entries to the Makefile as well. */
551 551
 PCM_CODEC  (PCM_ALAW,         AV_SAMPLE_FMT_S16, pcm_alaw,         "PCM A-law / G.711 A-law");
552
+PCM_DECODER(PCM_F16LE,        AV_SAMPLE_FMT_FLT, pcm_f16le,        "PCM 16.8 floating point little-endian");
553
+PCM_DECODER(PCM_F24LE,        AV_SAMPLE_FMT_FLT, pcm_f24le,        "PCM 24.0 floating point little-endian");
552 554
 PCM_CODEC  (PCM_F32BE,        AV_SAMPLE_FMT_FLT, pcm_f32be,        "PCM 32-bit floating point big-endian");
553 555
 PCM_CODEC  (PCM_F32LE,        AV_SAMPLE_FMT_FLT, pcm_f32le,        "PCM 32-bit floating point little-endian");
554 556
 PCM_CODEC  (PCM_F64BE,        AV_SAMPLE_FMT_DBL, pcm_f64be,        "PCM 64-bit floating point big-endian");
... ...
@@ -3500,6 +3500,8 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
3500 3500
     case AV_CODEC_ID_PCM_U32LE:
3501 3501
     case AV_CODEC_ID_PCM_F32BE:
3502 3502
     case AV_CODEC_ID_PCM_F32LE:
3503
+    case AV_CODEC_ID_PCM_F24LE:
3504
+    case AV_CODEC_ID_PCM_F16LE:
3503 3505
         return 32;
3504 3506
     case AV_CODEC_ID_PCM_F64BE:
3505 3507
     case AV_CODEC_ID_PCM_F64LE:
... ...
@@ -28,7 +28,7 @@
28 28
 #include "libavutil/version.h"
29 29
 
30 30
 #define LIBAVCODEC_VERSION_MAJOR  57
31
-#define LIBAVCODEC_VERSION_MINOR  68
31
+#define LIBAVCODEC_VERSION_MINOR  69
32 32
 #define LIBAVCODEC_VERSION_MICRO 100
33 33
 
34 34
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \