]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/pcm.c
avfilter/vf_psnr: remove unnecessary check
[ffmpeg] / libavcodec / pcm.c
index 83850cc793cc6986572c0699058c070385e7c025..79b33b935cb1d37684288a40fc8cc738976d93a1 100644 (file)
  * PCM codecs
  */
 
+#include "config.h"
 #include "libavutil/attributes.h"
 #include "libavutil/float_dsp.h"
+#include "libavutil/thread.h"
 #include "avcodec.h"
 #include "bytestream.h"
 #include "internal.h"
 static av_cold int pcm_encode_init(AVCodecContext *avctx)
 {
     avctx->frame_size = 0;
+#if !CONFIG_HARDCODED_TABLES
     switch (avctx->codec->id) {
-    case AV_CODEC_ID_PCM_ALAW:
-        pcm_alaw_tableinit();
-        break;
-    case AV_CODEC_ID_PCM_MULAW:
-        pcm_ulaw_tableinit();
-        break;
-    case AV_CODEC_ID_PCM_VIDC:
-        pcm_vidc_tableinit();
-        break;
+#define INIT_ONCE(id, name)                                                 \
+    case AV_CODEC_ID_PCM_ ## id:                                            \
+        if (CONFIG_PCM_ ## id ## _ENCODER) {                                \
+            static AVOnce init_static_once = AV_ONCE_INIT;                  \
+            ff_thread_once(&init_static_once, pcm_ ## name ## _tableinit);  \
+        }                                                                   \
+        break
+        INIT_ONCE(ALAW,  alaw);
+        INIT_ONCE(MULAW, ulaw);
+        INIT_ONCE(VIDC,  vidc);
     default:
         break;
     }
+#endif
 
     avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id);
     avctx->block_align           = avctx->channels * avctx->bits_per_coded_sample / 8;
@@ -235,13 +240,15 @@ static int pcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 typedef struct PCMDecode {
     short   table[256];
-    AVFloatDSPContext *fdsp;
+    void (*vector_fmul_scalar)(float *dst, const float *src, float mul,
+                               int len);
     float   scale;
 } PCMDecode;
 
 static av_cold int pcm_decode_init(AVCodecContext *avctx)
 {
     PCMDecode *s = avctx->priv_data;
+    AVFloatDSPContext *fdsp;
     int i;
 
     if (avctx->channels <= 0) {
@@ -264,10 +271,15 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx)
         break;
     case AV_CODEC_ID_PCM_F16LE:
     case AV_CODEC_ID_PCM_F24LE:
+        if (avctx->bits_per_coded_sample < 1 || avctx->bits_per_coded_sample > 24)
+            return AVERROR_INVALIDDATA;
+
         s->scale = 1. / (1 << (avctx->bits_per_coded_sample - 1));
-        s->fdsp = avpriv_float_dsp_alloc(0);
-        if (!s->fdsp)
+        fdsp = avpriv_float_dsp_alloc(0);
+        if (!fdsp)
             return AVERROR(ENOMEM);
+        s->vector_fmul_scalar = fdsp->vector_fmul_scalar;
+        av_free(fdsp);
         break;
     default:
         break;
@@ -281,15 +293,6 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int pcm_decode_close(AVCodecContext *avctx)
-{
-    PCMDecode *s = avctx->priv_data;
-
-    av_freep(&s->fdsp);
-
-    return 0;
-}
-
 /**
  * Read PCM samples macro
  * @param size   Data size of native machine format
@@ -416,6 +419,14 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
         for (; n > 0; n--)
             *samples++ = *src++ + 128;
         break;
+    case AV_CODEC_ID_PCM_SGA:
+        for (; n > 0; n--) {
+            int sign = *src >> 7;
+            int magn = *src & 0x7f;
+            *samples++ = sign ? 128 - magn : 128 + magn;
+            src++;
+        }
+        break;
     case AV_CODEC_ID_PCM_S8_PLANAR:
         n /= avctx->channels;
         for (c = 0; c < avctx->channels; c++) {
@@ -488,14 +499,6 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
             bytestream_get_buffer(&src, samples, n * sample_size);
         }
         break;
-    case AV_CODEC_ID_PCM_ZORK:
-        for (; n > 0; n--) {
-            int v = *src++;
-            if (v < 128)
-                v = 128 - v;
-            *samples++ = v;
-        }
-        break;
     case AV_CODEC_ID_PCM_ALAW:
     case AV_CODEC_ID_PCM_MULAW:
     case AV_CODEC_ID_PCM_VIDC:
@@ -512,13 +515,13 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
             dst_int32_t = (int32_t *)frame->extended_data[c];
             for (i = 0; i < n; i++) {
                 // extract low 20 bits and expand to 32 bits
-                *dst_int32_t++ =  (src[2]         << 28) |
+                *dst_int32_t++ =  ((uint32_t)src[2]<<28) |
                                   (src[1]         << 20) |
                                   (src[0]         << 12) |
                                  ((src[2] & 0x0F) <<  8) |
                                    src[1];
                 // extract high 20 bits and expand to 32 bits
-                *dst_int32_t++ =  (src[4]         << 24) |
+                *dst_int32_t++ =  ((uint32_t)src[4]<<24) |
                                   (src[3]         << 16) |
                                  ((src[2] & 0xF0) <<  8) |
                                   (src[4]         <<  4) |
@@ -534,9 +537,9 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
 
     if (avctx->codec_id == AV_CODEC_ID_PCM_F16LE ||
         avctx->codec_id == AV_CODEC_ID_PCM_F24LE) {
-        s->fdsp->vector_fmul_scalar((float *)frame->extended_data[0],
-                                    (const float *)frame->extended_data[0],
-                                    s->scale, FFALIGN(frame->nb_samples * avctx->channels, 4));
+        s->vector_fmul_scalar((float *)frame->extended_data[0],
+                              (const float *)frame->extended_data[0],
+                              s->scale, FFALIGN(frame->nb_samples * avctx->channels, 4));
         emms_c();
     }
 
@@ -547,7 +550,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
 
 #define PCM_ENCODER_0(id_, sample_fmt_, name_, long_name_)
 #define PCM_ENCODER_1(id_, sample_fmt_, name_, long_name_)                  \
-AVCodec ff_ ## name_ ## _encoder = {                                        \
+const AVCodec ff_ ## name_ ## _encoder = {                                  \
     .name         = #name_,                                                 \
     .long_name    = NULL_IF_CONFIG_SMALL(long_name_),                       \
     .type         = AVMEDIA_TYPE_AUDIO,                                     \
@@ -557,6 +560,7 @@ AVCodec ff_ ## name_ ## _encoder = {                                        \
     .capabilities = AV_CODEC_CAP_VARIABLE_FRAME_SIZE,                       \
     .sample_fmts  = (const enum AVSampleFormat[]){ sample_fmt_,             \
                                                    AV_SAMPLE_FMT_NONE },    \
+    .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,                          \
 }
 
 #define PCM_ENCODER_2(cf, id, sample_fmt, name, long_name)                  \
@@ -568,18 +572,18 @@ AVCodec ff_ ## name_ ## _encoder = {                                        \
 
 #define PCM_DECODER_0(id, sample_fmt, name, long_name)
 #define PCM_DECODER_1(id_, sample_fmt_, name_, long_name_)                  \
-AVCodec ff_ ## name_ ## _decoder = {                                        \
+const AVCodec ff_ ## name_ ## _decoder = {                                  \
     .name           = #name_,                                               \
     .long_name      = NULL_IF_CONFIG_SMALL(long_name_),                     \
     .type           = AVMEDIA_TYPE_AUDIO,                                   \
     .id             = AV_CODEC_ID_ ## id_,                                  \
     .priv_data_size = sizeof(PCMDecode),                                    \
     .init           = pcm_decode_init,                                      \
-    .close          = pcm_decode_close,                                     \
     .decode         = pcm_decode_frame,                                     \
     .capabilities   = AV_CODEC_CAP_DR1,                                     \
     .sample_fmts    = (const enum AVSampleFormat[]){ sample_fmt_,           \
                                                      AV_SAMPLE_FMT_NONE },  \
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,                         \
 }
 
 #define PCM_DECODER_2(cf, id, sample_fmt, name, long_name)                  \
@@ -623,7 +627,7 @@ PCM_CODEC  (PCM_U24BE,        AV_SAMPLE_FMT_S32, pcm_u24be,        "PCM unsigned
 PCM_CODEC  (PCM_U24LE,        AV_SAMPLE_FMT_S32, pcm_u24le,        "PCM unsigned 24-bit little-endian");
 PCM_CODEC  (PCM_U32BE,        AV_SAMPLE_FMT_S32, pcm_u32be,        "PCM unsigned 32-bit big-endian");
 PCM_CODEC  (PCM_U32LE,        AV_SAMPLE_FMT_S32, pcm_u32le,        "PCM unsigned 32-bit little-endian");
-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");
+PCM_DECODER(PCM_SGA,          AV_SAMPLE_FMT_U8,  pcm_sga,          "PCM SGA");